GRN2-180: First stages of refactoring code for v2.4 (#748)

* Email rescues and authenticator concern

* Application controller and helper clean up

* Moved controller code out of helpers

* More helper and email clean up

* Cleaned up remaining helpers and create omniauth_options

* Controller code clean up

* restructured views structure

* Restructured role code

* Restructured profile and code clean up

* Master merge

* Added bbb server concern to deal with bbb calls

* Bug fixes and changes after changes

* rspec

* More rubocop fixes
This commit is contained in:
farhatahmad 2019-08-19 11:28:48 -04:00 committed by farhatahmad
parent 194b5ddfa0
commit fd6077696d
76 changed files with 1187 additions and 1430 deletions

View File

@ -79,7 +79,7 @@ $(document).on('turbolinks:load', function(){
// Change the branding image to the image provided // Change the branding image to the image provided
function changeBrandingImage(path) { function changeBrandingImage(path) {
var url = $("#branding-url").val() var url = $("#branding-url").val()
$.post(path, {url: url}) $.post(path, {value: url})
} }
// Filters by role // Filters by role
@ -157,19 +157,19 @@ function loadColourSelectors() {
}); });
pickrRegular.on("save", (color, instance) => { pickrRegular.on("save", (color, instance) => {
$.post($("#coloring-path-regular").val(), {color: color.toHEXA().toString()}).done(function() { $.post($("#coloring-path-regular").val(), {value: color.toHEXA().toString()}).done(function() {
location.reload() location.reload()
}); });
}) })
pickrLighten.on("save", (color, instance) => { pickrLighten.on("save", (color, instance) => {
$.post($("#coloring-path-lighten").val(), {color: color.toHEXA().toString()}).done(function() { $.post($("#coloring-path-lighten").val(), {value: color.toHEXA().toString()}).done(function() {
location.reload() location.reload()
}); });
}) })
pickrDarken.on("save", (color, instance) => { pickrDarken.on("save", (color, instance) => {
$.post($("#coloring-path-darken").val(), {color: color.toHEXA().toString()}).done(function() { $.post($("#coloring-path-darken").val(), {value: color.toHEXA().toString()}).done(function() {
location.reload() location.reload()
}); });
}) })

View File

@ -24,46 +24,45 @@ class AccountActivationsController < ApplicationController
# GET /account_activations # GET /account_activations
def show def show
render :verify
end end
# GET /account_activations/edit # GET /account_activations/edit
def edit def edit
# If the user exists and is not verified and provided the correct token
if @user && !@user.activated? && @user.authenticated?(:activation, params[:token]) if @user && !@user.activated? && @user.authenticated?(:activation, params[:token])
# Verify user
@user.activate @user.activate
# Redirect user to root with account pending flash if account is still pending # Redirect user to root with account pending flash if account is still pending
return redirect_to root_path, return redirect_to root_path,
flash: { success: I18n.t("registration.approval.signup") } if @user.has_role?(:pending) flash: { success: I18n.t("registration.approval.signup") } if @user.has_role?(:pending)
flash[:success] = I18n.t("verify.activated") + " " + I18n.t("verify.signin") # Redirect user to sign in path with success flash
redirect_to signin_path redirect_to signin_path, flash: { success: I18n.t("verify.activated") + " " + I18n.t("verify.signin") }
else else
flash[:alert] = I18n.t("verify.invalid") redirect_to root_path, flash: { alert: I18n.t("verify.invalid") }
redirect_to root_path
end end
end end
# GET /account_activations/resend # GET /account_activations/resend
def resend def resend
if @user.activated? if @user.activated?
# User is already verified
flash[:alert] = I18n.t("verify.already_verified") flash[:alert] = I18n.t("verify.already_verified")
else else
begin # Resend
send_activation_email(@user) send_activation_email(@user)
rescue => e
logger.error "Support: Error in email delivery: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
else
flash[:success] = I18n.t("email_sent", email_type: t("verify.verification"))
end
end end
redirect_to(root_path) redirect_to root_path
end end
private private
def find_user
@user = User.find_by!(email: params[:email], provider: @user_domain)
end
def ensure_unauthenticated def ensure_unauthenticated
redirect_to current_user.main_room if current_user redirect_to current_user.main_room if current_user
end end
@ -71,8 +70,4 @@ class AccountActivationsController < ApplicationController
def email_params def email_params
params.require(:email).permit(:email, :token) params.require(:email).permit(:email, :token)
end end
def find_user
@user = User.find_by!(email: params[:email], provider: @user_domain)
end
end end

View File

@ -21,18 +21,17 @@ class AdminsController < ApplicationController
include Themer include Themer
include Emailer include Emailer
include Recorder include Recorder
include Rolify
manage_users = [:edit_user, :promote, :demote, :ban_user, :unban_user, :approve, :reset] manage_users = [:edit_user, :promote, :demote, :ban_user, :unban_user, :approve, :reset]
site_settings = [:branding, :coloring, :coloring_lighten, :coloring_darken,
:registration_method, :room_authentication, :room_limit, :default_recording_visibility]
authorize_resource class: false authorize_resource class: false
before_action :find_user, only: manage_users before_action :find_user, only: manage_users
before_action :verify_admin_of_user, only: manage_users before_action :verify_admin_of_user, only: manage_users
before_action :find_setting, only: site_settings
# GET /admins # GET /admins
def index def index
# Initializa the data manipulation variables
@search = params[:search] || "" @search = params[:search] || ""
@order_column = params[:column] && params[:direction] != "none" ? params[:column] : "created_at" @order_column = params[:column] && params[:direction] != "none" ? params[:column] : "created_at"
@order_direction = params[:direction] && params[:direction] != "none" ? params[:direction] : "DESC" @order_direction = params[:direction] && params[:direction] != "none" ? params[:direction] : "DESC"
@ -49,13 +48,14 @@ class AdminsController < ApplicationController
# GET /admins/server_recordings # GET /admins/server_recordings
def server_recordings def server_recordings
server_rooms = if Rails.configuration.loadbalanced_configuration server_rooms = if Rails.configuration.loadbalanced_configuration
Room.includes(:owner).where(users: { provider: user_settings_provider }).pluck(:bbb_id) Room.includes(:owner).where(users: { provider: @user_domain }).pluck(:bbb_id)
else else
Room.pluck(:bbb_id) Room.pluck(:bbb_id)
end end
@search, @order_column, @order_direction, recs = @search, @order_column, @order_direction, recs =
all_recordings(server_rooms, @user_domain, params.permit(:search, :column, :direction), true, true) all_recordings(server_rooms, params.permit(:search, :column, :direction), true, true)
@pagy, @recordings = pagy_array(recs) @pagy, @recordings = pagy_array(recs)
end end
@ -92,18 +92,11 @@ class AdminsController < ApplicationController
def invite def invite
emails = params[:invite_user][:email].split(",") emails = params[:invite_user][:email].split(",")
begin
emails.each do |email| emails.each do |email|
invitation = create_or_update_invite(email) invitation = create_or_update_invite(email)
send_invitation_email(current_user.name, email, invitation.invite_token) send_invitation_email(current_user.name, email, invitation.invite_token)
end end
rescue => e
logger.error "Support: Error in email delivery: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
else
flash[:success] = I18n.t("administrator.flash.invite", email: emails.join(', '))
end
redirect_to admins_path redirect_to admins_path
end end
@ -118,39 +111,30 @@ class AdminsController < ApplicationController
end end
# SITE SETTINGS # SITE SETTINGS
# POST /admins/branding # POST /admins/update_settings
def branding def update_settings
@settings.update_value("Branding Image", params[:url]) @settings.update_value(params[:setting], params[:value])
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
flash_message = I18n.t("administrator.flash.settings")
if params[:value] == "Default Recording Visibility"
flash_message += ". " + I18n.t("administrator.site_settings.recording_visibility.warning")
end
redirect_to admin_site_settings_path, flash: { success: flash_message }
end end
# POST /admins/color # POST /admins/color
def coloring def coloring
@settings.update_value("Primary Color", params[:color]) @settings.update_value("Primary Color", params[:value])
@settings.update_value("Primary Color Lighten", color_lighten(params[:color])) @settings.update_value("Primary Color Lighten", color_lighten(params[:value]))
@settings.update_value("Primary Color Darken", color_darken(params[:color])) @settings.update_value("Primary Color Darken", color_darken(params[:value]))
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
end
def coloring_lighten
@settings.update_value("Primary Color Lighten", params[:color])
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
end
def coloring_darken
@settings.update_value("Primary Color Darken", params[:color])
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
end
# POST /admins/room_authentication
def room_authentication
@settings.update_value("Room Authentication", params[:value])
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") } redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
end end
# POST /admins/registration_method/:method # POST /admins/registration_method/:method
def registration_method def registration_method
new_method = Rails.configuration.registration_methods[params[:method].to_sym] new_method = Rails.configuration.registration_methods[params[:value].to_sym]
# Only allow change to Join by Invitation if user has emails enabled # Only allow change to Join by Invitation if user has emails enabled
if !Rails.configuration.enable_email_verification && new_method == Rails.configuration.registration_methods[:invite] if !Rails.configuration.enable_email_verification && new_method == Rails.configuration.registration_methods[:invite]
@ -163,67 +147,19 @@ class AdminsController < ApplicationController
end end
end end
# POST /admins/room_limit
def room_limit
@settings.update_value("Room Limit", params[:limit])
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
end
# POST /admins/default_recording_visibility
def default_recording_visibility
@settings.update_value("Default Recording Visibility", params[:visibility])
redirect_to admin_site_settings_path, flash: {
success: I18n.t("administrator.flash.settings") + ". " +
I18n.t("administrator.site_settings.recording_visibility.warning")
}
end
# POST /admins/clear_cache
def clear_cache
Rails.cache.delete("#{@user_domain}/getUser")
Rails.cache.delete("#{@user_domain}/getUserGreenlightCredentials")
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
end
# ROLES # ROLES
# GET /admins/roles # GET /admins/roles
def roles def roles
@roles = Role.editable_roles(@user_domain) @roles = all_roles(params[:selected_role])
if @roles.count.zero?
Role.create_default_roles(@user_domain)
@roles = Role.editable_roles(@user_domain)
end end
@selected_role = if params[:selected_role].nil? # POST /admins/role
@roles.find_by(name: 'user') # This method creates a new role scoped to the users provider
else
@roles.find(params[:selected_role])
end
end
# POST /admin/role
# This method creates a new role scope to the users provider
def new_role def new_role
new_role_name = params[:role][:name] new_role = create_role(params[:role][:name])
# Make sure that the role name isn't a duplicate or a reserved name like super_admin return redirect_to admin_roles_path, flash: { alert: I18n.t("administrator.roles.invalid_create") } if new_role.nil?
if Role.duplicate_name(new_role_name, @user_domain)
flash[:alert] = I18n.t("administrator.roles.duplicate_name")
return redirect_to admin_roles_path
end
# Make sure the role name isn't empty
if new_role_name.strip.empty?
flash[:alert] = I18n.t("administrator.roles.empty_name")
return redirect_to admin_roles_path
end
new_role = Role.create_new_role(new_role_name, @user_domain)
redirect_to admin_roles_path(selected_role: new_role.id) redirect_to admin_roles_path(selected_role: new_role.id)
end end
@ -232,82 +168,16 @@ class AdminsController < ApplicationController
# This updates the priority of a site's roles # This updates the priority of a site's roles
# Note: A lower priority role will always get used before a higher priority one # Note: A lower priority role will always get used before a higher priority one
def change_role_order def change_role_order
user_role = Role.find_by(name: "user", provider: @user_domain) unless update_priority(params[:role])
admin_role = Role.find_by(name: "admin", provider: @user_domain) redirect_to admin_roles_path, flash: { alert: I18n.t("administrator.roles.invalid_order") }
current_user_role = current_user.highest_priority_role
# Users aren't allowed to update the priority of the admin or user roles
if params[:role].include?(user_role.id.to_s) || params[:role].include?(admin_role.id.to_s)
flash[:alert] = I18n.t("administrator.roles.invalid_order")
return redirect_to admin_roles_path
end end
# Restrict users to only updating the priority for roles in their domain with a higher
# priority
params[:role].each do |id|
role = Role.find(id)
if role.priority <= current_user_role.priority || role.provider != @user_domain
flash[:alert] = I18n.t("administrator.roles.invalid_update")
return redirect_to admin_roles_path
end
end
# Update the roles priority including the user role
top_priority = 0
params[:role].each_with_index do |id, index|
new_priority = index + [current_user_role.priority, 0].max + 1
top_priority = new_priority
Role.where(id: id).update_all(priority: new_priority)
end
user_role.priority = top_priority + 1
user_role.save!
end end
# POST /admin/role/:role_id # POST /admin/role/:role_id
# This method updates the permissions assigned to a role # This method updates the permissions assigned to a role
def update_role def update_role
role = Role.find(params[:role_id]) role = Role.find(params[:role_id])
current_user_role = current_user.highest_priority_role flash[:alert] = I18n.t("administrator.roles.invalid_update") unless update_permissions(role)
# Checks that it is valid for the provider to update the role
if role.priority <= current_user_role.priority || role.provider != @user_domain
flash[:alert] = I18n.t("administrator.roles.invalid_update")
return redirect_to admin_roles_path(selected_role: role.id)
end
role_params = params.require(:role).permit(:name)
permission_params = params.require(:role)
.permit(
:can_create_rooms,
:send_promoted_email,
:send_demoted_email,
:can_edit_site_settings,
:can_edit_roles,
:can_manage_users,
:colour
)
# Role is a default role so users can't change the name
role_params[:name] = role.name if Role::RESERVED_ROLE_NAMES.include?(role.name)
# Make sure if the user is updating the role name that the role name is valid
if role.name != role_params[:name] && !Role.duplicate_name(role_params[:name], @user_domain) &&
!role_params[:name].strip.empty?
role.name = role_params[:name]
elsif role.name != role_params[:name]
flash[:alert] = I18n.t("administrator.roles.duplicate_name")
return redirect_to admin_roles_path(selected_role: role.id)
end
role.update(permission_params)
role.save!
redirect_to admin_roles_path(selected_role: role.id) redirect_to admin_roles_path(selected_role: role.id)
end end
@ -337,10 +207,7 @@ class AdminsController < ApplicationController
@user = User.where(uid: params[:user_uid]).includes(:roles).first @user = User.where(uid: params[:user_uid]).includes(:roles).first
end end
def find_setting # Verifies that admin is an administrator of the user in the action
@settings = Setting.find_or_create_by!(provider: user_settings_provider)
end
def verify_admin_of_user def verify_admin_of_user
redirect_to admins_path, redirect_to admins_path,
flash: { alert: I18n.t("administrator.flash.unauthorized") } unless current_user.admin_of?(@user) flash: { alert: I18n.t("administrator.flash.unauthorized") } unless current_user.admin_of?(@user)
@ -355,7 +222,7 @@ class AdminsController < ApplicationController
end end
if Rails.configuration.loadbalanced_configuration if Rails.configuration.loadbalanced_configuration
initial_list.where(provider: user_settings_provider) initial_list.where(provider: @user_domain)
.admins_search(@search, @role) .admins_search(@search, @role)
.admins_order(@order_column, @order_direction) .admins_order(@order_column, @order_direction)
else else

View File

@ -16,35 +16,65 @@
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
require 'bigbluebutton_api'
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
include ApplicationHelper include BbbServer
include SessionsHelper
include ThemingHelper include ThemingHelper
# Force SSL for loadbalancer configurations.
before_action :redirect_to_https before_action :redirect_to_https
before_action :set_user_domain before_action :set_user_domain
before_action :set_user_settings
before_action :maintenance_mode? before_action :maintenance_mode?
before_action :migration_error? before_action :migration_error?
before_action :set_locale before_action :user_locale
before_action :check_admin_password before_action :check_admin_password
before_action :check_user_role before_action :check_user_role
# Manually handle BigBlueButton errors # Manually handle BigBlueButton errors
rescue_from BigBlueButton::BigBlueButtonException, with: :handle_bigbluebutton_error rescue_from BigBlueButton::BigBlueButtonException, with: :handle_bigbluebutton_error
protect_from_forgery with: :exception protect_from_forgery with: :exceptions
MEETING_NAME_LIMIT = 90 # Retrieves the current user.
USER_NAME_LIMIT = 32 def current_user
@current_user ||= User.where(id: session[:user_id]).includes(:roles).first
# Include user domain in lograge logs if Rails.configuration.loadbalanced_configuration
def append_info_to_payload(payload) if @current_user && !@current_user.has_role?(:super_admin) &&
super @current_user.provider != @user_domain
payload[:host] = @user_domain @current_user = nil
session.clear
end
end
@current_user
end
helper_method :current_user
def bbb_server
@bbb_server ||= Rails.configuration.loadbalanced_configuration ? bbb(@user_domain) : bbb("greenlight")
end
# Force SSL
def redirect_to_https
if Rails.configuration.loadbalanced_configuration && request.headers["X-Forwarded-Proto"] == "http"
redirect_to protocol: "https://"
end
end
# Sets the user domain variable
def set_user_domain
if Rails.env.test? || !Rails.configuration.loadbalanced_configuration
@user_domain = "greenlight"
else
@user_domain = parse_user_domain(request.host)
check_provider_exists
end
end
# Sets the settinfs variable
def set_user_settings
@settings = Setting.find_or_create_by(provider: @user_domain)
end end
# Show an information page when migration fails and there is a version error. # Show an information page when migration fails and there is a version error.
@ -52,8 +82,40 @@ class ApplicationController < ActionController::Base
render :migration_error, status: 500 unless ENV["DB_MIGRATE_FAILED"].blank? render :migration_error, status: 500 unless ENV["DB_MIGRATE_FAILED"].blank?
end end
# Sets the appropriate locale.
def user_locale(user = current_user)
locale = if user && user.language != 'default'
user.language
else
http_accept_language.language_region_compatible_from(I18n.available_locales)
end
I18n.locale = locale.tr('-', '_') unless locale.nil?
end
# Checks to make sure that the admin has changed his password from the default
def check_admin_password
if current_user&.has_role?(:admin) && current_user.email == "admin@example.com" &&
current_user&.greenlight_account? && current_user&.authenticate(Rails.configuration.admin_password_default)
flash.now[:alert] = I18n.t("default_admin",
edit_link: edit_user_path(user_uid: current_user.uid) + "?setting=password").html_safe
end
end
# Checks if the user is banned and logs him out if he is
def check_user_role
if current_user&.has_role? :denied
session.delete(:user_id)
redirect_to root_path, flash: { alert: I18n.t("registration.banned.fail") }
elsif current_user&.has_role? :pending
session.delete(:user_id)
redirect_to root_path, flash: { alert: I18n.t("registration.approval.fail") }
end
end
# Redirects the user to a Maintenance page if turned on
def maintenance_mode? def maintenance_mode?
if Rails.configuration.maintenance_mode if ENV["MAINTENANCE_MODE"] == "true"
render "errors/greenlight_error", status: 503, formats: :html, render "errors/greenlight_error", status: 503, formats: :html,
locals: { locals: {
status_code: 503, status_code: 503,
@ -68,30 +130,6 @@ class ApplicationController < ActionController::Base
end end
end end
# Sets the appropriate locale.
def set_locale
update_locale(current_user)
end
def update_locale(user)
locale = if user && user.language != 'default'
user.language
else
http_accept_language.language_region_compatible_from(I18n.available_locales)
end
I18n.locale = locale.tr('-', '_') unless locale.nil?
end
def meeting_name_limit
MEETING_NAME_LIMIT
end
helper_method :meeting_name_limit
def user_name_limit
USER_NAME_LIMIT
end
helper_method :user_name_limit
# Relative root helper (when deploying to subdirectory). # Relative root helper (when deploying to subdirectory).
def relative_root def relative_root
Rails.configuration.relative_url_root || "" Rails.configuration.relative_url_root || ""
@ -105,34 +143,53 @@ class ApplicationController < ActionController::Base
end end
helper_method :bigbluebutton_endpoint_default? helper_method :bigbluebutton_endpoint_default?
def recording_thumbnails? def allow_greenlight_accounts?
Rails.configuration.recording_thumbnails return Rails.configuration.allow_user_signup unless Rails.configuration.loadbalanced_configuration
return false unless @user_domain && !@user_domain.empty? && Rails.configuration.allow_user_signup
return false if @user_domain == "greenlight"
# Proceed with retrieving the provider info
begin
provider_info = retrieve_provider_info(@user_domain, 'api2', 'getUserGreenlightCredentials')
provider_info['provider'] == 'greenlight'
rescue => e
logger.error "Error in checking if greenlight accounts are allowed: #{e}"
false
end end
helper_method :recording_thumbnails?
def allow_greenlight_users?
allow_greenlight_accounts?
end end
helper_method :allow_greenlight_users? helper_method :allow_greenlight_accounts?
# Determines if a form field needs the is-invalid class. # Determine if Greenlight is configured to allow user signups.
def form_is_invalid?(obj, key) def allow_user_signup?
'is-invalid' unless obj.errors.messages[key].empty? Rails.configuration.allow_user_signup
end end
helper_method :form_is_invalid? helper_method :allow_user_signup?
# Default, unconfigured meeting options. # Gets all configured omniauth providers.
def default_meeting_options def configured_providers
invite_msg = I18n.t("invite_message") Rails.configuration.providers.select do |provider|
{ Rails.configuration.send("omniauth_#{provider}")
user_is_moderator: false, end
meeting_logout_url: request.base_url + logout_room_path(@room), end
meeting_recorded: true, helper_method :configured_providers
moderator_message: "#{invite_msg}\n\n#{request.base_url + room_path(@room)}",
host: request.host, # Parses the url for the user domain
recording_default_visibility: Setting.find_or_create_by!(provider: user_settings_provider) def parse_user_domain(hostname)
.get_value("Default Recording Visibility") == "public" return hostname.split('.').first if Rails.configuration.url_host.empty?
} Rails.configuration.url_host.split(',').each do |url_host|
return hostname.chomp(url_host).chomp('.') if hostname.include?(url_host)
end
''
end
# Include user domain in lograge logs
def append_info_to_payload(payload)
super
payload[:host] = @user_domain
end
# Manually Handle BigBlueButton errors
def handle_bigbluebutton_error
render "errors/bigbluebutton_error"
end end
# Manually deal with 401 errors # Manually deal with 401 errors
@ -140,50 +197,6 @@ class ApplicationController < ActionController::Base
render "errors/greenlight_error" render "errors/greenlight_error"
end end
# Checks to make sure that the admin has changed his password from the default
def check_admin_password
if current_user&.has_role?(:admin) && current_user.email == "admin@example.com" &&
current_user&.greenlight_account? && current_user&.authenticate(Rails.configuration.admin_password_default)
flash.now[:alert] = I18n.t("default_admin",
edit_link: edit_user_path(user_uid: current_user.uid) + "?setting=password").html_safe
end
end
def redirect_to_https
if Rails.configuration.loadbalanced_configuration && request.headers["X-Forwarded-Proto"] == "http"
redirect_to protocol: "https://"
end
end
def set_user_domain
if Rails.env.test? || !Rails.configuration.loadbalanced_configuration
@user_domain = "greenlight"
else
@user_domain = parse_user_domain(request.host)
check_provider_exists
end
end
helper_method :set_user_domain
# Checks if the user is banned and logs him out if he is
def check_user_role
if current_user&.has_role? :denied
session.delete(:user_id)
redirect_to root_path, flash: { alert: I18n.t("registration.banned.fail") }
elsif current_user&.has_role? :pending
session.delete(:user_id)
redirect_to root_path, flash: { alert: I18n.t("registration.approval.fail") }
end
end
helper_method :check_user_role
# Manually Handle BigBlueButton errors
def handle_bigbluebutton_error
render "errors/bigbluebutton_error"
end
private private
def check_provider_exists def check_provider_exists
@ -198,6 +211,7 @@ class ApplicationController < ActionController::Base
# Add a session variable if the provider exists # Add a session variable if the provider exists
session[:provider_exists] = @user_domain session[:provider_exists] = @user_domain
rescue => e rescue => e
logger.error "Error in retrieve provider info: #{e}"
# Use the default site settings # Use the default site settings
@user_domain = "greenlight" @user_domain = "greenlight"

View File

@ -16,15 +16,15 @@
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
module SessionsHelper module Authenticator
extend ActiveSupport::Concern
# Logs a user into GreenLight. # Logs a user into GreenLight.
def login(user) def login(user)
migrate_twitter_user(user) migrate_twitter_user(user)
session[:user_id] = user.id session[:user_id] = user.id
logger.info("Support: #{user.email} has successfully logged in.")
# If there are not terms, or the user has accepted them, check for email verification # If there are not terms, or the user has accepted them, check for email verification
if !Rails.configuration.terms || user.accepted_terms if !Rails.configuration.terms || user.accepted_terms
check_email_verified(user) check_email_verified(user)
@ -61,69 +61,9 @@ module SessionsHelper
session.delete(:user_id) if current_user session.delete(:user_id) if current_user
end end
# Retrieves the current user. private
def current_user
@current_user ||= User.where(id: session[:user_id]).includes(:roles).first
if Rails.configuration.loadbalanced_configuration
if @current_user && !@current_user.has_role?(:super_admin) &&
@current_user.provider != @user_domain
@current_user = nil
session.clear
end
end
@current_user
end
def generate_checksum(user_domain, redirect_url, secret)
string = user_domain + redirect_url + secret
OpenSSL::Digest.digest('sha1', string).unpack1("H*")
end
def parse_user_domain(hostname)
return hostname.split('.').first if Rails.configuration.url_host.empty?
Rails.configuration.url_host.split(',').each do |url_host|
return hostname.chomp(url_host).chomp('.') if hostname.include?(url_host)
end
''
end
def omniauth_options(env)
if env['omniauth.strategy'].options[:name] == "bn_launcher"
protocol = Rails.env.production? ? "https" : env["rack.url_scheme"]
customer_redirect_url = protocol + "://" + env["SERVER_NAME"] + ":" +
env["SERVER_PORT"]
user_domain = parse_user_domain(env["SERVER_NAME"])
env['omniauth.strategy'].options[:customer] = user_domain
env['omniauth.strategy'].options[:customer_redirect_url] = customer_redirect_url
env['omniauth.strategy'].options[:default_callback_url] = Rails.configuration.gl_callback_url
# This is only used in the old launcher and should eventually be removed
env['omniauth.strategy'].options[:checksum] = generate_checksum(user_domain, customer_redirect_url,
Rails.configuration.launcher_secret)
elsif env['omniauth.strategy'].options[:name] == "google"
set_hd(env, ENV['GOOGLE_OAUTH2_HD'])
elsif env['omniauth.strategy'].options[:name] == "office365"
set_hd(env, ENV['OFFICE365_HD'])
end
end
def set_hd(env, hd)
if hd
hd_opts = hd.split(',')
env['omniauth.strategy'].options[:hd] =
if hd_opts.empty?
nil
elsif hd_opts.length == 1
hd_opts[0]
else
hd_opts
end
end
end
# Migrates all of the twitter users rooms to the new account
def migrate_twitter_user(user) def migrate_twitter_user(user)
if !session["old_twitter_user_id"].nil? && user.provider != "twitter" if !session["old_twitter_user_id"].nil? && user.provider != "twitter"
old_user = User.find(session["old_twitter_user_id"]) old_user = User.find(session["old_twitter_user_id"])

View File

@ -0,0 +1,109 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
require 'bigbluebutton_api'
module BbbServer
extend ActiveSupport::Concern
include BbbApi
META_LISTED = "gl-listed"
# Checks if a room is running on the BigBlueButton server.
def room_running?(bbb_id)
bbb_server.is_meeting_running?(bbb_id)
end
def get_recordings(meeting_id)
bbb_server.get_recordings(meetingID: meeting_id)
end
def get_multiple_recordings(meeting_ids)
bbb_server.get_recordings(meetingID: meeting_ids)
end
# Returns a URL to join a user into a meeting.
def join_path(room, name, options = {}, uid = nil)
# Create the meeting, even if it's running
start_session(room, options)
# Determine the password to use when joining.
password = options[:user_is_moderator] ? room.moderator_pw : room.attendee_pw
# Generate the join URL.
join_opts = {}
join_opts[:userID] = uid if uid
join_opts[:join_via_html5] = true
join_opts[:guest] = true if options[:require_moderator_approval] && !options[:user_is_moderator]
bbb_server.join_meeting_url(room.bbb_id, name, password, join_opts)
end
# Creates a meeting on the BigBlueButton server.
def start_session(room, options = {})
create_options = {
record: options[:meeting_recorded].to_s,
logoutURL: options[:meeting_logout_url] || '',
moderatorPW: room.moderator_pw,
attendeePW: room.attendee_pw,
moderatorOnlyMessage: options[:moderator_message],
muteOnStart: options[:mute_on_start] || false,
"meta_#{META_LISTED}": options[:recording_default_visibility] || false,
"meta_bbb-origin-version": Greenlight::Application::VERSION,
"meta_bbb-origin": "Greenlight",
"meta_bbb-origin-server-name": options[:host]
}
create_options[:guestPolicy] = "ASK_MODERATOR" if options[:require_moderator_approval]
# Send the create request.
begin
meeting = bbb_server.create_meeting(room.name, room.bbb_id, create_options)
# Update session info.
unless meeting[:messageKey] == 'duplicateWarning'
room.update_attributes(sessions: room.sessions + 1,
last_session: DateTime.now)
end
rescue BigBlueButton::BigBlueButtonException => e
puts "BigBlueButton failed on create: #{e.key}: #{e.message}"
raise e
end
end
# Gets the number of recordings for this room
def recording_count(bbb_id)
bbb_server.get_recordings(meetingID: bbb_id)[:recordings].length
end
# Update a recording from a room
def update_recording(record_id, meta)
meta[:recordID] = record_id
bbb_server.send_api_request("updateRecordings", meta)
end
# Deletes a recording from a room.
def delete_recording(record_id)
bbb_server.delete_recordings(record_id)
end
# Deletes all recordings associated with the room.
def delete_all_recordings(bbb_id)
record_ids = bbb_server.get_recordings(meetingID: bbb_id)[:recordings].pluck(:recordID)
bbb_server.delete_recordings(record_ids) unless record_ids.empty?
end
end

View File

@ -21,69 +21,110 @@ module Emailer
# Sends account activation email. # Sends account activation email.
def send_activation_email(user) def send_activation_email(user)
begin
return unless Rails.configuration.enable_email_verification return unless Rails.configuration.enable_email_verification
@user = user UserMailer.verify_email(user, user_verification_link(user), @settings).deliver
UserMailer.verify_email(@user, user_verification_link, logo_image, user_color).deliver rescue => e
logger.error "Support: Error in email delivery: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
else
flash[:success] = I18n.t("email_sent", email_type: t("verify.verification"))
end
end end
# Sends password reset email. # Sends password reset email.
def send_password_reset_email(user) def send_password_reset_email(user)
begin
return unless Rails.configuration.enable_email_verification return unless Rails.configuration.enable_email_verification
@user = user UserMailer.password_reset(user, reset_link(user), @settings).deliver_now
UserMailer.password_reset(@user, reset_link, logo_image, user_color).deliver_now rescue => e
logger.error "Support: Error in email delivery: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
else
flash[:success] = I18n.t("email_sent", email_type: t("reset_password.subtitle"))
end
end end
def send_user_promoted_email(user, role) def send_user_promoted_email(user, role)
begin
return unless Rails.configuration.enable_email_verification return unless Rails.configuration.enable_email_verification
UserMailer.user_promoted(user, role, root_url, logo_image, user_color).deliver_now UserMailer.user_promoted(user, role, root_url, @settings).deliver_now
rescue => e
logger.error "Support: Error in email delivery: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
end
end end
def send_user_demoted_email(user, role) def send_user_demoted_email(user, role)
begin
return unless Rails.configuration.enable_email_verification return unless Rails.configuration.enable_email_verification
UserMailer.user_demoted(user, role, root_url, logo_image, user_color).deliver_now UserMailer.user_demoted(user, role, root_url, @settings).deliver_now
rescue => e
logger.error "Support: Error in email delivery: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
end
end end
# Sends inivitation to join # Sends inivitation to join
def send_invitation_email(name, email, token) def send_invitation_email(name, email, token)
begin
return unless Rails.configuration.enable_email_verification return unless Rails.configuration.enable_email_verification
@token = token UserMailer.invite_email(name, email, invitation_link(token), @settings).deliver_now
UserMailer.invite_email(name, email, invitation_link, logo_image, user_color).deliver_now rescue => e
logger.error "Support: Error in email delivery: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
else
flash[:success] = I18n.t("administrator.flash.invite", email: email)
end
end end
def send_user_approved_email(user) def send_user_approved_email(user)
begin
return unless Rails.configuration.enable_email_verification return unless Rails.configuration.enable_email_verification
UserMailer.approve_user(user, root_url, logo_image, user_color).deliver_now UserMailer.approve_user(user, root_url, @settings).deliver_now
rescue => e
logger.error "Support: Error in email delivery: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
else
flash[:success] = I18n.t("email_sent", email_type: t("verify.verification"))
end
end end
def send_approval_user_signup_email(user) def send_approval_user_signup_email(user)
begin
return unless Rails.configuration.enable_email_verification return unless Rails.configuration.enable_email_verification
admin_emails = admin_emails() admin_emails = admin_emails()
unless admin_emails.empty? UserMailer.approval_user_signup(user, admins_url, admin_emails, @settings).deliver_now unless admin_emails.empty?
UserMailer.approval_user_signup(user, admins_url, logo_image, user_color, admin_emails).deliver_now rescue => e
logger.error "Support: Error in email delivery: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
end end
end end
def send_invite_user_signup_email(user) def send_invite_user_signup_email(user)
begin
return unless Rails.configuration.enable_email_verification return unless Rails.configuration.enable_email_verification
admin_emails = admin_emails() admin_emails = admin_emails()
unless admin_emails.empty? UserMailer.invite_user_signup(user, admins_url, admin_emails, @settings).deliver_now unless admin_emails.empty?
UserMailer.invite_user_signup(user, admins_url, logo_image, user_color, admin_emails).deliver_now rescue => e
logger.error "Support: Error in email delivery: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
end end
end end
private private
# Returns the link the user needs to click to verify their account # Returns the link the user needs to click to verify their account
def user_verification_link def user_verification_link(user)
edit_account_activation_url(token: @user.activation_token, email: @user.email) edit_account_activation_url(token: user.activation_token, email: user.email)
end end
def admin_emails def admin_emails
@ -91,21 +132,21 @@ module Emailer
if Rails.configuration.loadbalanced_configuration if Rails.configuration.loadbalanced_configuration
admins = admins.without_role(:super_admin) admins = admins.without_role(:super_admin)
.where(provider: user_settings_provider) .where(provider: @user_domain)
end end
admins.collect(&:email).join(",") admins.collect(&:email).join(",")
end end
def reset_link def reset_link(user)
edit_password_reset_url(@user.reset_token, email: @user.email) edit_password_reset_url(user.reset_token, email: user.email)
end end
def invitation_link def invitation_link(token)
if allow_greenlight_users? if allow_greenlight_accounts?
signup_url(invite_token: @token) signup_url(invite_token: token)
else else
root_url(invite_token: @token) root_url(invite_token: token)
end end
end end
end end

View File

@ -18,29 +18,29 @@
module Recorder module Recorder
extend ActiveSupport::Concern extend ActiveSupport::Concern
include ::BbbApi include RecordingsHelper
# Fetches all recordings for a room. # Fetches all recordings for a room.
def recordings(room_bbb_id, provider, search_params = {}, ret_search_params = false) def recordings(room_bbb_id, search_params = {}, ret_search_params = false)
res = bbb(provider).get_recordings(meetingID: room_bbb_id) res = get_recordings(room_bbb_id)
format_recordings(res, search_params, ret_search_params) format_recordings(res, search_params, ret_search_params)
end end
# Fetches a rooms public recordings. # Fetches a rooms public recordings.
def public_recordings(room_bbb_id, provider, search_params = {}, ret_search_params = false) def public_recordings(room_bbb_id, search_params = {}, ret_search_params = false)
search, order_col, order_dir, recs = recordings(room_bbb_id, provider, search_params, ret_search_params) search, order_col, order_dir, recs = recordings(room_bbb_id, search_params, ret_search_params)
[search, order_col, order_dir, recs.select { |r| r[:metadata][:"gl-listed"] == "true" }] [search, order_col, order_dir, recs.select { |r| r[:metadata][:"gl-listed"] == "true" }]
end end
# Makes paginated API calls to get recordings # Makes paginated API calls to get recordings
def all_recordings(room_bbb_ids, provider, search_params = {}, ret_search_params = false, search_name = false) def all_recordings(room_bbb_ids, search_params = {}, ret_search_params = false, search_name = false)
res = { recordings: [] } res = { recordings: [] }
until room_bbb_ids.empty? until room_bbb_ids.empty?
# bbb.get_recordings returns an object # bbb.get_recordings returns an object
# take only the array portion of the object that is returned # take only the array portion of the object that is returned
full_res = bbb(provider).get_recordings(meetingID: room_bbb_ids.pop(Rails.configuration.pagination_number)) full_res = get_multiple_recordings(room_bbb_ids.pop(Rails.configuration.pagination_number))
res[:recordings].push(*full_res[:recordings]) res[:recordings].push(*full_res[:recordings])
end end

View File

@ -19,20 +19,12 @@
module Registrar module Registrar
extend ActiveSupport::Concern extend ActiveSupport::Concern
def registration_method
Setting.find_or_create_by!(provider: user_settings_provider).get_value("Registration Method")
end
def open_registration
registration_method == Rails.configuration.registration_methods[:open]
end
def approval_registration def approval_registration
registration_method == Rails.configuration.registration_methods[:approval] @settings.get_value("Registration Method") == Rails.configuration.registration_methods[:approval]
end end
def invite_registration def invite_registration
registration_method == Rails.configuration.registration_methods[:invite] @settings.get_value("Registration Method") == Rails.configuration.registration_methods[:invite]
end end
# Returns a hash containing whether the user has been invited and if they # Returns a hash containing whether the user has been invited and if they

View File

@ -0,0 +1,161 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
module Rolify
extend ActiveSupport::Concern
# Gets all roles
def all_roles(selected_role)
@roles = Role.editable_roles(@user_domain)
if @roles.count.zero?
Role.create_default_roles(@user_domain)
@roles = Role.editable_roles(@user_domain)
end
@selected_role = if selected_role.nil?
@roles.find_by(name: 'user')
else
@roles.find(selected_role)
end
@roles
end
# Creates a new role
def create_role(new_role_name)
# Make sure that the role name isn't a duplicate or a reserved name like super_admin or empty
return nil if Role.duplicate_name(new_role_name, @user_domain) || new_role_name.strip.empty?
Role.create_new_role(new_role_name, @user_domain)
end
# Updates a user's roles
def update_roles(roles)
# Check that the user can manage users
return true unless current_user.highest_priority_role.can_manage_users
new_roles = roles.split(' ').map(&:to_i)
old_roles = @user.roles.pluck(:id)
added_role_ids = new_roles - old_roles
removed_role_ids = old_roles - new_roles
added_roles = []
removed_roles = []
current_user_role = current_user.highest_priority_role
# Check that the user has the permissions to add all the new roles
added_role_ids.each do |id|
role = Role.find(id)
# Admins are able to add the admin role to other users. All other roles may only
# add roles with a higher priority
if (role.priority > current_user_role.priority || current_user_role.name == "admin") &&
role.provider == @user_domain
added_roles << role
else
return false
end
end
# Check that the user has the permissions to remove all the deleted roles
removed_role_ids.each do |id|
role = Role.find(id)
# Admins are able to remove the admin role from other users. All other roles may only
# remove roles with a higher priority
if (role.priority > current_user_role.priority || current_user_role.name == "admin") &&
role.provider == @user_domain
removed_roles << role
else
return false
end
end
# Send promoted/demoted emails
added_roles.each { |role| send_user_promoted_email(@user, role) if role.send_promoted_email }
removed_roles.each { |role| send_user_demoted_email(@user, role) if role.send_demoted_email }
# Update the roles
@user.roles.delete(removed_roles)
@user.roles << added_roles
# Make sure each user always has at least the user role
@user.roles = [Role.find_by(name: "user", provider: @user_domain)] if @user.roles.count.zero?
@user.save!
end
# Updates a roles priority
def update_priority(role_to_update)
user_role = Role.find_by(name: "user", provider: @user_domain)
admin_role = Role.find_by(name: "admin", provider: @user_domain)
current_user_role = current_user.highest_priority_role
# Users aren't allowed to update the priority of the admin or user roles
return false if role_to_update.include?(user_role.id.to_s) || role_to_update.include?(admin_role.id.to_s)
# Restrict users to only updating the priority for roles in their domain with a higher
# priority
role_to_update.each do |id|
role = Role.find(id)
return false if role.priority <= current_user_role.priority || role.provider != @user_domain
end
# Update the roles priority including the user role
top_priority = 0
role_to_update.each_with_index do |id, index|
new_priority = index + [current_user_role.priority, 0].max + 1
top_priority = new_priority
Role.where(id: id).update_all(priority: new_priority)
end
user_role.priority = top_priority + 1
user_role.save!
end
# Update Permissions
def update_permissions(role)
current_user_role = current_user.highest_priority_role
# Checks that it is valid for the provider to update the role
return false if role.priority <= current_user_role.priority || role.provider != @user_domain
role_params = params.require(:role).permit(:name)
permission_params = params.require(:role).permit(:can_create_rooms, :send_promoted_email,
:send_demoted_email, :can_edit_site_settings, :can_edit_roles, :can_manage_users, :colour)
# Role is a default role so users can't change the name
role_params[:name] = role.name if Role::RESERVED_ROLE_NAMES.include?(role.name)
# Make sure if the user is updating the role name that the role name is valid
if role.name != role_params[:name] && !Role.duplicate_name(role_params[:name], @user_domain) &&
!role_params[:name].strip.empty?
role.name = role_params[:name]
elsif role.name != role_params[:name]
return false
end
role.update(permission_params)
role.save!
end
end

View File

@ -24,41 +24,43 @@ class PasswordResetsController < ApplicationController
before_action :valid_user, only: [:edit, :update] before_action :valid_user, only: [:edit, :update]
before_action :check_expiration, only: [:edit, :update] before_action :check_expiration, only: [:edit, :update]
def index # POST /password_resets/new
def new
end end
# POST /password_resets
def create def create
@user = User.find_by(email: params[:password_reset][:email].downcase) begin
if @user # Check if user exists and throw an error if he doesn't
@user = User.find_by!(email: params[:password_reset][:email].downcase)
@user.create_reset_digest @user.create_reset_digest
send_password_reset_email(@user) send_password_reset_email(@user)
flash[:success] = I18n.t("email_sent", email_type: t("reset_password.subtitle"))
redirect_to root_path redirect_to root_path
else rescue
flash[:alert] = I18n.t("no_user_email_exists") # User doesn't exist
redirect_to new_password_reset_path redirect_to new_password_reset_path, flash: { alert: I18n.t("no_user_email_exists") }
end end
rescue => e
logger.error "Support: Error in email delivery: #{e}"
redirect_to root_path, alert: I18n.t(params[:message], default: I18n.t("delivery_error"))
end end
# GET /password_resets/:id/edit
def edit def edit
end end
# PATCH /password_resets/:id
def update def update
# Check if password is valid
if params[:user][:password].empty? if params[:user][:password].empty?
flash.now[:alert] = I18n.t("password_empty_notice") flash.now[:alert] = I18n.t("password_empty_notice")
render 'edit'
elsif params[:user][:password] != params[:user][:password_confirmation] elsif params[:user][:password] != params[:user][:password_confirmation]
# Password does not match password confirmation
flash.now[:alert] = I18n.t("password_different_notice") flash.now[:alert] = I18n.t("password_different_notice")
render 'edit'
elsif @user.update_attributes(user_params) elsif @user.update_attributes(user_params)
flash[:success] = I18n.t("password_reset_success") # Successfully reset password
redirect_to root_path return redirect_to root_path, flash: { success: I18n.t("password_reset_success") }
else
render 'edit'
end end
render 'edit'
end end
private private
@ -84,6 +86,7 @@ class PasswordResetsController < ApplicationController
end end
end end
# Redirects to 404 if emails are not enabled
def disable_password_reset def disable_password_reset
redirect_to '/404' redirect_to '/404'
end end

View File

@ -23,23 +23,23 @@ class RecordingsController < ApplicationController
META_LISTED = "gl-listed" META_LISTED = "gl-listed"
# POST /:meetingID/:record_id # POST /:meetingID/:record_id
def update_recording def update
meta = { meta = {
"meta_#{META_LISTED}" => (params[:state] == "public"), "meta_#{META_LISTED}" => (params[:state] == "public"),
} }
res = @room.update_recording(params[:record_id], meta) res = update_recording(params[:record_id], meta)
# Redirects to the page that made the initial request # Redirects to the page that made the initial request
redirect_to request.referrer if res[:updated] redirect_back fallback_location: root_path if res[:updated]
end end
# DELETE /:meetingID/:record_id # DELETE /:meetingID/:record_id
def delete_recording def delete
@room.delete_recording(params[:record_id]) delete_recording(params[:record_id])
# Redirects to the page that made the initial request # Redirects to the page that made the initial request
redirect_to request.referrer redirect_back fallback_location: root_path
end end
private private

View File

@ -17,7 +17,6 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
class RoomsController < ApplicationController class RoomsController < ApplicationController
include RecordingsHelper
include Pagy::Backend include Pagy::Backend
include Recorder include Recorder
@ -32,42 +31,47 @@ class RoomsController < ApplicationController
# POST / # POST /
def create def create
redirect_to(root_path) && return unless current_user # Return to root if user is not signed in
return redirect_to root_path unless current_user
# Check if the user has not exceeded the room limit
return redirect_to current_user.main_room, flash: { alert: I18n.t("room.room_limit") } if room_limit_exceeded return redirect_to current_user.main_room, flash: { alert: I18n.t("room.room_limit") } if room_limit_exceeded
# Create room
@room = Room.new(name: room_params[:name], access_code: room_params[:access_code]) @room = Room.new(name: room_params[:name], access_code: room_params[:access_code])
@room.owner = current_user @room.owner = current_user
@room.room_settings = create_room_settings_string(room_params[:mute_on_join], @room.room_settings = create_room_settings_string(room_params)
room_params[:require_moderator_approval], room_params[:anyone_can_start], room_params[:all_join_moderator])
# Save the room
if @room.save if @room.save
logger.info("Support: #{current_user.email} has created a new room #{@room.uid}.") logger.info "Support: #{current_user.email} has created a new room #{@room.uid}."
# Start the room if auto join was turned on
if room_params[:auto_join] == "1" if room_params[:auto_join] == "1"
start start
else else
flash[:success] = I18n.t("room.create_room_success") redirect_to @room, flash: { success: I18n.t("room.create_room_success") }
redirect_to @room
end end
else else
flash[:alert] = I18n.t("room.create_room_error") redirect_to current_user.main_room, flash: { alert: I18n.t("room.create_room_error") }
redirect_to current_user.main_room
end end
end end
# GET /:room_uid # GET /:room_uid
def show def show
@is_running = @room.running?
@anyone_can_start = JSON.parse(@room[:room_settings])["anyoneCanStart"] @anyone_can_start = JSON.parse(@room[:room_settings])["anyoneCanStart"]
@room_running = room_running?(@room.bbb_id)
# If its the current user's room
if current_user && @room.owned_by?(current_user) if current_user && @room.owned_by?(current_user)
if current_user.highest_priority_role.can_create_rooms if current_user.highest_priority_role.can_create_rooms
# User is allowed to have rooms
@search, @order_column, @order_direction, recs = @search, @order_column, @order_direction, recs =
recordings(@room.bbb_id, @user_domain, params.permit(:search, :column, :direction), true) recordings(@room.bbb_id, params.permit(:search, :column, :direction), true)
@pagy, @recordings = pagy_array(recs) @pagy, @recordings = pagy_array(recs)
else else
# Render view for users that cant create rooms
@recent_rooms = Room.where(id: cookies.encrypted["#{current_user.uid}_recently_joined_rooms"]) @recent_rooms = Room.where(id: cookies.encrypted["#{current_user.uid}_recently_joined_rooms"])
render :cant_create_rooms render :cant_create_rooms
end end
@ -84,7 +88,7 @@ class RoomsController < ApplicationController
end end
@search, @order_column, @order_direction, pub_recs = @search, @order_column, @order_direction, pub_recs =
public_recordings(@room.bbb_id, @user_domain, params.permit(:search, :column, :direction), true) public_recordings(@room.bbb_id, params.permit(:search, :column, :direction), true)
@pagy, @public_recordings = pagy_array(pub_recs) @pagy, @public_recordings = pagy_array(pub_recs)
@ -94,20 +98,13 @@ class RoomsController < ApplicationController
# PATCH /:room_uid # PATCH /:room_uid
def update def update
if params[:setting] == "rename_block" if params[:setting] == "rename_header"
@room = Room.find_by!(uid: params[:room_block_uid])
update_room_attributes("name")
elsif params[:setting] == "rename_header"
update_room_attributes("name") update_room_attributes("name")
elsif params[:setting] == "rename_recording" elsif params[:setting] == "rename_recording"
@room.update_recording(params[:record_id], "meta_name" => params[:record_name]) update_recording(params[:record_id], "meta_name" => params[:record_name])
end end
if request.referrer redirect_back fallback_location: room_path
redirect_to request.referrer
else
redirect_to room_path
end
end end
# POST /:room_uid # POST /:room_uid
@ -115,10 +112,8 @@ class RoomsController < ApplicationController
return redirect_to root_path, return redirect_to root_path,
flash: { alert: I18n.t("administrator.site_settings.authentication.user-info") } if auth_required flash: { alert: I18n.t("administrator.site_settings.authentication.user-info") } if auth_required
opts = default_meeting_options
unless @room.owned_by?(current_user) unless @room.owned_by?(current_user)
# Don't allow users to join unless they have a valid access code or the room doesn't # Don't allow users to join unless they have a valid access code or the room doesn't have an access code
# have an access code
if @room.access_code && !@room.access_code.empty? && @room.access_code != session[:access_code] if @room.access_code && !@room.access_code.empty? && @room.access_code != session[:access_code]
return redirect_to room_path(room_uid: params[:room_uid]), flash: { alert: I18n.t("room.access_code_required") } return redirect_to room_path(room_uid: params[:room_uid]), flash: { alert: I18n.t("room.access_code_required") }
end end
@ -138,41 +133,41 @@ class RoomsController < ApplicationController
if current_user if current_user
# create or update cookie to track the three most recent rooms a user joined # create or update cookie to track the three most recent rooms a user joined
recently_joined_rooms = cookies.encrypted["#{current_user.uid}_recently_joined_rooms"].to_a recently_joined_rooms = cookies.encrypted["#{current_user.uid}_recently_joined_rooms"].to_a
cookies.encrypted["#{current_user.uid}_recently_joined_rooms"] = recently_joined_rooms.prepend(@room.id) cookies.encrypted["#{current_user.uid}_recently_joined_rooms"] =
.uniq[0..2] recently_joined_rooms.prepend(@room.id).uniq[0..2]
end end
logger.info("Support: #{current_user.present? ? current_user.email : @join_name} is joining room #{@room.uid}") logger.info "Support: #{current_user.present? ? current_user.email : @join_name} is joining room #{@room.uid}"
join_room(default_meeting_options)
join_room(opts)
end end
# DELETE /:room_uid # DELETE /:room_uid
def destroy def destroy
# Don't delete the users home room. # Don't delete the users home room.
@room.destroy if @room.owned_by?(current_user) && @room != current_user.main_room if @room.owned_by?(current_user) && @room != current_user.main_room
@room.destroy
delete_all_recordings(@room.bbb_id)
end
redirect_to current_user.main_room redirect_to current_user.main_room
end end
# POST room/join # POST /room/join
def join_specific_room def join_specific_room
room_uid = params[:join_room][:url].split('/').last room_uid = params[:join_room][:url].split('/').last
begin begin
@room = Room.find_by(uid: room_uid) @room = Room.find_by!(uid: room_uid)
rescue ActiveRecord::RecordNotFound rescue ActiveRecord::RecordNotFound
return redirect_to current_user.main_room, alert: I18n.t("room.no_room.invalid_room_uid") return redirect_to current_user.main_room, alert: I18n.t("room.no_room.invalid_room_uid")
end end
return redirect_to current_user.main_room, alert: I18n.t("room.no_room.invalid_room_uid") if @room.nil?
redirect_to room_path(@room) redirect_to room_path(@room)
end end
# POST /:room_uid/start # POST /:room_uid/start
def start def start
logger.info("Support: #{current_user.email} is starting room #{@room.uid}") logger.info "Support: #{current_user.email} is starting room #{@room.uid}"
# Join the user in and start the meeting. # Join the user in and start the meeting.
opts = default_meeting_options opts = default_meeting_options
@ -184,7 +179,7 @@ class RoomsController < ApplicationController
opts[:require_moderator_approval] = room_settings["requireModeratorApproval"] opts[:require_moderator_approval] = room_settings["requireModeratorApproval"]
begin begin
redirect_to @room.join_path(current_user.name, opts, current_user.uid) redirect_to join_path(@room, current_user.name, opts, current_user.uid)
rescue BigBlueButton::BigBlueButtonException => e rescue BigBlueButton::BigBlueButtonException => e
logger.error("Support: #{@room.uid} start failed: #{e}") logger.error("Support: #{@room.uid} start failed: #{e}")
@ -208,7 +203,8 @@ class RoomsController < ApplicationController
update_room_attributes("name") if @room.name != room_params[:name] update_room_attributes("name") if @room.name != room_params[:name]
# Update the room's access code if it has changed # Update the room's access code if it has changed
update_room_attributes("access_code") if @room.access_code != room_params[:access_code] update_room_attributes("access_code") if @room.access_code != room_params[:access_code]
rescue StandardError rescue => e
logger.error "Error in updating room settings: #{e}"
flash[:alert] = I18n.t("room.update_settings_error") flash[:alert] = I18n.t("room.update_settings_error")
else else
flash[:success] = I18n.t("room.update_settings_success") flash[:success] = I18n.t("room.update_settings_success")
@ -218,7 +214,7 @@ class RoomsController < ApplicationController
# GET /:room_uid/logout # GET /:room_uid/logout
def logout def logout
logger.info("Support: #{current_user.present? ? current_user.email : 'Guest'} has left room #{@room.uid}") logger.info "Support: #{current_user.present? ? current_user.email : 'Guest'} has left room #{@room.uid}"
# Redirect the correct page. # Redirect the correct page.
redirect_to @room redirect_to @room
@ -240,8 +236,7 @@ class RoomsController < ApplicationController
if update_type.eql? "name" if update_type.eql? "name"
@room.update_attributes(name: params[:room_name] || room_params[:name]) @room.update_attributes(name: params[:room_name] || room_params[:name])
elsif update_type.eql? "settings" elsif update_type.eql? "settings"
room_settings_string = create_room_settings_string(room_params[:mute_on_join], room_settings_string = create_room_settings_string(room_params)
room_params[:require_moderator_approval], room_params[:anyone_can_start], room_params[:all_join_moderator])
@room.update_attributes(room_settings: room_settings_string) @room.update_attributes(room_settings: room_settings_string)
elsif update_type.eql? "access_code" elsif update_type.eql? "access_code"
@room.update_attributes(access_code: room_params[:access_code]) @room.update_attributes(access_code: room_params[:access_code])
@ -249,15 +244,15 @@ class RoomsController < ApplicationController
end end
end end
def create_room_settings_string(mute_res, require_approval_res, start_res, join_mod) def create_room_settings_string(options)
room_settings = {} room_settings = {}
room_settings["muteOnStart"] = mute_res == "1" room_settings["muteOnStart"] = options[:mute_on_join] == "1"
room_settings["requireModeratorApproval"] = require_approval_res == "1" room_settings["requireModeratorApproval"] = options[:require_moderator_approval] == "1"
room_settings["anyoneCanStart"] = start_res == "1" room_settings["anyoneCanStart"] = options[:anyone_can_start] == "1"
room_settings["joinModerator"] = join_mod == "1" room_settings["joinModerator"] = options[:all_join_moderator] == "1"
room_settings.to_json room_settings.to_json
end end
@ -289,15 +284,11 @@ class RoomsController < ApplicationController
end end
def validate_accepted_terms def validate_accepted_terms
if current_user redirect_to terms_path if current_user && !current_user&.accepted_terms
redirect_to terms_path unless current_user.accepted_terms
end
end end
def validate_verified_email def validate_verified_email
if current_user redirect_to account_activation_path(current_user) if current_user && !current_user&.activated?
redirect_to account_activation_path(current_user) unless current_user.activated?
end
end end
def verify_room_owner_verified def verify_room_owner_verified
@ -313,28 +304,28 @@ class RoomsController < ApplicationController
end end
def verify_user_not_admin def verify_user_not_admin
redirect_to admins_path if current_user && current_user&.has_role?(:super_admin) redirect_to admins_path if current_user&.has_role?(:super_admin)
end end
def auth_required def auth_required
Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Authentication") == "true" && @settings.get_value("Room Authentication") == "true" && current_user.nil?
current_user.nil?
end end
def room_limit_exceeded def room_limit_exceeded
limit = Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Limit").to_i limit = @settings.get_value("Room Limit").to_i
# Does not apply to admin # Does not apply to admin or users that aren't signed in
# 15+ option is used as unlimited # 15+ option is used as unlimited
return false if current_user&.has_role?(:admin) || limit == 15 return false if current_user&.has_role?(:admin) || limit == 15
current_user.rooms.count >= limit current_user.rooms.length >= limit
end end
helper_method :room_limit_exceeded
def join_room(opts) def join_room(opts)
room_settings = JSON.parse(@room[:room_settings]) room_settings = JSON.parse(@room[:room_settings])
if @room.running? || @room.owned_by?(current_user) || room_settings["anyoneCanStart"] if room_running?(@room.bbb_id) || @room.owned_by?(current_user) || room_settings["anyoneCanStart"]
# Determine if the user needs to join as a moderator. # Determine if the user needs to join as a moderator.
opts[:user_is_moderator] = @room.owned_by?(current_user) || room_settings["joinModerator"] opts[:user_is_moderator] = @room.owned_by?(current_user) || room_settings["joinModerator"]
@ -342,15 +333,15 @@ class RoomsController < ApplicationController
opts[:require_moderator_approval] = room_settings["requireModeratorApproval"] opts[:require_moderator_approval] = room_settings["requireModeratorApproval"]
if current_user if current_user
redirect_to @room.join_path(current_user.name, opts, current_user.uid) redirect_to join_path(@room, current_user.name, opts, current_user.uid)
else else
join_name = params[:join_name] || params[@room.invite_path][:join_name] join_name = params[:join_name] || params[@room.invite_path][:join_name]
redirect_to @room.join_path(join_name, opts) redirect_to join_path(@room, join_name, opts)
end end
else else
search_params = params[@room.invite_path] || params search_params = params[@room.invite_path] || params
@search, @order_column, @order_direction, pub_recs = @search, @order_column, @order_direction, pub_recs =
public_recordings(@room.bbb_id, @user_domain, search_params.permit(:search, :column, :direction), true) public_recordings(@room.bbb_id, search_params.permit(:search, :column, :direction), true)
@pagy, @public_recordings = pagy_array(pub_recs) @pagy, @public_recordings = pagy_array(pub_recs)
@ -362,4 +353,17 @@ class RoomsController < ApplicationController
def incorrect_user_domain def incorrect_user_domain
Rails.configuration.loadbalanced_configuration && @room.owner.provider != @user_domain Rails.configuration.loadbalanced_configuration && @room.owner.provider != @user_domain
end end
# Default, unconfigured meeting options.
def default_meeting_options
invite_msg = I18n.t("invite_message")
{
user_is_moderator: false,
meeting_logout_url: request.base_url + logout_room_path(@room),
meeting_recorded: true,
moderator_message: "#{invite_msg}\n\n#{request.base_url + room_path(@room)}",
host: request.host,
recording_default_visibility: @settings.get_value("Default Recording Visibility") == "public"
}
end
end end

View File

@ -17,21 +17,16 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
class SessionsController < ApplicationController class SessionsController < ApplicationController
include Authenticator
include Registrar include Registrar
include Emailer include Emailer
include LdapAuthenticator include LdapAuthenticator
skip_before_action :verify_authenticity_token, only: [:omniauth, :fail] skip_before_action :verify_authenticity_token, only: [:omniauth, :fail]
# GET /users/logout
def destroy
logout
redirect_to root_path
end
# POST /users/login # POST /users/login
def create def create
logger.info("Support: #{session_params[:email]} is attempting to login.") logger.info "Support: #{session_params[:email]} is attempting to login."
admin = User.find_by(email: session_params[:email]) admin = User.find_by(email: session_params[:email])
if admin&.has_role? :super_admin if admin&.has_role? :super_admin
@ -48,11 +43,22 @@ class SessionsController < ApplicationController
login(user) login(user)
end end
# GET /users/logout
def destroy
logout
redirect_to root_path
end
# GET/POST /auth/:provider/callback # GET/POST /auth/:provider/callback
def omniauth def omniauth
@auth = request.env['omniauth.auth'] @auth = request.env['omniauth.auth']
begin
process_signin process_signin
rescue => e
logger.error "Error authenticating via omniauth: #{e}"
omniauth_fail
end
end end
# POST /auth/failure # POST /auth/failure
@ -81,15 +87,16 @@ class SessionsController < ApplicationController
result = send_ldap_request(params[:session], ldap_config) result = send_ldap_request(params[:session], ldap_config)
if result return redirect_to(ldap_signin_path, alert: I18n.t("invalid_credentials")) unless result
result = result.first
else
return redirect_to(ldap_signin_path, alert: I18n.t("invalid_credentials"))
end
@auth = parse_auth(result, ENV['LDAP_ROLE_FIELD']) @auth = parse_auth(result.first, ENV['LDAP_ROLE_FIELD'])
begin
process_signin process_signin
rescue => e
logger.error "Support: Error authenticating via omniauth: #{e}"
omniauth_fail
end
end end
private private
@ -112,7 +119,6 @@ class SessionsController < ApplicationController
end end
def process_signin def process_signin
begin
@user_exists = check_user_exists @user_exists = check_user_exists
if !@user_exists && @auth['provider'] == "twitter" if !@user_exists && @auth['provider'] == "twitter"
@ -124,35 +130,28 @@ class SessionsController < ApplicationController
user = User.from_omniauth(@auth) user = User.from_omniauth(@auth)
logger.info("Support: Auth user #{user.email} is attempting to login.") logger.info "Support: Auth user #{user.email} is attempting to login."
# Add pending role if approval method and is a new user # Add pending role if approval method and is a new user
if approval_registration && !@user_exists if approval_registration && !@user_exists
user.add_role :pending user.add_role :pending
# Inform admins that a user signed up if emails are turned on # Inform admins that a user signed up if emails are turned on
send_approval_user_signup_email(user) if Rails.configuration.enable_email_verification send_approval_user_signup_email(user)
return redirect_to root_path, flash: { success: I18n.t("registration.approval.signup") } return redirect_to root_path, flash: { success: I18n.t("registration.approval.signup") }
end end
send_invite_user_signup_email(user) if Rails.configuration.enable_email_verification && send_invite_user_signup_email(user) if invite_registration && !@user_exists
invite_registration && !@user_exists
login(user) login(user)
if @auth['provider'] == "twitter" if @auth['provider'] == "twitter"
flash[:alert] = if allow_user_signup? && allow_greenlight_accounts? flash[:alert] = if allow_user_signup? && allow_greenlight_accounts?
I18n.t("registration.deprecated.twitter_signin", I18n.t("registration.deprecated.twitter_signin", link: signup_path(old_twitter_user_id: user.id))
link: signup_path(old_twitter_user_id: user.id))
else else
I18n.t("registration.deprecated.twitter_signin", I18n.t("registration.deprecated.twitter_signin", link: signin_path(old_twitter_user_id: user.id))
link: signin_path(old_twitter_user_id: user.id))
end end
end end
rescue => e
logger.error "Support: Error authenticating via omniauth: #{e}"
omniauth_fail
end
end end
end end

View File

@ -18,7 +18,6 @@
class ThemesController < ApplicationController class ThemesController < ApplicationController
skip_before_action :maintenance_mode? skip_before_action :maintenance_mode?
before_action :provider_settings
# GET /primary # GET /primary
def index def index
@ -39,10 +38,4 @@ class ThemesController < ApplicationController
format.css { render body: @compiled } format.css { render body: @compiled }
end end
end end
private
def provider_settings
@settings = Setting.find_or_create_by(provider: user_settings_provider)
end
end end

View File

@ -17,14 +17,16 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
class UsersController < ApplicationController class UsersController < ApplicationController
include RecordingsHelper
include Pagy::Backend include Pagy::Backend
include Authenticator
include Emailer include Emailer
include Registrar include Registrar
include Recorder include Recorder
include Rolify
before_action :find_user, only: [:edit, :update, :destroy] before_action :find_user, only: [:edit, :change_password, :delete_account, :update, :destroy]
before_action :ensure_unauthenticated, only: [:new, :create, :signin] before_action :ensure_unauthenticated, only: [:new, :create, :signin]
before_action :check_admin_of, only: [:edit, :change_password, :delete_account]
# POST /u # POST /u
def create def create
@ -43,7 +45,7 @@ class UsersController < ApplicationController
# User has passed all validations required # User has passed all validations required
@user.save @user.save
logger.info("Support: #{@user.email} user has been created.") logger.info "Support: #{@user.email} user has been created."
# Set user to pending and redirect if Approval Registration is set # Set user to pending and redirect if Approval Registration is set
if approval_registration if approval_registration
@ -53,12 +55,12 @@ class UsersController < ApplicationController
flash: { success: I18n.t("registration.approval.signup") } unless Rails.configuration.enable_email_verification flash: { success: I18n.t("registration.approval.signup") } unless Rails.configuration.enable_email_verification
end end
send_registration_email if Rails.configuration.enable_email_verification send_registration_email
# Sign in automatically if email verification is disabled or if user is already verified. # Sign in automatically if email verification is disabled or if user is already verified.
login(@user) && return if !Rails.configuration.enable_email_verification || @user.email_verified login(@user) && return if !Rails.configuration.enable_email_verification || @user.email_verified
send_verification send_activation_email(@user)
redirect_to root_path redirect_to root_path
end end
@ -109,11 +111,15 @@ class UsersController < ApplicationController
# GET /u/:user_uid/edit # GET /u/:user_uid/edit
def edit def edit
if current_user redirect_to root_path unless current_user
redirect_to current_user.main_room if @user != current_user && !current_user.admin_of?(@user)
else
redirect_to root_path
end end
# GET /u/:user_uid/change_password
def change_password
end
# GET /u/:user_uid/delete_account
def delete_account
end end
# PATCH /u/:user_uid/edit # PATCH /u/:user_uid/edit
@ -139,31 +145,32 @@ class UsersController < ApplicationController
if errors.empty? && @user.save if errors.empty? && @user.save
# Notify the user that their account has been updated. # Notify the user that their account has been updated.
flash[:success] = I18n.t("info_update_success") redirect_to redirect_path, flash: { success: I18n.t("info_update_success") }
redirect_to redirect_path
else else
# Append custom errors. # Append custom errors.
errors.each { |k, v| @user.errors.add(k, v) } errors.each { |k, v| @user.errors.add(k, v) }
render :edit, params: { settings: params[:settings] } render :edit, params: { settings: params[:settings] }
end end
elsif user_params[:email] != @user.email && @user.update_attributes(user_params) && update_roles
@user.update_attributes(email_verified: false)
flash[:success] = I18n.t("info_update_success")
redirect_to redirect_path
elsif @user.update_attributes(user_params) && update_roles
update_locale(@user)
flash[:success] = I18n.t("info_update_success")
redirect_to redirect_path
else else
if @user.update_attributes(user_params)
@user.update_attributes(email_verified: false) if user_params[:email] != @user.email
user_locale(@user)
if update_roles(params[:user][:role_ids])
return redirect_to redirect_path, flash: { success: I18n.t("info_update_success") }
else
flash[:alert] = I18n.t("administrator.roles.invalid_assignment")
end
end
render :edit, params: { settings: params[:settings] } render :edit, params: { settings: params[:settings] }
end end
end end
# DELETE /u/:user_uid # DELETE /u/:user_uid
def destroy def destroy
logger.info("Support: #{current_user.email} is deleting #{@user.email}.") logger.info "Support: #{current_user.email} is deleting #{@user.email}."
if current_user && current_user == @user if current_user && current_user == @user
@user.destroy @user.destroy
@ -186,8 +193,7 @@ class UsersController < ApplicationController
def recordings def recordings
if current_user && current_user.uid == params[:user_uid] if current_user && current_user.uid == params[:user_uid]
@search, @order_column, @order_direction, recs = @search, @order_column, @order_direction, recs =
all_recordings(current_user.rooms.pluck(:bbb_id), current_user.provider, all_recordings(current_user.rooms.pluck(:bbb_id), params.permit(:search, :column, :direction), true)
params.permit(:search, :column, :direction), true)
@pagy, @recordings = pagy_array(recs) @pagy, @recordings = pagy_array(recs)
else else
redirect_to root_path redirect_to root_path
@ -219,29 +225,12 @@ class UsersController < ApplicationController
:new_password, :provider, :accepted_terms, :language) :new_password, :provider, :accepted_terms, :language)
end end
def send_verification
# Start email verification and redirect to root.
begin
send_activation_email(@user)
rescue => e
logger.error "Support: Error in email delivery: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
else
flash[:success] = I18n.t("email_sent", email_type: t("verify.verification"))
end
end
def send_registration_email def send_registration_email
begin
if invite_registration if invite_registration
send_invite_user_signup_email(@user) send_invite_user_signup_email(@user)
elsif approval_registration elsif approval_registration
send_approval_user_signup_email(@user) send_approval_user_signup_email(@user)
end end
rescue => e
logger.error "Support: Error in email delivery: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
end
end end
# Add validation errors to model if they exist # Add validation errors to model if they exist
@ -264,64 +253,8 @@ class UsersController < ApplicationController
invitation[:present] invitation[:present]
end end
# Updates as user's roles # Checks that the user is allowed to edit this user
def update_roles def check_admin_of
# Check that the user can manage users redirect_to current_user.main_room if current_user && @user != current_user && !current_user.admin_of?(@user)
if current_user.highest_priority_role.can_manage_users
new_roles = params[:user][:role_ids].split(' ').map(&:to_i)
old_roles = @user.roles.pluck(:id)
added_role_ids = new_roles - old_roles
removed_role_ids = old_roles - new_roles
added_roles = []
removed_roles = []
current_user_role = current_user.highest_priority_role
# Check that the user has the permissions to add all the new roles
added_role_ids.each do |id|
role = Role.find(id)
# Admins are able to add the admin role to other users. All other roles may only
# add roles with a higher priority
if (role.priority > current_user_role.priority || current_user_role.name == "admin") &&
role.provider == @user_domain
added_roles << role
else
flash[:alert] = I18n.t("administrator.roles.invalid_assignment")
return false
end
end
# Check that the user has the permissions to remove all the deleted roles
removed_role_ids.each do |id|
role = Role.find(id)
# Admins are able to remove the admin role from other users. All other roles may only
# remove roles with a higher priority
if (role.priority > current_user_role.priority || current_user_role.name == "admin") &&
role.provider == @user_domain
removed_roles << role
else
flash[:alert] = I18n.t("administrator.roles.invalid_removal")
return false
end
end
# Send promoted/demoted emails
added_roles.each { |role| send_user_promoted_email(@user, role) if role.send_promoted_email }
removed_roles.each { |role| send_user_demoted_email(@user, role) if role.send_demoted_email }
# Update the roles
@user.roles.delete(removed_roles)
@user.roles << added_roles
# Make sure each user always has at least the user role
@user.roles = [Role.find_by(name: "user", provider: @user_domain)] if @user.roles.count.zero?
@user.save!
else
true
end
end end
end end

View File

@ -1,20 +0,0 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
module AccountActivationsHelper
end

View File

@ -19,36 +19,17 @@
module AdminsHelper module AdminsHelper
include Pagy::Frontend include Pagy::Frontend
# Returns the action method of the current page
def active_page
route = Rails.application.routes.recognize_path(request.env['PATH_INFO'])
route[:action]
end
# Gets the email of the room owner to which the recording belongs to # Gets the email of the room owner to which the recording belongs to
def recording_owner_email(room_id) def recording_owner_email(room_id)
Room.find_by(bbb_id: room_id).owner.email Room.find_by(bbb_id: room_id).owner.email
end end
def display_invite
current_page?(admins_path) && invite_registration
end
def registration_method
Setting.find_or_create_by!(provider: user_settings_provider).get_value("Registration Method")
end
def invite_registration def invite_registration
registration_method == Rails.configuration.registration_methods[:invite] @settings.get_value("Registration Method") == Rails.configuration.registration_methods[:invite]
end
def approval_registration
registration_method == Rails.configuration.registration_methods[:approval]
end end
def room_authentication_string def room_authentication_string
if Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Authentication") == "true" if @settings.get_value("Room Authentication") == "true"
I18n.t("administrator.site_settings.authentication.enabled") I18n.t("administrator.site_settings.authentication.enabled")
else else
I18n.t("administrator.site_settings.authentication.disabled") I18n.t("administrator.site_settings.authentication.disabled")
@ -56,8 +37,7 @@ module AdminsHelper
end end
def recording_default_visibility_string def recording_default_visibility_string
if Setting.find_or_create_by!(provider: user_settings_provider) if @settings.get_value("Default Recording Visibility") == "public"
.get_value("Default Recording Visibility") == "public"
I18n.t("recording.visibility.public") I18n.t("recording.visibility.public")
else else
I18n.t("recording.visibility.unlisted") I18n.t("recording.visibility.unlisted")
@ -65,7 +45,7 @@ module AdminsHelper
end end
def registration_method_string def registration_method_string
case registration_method case @settings.get_value("Registration Method")
when Rails.configuration.registration_methods[:open] when Rails.configuration.registration_methods[:open]
I18n.t("administrator.site_settings.registration.methods.open") I18n.t("administrator.site_settings.registration.methods.open")
when Rails.configuration.registration_methods[:invite] when Rails.configuration.registration_methods[:invite]
@ -76,7 +56,7 @@ module AdminsHelper
end end
def room_limit_number def room_limit_number
Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Limit").to_i @settings.get_value("Room Limit").to_i
end end
def edit_disabled def edit_disabled

View File

@ -18,20 +18,8 @@
require 'bbb_api' require 'bbb_api'
require 'uri' require 'uri'
require 'i18n/language/mapping'
module ApplicationHelper module ApplicationHelper
include MeetingsHelper
include BbbApi
include I18n::Language::Mapping
# Gets all configured omniauth providers.
def configured_providers
Rails.configuration.providers.select do |provider|
Rails.configuration.send("omniauth_#{provider}")
end
end
# Determines which providers can show a login button in the login modal. # Determines which providers can show a login button in the login modal.
def iconset_providers def iconset_providers
providers = configured_providers & [:google, :twitter, :office365, :ldap] providers = configured_providers & [:google, :twitter, :office365, :ldap]
@ -50,53 +38,9 @@ module ApplicationHelper
end end
end end
# Determine if Greenlight is configured to allow user signups. # Determines if a form field needs the is-invalid class.
def allow_user_signup? def form_is_invalid?(obj, key)
Rails.configuration.allow_user_signup 'is-invalid' unless obj.errors.messages[key].empty?
end
# Determines if the BigBlueButton endpoint is the default.
def bigbluebutton_endpoint_default?
Rails.configuration.bigbluebutton_endpoint_default == Rails.configuration.bigbluebutton_endpoint
end
# Returns language selection options
def language_options
locales = I18n.available_locales
language_opts = [['<<<< ' + t("language_default") + ' >>>>', "default"]]
locales.each do |locale|
language_mapping = I18n::Language::Mapping.language_mapping_list[locale.to_s.gsub("_", "-")]
language_opts.push([language_mapping["nativeName"], locale.to_s])
end
language_opts.sort
end
# Parses markdown for rendering.
def markdown(text)
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML,
no_intra_emphasis: true,
fenced_code_blocks: true,
disable_indented_code_blocks: true,
autolink: true,
tables: true,
underline: true,
highlight: true)
markdown.render(text).html_safe
end
def allow_greenlight_accounts?
return Rails.configuration.allow_user_signup unless Rails.configuration.loadbalanced_configuration
return false unless @user_domain && !@user_domain.empty? && Rails.configuration.allow_user_signup
return false if @user_domain == "greenlight"
# Proceed with retrieving the provider info
begin
provider_info = retrieve_provider_info(@user_domain, 'api2', 'getUserGreenlightCredentials')
provider_info['provider'] == 'greenlight'
rescue => e
logger.info e
false
end
end end
# Return all the translations available in the client side through javascript # Return all the translations available in the client side through javascript
@ -118,6 +62,13 @@ module ApplicationHelper
current_user.main_room current_user.main_room
end end
# Returns the action method of the current page
def active_page
route = Rails.application.routes.recognize_path(request.env['PATH_INFO'])
route[:action]
end
def role_colour(role) def role_colour(role)
role.colour || Rails.configuration.primary_color_default role.colour || Rails.configuration.primary_color_default
end end

View File

@ -1,20 +0,0 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
module ErrorsHelper
end

View File

@ -1,20 +0,0 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
module MainHelper
end

View File

@ -1,20 +0,0 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
module MeetingsHelper
end

View File

@ -1,20 +0,0 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
module PasswordResetsHelper
end

View File

@ -17,8 +17,6 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
module RecordingsHelper module RecordingsHelper
include Pagy::Frontend
# Helper for converting BigBlueButton dates into the desired format. # Helper for converting BigBlueButton dates into the desired format.
def recording_date(date) def recording_date(date)
I18n.l date, format: "%B %d, %Y" I18n.l date, format: "%B %d, %Y"
@ -48,4 +46,9 @@ module RecordingsHelper
def room_uid_from_bbb(bbb_id) def room_uid_from_bbb(bbb_id)
Room.find_by(bbb_id: bbb_id)[:uid] Room.find_by(bbb_id: bbb_id)[:uid]
end end
# returns whether recording thumbnails are enabled on the server
def recording_thumbnails?
Rails.configuration.recording_thumbnails
end
end end

View File

@ -24,27 +24,13 @@ module RoomsHelper
end end
def room_authentication_required def room_authentication_required
Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Authentication") == "true" && @settings.get_value("Room Authentication") == "true" &&
current_user.nil? current_user.nil?
end end
def number_of_rooms_allowed
Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Limit").to_i
end
def room_limit_exceeded
limit = Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Limit").to_i
# Does not apply to admin or users that aren't signed in
# 15+ option is used as unlimited
return false if current_user&.has_role?(:admin) || limit == 15
current_user.rooms.length >= limit
end
def current_room_exceeds_limit(room) def current_room_exceeds_limit(room)
# Get how many rooms need to be deleted to reach allowed room number # Get how many rooms need to be deleted to reach allowed room number
limit = Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Limit").to_i limit = @settings.get_value("Room Limit").to_i
return false if current_user&.has_role?(:admin) || limit == 15 return false if current_user&.has_role?(:admin) || limit == 15

View File

@ -19,24 +19,11 @@
module ThemingHelper module ThemingHelper
# Returns the logo based on user's provider # Returns the logo based on user's provider
def logo_image def logo_image
Setting.find_or_create_by(provider: user_settings_provider) @settings.get_value("Branding Image") || Rails.configuration.branding_image_default
.get_value("Branding Image") || Rails.configuration.branding_image_default
end end
# Returns the primary color based on user's provider # Returns the primary color based on user's provider
def user_color def user_color
Setting.find_or_create_by(provider: user_settings_provider) @settings.get_value("Primary Color") || Rails.configuration.primary_color_default
.get_value("Primary Color") || Rails.configuration.primary_color_default
end
# Returns the user's provider in the settings context
def user_settings_provider
if Rails.configuration.loadbalanced_configuration && current_user && !current_user&.has_role?(:super_admin)
current_user.provider
elsif Rails.configuration.loadbalanced_configuration
@user_domain
else
"greenlight"
end
end end
end end

View File

@ -16,7 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
require 'i18n/language/mapping'
module UsersHelper module UsersHelper
include I18n::Language::Mapping
def recaptcha_enabled? def recaptcha_enabled?
Rails.configuration.recaptcha_enabled Rails.configuration.recaptcha_enabled
end end
@ -36,4 +40,29 @@ module UsersHelper
user.roles.by_priority.pluck(:id) | disallowed_roles user.roles.by_priority.pluck(:id) | disallowed_roles
end end
# Returns language selection options for user edit
def language_options
locales = I18n.available_locales
language_opts = [['<<<< ' + t("language_default") + ' >>>>', "default"]]
locales.each do |locale|
language_mapping = I18n::Language::Mapping.language_mapping_list[locale.to_s.gsub("_", "-")]
language_opts.push([language_mapping["nativeName"], locale.to_s])
end
language_opts.sort
end
# Parses markdown for rendering.
def markdown(text)
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML,
no_intra_emphasis: true,
fenced_code_blocks: true,
disable_indented_code_blocks: true,
autolink: true,
tables: true,
underline: true,
highlight: true)
markdown.render(text).html_safe
end
end end

View File

@ -17,7 +17,6 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
class ApplicationMailer < ActionMailer::Base class ApplicationMailer < ActionMailer::Base
add_template_helper(ThemingHelper)
default from: 'from@example.com' default from: 'from@example.com'
layout 'mailer' layout 'mailer'
end end

View File

@ -18,74 +18,83 @@
class UserMailer < ApplicationMailer class UserMailer < ApplicationMailer
include ApplicationHelper include ApplicationHelper
include ThemingHelper
default from: Rails.configuration.smtp_sender default from: Rails.configuration.smtp_sender
def verify_email(user, url, image, color) def verify_email(user, url, settings)
@settings = settings
@user = user @user = user
@url = url @url = url
@image = image @image = logo_image
@color = color @color = user_color
mail(to: @user.email, subject: t('landing.welcome')) mail(to: @user.email, subject: t('landing.welcome'))
end end
def password_reset(user, url, image, color) def password_reset(user, url, settings)
@settings = settings
@user = user @user = user
@url = url @url = url
@image = image @image = logo_image
@color = color @color = user_color
mail to: user.email, subject: t('reset_password.subtitle') mail to: user.email, subject: t('reset_password.subtitle')
end end
def user_promoted(user, role, url, image, color) def user_promoted(user, role, url, settings)
@settings = settings
@url = url @url = url
@admin_url = url + "admins" @admin_url = url + "admins"
@image = image @image = logo_image
@color = color @color = user_color
@role = translated_role_name(role) @role = translated_role_name(role)
mail to: user.email, subject: t('mailer.user.promoted.subtitle', role: translated_role_name(role)) mail to: user.email, subject: t('mailer.user.promoted.subtitle', role: translated_role_name(role))
end end
def user_demoted(user, role, url, image, color) def user_demoted(user, role, url, settings)
@settings = settings
@url = url @url = url
@root_url = url @root_url = url
@image = image @image = logo_image
@color = color @color = user_color
@role = translated_role_name(role) @role = translated_role_name(role)
mail to: user.email, subject: t('mailer.user.demoted.subtitle', role: translated_role_name(role)) mail to: user.email, subject: t('mailer.user.demoted.subtitle', role: translated_role_name(role))
end end
def invite_email(name, email, url, image, color) def invite_email(name, email, url, settings)
@settings = settings
@name = name @name = name
@email = email @email = email
@url = url @url = url
@image = image @image = logo_image
@color = color @color = user_color
mail to: email, subject: t('mailer.user.invite.subject') mail to: email, subject: t('mailer.user.invite.subject')
end end
def approve_user(user, url, image, color) def approve_user(user, url, settings)
@settings = settings
@user = user @user = user
@url = url @url = url
@image = image @image = logo_image
@color = color @color = user_color
mail to: user.email, subject: t('mailer.user.approve.subject') mail to: user.email, subject: t('mailer.user.approve.subject')
end end
def approval_user_signup(user, url, image, color, admin_emails) def approval_user_signup(user, url, admin_emails, settings)
@settings = settings
@user = user @user = user
@url = url @url = url
@image = image @image = logo_image
@color = color @color = user_color
mail to: admin_emails, subject: t('mailer.user.approve.signup.subject') mail to: admin_emails, subject: t('mailer.user.approve.signup.subject')
end end
def invite_user_signup(user, url, image, color, admin_emails) def invite_user_signup(user, url, admin_emails, settings)
@settings = settings
@user = user @user = user
@url = url @url = url
@image = image @image = logo_image
@color = color @color = user_color
mail to: admin_emails, subject: t('mailer.user.invite.signup.subject') mail to: admin_emails, subject: t('mailer.user.invite.signup.subject')
end end

View File

@ -27,8 +27,7 @@ class Ability
else else
highest_role = user.highest_priority_role highest_role = user.highest_priority_role
if highest_role.can_edit_site_settings if highest_role.can_edit_site_settings
can [:index, :site_settings, :server_recordings, :branding, :coloring, :coloring_lighten, :coloring_darken, can [:index, :site_settings, :server_recordings, :update_settings, :coloring, :registration_method], :admin
:room_authentication, :registration_method, :room_limit, :default_recording_visibility], :admin
end end
if highest_role.can_edit_roles if highest_role.can_edit_roles

View File

@ -19,128 +19,28 @@
require 'bbb_api' require 'bbb_api'
class Room < ApplicationRecord class Room < ApplicationRecord
include ::BbbApi
before_create :setup before_create :setup
before_destroy :delete_all_recordings
validates :name, presence: true validates :name, presence: true
belongs_to :owner, class_name: 'User', foreign_key: :user_id belongs_to :owner, class_name: 'User', foreign_key: :user_id
META_LISTED = "gl-listed"
# Determines if a user owns a room. # Determines if a user owns a room.
def owned_by?(user) def owned_by?(user)
return false if user.nil? return false if user.nil?
user.rooms.include?(self) user.rooms.include?(self)
end end
# Checks if a room is running on the BigBlueButton server.
def running?
bbb(owner.provider).is_meeting_running?(bbb_id)
end
# Determines the invite path for the room. # Determines the invite path for the room.
def invite_path def invite_path
"#{Rails.configuration.relative_url_root}/#{CGI.escape(uid)}" "#{Rails.configuration.relative_url_root}/#{CGI.escape(uid)}"
end end
# Creates a meeting on the BigBlueButton server.
def start_session(options = {})
create_options = {
record: options[:meeting_recorded].to_s,
logoutURL: options[:meeting_logout_url] || '',
moderatorPW: moderator_pw,
attendeePW: attendee_pw,
moderatorOnlyMessage: options[:moderator_message],
muteOnStart: options[:mute_on_start] || false,
"meta_#{META_LISTED}": options[:recording_default_visibility] || false,
"meta_bbb-origin-version": Greenlight::Application::VERSION,
"meta_bbb-origin": "Greenlight",
"meta_bbb-origin-server-name": options[:host]
}
create_options[:guestPolicy] = "ASK_MODERATOR" if options[:require_moderator_approval]
# Send the create request.
begin
meeting = bbb(owner.provider).create_meeting(name, bbb_id, create_options)
# Update session info.
unless meeting[:messageKey] == 'duplicateWarning'
update_attributes(sessions: sessions + 1,
last_session: DateTime.now)
end
rescue BigBlueButton::BigBlueButtonException => e
puts "BigBlueButton failed on create: #{e.key}: #{e.message}"
raise e
end
end
# Returns a URL to join a user into a meeting.
def join_path(name, options = {}, uid = nil)
# Create the meeting, even if it's running
start_session(options)
# Set meeting options.
options[:meeting_logout_url] ||= nil
options[:moderator_message] ||= ''
options[:user_is_moderator] ||= false
options[:meeting_recorded] ||= false
return call_invalid_res unless bbb(owner.provider)
# Get the meeting info.
meeting_info = bbb(owner.provider).get_meeting_info(bbb_id, nil)
# Determine the password to use when joining.
password = if options[:user_is_moderator]
meeting_info[:moderatorPW]
else
meeting_info[:attendeePW]
end
# Generate the join URL.
join_opts = {}
join_opts[:userID] = uid if uid
join_opts[:join_via_html5] = true
join_opts[:guest] = true if options[:require_moderator_approval] && !options[:user_is_moderator]
bbb(owner.provider).join_meeting_url(bbb_id, name, password, join_opts)
end
# Notify waiting users that a meeting has started. # Notify waiting users that a meeting has started.
def notify_waiting def notify_waiting
ActionCable.server.broadcast("#{uid}_waiting_channel", action: "started") ActionCable.server.broadcast("#{uid}_waiting_channel", action: "started")
end end
# Retrieves all the users in a room.
def participants
res = bbb(owner.provider).get_meeting_info(bbb_id, nil)
res[:attendees].map do |att|
User.find_by(uid: att[:userID], name: att[:fullName])
end
rescue BigBlueButton::BigBlueButtonException
# The meeting is most likely not running.
[]
end
def recording_count
bbb(owner.provider).get_recordings(meetingID: bbb_id)[:recordings].length
end
def update_recording(record_id, meta)
meta[:recordID] = record_id
bbb(owner.provider).send_api_request("updateRecordings", meta)
end
# Deletes a recording from a room.
def delete_recording(record_id)
bbb(owner.provider).delete_recordings(record_id)
end
private private
# Generates a uid for the room and BigBlueButton. # Generates a uid for the room and BigBlueButton.
@ -151,12 +51,6 @@ class Room < ApplicationRecord
self.attendee_pw = RandomPassword.generate(length: 12) self.attendee_pw = RandomPassword.generate(length: 12)
end end
# Deletes all recordings associated with the room.
def delete_all_recordings
record_ids = bbb(owner.provider).get_recordings(meetingID: bbb_id)[:recordings].pluck(:recordID)
delete_recording(record_ids) unless record_ids.empty?
end
# Generates a three character uid chunk. # Generates a three character uid chunk.
def uid_chunk def uid_chunk
charset = ("a".."z").to_a - %w(b i l o s) + ("2".."9").to_a - %w(5 8) charset = ("a".."z").to_a - %w(b i l o s) + ("2".."9").to_a - %w(5 8)

View File

@ -19,8 +19,6 @@
require 'bbb_api' require 'bbb_api'
class User < ApplicationRecord class User < ApplicationRecord
include ::BbbApi
attr_accessor :reset_token attr_accessor :reset_token
after_create :assign_default_role after_create :assign_default_role
after_create :initialize_main_room after_create :initialize_main_room
@ -203,12 +201,7 @@ class User < ApplicationRecord
end end
def greenlight_account? def greenlight_account?
return true unless provider # For testing cases when provider is set to null social_uid.nil?
return true if provider == "greenlight"
return false unless Rails.configuration.loadbalanced_configuration
# Proceed with fetching the provider info
provider_info = retrieve_provider_info(provider, 'api2', 'getUserGreenlightCredentials')
provider_info['provider'] == 'greenlight'
end end
def activation_token def activation_token

View File

@ -21,7 +21,9 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<p><%= t("verify.not_verified") %></p> <p><%= t("verify.not_verified") %></p>
<%= render "/shared/components/resend_button" %> <div class="btn-list text-right pt-8">
<%= button_to t("verify.resend"), resend_email_path, params: { email: params['email'], email_verified: false }, class: "btn btn-primary btn-space" %>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -22,7 +22,7 @@
<div class="input-group"> <div class="input-group">
<input id="branding-url" type="text" class="form-control" value="<%= logo_image %>"> <input id="branding-url" type="text" class="form-control" value="<%= logo_image %>">
<span class="input-group-append"> <span class="input-group-append">
<button id="branding-image" onclick="changeBrandingImage('<%= admin_branding_path %>')" class="btn btn-primary" type="button"><%= t("administrator.site_settings.branding.change") %></button> <button id="branding-image" onclick="changeBrandingImage('<%= admin_update_settings_path(setting: 'Branding Image') %>')" class="btn btn-primary" type="button"><%= t("administrator.site_settings.branding.change") %></button>
</span> </span>
</div> </div>
</div> </div>
@ -34,9 +34,9 @@
<label class="form-label"><%= t("administrator.site_settings.color.title") %></label> <label class="form-label"><%= t("administrator.site_settings.color.title") %></label>
<label class="form-label text-muted"><%= t("administrator.site_settings.color.info") %></label> <label class="form-label text-muted"><%= t("administrator.site_settings.color.info") %></label>
<div class="color-inputs"> <div class="color-inputs">
<input id="coloring-path-regular" type="hidden" value="<%= admin_coloring_path%>"> <input id="coloring-path-regular" type="hidden" value="<%= admin_coloring_path %>">
<input id="coloring-path-lighten" type="hidden" value="<%= admin_coloring_lighten_path%>"> <input id="coloring-path-lighten" type="hidden" value="<%= admin_update_settings_path(setting: "Primary Color Lighten") %>">
<input id="coloring-path-darken" type="hidden" value="<%= admin_coloring_darken_path%>"> <input id="coloring-path-darken" type="hidden" value="<%= admin_update_settings_path(setting: "Primary Color Darken") %>">
<div id="colorinput-regular" class="btn primary-regular mr-3"> <div id="colorinput-regular" class="btn primary-regular mr-3">
<%= t("administrator.site_settings.color.regular") %> <%= t("administrator.site_settings.color.regular") %>
@ -64,13 +64,13 @@
<%= registration_method_string %> <%= registration_method_string %>
</button> </button>
<div class="dropdown-menu" aria-labelledby="registrationMethods"> <div class="dropdown-menu" aria-labelledby="registrationMethods">
<%= button_to admin_change_registration_path("open"), class: "dropdown-item" do %> <%= button_to admin_change_registration_path(value: "open"), class: "dropdown-item" do %>
<%= t("administrator.site_settings.registration.methods.open") %> <%= t("administrator.site_settings.registration.methods.open") %>
<% end %> <% end %>
<%= button_to admin_change_registration_path("invite"), class: "dropdown-item" do %> <%= button_to admin_change_registration_path(value: "invite"), class: "dropdown-item" do %>
<%= t("administrator.site_settings.registration.methods.invite") %> <%= t("administrator.site_settings.registration.methods.invite") %>
<% end %> <% end %>
<%= button_to admin_change_registration_path("approval"), class: "dropdown-item" do %> <%= button_to admin_change_registration_path(value: "approval"), class: "dropdown-item" do %>
<%= t("administrator.site_settings.registration.methods.approval") %> <%= t("administrator.site_settings.registration.methods.approval") %>
<% end %> <% end %>
</div> </div>
@ -88,10 +88,10 @@
<%= room_authentication_string %> <%= room_authentication_string %>
</button> </button>
<div class="dropdown-menu" aria-labelledby="room-auth"> <div class="dropdown-menu" aria-labelledby="room-auth">
<%= button_to admin_room_authentication_path(value: "true"), class: "dropdown-item" do %> <%= button_to admin_update_settings_path(setting: "Room Authentication", value: "true"), class: "dropdown-item" do %>
<%= t("administrator.site_settings.authentication.enabled") %> <%= t("administrator.site_settings.authentication.enabled") %>
<% end %> <% end %>
<%= button_to admin_room_authentication_path(value: "false"), class: "dropdown-item" do %> <%= button_to admin_update_settings_path(setting: "Room Authentication", value: "false"), class: "dropdown-item" do %>
<%= t("administrator.site_settings.authentication.disabled") %> <%= t("administrator.site_settings.authentication.disabled") %>
<% end %> <% end %>
</div> </div>
@ -109,10 +109,10 @@
<%= recording_default_visibility_string %> <%= recording_default_visibility_string %>
</button> </button>
<div class="dropdown-menu" aria-labelledby="room-auth"> <div class="dropdown-menu" aria-labelledby="room-auth">
<%= button_to admin_recording_visibility_path(visibility: "public"), class: "dropdown-item" do %> <%= button_to admin_update_settings_path(setting: "Default Recording Visibility", value: "public"), class: "dropdown-item" do %>
<%= t("recording.visibility.public") %> <%= t("recording.visibility.public") %>
<% end %> <% end %>
<%= button_to admin_recording_visibility_path(visibility: "private"), class: "dropdown-item" do %> <%= button_to admin_update_settings_path(setting: "Default Recording Visibility", value: "private"), class: "dropdown-item" do %>
<%= t("recording.visibility.unlisted") %> <%= t("recording.visibility.unlisted") %>
<% end %> <% end %>
</div> </div>
@ -128,25 +128,25 @@
<div class="row gutters-xs"> <div class="row gutters-xs">
<div class="col-auto"> <div class="col-auto">
<label class="colorinput"> <label class="colorinput">
<%= button_to admin_room_limit_path(limit: 1), class: "colorinput-input" do %><% end %> <%= button_to admin_update_settings_path(setting: "Room Limit", value: 1), class: "colorinput-input" do %><% end %>
<span class="colorinput-color <%= room_limit_number == 1 ? "btn-primary" : "btn-outline-primary" %>">1</span> <span class="colorinput-color <%= room_limit_number == 1 ? "btn-primary" : "btn-outline-primary" %>">1</span>
</label> </label>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<label class="colorinput"> <label class="colorinput">
<%= button_to admin_room_limit_path(limit: 5), class: "colorinput-input" do %><% end %> <%= button_to admin_update_settings_path(setting: "Room Limit", value: 5), class: "colorinput-input" do %><% end %>
<span class="colorinput-color <%= room_limit_number == 5 ? "btn-primary" : "btn-outline-primary" %>">5</span> <span class="colorinput-color <%= room_limit_number == 5 ? "btn-primary" : "btn-outline-primary" %>">5</span>
</label> </label>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<label class="colorinput"> <label class="colorinput">
<%= button_to admin_room_limit_path(limit: 10), class: "colorinput-input" do %><% end %> <%= button_to admin_update_settings_path(setting: "Room Limit", value: 10), class: "colorinput-input" do %><% end %>
<span class="colorinput-color <%= room_limit_number == 10 ? "btn-primary" : "btn-outline-primary" %>">10</span> <span class="colorinput-color <%= room_limit_number == 10 ? "btn-primary" : "btn-outline-primary" %>">10</span>
</label> </label>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<label class="colorinput"> <label class="colorinput">
<%= button_to admin_room_limit_path(limit: 15), class: "colorinput-input" do %><% end %> <%= button_to admin_update_settings_path(setting: "Room Limit", value: 15), class: "colorinput-input" do %><% end %>
<span class="colorinput-color <%= room_limit_number == 15 ? "btn-primary" : "btn-outline-primary" %>">15+</span> <span class="colorinput-color <%= room_limit_number == 15 ? "btn-primary" : "btn-outline-primary" %>">15+</span>
</label> </label>
</div> </div>

View File

@ -29,7 +29,7 @@
%> %>
<% unless @role.nil? %> <% unless @role.nil? %>
<%= render "shared/components/admins_tags" %> <%= render "admins/components/admins_tags" %>
<% end %> <% end %>
<div class="form-group"> <div class="form-group">
@ -88,7 +88,7 @@
<td><%= user.provider %></td> <td><%= user.provider %></td>
<td class="text-center"> <td class="text-center">
<% roles = user.roles().pluck(:name) %> <% roles = user.roles().pluck(:name) %>
<%= render "shared/components/admins_role", role: user.highest_priority_role %> <%= render "admins/components/admins_role", role: user.highest_priority_role %>
</td> </td>
<td> <td>
<% if roles.include?("pending") %> <% if roles.include?("pending") %>

View File

@ -21,7 +21,7 @@
<%= render "admins/components/menu_buttons" %> <%= render "admins/components/menu_buttons" %>
</div> </div>
<div id="edit_user" class="col-lg-9"> <div id="edit_user" class="col-lg-9">
<%= render "shared/settings/setting_view", setting_id: "account", setting_title: t("settings.account.subtitle") %> <%= render "users/components/setting_view", setting_id: "account", setting_title: t("settings.account.subtitle") %>
</div> </div>
</div> </div>
</div> </div>

View File

@ -28,4 +28,4 @@
</div> </div>
</div> </div>
<%= render "shared/features" %> <%= render "main/components/features" %>

View File

@ -14,7 +14,7 @@
%> %>
<% valid_access_code = @room.access_code.nil? || @room.access_code.empty? || @room.access_code == session[:access_code] %> <% valid_access_code = @room.access_code.nil? || @room.access_code.empty? || @room.access_code == session[:access_code] %>
<%= render 'shared/room_event', render_recordings: valid_access_code do %> <%= render 'rooms/components/room_event', render_recordings: valid_access_code do %>
<% if room_authentication_required %> <% if room_authentication_required %>
<h2><%= t("administrator.site_settings.authentication.user-info") %></h2> <h2><%= t("administrator.site_settings.authentication.user-info") %></h2>
<% elsif !valid_access_code %> <% elsif !valid_access_code %>
@ -43,7 +43,7 @@
readonly: !current_user.nil?, readonly: !current_user.nil?,
autofocus: true autofocus: true
%> %>
<%= f.submit (!@is_running && @anyone_can_start)? t("room.start") : t("room.join"), class: "btn btn-primary btn-sm col-sm-3 form-control join-form" %> <%= f.submit (!@room_running && @anyone_can_start)? t("room.start") : t("room.join"), class: "btn btn-primary btn-sm col-sm-3 form-control join-form" %>
</div> </div>
<% end %> <% end %>
<% end %> <% end %>

View File

@ -66,7 +66,7 @@
<% end %> <% end %>
</div> </div>
<div class="offset-lg-1 col-lg-3 col-sm-12 force-bottom mt-5 pr-0"> <div class="offset-lg-1 col-lg-3 col-sm-12 force-bottom mt-5 pr-0">
<% if @is_running %> <% if @room_running %>
<%= button_to t("room.join"), room_path(@room), class: "btn btn-primary btn-block px-7 start-button float-right" %> <%= button_to t("room.join"), room_path(@room), class: "btn btn-primary btn-block px-7 start-button float-right" %>
<% else %> <% else %>
<% unless exceeds_limit %> <% unless exceeds_limit %>
@ -80,20 +80,20 @@
<% if current_user.rooms.length > 1 %> <% if current_user.rooms.length > 1 %>
<div class="col-lg-4 col-md-6 col-sm-12"> <div class="col-lg-4 col-md-6 col-sm-12">
<%= link_to current_user.main_room do %> <%= link_to current_user.main_room do %>
<%= render "shared/components/room_block", room: current_user.main_room %> <%= render "rooms/components/room_block", room: current_user.main_room %>
<% end %> <% end %>
</div> </div>
<% current_user.secondary_rooms.each do |room| %> <% current_user.secondary_rooms.each do |room| %>
<div class="col-lg-4 col-md-6 col-sm-12"> <div class="col-lg-4 col-md-6 col-sm-12">
<%= link_to room do %> <%= link_to room do %>
<%= render "shared/components/room_block", room: room %> <%= render "rooms/components/room_block", room: room %>
<% end %> <% end %>
</div> </div>
<%= render "shared/modals/delete_room_modal", recording_count: room.recording_count, room: room %> <%= render "shared/modals/delete_room_modal", room: room %>
<% end %> <% end %>
<% end %> <% end %>
<% unless room_limit_exceeded %> <% unless room_limit_exceeded %>
<%= render "shared/components/create_room_block"%> <%= render "rooms/components/create_room_block"%>
<% end %> <% end %>
</div> </div>
</div> </div>

View File

@ -13,7 +13,7 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
%> %>
<%= render 'shared/room_event', render_recordings: true do %> <%= render 'rooms/components/room_event', render_recordings: true do %>
<div class="row"> <div class="row">
<div class="col-9"> <div class="col-9">
<h3><%= t("room.wait.message") %></h3> <h3><%= t("room.wait.message") %></h3>

View File

@ -1,18 +0,0 @@
<%
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
%>
<div class="btn-list text-right pt-8">
<%= button_to t("verify.resend"), resend_email_path, params: { email: params['email'], email_verified: false }, class: "btn btn-primary btn-space" %>
</div>

View File

@ -14,12 +14,13 @@
%> %>
<div class="row mt-2"> <div class="row mt-2">
<% if search %>
<div class="col-4"> <div class="col-4">
<p class="subtitle"><%= subtitle %></p> <p class="subtitle"><%= subtitle %></p>
</div> </div>
<% if search %>
<div class="col-8"> <div class="col-8">
<% if display_invite %> <% if invite_registration %>
<div id="invite-user" class="d-inline-block float-right ml-3"> <div id="invite-user" class="d-inline-block float-right ml-3">
<%= link_to "#inviteModal", :class => "btn btn-primary", "data-toggle": "modal" do %> <%= link_to "#inviteModal", :class => "btn btn-primary", "data-toggle": "modal" do %>
<%= t("administrator.users.invite") %> <i class="fas fa-paper-plane ml-1"></i> <%= t("administrator.users.invite") %> <i class="fas fa-paper-plane ml-1"></i>
@ -43,6 +44,10 @@
</div> </div>
</div> </div>
</div> </div>
<% else %>
<div class="col-12">
<p class="subtitle"><%= subtitle %></p>
</div>
<% end %> <% end %>
</div> </div>

View File

@ -1,18 +0,0 @@
<%
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
%>
<div class="btn-list text-right pt-8">
<%= button_to t("terms.accept_existing"), terms_path, params: { accept: true }, class: "btn btn-primary btn-space" %>
</div>

View File

@ -34,8 +34,8 @@
<div class="card-footer"> <div class="card-footer">
<p> <p>
<%= t("modal.delete_room.warning").html_safe %> <%= t("modal.delete_room.warning").html_safe %>
<% if recording_count > 0 %> <% if @recordings.length > 0 %>
<%= t("modal.delete_room.recording_warning", recordings_num: recording_count).html_safe %> <%= t("modal.delete_room.recording_warning", recordings_num: @recordings.length).html_safe %>
<% end %> <% end %>
</p> </p>
</div> </div>

View File

@ -12,7 +12,15 @@
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
%> %>
<div class="container pt-6">
<%= render "shared/components/subtitle", subtitle: t("settings.title"), search: false %>
<div class="btn-list text-right pt-8"> <div class="row">
<%= button_to t("verify.accept"), confirm_path, params: { user_uid: params[:user_uid], email_verified: true }, class: "btn btn-primary btn-space" %> <div class="col-lg-3 mb-4">
<%= render "users/components/menu_buttons" %>
</div>
<div class="col-lg-9">
<%= render "users/components/setting_view", setting_id: "password", setting_title: t("settings.password.subtitle") %>
</div>
</div>
</div> </div>

View File

@ -0,0 +1,26 @@
<%
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
%>
<div class="list-group list-group-transparent mb-0">
<%= link_to edit_user_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "edit"}" do %>
<span class="icon mr-3"><i class="fas fa-user"></i></span><%= t("settings.account.title") %>
<% end %>
<%= link_to change_password_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "change_password"}" do %>
<span class="icon mr-3"><i class="fas fa-key"></i></span><%= t("settings.password.title") %>
<% end %>
<%= link_to delete_account_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "delete_account"}" do %>
<span class="icon mr-3"><i class="fas fa-trash-alt"></i></span><%= t("settings.delete.title") %>
<% end %>
</div>

View File

@ -17,10 +17,10 @@
<div class="card-body p-6"> <div class="card-body p-6">
<div class="card-title text-primary"> <div class="card-title text-primary">
<div class="form-group"> <div class="form-group">
<%= render "shared/components/subtitle", subtitle: setting_title, search: setting_id == "users" %> <%= render "shared/components/subtitle", subtitle: setting_title, search: false %>
</div> </div>
</div> </div>
<%= render "shared/settings/#{setting_id}" %> <%= render "users/components/#{setting_id}" %>
</div> </div>
<% end %> <% end %>

View File

@ -12,11 +12,15 @@
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
%> %>
<div class="container pt-6">
<%= render "shared/components/subtitle", subtitle: t("settings.title"), search: false %>
<div class="form-group">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-lg-3 mb-4">
<center><%= t("settings.design.not_supported") %></center> <%= render "users/components/menu_buttons" %>
</div>
<div class="col-lg-9">
<%= render "users/components/setting_view", setting_id: "delete", setting_title: t("settings.delete.subtitle") %>
</div> </div>
</div> </div>
</div> </div>

View File

@ -12,48 +12,15 @@
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
%> %>
<div class="container pt-6"> <div class="container pt-6">
<%= render "shared/components/subtitle", subtitle: t("settings.title"), search: false %> <%= render "shared/components/subtitle", subtitle: t("settings.title"), search: false %>
<div class="row"> <div class="row">
<div class="col-lg-3 mb-4"> <div class="col-lg-3 mb-4">
<div class="list-group list-group-transparent mb-0"> <%= render "users/components/menu_buttons" %>
<button id="account" class="list-group-item list-group-item-action dropdown-item setting-btn <%= "active" if !params[:setting] || params[:setting] == "account"%>">
<span class="icon mr-3"><i class="fas fa-user"></i></span><%= t("settings.account.title") %>
</button>
<% if @user.social_uid.nil? %>
<button id="password" class="list-group-item list-group-item-action dropdown-item setting-btn <%= "active" if params[:setting] == "password"%>">
<span class="icon mr-3"><i class="fas fa-lock"></i></span><%= t("settings.password.title") %>
</button>
<% end %>
<button id="delete" class="list-group-item list-group-item-action dropdown-item setting-btn <%= "active" if params[:setting] == "delete"%>">
<span class="icon mr-3"><i class="fas fa-trash-alt"></i></span><%= t("settings.delete.title") %>
</button>
</div> </div>
<% if @user.errors.any? %>
<h5 class="mt-8"><%= t("errors.title") %>:</h5>
<ul>
<% @user.errors.full_messages.each do |err| %>
<li class="text-danger"><%= err %>.</li>
<% end %>
</ul>
<% end %>
</div>
<div class="col-lg-9"> <div class="col-lg-9">
<%= render "shared/settings/setting_view", setting_id: "account", setting_title: t("settings.account.subtitle") %> <%= render "users/components/setting_view", setting_id: "account", setting_title: t("settings.account.subtitle") %>
<% if @user.social_uid.nil? %>
<%= render "shared/settings/setting_view", setting_id: "password", setting_title: t("settings.password.subtitle") %>
<% end %>
<%= render "shared/settings/setting_view", setting_id: "delete", setting_title: t("settings.delete.subtitle") %>
</div> </div>
</div> </div>
</div> </div>

View File

@ -24,7 +24,9 @@
<%= markdown(Rails.configuration.terms) %> <%= markdown(Rails.configuration.terms) %>
</div> </div>
<% if Rails.configuration.terms && current_user && !current_user.accepted_terms %> <% if Rails.configuration.terms && current_user && !current_user.accepted_terms %>
<%= render "/shared/components/terms_button" %> <div class="btn-list text-right pt-8">
<%= button_to t("terms.accept_existing"), terms_path, params: { accept: true }, class: "btn btn-primary btn-space" %>
</div>
<% end %> <% end %>
</form> </form>
</div> </div>

View File

@ -1,6 +1,9 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'office365' require 'office365'
require 'omniauth_options'
include OmniauthOptions
# List of supported Omniauth providers. # List of supported Omniauth providers.
Rails.application.config.providers = [] Rails.application.config.providers = []
@ -16,7 +19,7 @@ Rails.application.config.omniauth_office365 = ENV['OFFICE365_KEY'].present? &&
ENV['OFFICE365_SECRET'].present? ENV['OFFICE365_SECRET'].present?
SETUP_PROC = lambda do |env| SETUP_PROC = lambda do |env|
SessionsController.helpers.omniauth_options env OmniauthOptions.omniauth_options env
end end
OmniAuth.config.logger = Rails.logger OmniAuth.config.logger = Rails.logger

View File

@ -88,10 +88,9 @@ en:
roles: roles:
can_create_rooms: Can create rooms can_create_rooms: Can create rooms
delete: Delete the role delete: Delete the role
duplicate_name: The role name you provided was a duplicate. All role names must be unique invalid_create: There was a problem creating a new role. Please check the role values and try again
empty_name: All roles must have a non empty name invalid_order: There was a problem updating the priority of the role. Please check the values and try again
invalid_order: The user role must be the lowest priority role and the admin role must be the highest priority role invalid_update: There was a problem updating the permissions of the role. Please check the values and try again
invalid_update: You can't update a role with a higher priority than your own role
name: Role Name name: Role Name
new_role: Create a new role new_role: Create a new role
role_has_users: This role is assigned to %{user_count} accounts. Please remove all accounts from this role before deleting it. role_has_users: This role is assigned to %{user_count} accounts. Please remove all accounts from this role before deleting it.
@ -101,8 +100,7 @@ en:
edit_site_settings: Allow users with this role to edit site settings edit_site_settings: Allow users with this role to edit site settings
edit_roles: Allow users with this role to edit other roles edit_roles: Allow users with this role to edit other roles
manage_users: Allow users with this role to manage users manage_users: Allow users with this role to manage users
invalid_assignment: You can't assign a role with a higher priority than your own to a user invalid_assignment: There was a problem assigning the roles to the user. Please check the values and try again
invalid_removal: You can't remove a role with a higher priority than your own
colour: colour:
title: Role Colour title: Role Colour
info: Set the colour that will be associated with the role info: Set the colour that will be associated with the role

View File

@ -37,25 +37,23 @@ Rails.application.routes.draw do
resources :admins, only: [:index] resources :admins, only: [:index]
scope '/admins' do scope '/admins' do
get '/site_settings', to: 'admins#site_settings', as: :admin_site_settings # Panel Tabs
get '/recordings', to: 'admins#server_recordings', as: :admin_recordings get '/recordings', to: 'admins#server_recordings', as: :admin_recordings
post '/branding', to: 'admins#branding', as: :admin_branding get '/site_settings', to: 'admins#site_settings', as: :admin_site_settings
post '/coloring', to: 'admins#coloring', as: :admin_coloring get '/roles', to: 'admins#roles', as: :admin_roles
post '/room_authentication', to: 'admins#room_authentication', as: :admin_room_authentication # Manage Users
post '/coloring_lighten', to: 'admins#coloring_lighten', as: :admin_coloring_lighten
post '/coloring_darken', to: 'admins#coloring_darken', as: :admin_coloring_darken
post '/signup', to: 'admins#signup', as: :admin_signup
get '/edit/:user_uid', to: 'admins#edit_user', as: :admin_edit_user get '/edit/:user_uid', to: 'admins#edit_user', as: :admin_edit_user
post '/ban/:user_uid', to: 'admins#ban_user', as: :admin_ban post '/ban/:user_uid', to: 'admins#ban_user', as: :admin_ban
post '/unban/:user_uid', to: 'admins#unban_user', as: :admin_unban post '/unban/:user_uid', to: 'admins#unban_user', as: :admin_unban
post '/invite', to: 'admins#invite', as: :invite_user post '/invite', to: 'admins#invite', as: :invite_user
post '/registration_method/:method', to: 'admins#registration_method', as: :admin_change_registration
post '/approve/:user_uid', to: 'admins#approve', as: :admin_approve post '/approve/:user_uid', to: 'admins#approve', as: :admin_approve
get '/reset', to: 'admins#reset', as: :admin_reset get '/reset', to: 'admins#reset', as: :admin_reset
post '/room_limit', to: 'admins#room_limit', as: :admin_room_limit # Site Settings
post '/default_recording_visibility', to: 'admins#default_recording_visibility', as: :admin_recording_visibility post '/update_settings', to: 'admins#update_settings', as: :admin_update_settings
post '/registration_method', to: 'admins#registration_method', as: :admin_change_registration
post '/coloring', to: 'admins#coloring', as: :admin_coloring
post '/clear_cache', to: 'admins#clear_cache', as: :admin_clear_cache post '/clear_cache', to: 'admins#clear_cache', as: :admin_clear_cache
get '/roles', to: 'admins#roles', as: :admin_roles # Roles
post '/role', to: 'admins#new_role', as: :admin_new_role post '/role', to: 'admins#new_role', as: :admin_new_role
patch 'roles/order', to: 'admins#change_role_order', as: :admin_roles_order patch 'roles/order', to: 'admins#change_role_order', as: :admin_roles_order
post '/role/:role_id', to: 'admins#update_role', as: :admin_update_role post '/role/:role_id', to: 'admins#update_role', as: :admin_update_role
@ -86,6 +84,8 @@ Rails.application.routes.draw do
# Account management. # Account management.
get '/:user_uid/edit', to: 'users#edit', as: :edit_user get '/:user_uid/edit', to: 'users#edit', as: :edit_user
get '/:user_uid/change_password', to: 'users#change_password', as: :change_password
get '/:user_uid/delete_account', to: 'users#delete_account', as: :delete_account
patch '/:user_uid/edit', to: 'users#update', as: :update_user patch '/:user_uid/edit', to: 'users#update', as: :update_user
delete '/:user_uid', to: 'users#destroy', as: :delete_user delete '/:user_uid', to: 'users#destroy', as: :delete_user
@ -118,8 +118,8 @@ Rails.application.routes.draw do
scope '/:meetingID' do scope '/:meetingID' do
# Manage recordings # Manage recordings
scope '/:record_id' do scope '/:record_id' do
post '/', to: 'recordings#update_recording', as: :update_recording post '/', to: 'recordings#update', as: :update_recording
delete '/', to: 'recordings#delete_recording', as: :delete_recording delete '/', to: 'recordings#delete', as: :delete_recording
end end
end end

71
lib/omniauth_options.rb Normal file
View File

@ -0,0 +1,71 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
module OmniauthOptions
module_function
def omniauth_options(env)
if env['omniauth.strategy'].options[:name] == "bn_launcher"
protocol = Rails.env.production? ? "https" : env["rack.url_scheme"]
customer_redirect_url = protocol + "://" + env["SERVER_NAME"] + ":" +
env["SERVER_PORT"]
user_domain = parse_user_domain(env["SERVER_NAME"])
env['omniauth.strategy'].options[:customer] = user_domain
env['omniauth.strategy'].options[:customer_redirect_url] = customer_redirect_url
env['omniauth.strategy'].options[:default_callback_url] = Rails.configuration.gl_callback_url
# This is only used in the old launcher and should eventually be removed
env['omniauth.strategy'].options[:checksum] = generate_checksum(user_domain, customer_redirect_url,
Rails.configuration.launcher_secret)
elsif env['omniauth.strategy'].options[:name] == "google"
set_hd(env, ENV['GOOGLE_OAUTH2_HD'])
elsif env['omniauth.strategy'].options[:name] == "office365"
set_hd(env, ENV['OFFICE365_HD'])
end
end
# Limits the domain that can be used with the provider
def set_hd(env, hd)
if hd
hd_opts = hd.split(',')
env['omniauth.strategy'].options[:hd] = if hd_opts.empty?
nil
elsif hd_opts.length == 1
hd_opts[0]
else
hd_opts
end
end
end
# Parses the url for the user domain
def parse_user_domain(hostname)
return hostname.split('.').first if Rails.configuration.url_host.empty?
Rails.configuration.url_host.split(',').each do |url_host|
return hostname.chomp(url_host).chomp('.') if hostname.include?(url_host)
end
''
end
# Generates a checksum to use alongside the omniauth request
def generate_checksum(user_domain, redirect_url, secret)
string = user_domain + redirect_url + secret
OpenSSL::Digest.digest('sha1', string).unpack1("H*")
end
end

View File

@ -0,0 +1,88 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
require "rails_helper"
require 'bigbluebutton_api'
describe BbbServer do
include BbbServer
let(:bbb_server) { BigBlueButton::BigBlueButtonApi.new("http://bbb.example.com/bigbluebutton/api", "secret", "0.8") }
before do
@user = create(:user)
@room = @user.main_room
end
context "#running?" do
it "should return false when not running" do
expect(room_running?(@room.bbb_id)).to be false
end
it "should return true when running" do
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(true)
expect(room_running?(@room.bbb_id)).to be true
end
end
context "#start_session" do
it "should update latest session info" do
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:create_meeting).and_return(
messageKey: ""
)
expect do
start_session(@room)
end.to change { @room.sessions }.by(1)
expect(@room.last_session).not_to be nil
end
end
context "#join_path" do
it "should return correct join URL for user" do
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_meeting_info).and_return(
attendeePW: @room.attendee_pw
)
endpoint = Rails.configuration.bigbluebutton_endpoint
secret = Rails.configuration.bigbluebutton_secret
fullname = "fullName=Example"
join_via_html5 = "&join_via_html5=true"
meeting_id = "&meetingID=#{@room.bbb_id}"
password = "&password=#{@room.attendee_pw}"
query = fullname + join_via_html5 + meeting_id + password
checksum_string = "join#{query + secret}"
checksum = OpenSSL::Digest.digest('sha1', checksum_string).unpack1("H*")
expect(join_path(@room, "Example")).to eql("#{endpoint}join?#{query}&checksum=#{checksum}")
end
end
context "#recordings" do
it "deletes the recording" do
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:delete_recordings).and_return(
returncode: true, deleted: true
)
expect(delete_recording(Faker::IDNumber.valid))
.to contain_exactly([:returncode, true], [:deleted, true])
end
end
end

View File

@ -19,13 +19,15 @@
require "rails_helper" require "rails_helper"
require 'bigbluebutton_api' require 'bigbluebutton_api'
shared_examples_for "recorder" do describe Recorder do
let(:controller) { described_class } # the class that includes the concern include Recorder
include BbbServer
let(:bbb_server) { BigBlueButton::BigBlueButtonApi.new("http://bbb.example.com/bigbluebutton/api", "secret", "0.8") }
before do before do
@user = create(:user) @user = create(:user)
@room = @user.main_room @room = @user.main_room
allow_any_instance_of(Room).to receive(:owner).and_return(@user) allow_any_instance_of(Room).to receive(:owner).and_return(@user)
end end
@ -44,7 +46,7 @@ shared_examples_for "recorder" do
] ]
) )
expect(recordings(@room.bbb_id, @room.owner.provider)).to contain_exactly( expect(recordings(@room.bbb_id)).to contain_exactly(
name: "Example", name: "Example",
playbacks: playbacks:
[ [
@ -118,7 +120,7 @@ shared_examples_for "recorder" do
] ]
) )
expect(all_recordings(@user.rooms.pluck(:bbb_id), @user.provider, search: "Exam", column: "name", expect(all_recordings(@user.rooms.pluck(:bbb_id), search: "Exam", column: "name",
direction: "desc")).to eq( direction: "desc")).to eq(
[ [
{ {
@ -219,7 +221,7 @@ shared_examples_for "recorder" do
end end
it "should filter recordings on name" do it "should filter recordings on name" do
expect(recordings(@room.bbb_id, @room.owner.provider, search: "Exam")).to contain_exactly( expect(recordings(@room.bbb_id, search: "Exam")).to contain_exactly(
{ {
meetingID: @room.bbb_id, meetingID: @room.bbb_id,
name: "aExamaaa", name: "aExamaaa",
@ -250,7 +252,7 @@ shared_examples_for "recorder" do
end end
it "should filter recordings on participants" do it "should filter recordings on participants" do
expect(recordings(@room.bbb_id, @room.owner.provider, search: "5")).to contain_exactly( expect(recordings(@room.bbb_id, search: "5")).to contain_exactly(
meetingID: @room.bbb_id, meetingID: @room.bbb_id,
name: "aExamaaa", name: "aExamaaa",
participants: "5", participants: "5",
@ -267,7 +269,7 @@ shared_examples_for "recorder" do
end end
it "should filter recordings on format" do it "should filter recordings on format" do
expect(recordings(@room.bbb_id, @room.owner.provider, search: "presentation")).to contain_exactly( expect(recordings(@room.bbb_id, search: "presentation")).to contain_exactly(
{ {
meetingID: @room.bbb_id, meetingID: @room.bbb_id,
name: "test", name: "test",
@ -298,7 +300,7 @@ shared_examples_for "recorder" do
end end
it "should filter recordings on visibility" do it "should filter recordings on visibility" do
expect(recordings(@room.bbb_id, @room.owner.provider, search: "public")).to contain_exactly( expect(recordings(@room.bbb_id, search: "public")).to contain_exactly(
{ {
meetingID: @room.bbb_id, meetingID: @room.bbb_id,
name: "test", name: "test",
@ -329,7 +331,7 @@ shared_examples_for "recorder" do
end end
it "should filter recordings on metadata name by default" do it "should filter recordings on metadata name by default" do
expect(recordings(@room.bbb_id, @room.owner.provider, search: "metadata")).to contain_exactly( expect(recordings(@room.bbb_id, search: "metadata")).to contain_exactly(
meetingID: @room.bbb_id, meetingID: @room.bbb_id,
name: "Exam", name: "Exam",
participants: "1", participants: "1",
@ -385,7 +387,7 @@ shared_examples_for "recorder" do
end end
it "should sort recordings on name" do it "should sort recordings on name" do
expect(recordings(@room.bbb_id, @room.owner.provider, column: "name", direction: "asc")).to eq( expect(recordings(@room.bbb_id, column: "name", direction: "asc")).to eq(
[ [
{ {
meetingID: @room.bbb_id, meetingID: @room.bbb_id,
@ -421,7 +423,7 @@ shared_examples_for "recorder" do
end end
it "should sort recordings on participants" do it "should sort recordings on participants" do
expect(recordings(@room.bbb_id, @room.owner.provider, column: "users", direction: "desc")).to eq( expect(recordings(@room.bbb_id, column: "users", direction: "desc")).to eq(
[ [
{ {
meetingID: @room.bbb_id, meetingID: @room.bbb_id,
@ -457,7 +459,7 @@ shared_examples_for "recorder" do
end end
it "should sort recordings on visibility" do it "should sort recordings on visibility" do
expect(recordings(@room.bbb_id, @room.owner.provider, column: "visibility", direction: "desc")).to eq( expect(recordings(@room.bbb_id, column: "visibility", direction: "desc")).to eq(
[ [
{ {
meetingID: @room.bbb_id, meetingID: @room.bbb_id,
@ -493,7 +495,7 @@ shared_examples_for "recorder" do
end end
it "should sort recordings on length" do it "should sort recordings on length" do
expect(recordings(@room.bbb_id, @room.owner.provider, column: "length", direction: "asc")).to eq( expect(recordings(@room.bbb_id, column: "length", direction: "asc")).to eq(
[ [
{ {
meetingID: @room.bbb_id, meetingID: @room.bbb_id,
@ -529,7 +531,7 @@ shared_examples_for "recorder" do
end end
it "should sort recordings on format" do it "should sort recordings on format" do
expect(recordings(@room.bbb_id, @room.owner.provider, column: "formats", direction: "desc")).to eq( expect(recordings(@room.bbb_id, column: "formats", direction: "desc")).to eq(
[ [
{ {
meetingID: @room.bbb_id, meetingID: @room.bbb_id,

View File

@ -37,7 +37,7 @@ describe AccountActivationsController, type: :controller do
get :show, params: { email: user.email } get :show, params: { email: user.email }
expect(response).to render_template(:verify) expect(response).to render_template(:show)
end end
end end

View File

@ -91,7 +91,7 @@ describe AdminsController, type: :controller do
context "POST #invite" do context "POST #invite" do
before do before do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true) allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow_any_instance_of(ApplicationController).to receive(:allow_greenlight_users?).and_return(true) allow_any_instance_of(ApplicationController).to receive(:allow_greenlight_accounts?).and_return(true)
allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true) allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
end end
@ -177,7 +177,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
fake_image_url = "example.com" fake_image_url = "example.com"
post :branding, params: { url: fake_image_url } post :update_settings, params: { setting: "Branding Image", value: fake_image_url }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Branding Image") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Branding Image")
@ -194,7 +194,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
primary_color = Faker::Color.hex_color primary_color = Faker::Color.hex_color
post :coloring, params: { color: primary_color } post :coloring, params: { value: primary_color }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color")
@ -209,7 +209,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
primary_color = Faker::Color.hex_color primary_color = Faker::Color.hex_color
post :coloring_lighten, params: { color: primary_color } post :update_settings, params: { setting: "Primary Color Lighten", value: primary_color }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Lighten") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Lighten")
@ -224,7 +224,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
primary_color = Faker::Color.hex_color primary_color = Faker::Color.hex_color
post :coloring_darken, params: { color: primary_color } post :update_settings, params: { setting: "Primary Color Darken", value: primary_color }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Darken") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Darken")
@ -243,7 +243,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
post :registration_method, params: { method: "invite" } post :registration_method, params: { value: "invite" }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Registration Method") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Registration Method")
@ -259,7 +259,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
post :registration_method, params: { method: "invite" } post :registration_method, params: { value: "invite" }
expect(flash[:alert]).to be_present expect(flash[:alert]).to be_present
expect(response).to redirect_to(admin_site_settings_path) expect(response).to redirect_to(admin_site_settings_path)
@ -273,7 +273,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
post :room_authentication, params: { value: "true" } post :update_settings, params: { setting: "Room Authentication", value: "true" }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Authentication") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Authentication")
@ -289,7 +289,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
post :room_limit, params: { limit: 5 } post :update_settings, params: { setting: "Room Limit", value: 5 }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Limit") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Limit")
@ -305,7 +305,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
post :default_recording_visibility, params: { visibility: "public" } post :update_settings, params: { setting: "Default Recording Visibility", value: "public" }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Default Recording Visibility") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Default Recording Visibility")
@ -353,7 +353,7 @@ describe AdminsController, type: :controller do
post :new_role, params: { role: { name: "admin" } } post :new_role, params: { role: { name: "admin" } }
expect(response).to redirect_to admin_roles_path expect(response).to redirect_to admin_roles_path
expect(flash[:alert]).to eq(I18n.t("administrator.roles.duplicate_name")) expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_create"))
end end
it "should fail with empty role name" do it "should fail with empty role name" do
@ -362,7 +362,7 @@ describe AdminsController, type: :controller do
post :new_role, params: { role: { name: " " } } post :new_role, params: { role: { name: " " } }
expect(response).to redirect_to admin_roles_path expect(response).to redirect_to admin_roles_path
expect(flash[:alert]).to eq(I18n.t("administrator.roles.empty_name")) expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_create"))
end end
it "should create new role and increase user role priority" do it "should create new role and increase user role priority" do
@ -412,7 +412,7 @@ describe AdminsController, type: :controller do
patch :change_role_order, params: { role: [new_role3.id, new_role2.id] } patch :change_role_order, params: { role: [new_role3.id, new_role2.id] }
expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_update")) expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_order"))
expect(response).to redirect_to admin_roles_path expect(response).to redirect_to admin_roles_path
end end
@ -432,7 +432,7 @@ describe AdminsController, type: :controller do
patch :change_role_order, params: { role: [new_role3.id, new_role2.id] } patch :change_role_order, params: { role: [new_role3.id, new_role2.id] }
expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_update")) expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_order"))
expect(response).to redirect_to admin_roles_path expect(response).to redirect_to admin_roles_path
end end
@ -489,7 +489,7 @@ describe AdminsController, type: :controller do
patch :update_role, params: { role_id: new_role.id, role: { name: "admin" } } patch :update_role, params: { role_id: new_role.id, role: { name: "admin" } }
expect(flash[:alert]).to eq(I18n.t("administrator.roles.duplicate_name")) expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_update"))
expect(response).to redirect_to admin_roles_path(selected_role: new_role.id) expect(response).to redirect_to admin_roles_path(selected_role: new_role.id)
end end

View File

@ -63,6 +63,64 @@ describe ApplicationController do
end end
end end
context "getters" do
it "returns whether user signup is allowed" do
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
expect(controller.allow_user_signup?).to eql(true)
end
it "returns whether the default bbb endpoint is being used" do
allow(Rails.configuration).to receive(:bigbluebutton_endpoint)
.and_return("http://test-install.blindsidenetworks.com/bigbluebutton/api/")
allow(Rails.configuration).to receive(:bigbluebutton_endpoint_default)
.and_return("http://test-install.blindsidenetworks.com/bigbluebutton/api/")
expect(controller.bigbluebutton_endpoint_default?).to eql(true)
end
end
context "allow_greenlight_accounts" do
it "allows if user sign up is turned on" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(false)
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
expect(controller.allow_greenlight_accounts?).to eql(true)
end
it "doesn't allow if user sign up is turned off" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(false)
allow(Rails.configuration).to receive(:allow_user_signup).and_return(false)
expect(controller.allow_greenlight_accounts?).to eql(false)
end
it "doesn't allow if user_domain is blank" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
expect(controller.allow_greenlight_accounts?).to eql(false)
end
it "allows if user provider is set to greenlight" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
allow(controller).to receive(:retrieve_provider_info).and_return("provider" => "greenlight")
controller.instance_variable_set(:@user_domain, "provider1")
expect(controller.allow_greenlight_accounts?).to eql(true)
end
it "doesnt allow if user provider is not set to greenlight" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
allow(controller).to receive(:retrieve_provider_info).and_return("provider" => "google")
controller.instance_variable_set(:@user_domain, "provider1")
expect(controller.allow_greenlight_accounts?).to eql(false)
end
end
context "errors" do context "errors" do
it "renders a BigBlueButton error if a BigBlueButtonException occurrs" do it "renders a BigBlueButton error if a BigBlueButtonException occurrs" do
routes.draw { get "error" => "anonymous#error" } routes.draw { get "error" => "anonymous#error" }
@ -74,7 +132,7 @@ describe ApplicationController do
it "renders a 404 error if user is not found" do it "renders a 404 error if user is not found" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true) allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow(Rails.env).to receive(:test?).and_return(false) allow(Rails.env).to receive(:test?).and_return(false)
allow_any_instance_of(SessionsHelper).to receive(:parse_user_domain).and_return("fake_provider") allow_any_instance_of(ApplicationController).to receive(:parse_user_domain).and_return("fake_provider")
allow_any_instance_of(BbbApi).to receive(:retrieve_provider_info).and_raise("No user with that id exists") allow_any_instance_of(BbbApi).to receive(:retrieve_provider_info).and_raise("No user with that id exists")
routes.draw { get "user_not_found" => "anonymous#user_not_found" } routes.draw { get "user_not_found" => "anonymous#user_not_found" }
@ -86,7 +144,7 @@ describe ApplicationController do
it "renders a 404 error if user is not given" do it "renders a 404 error if user is not given" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true) allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow(Rails.env).to receive(:test?).and_return(false) allow(Rails.env).to receive(:test?).and_return(false)
allow_any_instance_of(SessionsHelper).to receive(:parse_user_domain).and_return("") allow_any_instance_of(ApplicationController).to receive(:parse_user_domain).and_return("")
allow_any_instance_of(BbbApi).to receive(:retrieve_provider_info).and_raise("Provider not included.") allow_any_instance_of(BbbApi).to receive(:retrieve_provider_info).and_raise("Provider not included.")
routes.draw { get "user_not_found" => "anonymous#user_not_found" } routes.draw { get "user_not_found" => "anonymous#user_not_found" }
@ -98,7 +156,7 @@ describe ApplicationController do
it "renders a 500 error if any other error related to bbb api" do it "renders a 500 error if any other error related to bbb api" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true) allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow(Rails.env).to receive(:test?).and_return(false) allow(Rails.env).to receive(:test?).and_return(false)
allow_any_instance_of(SessionsHelper).to receive(:parse_user_domain).and_return("") allow_any_instance_of(ApplicationController).to receive(:parse_user_domain).and_return("")
allow_any_instance_of(BbbApi).to receive(:retrieve_provider_info).and_raise("Other error") allow_any_instance_of(BbbApi).to receive(:retrieve_provider_info).and_raise("Other error")
routes.draw { get "user_not_found" => "anonymous#user_not_found" } routes.draw { get "user_not_found" => "anonymous#user_not_found" }

View File

@ -73,7 +73,9 @@ describe PasswordResetsController, type: :controller do
end end
describe "PATCH #update" do describe "PATCH #update" do
before { allow(Rails.configuration).to receive(:enable_email_verification).and_return(true) } before do
allow(Rails.configuration).to receive(:enable_email_verification).and_return(true)
end
context "valid user" do context "valid user" do
it "reloads page with notice if password is empty" do it "reloads page with notice if password is empty" do
@ -120,7 +122,7 @@ describe PasswordResetsController, type: :controller do
allow(controller).to receive(:valid_user).and_return(nil) allow(controller).to receive(:valid_user).and_return(nil)
allow(controller).to receive(:check_expiration).and_return(nil) allow(controller).to receive(:check_expiration).and_return(nil)
allow(controller).to receive(:current_user).and_return(user) controller.instance_variable_set(:@user, user)
params = { params = {
id: token, id: token,

View File

@ -27,10 +27,10 @@ describe RecordingsController, type: :controller do
context "POST #update_recording" do context "POST #update_recording" do
it "updates the recordings details" do it "updates the recordings details" do
allow_any_instance_of(Room).to receive(:update_recording).and_return(updated: true) allow_any_instance_of(BbbServer).to receive(:update_recording).and_return(updated: true)
@request.session[:user_id] = @user.uid @request.session[:user_id] = @user.uid
post :update_recording, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" } post :update, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" }
expect(response).to have_http_status(302) expect(response).to have_http_status(302)
end end
@ -38,7 +38,7 @@ describe RecordingsController, type: :controller do
it "redirects to root if not the room owner" do it "redirects to root if not the room owner" do
@request.session[:user_id] = @secondary_user.uid @request.session[:user_id] = @secondary_user.uid
post :update_recording, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" } post :update, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" }
expect(response).to redirect_to(root_path) expect(response).to redirect_to(root_path)
end end
@ -46,10 +46,10 @@ describe RecordingsController, type: :controller do
context "DELETE #delete_recording" do context "DELETE #delete_recording" do
it "deletes the recording" do it "deletes the recording" do
allow_any_instance_of(Room).to receive(:delete_recording).and_return(true) allow_any_instance_of(BbbServer).to receive(:delete_recording).and_return(true)
@request.session[:user_id] = @user.uid @request.session[:user_id] = @user.uid
post :delete_recording, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" } post :delete, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" }
expect(response).to have_http_status(302) expect(response).to have_http_status(302)
end end
@ -57,7 +57,7 @@ describe RecordingsController, type: :controller do
it "redirects to root if not the room owner" do it "redirects to root if not the room owner" do
@request.session[:user_id] = @secondary_user.uid @request.session[:user_id] = @secondary_user.uid
post :delete_recording, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" } post :delete, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" }
expect(response).to redirect_to(root_path) expect(response).to redirect_to(root_path)
end end

View File

@ -28,8 +28,11 @@ def random_valid_room_params
end end
describe RoomsController, type: :controller do describe RoomsController, type: :controller do
it_behaves_like "recorder"
include Recorder include Recorder
include BbbServer
let(:bbb_server) { BigBlueButton::BigBlueButtonApi.new("http://bbb.example.com/bigbluebutton/api", "secret", "0.8") }
describe "GET #show" do describe "GET #show" do
before do before do
@user = create(:user) @user = create(:user)
@ -41,8 +44,7 @@ describe RoomsController, type: :controller do
get :show, params: { room_uid: @owner.main_room } get :show, params: { room_uid: @owner.main_room }
expect(assigns(:recordings)).to eql(recordings(@owner.main_room.bbb_id, @owner.provider)) expect(assigns(:recordings)).to eql(recordings(@owner.main_room.bbb_id))
expect(assigns(:is_running)).to eql(@owner.main_room.running?)
end end
it "should be able to search recordings if user is owner" do it "should be able to search recordings if user is owner" do
@ -199,11 +201,6 @@ describe RoomsController, type: :controller do
@user = create(:user) @user = create(:user)
@owner = create(:user) @owner = create(:user)
@room = @owner.main_room @room = @owner.main_room
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_meeting_info).and_return(
moderatorPW: "modpass",
attendeePW: "attpass",
)
end end
it "should use account name if user is logged in and meeting running" do it "should use account name if user is logged in and meeting running" do
@ -212,7 +209,7 @@ describe RoomsController, type: :controller do
@request.session[:user_id] = @user.id @request.session[:user_id] = @user.id
post :join, params: { room_uid: @room, join_name: @user.name } post :join, params: { room_uid: @room, join_name: @user.name }
expect(response).to redirect_to(@owner.main_room.join_path(@user.name, {}, @user.uid)) expect(response).to redirect_to(join_path(@owner.main_room, @user.name, {}, @user.uid))
end end
it "should use join name if user is not logged in and meeting running" do it "should use join name if user is not logged in and meeting running" do
@ -220,7 +217,7 @@ describe RoomsController, type: :controller do
post :join, params: { room_uid: @room, join_name: "Join Name" } post :join, params: { room_uid: @room, join_name: "Join Name" }
expect(response).to redirect_to(@owner.main_room.join_path("Join Name", {})) expect(response).to redirect_to(join_path(@owner.main_room, "Join Name", {}))
end end
it "should render wait if meeting isn't running" do it "should render wait if meeting isn't running" do
@ -243,7 +240,7 @@ describe RoomsController, type: :controller do
@request.session[:user_id] = @user.id @request.session[:user_id] = @user.id
post :join, params: { room_uid: room, join_name: @user.name } post :join, params: { room_uid: room, join_name: @user.name }
expect(response).to redirect_to(room.join_path(@user.name, { user_is_moderator: false }, @user.uid)) expect(response).to redirect_to(join_path(room, @user.name, { user_is_moderator: false }, @user.uid))
end end
it "should join the room as moderator if room has the all_join_moderator setting" do it "should join the room as moderator if room has the all_join_moderator setting" do
@ -257,7 +254,7 @@ describe RoomsController, type: :controller do
@request.session[:user_id] = @user.id @request.session[:user_id] = @user.id
post :join, params: { room_uid: room, join_name: @user.name } post :join, params: { room_uid: room, join_name: @user.name }
expect(response).to redirect_to(room.join_path(@user.name, { user_is_moderator: true }, @user.uid)) expect(response).to redirect_to(join_path(room, @user.name, { user_is_moderator: true }, @user.uid))
end end
it "should render wait if the correct access code is supplied" do it "should render wait if the correct access code is supplied" do
@ -292,7 +289,7 @@ describe RoomsController, type: :controller do
@request.session[:user_id] = @owner.id @request.session[:user_id] = @owner.id
post :join, params: { room_uid: @room, join_name: @owner.name } post :join, params: { room_uid: @room, join_name: @owner.name }
expect(response).to redirect_to(@owner.main_room.join_path(@owner.name, { user_is_moderator: true }, @owner.uid)) expect(response).to redirect_to(join_path(@owner.main_room, @owner.name, { user_is_moderator: true }, @owner.uid))
end end
it "redirects to root if owner of room is not verified" do it "redirects to root if owner of room is not verified" do
@ -362,7 +359,7 @@ describe RoomsController, type: :controller do
@request.session[:user_id] = @user.id @request.session[:user_id] = @user.id
post :start, params: { room_uid: @user.main_room } 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)) expect(response).to redirect_to(join_path(@user.main_room, @user.name, { user_is_moderator: true }, @user.uid))
end end
it "should bring to room if not owner" do it "should bring to room if not owner" do

View File

@ -373,7 +373,7 @@ describe UsersController, type: :controller do
user.reload user.reload
expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_removal")) expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_assignment"))
expect(response).to render_template(:edit) expect(response).to render_template(:edit)
end end
@ -439,7 +439,6 @@ describe UsersController, type: :controller do
it "allows admins to delete users" do it "allows admins to delete users" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true) allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true) allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
allow_any_instance_of(Room).to receive(:delete_all_recordings).and_return('')
allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("provider1") allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("provider1")
controller.instance_variable_set(:@user_domain, "provider1") controller.instance_variable_set(:@user_domain, "provider1")

View File

@ -1,44 +0,0 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
require "rails_helper"
describe AdminsHelper do
describe "edit_disabled" do
it "should disable inputs for roles with a higher priority" do
user = create(:user)
admin_role = Role.find_by(name: "admin", provider: "greenlight")
helper.instance_variable_set(:@selected_role, admin_role)
allow_any_instance_of(SessionsHelper).to receive(:current_user).and_return(user)
expect(helper.edit_disabled).to eq(true)
end
it "should enable inputs for roles with a lower priority" do
user = create(:user)
user.roles << Role.find_by(name: "admin", provider: "greenlight")
user_role = Role.find_by(name: "user", provider: "greenlight")
helper.instance_variable_set(:@selected_role, user_role)
allow_any_instance_of(SessionsHelper).to receive(:current_user).and_return(user)
expect(helper.edit_disabled).to eq(false)
end
end
end

View File

@ -20,21 +20,6 @@ require "rails_helper"
describe ApplicationHelper do describe ApplicationHelper do
describe "#getter functions" do describe "#getter functions" do
it "returns whether user signup is allowed" do
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
expect(helper.allow_user_signup?).to eql(true)
end
it "returns whether the default bbb endpoint is being used" do
allow(Rails.configuration).to receive(:bigbluebutton_endpoint)
.and_return("http://test-install.blindsidenetworks.com/bigbluebutton/api/")
allow(Rails.configuration).to receive(:bigbluebutton_endpoint_default)
.and_return("http://test-install.blindsidenetworks.com/bigbluebutton/api/")
expect(helper.bigbluebutton_endpoint_default?).to eql(true)
end
it "returns the correct omniauth login url" do it "returns the correct omniauth login url" do
allow(Rails.configuration).to receive(:relative_url_root).and_return("/b") allow(Rails.configuration).to receive(:relative_url_root).and_return("/b")
provider = Faker::Company.name provider = Faker::Company.name
@ -43,51 +28,8 @@ describe ApplicationHelper do
end end
end end
describe "#allow_greenlight_accounts" do describe "role_colur" do
it "allows if user sign up is turned on" do it "should use default if the user doesn't have a role" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(false)
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
expect(helper.allow_greenlight_accounts?).to eql(true)
end
it "doesn't allow if user sign up is turned off" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(false)
allow(Rails.configuration).to receive(:allow_user_signup).and_return(false)
expect(helper.allow_greenlight_accounts?).to eql(false)
end
it "doesn't allow if user_domain is blank" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
expect(helper.allow_greenlight_accounts?).to eql(false)
end
it "allows if user provider is set to greenlight" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
allow(helper).to receive(:retrieve_provider_info).and_return("provider" => "greenlight")
@user_domain = "provider1"
expect(helper.allow_greenlight_accounts?).to eql(true)
end
it "doesnt allow if user provider is not set to greenlight" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
allow(helper).to receive(:retrieve_provider_info).and_return("provider" => "google")
@user_domain = "provider1"
expect(helper.allow_greenlight_accounts?).to eql(false)
end
end
describe "role_clour" do
it "should use default if the user doens't have a role" do
expect(helper.role_colour(Role.create(name: "test"))).to eq(Rails.configuration.primary_color_default) expect(helper.role_colour(Role.create(name: "test"))).to eq(Rails.configuration.primary_color_default)
end end

View File

@ -1,44 +0,0 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
require "rails_helper"
describe UsersHelper do
describe "disabled roles" do
it "should return roles with a less than or equal to priority for non admins" do
user = create(:user)
allow_any_instance_of(SessionsHelper).to receive(:current_user).and_return(user)
disabled_roles = helper.disabled_roles(user)
expect(disabled_roles.count).to eq(1)
end
it "should return roles with a lesser priority for admins" do
admin = create(:user)
admin.add_role :admin
user = create(:user)
allow_any_instance_of(SessionsHelper).to receive(:current_user).and_return(admin)
disabled_roles = helper.disabled_roles(user)
expect(disabled_roles.count).to eq(1)
end
end
end

View File

@ -62,52 +62,6 @@ describe Room, type: :model do
end end
end end
context "#running?" do
it "should return false when not running" do
expect(@room.running?).to be false
end
it "should return true when running" do
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(true)
expect(@room.running?).to be true
end
end
context "#start_session" do
it "should update latest session info" do
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:create_meeting).and_return(
messageKey: ""
)
expect do
@room.start_session
end.to change { @room.sessions }.by(1)
expect(@room.last_session).not_to be nil
end
end
context "#join_path" do
it "should return correct join URL for user" do
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_meeting_info).and_return(
attendeePW: "testpass"
)
endpoint = Rails.configuration.bigbluebutton_endpoint
secret = Rails.configuration.bigbluebutton_secret
fullname = "fullName=Example"
join_via_html5 = "&join_via_html5=true"
meeting_id = "&meetingID=#{@room.bbb_id}"
password = "&password=testpass"
query = fullname + join_via_html5 + meeting_id + password
checksum_string = "join#{query + secret}"
checksum = OpenSSL::Digest.digest('sha1', checksum_string).unpack1("H*")
expect(@room.join_path("Example")).to eql("#{endpoint}join?#{query}&checksum=#{checksum}")
end
end
context "#notify_waiting" do context "#notify_waiting" do
it "should broadcast to waiting channel with started action" do it "should broadcast to waiting channel with started action" do
expect do expect do
@ -115,32 +69,4 @@ describe Room, type: :model do
end.to have_broadcasted_to("#{@room.uid}_waiting_channel").with(a_hash_including(action: "started")) end.to have_broadcasted_to("#{@room.uid}_waiting_channel").with(a_hash_including(action: "started"))
end end
end end
context "#participants" do
it "should link participants to accounts" do
user1 = create(:user)
user2 = create(:user)
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_meeting_info).and_return(
attendees: [
{ userID: user1.uid, fullName: user1.name },
{ userID: "non-matching-uid", fullName: "Guest User" },
{ userID: user2.uid, fullName: user2.name },
],
)
expect(@room.participants).to contain_exactly(user1, nil, user2)
end
end
context "#recordings" do
it "deletes the recording" do
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:delete_recordings).and_return(
returncode: true, deleted: true
)
expect(@room.delete_recording(Faker::IDNumber.valid))
.to contain_exactly([:returncode, true], [:deleted, true])
end
end
end end