diff --git a/app/views/shared/_footer.html.erb b/app/views/shared/_footer.html.erb
index 987f1fef..686d95ec 100644
--- a/app/views/shared/_footer.html.erb
+++ b/app/views/shared/_footer.html.erb
@@ -1,3 +1,3 @@
-
+
diff --git a/config/application.rb b/config/application.rb
index a7548614..3eb027a3 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -17,7 +17,7 @@ module Greenlight
# Use custom error routes.
config.exceptions_app = routes
- config.loadbalanced_configuration = (ENV["USE_LOADBALANCED_CONFIGURATION"] == "true")
+ config.loadbalanced_configuration = ENV["LOADBALANCER_ENDPOINT"].present? && ENV["LOADBALANCER_SECRET"].present?
# Default credentials (test-install.blindsidenetworks.com/bigbluebutton).
diff --git a/config/initializers/html5.rb b/config/initializers/html5.rb
deleted file mode 100644
index 635767a5..00000000
--- a/config/initializers/html5.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-# frozen_string_literal: true
-
-# Send a request to check if the HTML5 client is enabled on the BigBlueButton server.
-uri = URI.parse(Rails.configuration.bigbluebutton_endpoint.gsub('bigbluebutton/api', 'html5client/check'))
-res = Net::HTTP.get_response(uri)
-
-# Set the HTML5 status.
-Rails.application.config.html5_enabled = (res.code.to_i == 200)
diff --git a/sample.env b/sample.env
index d60f565f..26973ac0 100644
--- a/sample.env
+++ b/sample.env
@@ -20,7 +20,7 @@ BIGBLUEBUTTON_SECRET=
#
# For in-depth steps on setting up a Google Login Provider, see:
#
-# http://docs.bigbluebutton.org/install/green-light.html#google-oauth
+# http://docs.bigbluebutton.org/install/greenlight.html#google-oauth2
#
# The GOOGLE_OAUTH2_HD variable is used to limit sign-in to a particular Google Apps hosted
# domain. This can be a string such as, 'domain.com'. If left blank, GreenLight will allow
@@ -33,14 +33,16 @@ GOOGLE_OAUTH2_HD=
#
# For in-depth steps on setting up a Twitter Login Provider, see:
#
-# http://docs.bigbluebutton.org/install/green-light.html#twitter-oauth
+# http://docs.bigbluebutton.org/install/greenlight.html#twitter-oauth2
#
TWITTER_ID=
TWITTER_SECRET=
# Set this to true if you want GreenLight to support user signup and login without
-# Omniauth. This will allow users to create an account at www.hostname.com/signup
-# and use that account to fully interact with GreenLight.
+# Omniauth. For more information, see:
+#
+# http://docs.bigbluebutton.org/install/greenlight.html#in-application-greenlight
+#
ALLOW_GREENLIGHT_ACCOUNTS=true
# Prefix for the applications root URL.
diff --git a/spec/controllers/errors_controller_spec.rb b/spec/controllers/errors_controller_spec.rb
new file mode 100644
index 00000000..a64976de
--- /dev/null
+++ b/spec/controllers/errors_controller_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require "rails_helper"
+
+describe ErrorsController, type: :controller do
+ describe "GET #not_found" do
+ it "returns not_found" do
+ get :not_found
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ describe "GET #unprocessable" do
+ it "returns unprocessable" do
+ get :unprocessable
+ expect(response).to have_http_status(422)
+ end
+ end
+
+ describe "GET #internal_error" do
+ it "returns internal_error" do
+ get :internal_error
+ expect(response).to have_http_status(500)
+ end
+ end
+end
diff --git a/spec/controllers/main_controller_spec.rb b/spec/controllers/main_controller_spec.rb
new file mode 100644
index 00000000..722cf796
--- /dev/null
+++ b/spec/controllers/main_controller_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require "rails_helper"
+
+describe MainController, type: :controller do
+ describe "GET #index" do
+ it "returns success" do
+ get :index
+ expect(response).to be_successful
+ end
+ end
+end
diff --git a/spec/controllers/rooms_controller_spec.rb b/spec/controllers/rooms_controller_spec.rb
new file mode 100644
index 00000000..90fc9893
--- /dev/null
+++ b/spec/controllers/rooms_controller_spec.rb
@@ -0,0 +1,189 @@
+# frozen_string_literal: true
+
+require "rails_helper"
+
+describe RoomsController, type: :controller do
+ describe "GET #show" do
+ before do
+ @user = create(:user)
+ @owner = create(:user)
+ end
+
+ it "should fetch recordings and room state if user is owner" do
+ @request.session[:user_id] = @owner.id
+
+ get :show, params: { room_uid: @owner.main_room }
+
+ expect(assigns(:recordings)).to eql(@owner.main_room.recordings)
+ expect(assigns(:is_running)).to eql(@owner.main_room.running?)
+ end
+
+ it "should render join if user is not owner" do
+ @request.session[:user_id] = @user.id
+
+ get :show, params: { room_uid: @owner.main_room }
+
+ expect(response).to render_template(:join)
+ end
+
+ it "should raise if room is not valid" do
+ expect do
+ get :show, params: { room_uid: "non_existent" }
+ end.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
+
+ describe "POST #create" do
+ before do
+ @owner = create(:user)
+ end
+
+ it "should create room with name" do
+ @request.session[:user_id] = @owner.id
+ name = Faker::Pokemon.name
+ post :create, params: { room: { name: name } }
+
+ r = @owner.secondary_rooms.last
+ expect(r.name).to eql(name)
+ expect(r.owner).to eql(@owner)
+ expect(response).to redirect_to(r)
+ end
+
+ it "it should redirect to root if not logged in" do
+ expect do
+ name = Faker::Pokemon.name
+ post :create, params: { room: { name: name } }
+ end.to change { Room.count }.by(0)
+
+ expect(response).to redirect_to(root_path)
+ end
+ end
+
+ describe "POST #join" do
+ before do
+ @user = create(:user)
+ @owner = create(:user)
+ @room = @owner.main_room
+
+ allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_meeting_info).and_return(
+ moderatorPW: "modpass",
+ attendeePW: "attpass",
+ )
+ end
+
+ it "should use account name if user is logged in and meeting running" do
+ allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(true)
+
+ @request.session[:user_id] = @user.id
+ post :join, params: { room_uid: @room, join_name: @user.name }
+
+ expect(response).to redirect_to(@user.main_room.join_path(@user.name, {}, @user.uid))
+ end
+
+ it "should use join name if user is not logged in and meeting running" do
+ allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(true)
+
+ post :join, params: { room_uid: @room, join_name: "Join Name" }
+
+ expect(response).to redirect_to(@user.main_room.join_path("Join Name", {}))
+ end
+
+ it "should render wait if meeting isn't running" do
+ allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(false)
+
+ @request.session[:user_id] = @user.id
+ post :join, params: { room_uid: @room, join_name: @user.name }
+
+ expect(response).to render_template(:wait)
+ end
+
+ it "should join owner as moderator if meeting running" do
+ allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(true)
+
+ @request.session[:user_id] = @owner.id
+ post :join, params: { room_uid: @room, join_name: @owner.name }
+
+ expect(response).to redirect_to(@user.main_room.join_path(@owner.name, { user_is_moderator: true }, @owner.uid))
+ end
+ end
+
+ describe "DELETE #destroy" do
+ before do
+ @user = create(:user)
+ @secondary_room = create(:room, owner: @user)
+ end
+
+ it "should delete room and redirect to main room" do
+ @request.session[:user_id] = @user.id
+
+ expect do
+ delete :destroy, params: { room_uid: @secondary_room }
+ end.to change { Room.count }.by(-1)
+
+ expect(response).to redirect_to(@user.main_room)
+ end
+
+ it "should not delete room if not owner" do
+ random_user = create(:user)
+ @request.session[:user_id] = random_user.id
+
+ expect do
+ delete :destroy, params: { room_uid: @user.main_room }
+ end.to change { Room.count }.by(0)
+ end
+
+ it "should not delete room not logged in" do
+ expect do
+ delete :destroy, params: { room_uid: @user.main_room }
+ end.to change { Room.count }.by(0)
+ end
+ end
+
+ describe "POST #start" do
+ before do
+ @user = create(:user)
+ @other_room = create(:room)
+
+ allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_meeting_info).and_return(
+ moderatorPW: "modpass",
+ attendeePW: "attpass",
+ )
+ end
+
+ it "should redirect to join path if owner" do
+ @request.session[:user_id] = @user.id
+ post :start, params: { room_uid: @user.main_room }
+
+ expect(response).to redirect_to(@user.main_room.join_path(@user.name, { user_is_moderator: true }, @user.uid))
+ end
+
+ it "should bring to room if not owner" do
+ @request.session[:user_id] = @user.id
+ post :start, params: { room_uid: @other_room }
+
+ expect(response).to redirect_to(@user.main_room)
+ end
+
+ it "should bring to root if not authenticated" do
+ post :start, params: { room_uid: @other_room }
+
+ expect(response).to redirect_to(root_path)
+ end
+ end
+
+ describe "POST #home" do
+ before do
+ @user = create(:user)
+ @secondary_room = create(:room, owner: @user)
+ end
+
+ it "should change users home room" do
+ @request.session[:user_id] = @user.id
+ post :home, params: { room_uid: @secondary_room }
+ @user.reload
+
+ expect(@user.main_room).to eql(@secondary_room)
+ expect(response).to redirect_to(@secondary_room)
+ end
+ end
+end
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
new file mode 100644
index 00000000..8713b215
--- /dev/null
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -0,0 +1,92 @@
+# frozen_string_literal: true
+
+require "rails_helper"
+
+describe SessionsController, type: :controller do
+ before(:all) do
+ @user = create(:user, password: "example", password_confirmation: "example")
+ end
+
+ describe "GET #destroy" do
+ before(:each) do
+ @request.session[:user_id] = @user.id
+ get :destroy
+ end
+
+ it "should logout user" do
+ expect(@request.session[:user_id]).to be_nil
+ end
+
+ it "should redirect to root" do
+ expect(response).to redirect_to(root_path)
+ end
+ end
+
+ describe "POST #create" do
+ it "should login user in if credentials valid" do
+ post :create, params: {
+ session: {
+ email: @user.email,
+ password: "example",
+ },
+ }
+
+ expect(@request.session[:user_id]).to eql(@user.id)
+ end
+
+ it "should not login user in if credentials invalid" do
+ post :create, params: {
+ session: {
+ email: @user.email,
+ password: "invalid",
+ },
+ }
+
+ expect(@request.session[:user_id]).to be_nil
+ end
+ end
+
+ describe "GET/POST #omniauth" do
+ before(:all) do
+ OmniAuth.config.test_mode = true
+
+ OmniAuth.config.mock_auth[:twitter] = OmniAuth::AuthHash.new(
+ provider: "twitter",
+ uid: "twitter-user",
+ info: {
+ email: "user@twitter.com",
+ name: "Twitter User",
+ nickname: "username",
+ image: "example.png",
+ },
+ )
+
+ OmniAuth.config.on_failure = proc { |env|
+ OmniAuth::FailureEndpoint.new(env).redirect_to_failure
+ }
+ end
+
+ it "should create and login user with omniauth" do
+ request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter]
+ get :omniauth, params: { provider: :twitter }
+
+ u = User.last
+ expect(u.provider).to eql("twitter")
+ expect(u.email).to eql("user@twitter.com")
+ expect(@request.session[:user_id]).to eql(u.id)
+ end
+
+ it "should redirect to root on invalid omniauth login" do
+ request.env["omniauth.auth"] = :invalid_credentials
+ get :omniauth, params: { provider: :twitter }
+
+ expect(response).to redirect_to(root_path)
+ end
+
+ it "should not create session without omniauth env set" do
+ get :omniauth, params: { provider: 'google' }
+
+ expect(response).to redirect_to(root_path)
+ end
+ end
+end
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
new file mode 100644
index 00000000..6a4b8c10
--- /dev/null
+++ b/spec/controllers/users_controller_spec.rb
@@ -0,0 +1,91 @@
+# frozen_string_literal: true
+
+require "rails_helper"
+
+def random_valid_user_params
+ pass = Faker::Internet.password(8)
+ {
+ user: {
+ name: Faker::Name.first_name,
+ email: Faker::Internet.email,
+ password: pass,
+ password_confirmation: pass,
+ },
+ }
+end
+
+describe UsersController, type: :controller do
+ let(:invalid_params) do
+ {
+ user: {
+ name: "Invalid",
+ email: "example.com",
+ password: "pass",
+ passwrd_confirmation: "invalid",
+ },
+ }
+ end
+
+ describe "GET #new" do
+ it "assigns a blank user to the view" do
+ get :new
+ expect(assigns(:user)).to be_a_new(User)
+ end
+ end
+
+ describe "POST #create" do
+ it "redirects to user room on succesful create" do
+ params = random_valid_user_params
+ post :create, params: params
+
+ u = User.find_by(name: params[:user][:name], email: params[:user][:email])
+
+ expect(u).to_not be_nil
+ expect(u.name).to eql(params[:user][:name])
+ expect(response).to redirect_to(room_path(u.main_room))
+ end
+
+ it "redirects to main room if already authenticated" do
+ user = create(:user)
+ @request.session[:user_id] = user.id
+
+ post :create, params: random_valid_user_params
+ expect(response).to redirect_to(room_path(user.main_room))
+ end
+
+ it "user saves with greenlight provider" do
+ params = random_valid_user_params
+ post :create, params: params
+
+ u = User.find_by(name: params[:user][:name], email: params[:user][:email])
+
+ expect(u.provider).to eql("greenlight")
+ end
+
+ it "renders #new on unsuccessful save" do
+ post :create, params: invalid_params
+
+ expect(response).to render_template(:new)
+ end
+ end
+
+ describe "PATCH #update" do
+ it "properly updates user attributes" do
+ user = create(:user)
+
+ params = random_valid_user_params
+ patch :update, params: params.merge!(user_uid: user)
+ user.reload
+
+ expect(user.name).to eql(params[:user][:name])
+ expect(user.email).to eql(params[:user][:email])
+ end
+
+ it "renders #edit on unsuccessful save" do
+ @user = create(:user)
+
+ patch :update, params: invalid_params.merge!(user_uid: @user)
+ expect(response).to render_template(:edit)
+ end
+ end
+end
diff --git a/spec/factories.rb b/spec/factories.rb
index d99ff9d0..69a03c04 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -4,7 +4,7 @@ FactoryBot.define do
factory :user do
password = Faker::Internet.password(8)
- provider { %w(greenlight google twitter).sample }
+ provider { %w(google twitter).sample }
uid { rand(10**8) }
name { Faker::Name.first_name }
username { Faker::Internet.user_name }
diff --git a/spec/models/room_spec.rb b/spec/models/room_spec.rb
index 12f0df90..6cb8a7d6 100644
--- a/spec/models/room_spec.rb
+++ b/spec/models/room_spec.rb
@@ -78,11 +78,10 @@ describe Room, type: :model do
endpoint = Rails.configuration.bigbluebutton_endpoint
secret = Rails.configuration.bigbluebutton_secret
fullname = "fullName=Example"
- html = Rails.configuration.html5_enabled ? "&joinViaHtml5=true" : ""
meeting_id = "&meetingID=#{@room.bbb_id}"
password = "&password=testpass"
- query = fullname + html + meeting_id + password
+ query = fullname + meeting_id + password
checksum_string = "join#{query + secret}"
checksum = OpenSSL::Digest.digest('sha1', checksum_string).unpack("H*").first
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index cb0b497c..af3c9aed 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -59,8 +59,8 @@ describe User, type: :model do
end
context '#from_omniauth' do
- it "should create user from omniauth" do
- auth = {
+ let(:auth) do
+ {
"uid" => "123456789",
"provider" => "twitter",
"info" => {
@@ -70,7 +70,9 @@ describe User, type: :model do
"image" => "example.png",
},
}
+ end
+ it "should create user from omniauth" do
expect do
user = User.from_omniauth(auth)