diff --git a/.rubocop.yml b/.rubocop.yml
index c249f85a..0e5d326b 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -409,6 +409,9 @@ Style/StringLiteralsInInterpolation:
- single_quotes
- double_quotes
+Style/Strip:
+ Enabled: true
+
Layout/SpaceAroundBlockParameters:
EnforcedStyleInsidePipes: no_space
SupportedStylesInsidePipes:
@@ -1092,9 +1095,6 @@ Performance/FixedSize:
Performance/FlatMap:
EnabledForFlattenWithoutParams: false
-Performance/LstripRstrip:
- Enabled: true
-
Performance/RangeInclude:
Enabled: true
diff --git a/.travis.yml b/.travis.yml
index b83e18ac..4ea74d2b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,7 +15,7 @@ jobs:
- stage: test
name: rspec
- script: bundle exec rspec
+ script: gem install bundler & bundle exec rspec
if: env(CD_TEST_IGNORE) IS NOT present
- stage: build
diff --git a/Gemfile b/Gemfile
index 245a0094..7da2a440 100644
--- a/Gemfile
+++ b/Gemfile
@@ -78,7 +78,6 @@ end
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platform: :mri
-
# Environment configuration.
gem 'dotenv-rails'
end
diff --git a/app/controllers/account_activations_controller.rb b/app/controllers/account_activations_controller.rb
index cb7515c9..9e7eee79 100644
--- a/app/controllers/account_activations_controller.rb
+++ b/app/controllers/account_activations_controller.rb
@@ -27,7 +27,7 @@ class AccountActivationsController < ApplicationController
# GET /account_activations/edit
def edit
- if @user && !@user.email_verified? && @user.authenticated?(:activation, params[:token])
+ if @user && !@user.activated? && @user.authenticated?(:activation, params[:token])
@user.activate
flash[:success] = I18n.t("verify.activated") + " " + I18n.t("verify.signin")
@@ -40,7 +40,7 @@ class AccountActivationsController < ApplicationController
# GET /account_activations/resend
def resend
- if @user.email_verified
+ if @user.activated?
flash[:alert] = I18n.t("verify.already_verified")
else
begin
@@ -67,10 +67,10 @@ class AccountActivationsController < ApplicationController
end
def email_params
- params.require(:email).permit(:token)
+ params.require(:email).permit(:email, :token)
end
def find_user
- @user = User.find_by!(email: params[:email], provider: "greenlight")
+ @user = User.find_by!(email: params[:email], provider: @user_domain)
end
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 4dc368a5..cd40cd46 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -23,6 +23,7 @@ class ApplicationController < ActionController::Base
before_action :migration_error?
before_action :set_locale
+ before_action :set_user_domain
# Force SSL for loadbalancer configurations.
before_action :redirect_to_https
@@ -68,16 +69,11 @@ class ApplicationController < ActionController::Base
# Determines if the BigBlueButton endpoint is configured (or set to default).
def bigbluebutton_endpoint_default?
- return false if loadbalanced_configuration?
+ return false if Rails.configuration.loadbalanced_configuration
Rails.configuration.bigbluebutton_endpoint_default == Rails.configuration.bigbluebutton_endpoint
end
helper_method :bigbluebutton_endpoint_default?
- def loadbalanced_configuration?
- Rails.configuration.loadbalanced_configuration
- end
- helper_method :loadbalanced_configuration?
-
def recording_thumbnails?
Rails.configuration.recording_thumbnails
end
@@ -106,6 +102,17 @@ class ApplicationController < ActionController::Base
end
def redirect_to_https
- redirect_to protocol: "https://" if loadbalanced_configuration? && request.headers["X-Forwarded-Proto"] == "http"
+ if Rails.configuration.loadbalanced_configuration && request.headers["X-Forwarded-Proto"] == "http"
+ redirect_to protocol: "https://"
+ end
end
+
+ def set_user_domain
+ @user_domain = if Rails.env.test? || !Rails.configuration.loadbalanced_configuration
+ "greenlight"
+ else
+ parse_user_domain(request.env["SERVER_NAME"])
+ end
+ end
+ helper_method :set_user_domain
end
diff --git a/app/controllers/password_resets_controller.rb b/app/controllers/password_resets_controller.rb
index df7e700f..a3e5c037 100644
--- a/app/controllers/password_resets_controller.rb
+++ b/app/controllers/password_resets_controller.rb
@@ -84,7 +84,7 @@ class PasswordResetsController < ApplicationController
# Confirms a valid user.
def valid_user
- unless current_user&.email_verified && current_user.authenticated?(:reset, params[:id])
+ unless current_user&.activated? && current_user.authenticated?(:reset, params[:id])
redirect_to root_url
end
end
diff --git a/app/controllers/rooms_controller.rb b/app/controllers/rooms_controller.rb
index 234d8811..f6a2e6c9 100644
--- a/app/controllers/rooms_controller.rb
+++ b/app/controllers/rooms_controller.rb
@@ -224,12 +224,12 @@ class RoomsController < ApplicationController
def validate_verified_email
if current_user
- redirect_to account_activation_path(current_user) unless current_user.email_verified
+ redirect_to account_activation_path(current_user) unless current_user.activated?
end
end
def verify_room_owner_verified
- unless @room.owner.email_verified
+ unless @room.owner.activated?
flash[:alert] = t("room.unavailable")
if current_user
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 96128b7b..62c8f613 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -27,18 +27,13 @@ class SessionsController < ApplicationController
# POST /users/login
def create
- user = User.find_by(email: session_params[:email])
- if user && !user.greenlight_account?
- redirect_to root_path, alert: I18n.t("invalid_login_method")
- elsif user.try(:authenticate, session_params[:password])
- if user.email_verified
- login(user)
- else
- redirect_to(account_activation_path(email: user.email)) && return
- end
- else
- redirect_to root_path, alert: I18n.t("invalid_credentials")
- end
+ user = User.find_by(email: session_params[:email], provider: @user_domain)
+ redirect_to(root_path, alert: I18n.t("invalid_user")) && return unless user
+ redirect_to(root_path, alert: I18n.t("invalid_login_method")) && return unless user.greenlight_account?
+ redirect_to(root_path, alert: I18n.t("invalid_credentials")) && return unless user.try(:authenticate,
+ session_params[:password])
+ redirect_to(account_activation_path(email: user.email)) && return unless user.activated?
+ login(user)
end
# GET/POST /auth/:provider/callback
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 32e5f5bf..aea7b4ba 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -28,40 +28,24 @@ class UsersController < ApplicationController
return unless Rails.configuration.allow_user_signup
@user = User.new(user_params)
- @user.provider = "greenlight"
+ @user.provider = @user_domain
- # Check if user already exists
- if User.exists?(email: user_params[:email], provider: @user.provider)
- existing_user = User.find_by!(email: user_params[:email], provider: @user.provider)
- if Rails.configuration.enable_email_verification && !existing_user.email_verified?
- # User exists but is not verified
- redirect_to(account_activation_path(email: existing_user.email)) && return
- else
- # User already exists and is verified
- # Attempt to save so that the correct errors appear
- @user.save
+ # Handle error on user creation.
+ render(:new) && return unless @user.save
- render(:new) && return
- end
- elsif Rails.configuration.enable_email_verification && @user.save
- begin
- @user.send_activation_email(verification_link)
- rescue => e
- logger.error "Error in email delivery: #{e}"
- flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
- else
- flash[:success] = I18n.t("email_sent")
- end
+ # Sign in automatically if email verification is disabled.
+ login(@user) && return unless Rails.configuration.enable_email_verification
- redirect_to(root_path) && return
- elsif @user.save
- # User doesn't exist and email verification is turned off
- @user.activate
- login(@user)
+ # Start email verification and redirect to root.
+ begin
+ @user.send_activation_email(verification_link)
+ rescue => e
+ logger.error "Error in email delivery: #{e}"
+ flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
else
- # Handle error on user creation.
- render(:new) && return
+ flash[:success] = I18n.t("email_sent")
end
+ redirect_to(root_path)
end
# GET /signup
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index fb4886f6..f8b99126 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -16,8 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see .
+require 'bbb_api'
+
module ApplicationHelper
include MeetingsHelper
+ include BbbApi
# Gets all configured omniauth providers.
def configured_providers
@@ -71,4 +74,14 @@ module ApplicationHelper
markdown.render(text).html_safe
end
+
+ def allow_greenlight_accounts?
+ return true unless Rails.configuration.loadbalanced_configuration
+ return false unless Rails.configuration.allow_user_signup
+ # No need to retrieve the provider info if the provider is whitelisted
+ return true if launcher_allow_user_signup_whitelisted?(@user_domain)
+ # Proceed with retrieving the provider info
+ provider_info = retrieve_provider_info(@user_domain, 'api2', 'getUserGreenlightCredentials')
+ provider_info['provider'] == 'greenlight'
+ end
end
diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb
index a483a2cd..f0d63d62 100644
--- a/app/helpers/sessions_helper.rb
+++ b/app/helpers/sessions_helper.rb
@@ -31,7 +31,7 @@ module SessionsHelper
# If email verification is disabled, or the user has verified, go to their room
def check_email_verified(user)
- if !Rails.configuration.enable_email_verification || user.email_verified
+ if user.activated?
redirect_to user.main_room
else
redirect_to resend_path
@@ -48,24 +48,24 @@ module SessionsHelper
@current_user ||= User.find_by(id: session[:user_id])
end
- def generate_checksum(customer_name, redirect_url, secret)
- string = customer_name + redirect_url + secret
+ def generate_checksum(user_domain, redirect_url, secret)
+ string = user_domain + redirect_url + secret
OpenSSL::Digest.digest('sha1', string).unpack("H*").first
end
- def parse_customer_name(hostname)
- provider = hostname.split('.')
- provider.first == 'www' ? provider.second : provider.first
+ def parse_user_domain(hostname)
+ hostname.split('.').first
end
def omniauth_options(env)
gl_redirect_url = (Rails.env.production? ? "https" : env["rack.url_scheme"]) + "://" + env["SERVER_NAME"] + ":" +
env["SERVER_PORT"]
- env['omniauth.strategy'].options[:customer] = parse_customer_name env["SERVER_NAME"]
+ user_domain = parse_user_domain(env["SERVER_NAME"])
+ env['omniauth.strategy'].options[:customer] = user_domain
env['omniauth.strategy'].options[:gl_redirect_url] = gl_redirect_url
env['omniauth.strategy'].options[:default_callback_url] = Rails.configuration.gl_callback_url
- env['omniauth.strategy'].options[:checksum] = generate_checksum parse_customer_name(env["SERVER_NAME"]),
- gl_redirect_url, Rails.configuration.launcher_secret
+ env['omniauth.strategy'].options[:checksum] = generate_checksum(user_domain, gl_redirect_url,
+ Rails.configuration.launcher_secret)
end
def google_omniauth_hd(env, hd)
diff --git a/app/models/concerns/api_concern.rb b/app/models/concerns/api_concern.rb
index e45ae312..8c46d617 100644
--- a/app/models/concerns/api_concern.rb
+++ b/app/models/concerns/api_concern.rb
@@ -19,77 +19,6 @@
module APIConcern
extend ActiveSupport::Concern
- RETURNCODE_SUCCESS = "SUCCESS"
-
- def bbb_endpoint
- Rails.configuration.bigbluebutton_endpoint
- end
-
- def bbb_secret
- Rails.configuration.bigbluebutton_secret
- end
-
- # Sets a BigBlueButtonApi object for interacting with the API.
- def bbb
- @bbb ||= if Rails.configuration.loadbalanced_configuration
- if instance_of? Room
- # currently in the Room Model
- lb_user = retrieve_loadbalanced_credentials(owner.provider)
- elsif instance_of? User
- # currently in the User Model
- lb_user = retrieve_loadbalanced_credentials(provider)
- end
- BigBlueButton::BigBlueButtonApi.new(remove_slash(lb_user["apiURL"]), lb_user["secret"], "0.8")
- else
- BigBlueButton::BigBlueButtonApi.new(remove_slash(bbb_endpoint), bbb_secret, "0.8")
- end
- end
-
- # Rereives the loadbalanced BigBlueButton credentials for a user.
- def retrieve_loadbalanced_credentials(provider)
- # Include Omniauth accounts under the Greenlight provider.
- provider = "greenlight" if Rails.configuration.providers.include?(provider.to_sym)
-
- # Build the URI.
- uri = encode_bbb_url(
- Rails.configuration.loadbalancer_endpoint + "getUser",
- Rails.configuration.loadbalancer_secret,
- name: provider
- )
-
- # Make the request.
- http = Net::HTTP.new(uri.host, uri.port)
- http.use_ssl = (uri.scheme == 'https')
- response = http.get(uri.request_uri)
-
- unless response.is_a?(Net::HTTPSuccess)
- raise "Error retrieving provider credentials: #{response.code} #{response.message}"
- end
-
- # Parse XML.
- doc = XmlSimple.xml_in(response.body, 'ForceArray' => false)
-
- # Return the user credentials if the request succeeded on the loadbalancer.
- return doc['user'] if doc['returncode'] == RETURNCODE_SUCCESS
-
- raise "User with provider #{provider} does not exist." if doc['messageKey'] == "noSuchUser"
- raise "API call #{url} failed with #{doc['messageKey']}."
- end
-
- # Builds a request to retrieve credentials from the load balancer.
- def encode_bbb_url(base_url, secret, params)
- encoded_params = OAuth::Helper.normalize(params)
- string = "getUser" + encoded_params + secret
- checksum = OpenSSL::Digest.digest('sha1', string).unpack("H*").first
-
- URI.parse("#{base_url}?#{encoded_params}&checksum=#{checksum}")
- end
-
- # Removes trailing forward slash from a URL.
- def remove_slash(s)
- s.nil? ? nil : s.chomp("/")
- end
-
# Format recordings to match their current use in the app
def format_recordings(api_res)
api_res[:recordings].each do |r|
diff --git a/app/models/room.rb b/app/models/room.rb
index 224e1d64..72c756e4 100644
--- a/app/models/room.rb
+++ b/app/models/room.rb
@@ -16,8 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see .
+require 'bbb_api'
+
class Room < ApplicationRecord
include ::APIConcern
+ include ::BbbApi
before_create :setup
diff --git a/app/models/user.rb b/app/models/user.rb
index f234f7ff..342f216d 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -16,13 +16,15 @@
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see .
+require 'bbb_api'
+
class User < ApplicationRecord
include ::APIConcern
+ include ::BbbApi
- attr_accessor :reset_token, :activation_token
- after_create :create_home_room_if_verified
+ attr_accessor :reset_token
+ after_create :initialize_main_room
before_save { email.try(:downcase!) }
- before_create :create_activation_digest
before_destroy :destroy_rooms
@@ -125,8 +127,11 @@ class User < ApplicationRecord
def activate
update_attribute(:email_verified, true)
update_attribute(:activated_at, Time.zone.now)
+ end
- initialize_main_room
+ def activated?
+ return true unless Rails.configuration.enable_email_verification
+ email_verified
end
def send_activation_email(url)
@@ -180,7 +185,17 @@ class User < ApplicationRecord
end
def greenlight_account?
- provider == "greenlight"
+ return provider == "greenlight" unless Rails.configuration.loadbalanced_configuration
+ # No need to retrive the provider info if the provider is whitelisted
+ return true if launcher_allow_user_signup_whitelisted?(provider)
+ # Proceed with fetching the provider info
+ provider_info = retrieve_provider_info(provider, 'api2', 'getUserGreenlightCredentials')
+ provider_info['provider'] == 'greenlight'
+ end
+
+ def activation_token
+ # Create the token.
+ create_reset_activation_digest(User.new_token)
end
def self.digest(string)
@@ -195,10 +210,11 @@ class User < ApplicationRecord
private
- def create_activation_digest
- # Create the token and digest.
- self.activation_token = User.new_token
- self.activation_digest = User.digest(activation_token)
+ def create_reset_activation_digest(token)
+ # Create the digest and persist it.
+ self.activation_digest = User.digest(token)
+ save
+ token
end
# Destory a users rooms when they are removed.
@@ -206,16 +222,9 @@ class User < ApplicationRecord
rooms.destroy_all
end
- # Assigns the user a BigBlueButton id and a home room if verified
- def create_home_room_if_verified
- self.uid = "gl-#{(0...12).map { (65 + rand(26)).chr }.join.downcase}"
-
- initialize_main_room if email_verified
- save
- end
-
# Initializes a room for the user and assign a BigBlueButton user id.
def initialize_main_room
+ self.uid = "gl-#{(0...12).map { (65 + rand(26)).chr }.join.downcase}"
self.main_room = Room.create!(owner: self, name: I18n.t("home_room"))
save
end
diff --git a/app/views/shared/_header.html.erb b/app/views/shared/_header.html.erb
index 12526319..ad779d40 100755
--- a/app/views/shared/_header.html.erb
+++ b/app/views/shared/_header.html.erb
@@ -56,21 +56,21 @@
<% else %>
- <% if Rails.configuration.omniauth_bn_launcher %>
- <%= link_to t("login"), omniauth_login_url(:bn_launcher), :class => "btn btn-pill btn-outline-primary mx-2" %>
- <% elsif Rails.configuration.omniauth_ldap %>
- <%= link_to t("login"), omniauth_login_url(:ldap), :class => "btn btn-pill btn-outline-primary mx-2" %>
- <% else %>
+ <% if Rails.configuration.omniauth_ldap %>
+ <%= link_to t("login"), omniauth_login_url(:ldap), :class => "btn btn-pill btn-outline-primary mx-2" %>
+ <% elsif allow_greenlight_accounts? %>
<%= link_to t("login"), "#loginModal", :class => "btn btn-pill btn-outline-primary mx-2", "data-toggle": "modal" %>
+ <% else %>
+ <%= link_to t("login"), omniauth_login_url(:bn_launcher), :class => "btn btn-pill btn-outline-primary mx-2" %>
<% end %>
- <% if allow_user_signup? %>
- <%= link_to t("signup.title"), signup_path, :class => "btn btn-pill btn-outline-primary mx-2" %>
- <% end %>
+ <% if allow_user_signup? && allow_greenlight_accounts? %>
+ <%= link_to t("signup.title"), signup_path, :class => "btn btn-pill btn-outline-primary mx-2" %>
+ <% end %>
- <%= render "shared/modals/login_modal" %>
- <% end %>
-
-
-
+ <%= render "shared/modals/login_modal" %>
+ <% end %>
+
+
+
diff --git a/app/views/shared/components/_resend_button.html.erb b/app/views/shared/components/_resend_button.html.erb
index 0662bb7f..368b347f 100644
--- a/app/views/shared/components/_resend_button.html.erb
+++ b/app/views/shared/components/_resend_button.html.erb
@@ -14,5 +14,5 @@
%>
- <%= button_to t("verify.resend"), resend_email_path, params: { email_verified: false }, class: "btn btn-primary btn-space" %>
+ <%= button_to t("verify.resend"), resend_email_path, params: { email: params['email'], email_verified: false }, class: "btn btn-primary btn-space" %>
diff --git a/config/application.rb b/config/application.rb
index 7c451837..cd0f3457 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -48,22 +48,22 @@ module Greenlight
config.gl_callback_url = ENV["GL_CALLBACK_URL"]
# Default credentials (test-install.blindsidenetworks.com/bigbluebutton).
- config.bigbluebutton_endpoint_default = "http://test-install.blindsidenetworks.com/bigbluebutton/api/"
+ config.bigbluebutton_endpoint_default = "http://test-install.blindsidenetworks.com/bigbluebutton/"
config.bigbluebutton_secret_default = "8cd8ef52e8e101574e400365b55e11a6"
- # Setup BigBlueButton configuration.
+ # Use standalone BigBlueButton server.
+ config.bigbluebutton_endpoint = ENV["BIGBLUEBUTTON_ENDPOINT"] || config.bigbluebutton_endpoint_default
+ config.bigbluebutton_secret = ENV["BIGBLUEBUTTON_SECRET"] || config.bigbluebutton_secret_default
+
+ # Fix endpoint format if required.
+ config.bigbluebutton_endpoint += "api/" unless config.bigbluebutton_endpoint.ends_with?('api/')
+
if config.loadbalanced_configuration
- # Fetch credentials from a loadbalancer based on provider.
+ # Settings for fetching credentials from a loadbalancer based on provider.
config.loadbalancer_endpoint = ENV["LOADBALANCER_ENDPOINT"]
config.loadbalancer_secret = ENV["LOADBALANCER_SECRET"]
config.launcher_secret = ENV["LAUNCHER_SECRET"]
- else
- # Use standalone BigBlueButton server.
- config.bigbluebutton_endpoint = ENV["BIGBLUEBUTTON_ENDPOINT"] || config.bigbluebutton_endpoint_default
- config.bigbluebutton_secret = ENV["BIGBLUEBUTTON_SECRET"] || config.bigbluebutton_secret_default
-
- # Fix endpoint format if required.
- config.bigbluebutton_endpoint += "api/" unless config.bigbluebutton_endpoint.ends_with?('api/')
+ config.launcher_allow_user_signup = ENV["LAUNCHER_ALLOW_GREENLIGHT_ACCOUNTS"]
end
# Specify the email address that all mail is sent from
diff --git a/config/database.yml b/config/database.yml
index 5421b6e0..77296e69 100644
--- a/config/database.yml
+++ b/config/database.yml
@@ -10,9 +10,9 @@ development:
test:
<<: *default
adapter: sqlite3
- database: db/development.sqlite3
+ database: db/test.sqlite3
-# Use sqlite in production by default. Greenlight supports
+# Use sqlite in production by default. Greenlight supports
production:
<<: *default
adapter: <%= ENV['DB_ADAPTER'] || 'sqlite3' %>
diff --git a/config/environments/test.rb b/config/environments/test.rb
index 0c28efe9..5f68c35b 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -41,4 +41,12 @@ Rails.application.configure do
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
+
+ # Default credentials (test-install.blindsidenetworks.com/bigbluebutton).
+ config.bigbluebutton_endpoint_default = 'http://bbb.example.com/bigbluebutton/api/'
+ config.bigbluebutton_secret_default = 'secret'
+
+ # Use standalone BigBlueButton server.
+ config.bigbluebutton_endpoint = config.bigbluebutton_endpoint_default
+ config.bigbluebutton_secret = config.bigbluebutton_secret_default
end
diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb
index 6d56e439..1be07628 100644
--- a/config/initializers/application_controller_renderer.rb
+++ b/config/initializers/application_controller_renderer.rb
@@ -4,7 +4,7 @@
# ActiveSupport::Reloader.to_prepare do
# ApplicationController.renderer.defaults.merge!(
-# http_host: 'example.org',
+# http_host: 'example.com',
# https: false
# )
# end
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
index c303e150..e3e54a78 100644
--- a/config/initializers/omniauth.rb
+++ b/config/initializers/omniauth.rb
@@ -1,17 +1,17 @@
# frozen_string_literal: true
# List of supported Omniauth providers.
-Rails.application.config.providers = [:google, :twitter, :microsoft_office365, :ldap]
+Rails.application.config.providers = []
# Set which providers are configured.
-Rails.application.config.omniauth_google = ENV['GOOGLE_OAUTH2_ID'].present? && ENV['GOOGLE_OAUTH2_SECRET'].present?
-Rails.application.config.omniauth_twitter = ENV['TWITTER_ID'].present? && ENV['TWITTER_SECRET'].present?
-Rails.application.config.omniauth_microsoft_office365 = ENV['OFFICE365_KEY'].present? &&
- ENV['OFFICE365_SECRET'].present?
+Rails.application.config.omniauth_bn_launcher = Rails.configuration.loadbalanced_configuration
Rails.application.config.omniauth_ldap = ENV['LDAP_SERVER'].present? && ENV['LDAP_UID'].present? &&
ENV['LDAP_BASE'].present? && ENV['LDAP_BIND_DN'].present? &&
ENV['LDAP_PASSWORD'].present?
-Rails.application.config.omniauth_bn_launcher = Rails.configuration.loadbalanced_configuration
+Rails.application.config.omniauth_twitter = ENV['TWITTER_ID'].present? && ENV['TWITTER_SECRET'].present?
+Rails.application.config.omniauth_google = ENV['GOOGLE_OAUTH2_ID'].present? && ENV['GOOGLE_OAUTH2_SECRET'].present?
+Rails.application.config.omniauth_microsoft_office365 = ENV['OFFICE365_KEY'].present? &&
+ ENV['OFFICE365_SECRET'].present?
# If LDAP is enabled, override and disable allow_user_signup.
Rails.application.config.allow_user_signup = false if Rails.application.config.omniauth_ldap
@@ -32,27 +32,39 @@ Rails.application.config.middleware.use OmniAuth::Builder do
client_secret: ENV['CLIENT_SECRET'],
client_options: { site: ENV['BN_LAUNCHER_REDIRECT_URI'] },
setup: SETUP_PROC
+ elsif Rails.configuration.omniauth_ldap
+ Rails.application.config.providers << :ldap
+
+ provider :ldap,
+ host: ENV['LDAP_SERVER'],
+ port: ENV['LDAP_PORT'] || '389',
+ method: ENV['LDAP_METHOD'].blank? ? :plain : ENV['LDAP_METHOD'].to_sym,
+ allow_username_or_email_login: true,
+ uid: ENV['LDAP_UID'],
+ base: ENV['LDAP_BASE'],
+ bind_dn: ENV['LDAP_BIND_DN'],
+ password: ENV['LDAP_PASSWORD']
+ else
+ if Rails.configuration.omniauth_twitter
+ Rails.application.config.providers << :twitter
+
+ provider :twitter, ENV['TWITTER_ID'], ENV['TWITTER_SECRET']
+ end
+ if Rails.configuration.omniauth_google
+ Rails.application.config.providers << :google
+
+ provider :google_oauth2, ENV['GOOGLE_OAUTH2_ID'], ENV['GOOGLE_OAUTH2_SECRET'],
+ scope: %w(profile email),
+ access_type: 'online',
+ name: 'google',
+ setup: SETUP_PROC
+ end
+ if Rails.configuration.omniauth_microsoft_office365
+ Rails.application.config.providers << :microsoft_office365
+
+ provider :microsoft_office365, ENV['OFFICE365_KEY'], ENV['OFFICE365_SECRET']
+ end
end
-
- provider :twitter, ENV['TWITTER_ID'], ENV['TWITTER_SECRET']
-
- provider :google_oauth2, ENV['GOOGLE_OAUTH2_ID'], ENV['GOOGLE_OAUTH2_SECRET'],
- scope: %w(profile email),
- access_type: 'online',
- name: 'google',
- setup: SETUP_PROC
-
- provider :microsoft_office365, ENV['OFFICE365_KEY'], ENV['OFFICE365_SECRET']
-
- provider :ldap,
- host: ENV['LDAP_SERVER'],
- port: ENV['LDAP_PORT'] || '389',
- method: ENV['LDAP_METHOD'].blank? ? :plain : ENV['LDAP_METHOD'].to_sym,
- allow_username_or_email_login: true,
- uid: ENV['LDAP_UID'],
- base: ENV['LDAP_BASE'],
- bind_dn: ENV['LDAP_BIND_DN'],
- password: ENV['LDAP_PASSWORD']
end
# Redirect back to login in development mode.
diff --git a/config/locales/en.yml b/config/locales/en.yml
index f10b79c1..7c810bc9 100755
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -77,6 +77,7 @@ en:
signout: Sign out
home_room: Home Room
info_update_success: Information successfully updated.
+ invalid_user: Login failed due to user not found. Are you sure the email account is correct?
invalid_credentials: Login failed due to invalid credentials. Are you sure you entered them correctly?
invalid_login_method: Login failed due to account mismatch. You need to log in with omniauth.
invite_message: "To invite someone to the meeting, send them this link:"
diff --git a/config/routes.rb b/config/routes.rb
index 9d38b89d..8c8791b9 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -38,7 +38,7 @@ Rails.application.routes.draw do
scope '/account_activations' do
get '/', to: 'account_activations#show', as: :account_activation
get '/edit', to: 'account_activations#edit', as: :edit_account_activation
- get '/resend', to: 'account_activations#resend', as: :resend_email
+ post '/resend', to: 'account_activations#resend', as: :resend_email
end
# User resources.
diff --git a/lib/bbb_api.rb b/lib/bbb_api.rb
new file mode 100644
index 00000000..ef16d256
--- /dev/null
+++ b/lib/bbb_api.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+module BbbApi
+ RETURNCODE_SUCCESS = "SUCCESS"
+
+ def bbb_endpoint
+ Rails.configuration.bigbluebutton_endpoint
+ end
+
+ def bbb_secret
+ Rails.configuration.bigbluebutton_secret
+ end
+
+ # Sets a BigBlueButtonApi object for interacting with the API.
+ def bbb
+ if Rails.configuration.loadbalanced_configuration
+ if instance_of? Room
+ # currently in the Room Model
+ user_domain = retrieve_provider_info(owner.provider)
+ elsif instance_of? User
+ # currently in the User Model
+ user_domain = retrieve_provider_info(provider)
+ end
+
+ BigBlueButton::BigBlueButtonApi.new(remove_slash(user_domain["apiURL"]), user_domain["secret"], "0.8")
+ else
+ BigBlueButton::BigBlueButtonApi.new(remove_slash(bbb_endpoint), bbb_secret, "0.8")
+ end
+ end
+
+ # Rereives info from the loadbalanced in regards to a Provider (or tenant).
+ def retrieve_provider_info(provider, api = 'api', route = 'getUser')
+ # Include Omniauth accounts under the Greenlight provider.
+ provider ||= 'greenlight'
+
+ # Build the URI.
+ uri = encode_bbb_url(
+ Rails.configuration.loadbalancer_endpoint + api + '/',
+ Rails.configuration.loadbalancer_secret,
+ { name: provider },
+ route
+ )
+
+ logger.info uri
+
+ # Make the request.
+ http = Net::HTTP.new(uri.host, uri.port)
+ http.use_ssl = (uri.scheme == 'https')
+ response = http.get(uri.request_uri)
+
+ # Parse XML.
+ doc = XmlSimple.xml_in(response.body, 'ForceArray' => false)
+
+ raise doc['message'] unless response.is_a?(Net::HTTPSuccess)
+
+ # Return the user credentials if the request succeeded on the loadbalancer.
+ return doc['user'] if doc['returncode'] == 'SUCCESS'
+
+ raise "User with provider #{provider} does not exist." if doc['messageKey'] == 'noSuchUser'
+ raise "API call #{url} failed with #{doc['messageKey']}."
+ end
+
+ # Builds a request to retrieve credentials from the load balancer.
+ def encode_bbb_url(base_url, secret, params, route = 'getUser')
+ encoded_params = params.to_param
+ string = route + encoded_params + secret
+ checksum = OpenSSL::Digest.digest('sha1', string).unpack('H*').first
+
+ URI.parse("#{base_url}#{route}?#{encoded_params}&checksum=#{checksum}")
+ end
+
+ # Removes trailing forward slash from a URL.
+ def remove_slash(s)
+ s.nil? ? nil : s.chomp("/")
+ end
+
+ def launcher_allow_user_signup_whitelisted?(provider)
+ return false unless Rails.configuration.launcher_allow_user_signup
+ whitelist = Rails.configuration.launcher_allow_user_signup.split(',')
+ whitelist.include?(provider)
+ end
+end
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
index 2faaa7f1..e9e970c6 100644
--- a/spec/controllers/sessions_controller_spec.rb
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -19,14 +19,10 @@
require "rails_helper"
describe SessionsController, type: :controller do
- before(:all) do
- @user = create(:user, provider: "greenlight", password: "example", password_confirmation: "example")
- @omni_user = create(:user, password: "example", password_confirmation: "example")
- end
-
describe "GET #destroy" do
before(:each) do
- @request.session[:user_id] = @user.id
+ user = create(:user, provider: "greenlight")
+ @request.session[:user_id] = user.id
get :destroy
end
@@ -40,22 +36,28 @@ describe SessionsController, type: :controller do
end
describe "POST #create" do
+ before { allow(Rails.configuration).to receive(:enable_email_verification).and_return(true) }
+ before(:each) do
+ @user1 = create(:user, provider: 'greenlight', password: 'example', password_confirmation: 'example')
+ @user2 = create(:user, password: 'example', password_confirmation: "example")
+ end
+
it "should login user in if credentials valid" do
post :create, params: {
session: {
- email: @user.email,
- password: "example",
+ email: @user1.email,
+ password: 'example',
},
}
- expect(@request.session[:user_id]).to eql(@user.id)
+ expect(@request.session[:user_id]).to eql(@user1.id)
end
it "should not login user in if credentials invalid" do
post :create, params: {
session: {
- email: @user.email,
- password: "invalid",
+ email: @user1.email,
+ password: 'invalid',
},
}
@@ -65,7 +67,7 @@ describe SessionsController, type: :controller do
it "should not login user in if account mismatch" do
post :create, params: {
session: {
- email: @omni_user.email,
+ email: @user2.email,
password: "example",
},
}
@@ -74,18 +76,18 @@ describe SessionsController, type: :controller do
end
it "should not login user if account is not verified" do
- @secondary_user = create(:user, email_verified: false, provider: "greenlight",
- password: "example", password_confirmation: "example")
+ @user3 = create(:user, email_verified: false, provider: "greenlight",
+ password: "example", password_confirmation: 'example')
post :create, params: {
session: {
- email: @secondary_user.email,
- password: "example",
+ email: @user3.email,
+ password: 'example',
},
}
expect(@request.session[:user_id]).to be_nil
- expect(response).to redirect_to(account_activation_path(email: @secondary_user.email))
+ expect(response).to redirect_to(account_activation_path(email: @user3.email))
end
end
@@ -99,7 +101,7 @@ describe SessionsController, type: :controller do
info: {
email: "user@twitter.com",
name: "Twitter User",
- nickname: "username",
+ nickname: "twitteruser",
image: "example.png",
},
)
@@ -108,11 +110,11 @@ describe SessionsController, type: :controller do
provider: "bn_launcher",
uid: "bn-launcher-user",
info: {
- email: "user1@google.com",
- name: "User1",
- nickname: "nick",
+ email: "user@google.com",
+ name: "Google User",
+ nickname: "googleuser",
image: "touch.png",
- customer: 'ocps',
+ customer: 'customer1',
}
)
@@ -121,37 +123,39 @@ describe SessionsController, type: :controller do
}
end
- it "should create and login user with omniauth twitter" do
- request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter]
- get :omniauth, params: { provider: :twitter }
+ unless Rails.configuration.omniauth_bn_launcher
+ it "should create and login user with omniauth twitter" 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
+ 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 create and login user with omniauth bn launcher" do
- request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:bn_launcher]
- get :omniauth, params: { provider: 'bn_launcher' }
+ it "should create and login user with omniauth bn launcher" do
+ request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:bn_launcher]
+ get :omniauth, params: { provider: 'bn_launcher' }
- u = User.last
- expect(u.provider).to eql("ocps")
- expect(u.email).to eql("user1@google.com")
- expect(@request.session[:user_id]).to eql(u.id)
- end
+ u = User.last
+ expect(u.provider).to eql("customer1")
+ expect(u.email).to eql("user@google.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 }
+ 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
+ expect(response).to redirect_to(root_path)
+ end
- it "should not create session without omniauth env set for google" do
- get :omniauth, params: { provider: 'google' }
+ it "should not create session without omniauth env set for google" do
+ get :omniauth, params: { provider: 'google' }
- expect(response).to redirect_to(root_path)
+ expect(response).to redirect_to(root_path)
+ end
end
it "should not create session without omniauth env set for bn_launcher" do
diff --git a/spec/models/room_spec.rb b/spec/models/room_spec.rb
index c1f340d1..dfcc714b 100644
--- a/spec/models/room_spec.rb
+++ b/spec/models/room_spec.rb
@@ -83,7 +83,7 @@ describe Room, type: :model do
@room.start_session
end.to change { @room.sessions }.by(1)
- expect(@room.last_session.utc.to_i).to eq(Time.now.to_i)
+ expect(@room.last_session).not_to be nil
end
end
@@ -93,13 +93,8 @@ describe Room, type: :model do
attendeePW: "testpass"
)
- if Rails.configuration.loadbalanced_configuration
- endpoint = Rails.configuration.loadbalancer_endpoint
- secret = Rails.configuration.loadbalancer_secret
- else
- endpoint = Rails.configuration.bigbluebutton_endpoint
- secret = Rails.configuration.bigbluebutton_secret
- end
+ endpoint = Rails.configuration.bigbluebutton_endpoint
+ secret = Rails.configuration.bigbluebutton_secret
fullname = "fullName=Example"
meeting_id = "&meetingID=#{@room.bbb_id}"
password = "&password=testpass"
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index e5891e6d..72af5432 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -76,30 +76,32 @@ describe User, type: :model do
end
end
- context '#from_omniauth' do
- let(:auth) do
- {
- "uid" => "123456789",
- "provider" => "twitter",
- "info" => {
- "name" => "Test Name",
- "nickname" => "username",
- "email" => "test@example.com",
- "image" => "example.png",
- },
- }
- end
+ unless Rails.configuration.omniauth_bn_launcher
+ context '#from_omniauth' do
+ let(:auth) do
+ {
+ "uid" => "123456789",
+ "provider" => "twitter",
+ "info" => {
+ "name" => "Test Name",
+ "nickname" => "username",
+ "email" => "test@example.com",
+ "image" => "example.png",
+ },
+ }
+ end
- it "should create user from omniauth" do
- expect do
- user = User.from_omniauth(auth)
+ it "should create user from omniauth" do
+ expect do
+ user = User.from_omniauth(auth)
- expect(user.name).to eq("Test Name")
- expect(user.email).to eq("test@example.com")
- expect(user.image).to eq("example.png")
- expect(user.provider).to eq("twitter")
- expect(user.social_uid).to eq("123456789")
- end.to change { User.count }.by(1)
+ expect(user.name).to eq("Test Name")
+ expect(user.email).to eq("test@example.com")
+ expect(user.image).to eq("example.png")
+ expect(user.provider).to eq("twitter")
+ expect(user.social_uid).to eq("123456789")
+ end.to change { User.count }.by(1)
+ end
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index e085ae1f..1183220d 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -47,7 +47,7 @@ RSpec.configure do |config|
# external servers, api stubbing is used to simulate external server
# responses
config.before(:each) do
- stub_request(:any, /#{ENV['BIGBLUEBUTTON_ENDPOINT']}/)
+ stub_request(:any, /#{"http:\/\/bbb.example.com\/bigbluebutton\/api"}/)
.with(
headers:
{
@@ -57,7 +57,7 @@ RSpec.configure do |config|
}
)
.to_return(status: 200, body: "", headers: {})
- stub_request(:any, /#{ENV['LOADBALANCER_ENDPOINT']}/)
+ stub_request(:any, /#{ENV['LOADBALANCER_ENDPOINT'] + 'api'}/)
.with(
headers:
{
@@ -66,8 +66,8 @@ RSpec.configure do |config|
'User-Agent': 'Ruby',
}
)
- .to_return(status: 200, body: "", headers: {})
- stub_request(:any, /#{ENV['LOADBALANCER_ENDPOINT'] + 'getUser'}/)
+ .to_return(status: 200, body: "", headers: {}) if ENV['LOADBALANCER_ENDPOINT']
+ stub_request(:any, /#{ENV['LOADBALANCER_ENDPOINT'] + 'api\/getUser'}/)
.with(
headers:
{
@@ -83,8 +83,26 @@ RSpec.configure do |config|
greenlight
1000
- #{ENV['LOADBALANCER_ENDPOINT']}
- #{ENV['LOADBALANCER_SECRET']}
+ http:\/\/bbb.example.com\/bigbluebutton\/api
+ secret
+
+ ", headers: {}) if ENV['LOADBALANCER_ENDPOINT']
+ stub_request(:any, /#{ENV['LOADBALANCER_ENDPOINT'] + 'api2\/getUserGreenlightCredentials'}/)
+ .with(
+ headers:
+ {
+ 'Accept': '*/*',
+ 'Accept-Encoding': 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
+ 'User-Agent': 'Ruby',
+ }
+ )
+ .to_return(status: 200, body: "
+
+ 2.0
+ SUCCESS
+
+ greenlight
+
", headers: {}) if ENV['LOADBALANCER_ENDPOINT']
end