diff --git a/app/assets/javascripts/admins.js b/app/assets/javascripts/admins.js
index 88521567..a7a4245e 100644
--- a/app/assets/javascripts/admins.js
+++ b/app/assets/javascripts/admins.js
@@ -79,7 +79,7 @@ $(document).on('turbolinks:load', function(){
// Change the branding image to the image provided
function changeBrandingImage(path) {
var url = $("#branding-url").val()
- $.post(path, {url: url})
+ $.post(path, {value: url})
}
// Filters by role
@@ -157,19 +157,19 @@ function loadColourSelectors() {
});
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()
});
})
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()
});
})
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()
});
})
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index dceefaa2..71eb2e74 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -33,7 +33,7 @@ function getLocalizedString(key) {
})
// If key is not found, search the fallback language for the key
- if (translated == undefined) {
+ if (translated === undefined) {
translated = I18nFallback
keyArr.forEach(function(k) {
diff --git a/app/assets/javascripts/rename.js b/app/assets/javascripts/rename.js
index a8f32c6a..1631d9e1 100644
--- a/app/assets/javascripts/rename.js
+++ b/app/assets/javascripts/rename.js
@@ -123,8 +123,8 @@ $(document).on('turbolinks:load', function(){
if(element.is('#room-title')){
submit_update_request({
setting: "rename_header",
- room_name: element.find('#user-text').text(),
- }, element.data('path'));
+ name: element.find('#user-text').text(),
+ }, element.data('path'), "POST");
}
else if(element.is('#recording-title')){
submit_update_request({
@@ -132,16 +132,16 @@ $(document).on('turbolinks:load', function(){
record_id: element.data('recordid'),
record_name: element.find('text').text(),
room_uid: element.data('room-uid'),
- }, element.data('path'));
+ }, element.data('path'), "PATCH");
}
}
// Helper for submitting ajax requests
- var submit_update_request = function(data, path){
+ var submit_update_request = function(data, path, action){
// Send ajax request for update
$.ajax({
url: path,
- type: "PATCH",
+ type: action,
data: data,
});
}
diff --git a/app/assets/javascripts/room.js b/app/assets/javascripts/room.js
index f6fe3b27..d03fac8e 100644
--- a/app/assets/javascripts/room.js
+++ b/app/assets/javascripts/room.js
@@ -44,93 +44,82 @@ $(document).on('turbolinks:load', function(){
if ($("#cant-create-room-wrapper").length){
$(".wrapper").css('height', '100%').css('height', '-=130px');
}
- }
- // Display and update all fields related to creating a room in the createRoomModal
- $("#create-room-block").click(function(){
- $("#create-room-name").val("")
- $("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code_placeholder"))
- $("#room_access_code").val(null)
-
- $("#createRoomModal form").attr("action", $("body").data('relative-root'))
- $("#room_mute_on_join").prop("checked", false)
- $("#room_require_moderator_approval").prop("checked", false)
- $("#room_anyone_can_start").prop("checked", false)
- $("#room_all_join_moderator").prop("checked", false)
-
- //show all elements & their children with a create-only class
- $(".create-only").each(function() {
- $(this).show()
- if($(this).children().length > 0) { $(this).children().show() }
+ // Display and update all fields related to creating a room in the createRoomModal
+ $("#create-room-block").click(function(){
+ showCreateRoom()
})
- //hide all elements & their children with a update-only class
- $(".update-only").each(function() {
- $(this).attr('style',"display:none !important")
- if($(this).children().length > 0) { $(this).children().attr('style',"display:none !important") }
+ // Display and update all fields related to creating a room in the createRoomModal
+ $(".update-room").click(function(){
+ showUpdateRoom()
})
- })
-
- // Display and update all fields related to creating a room in the createRoomModal
- $(".update-room").click(function(){
- var room_block_uid = $(this).closest("#room-block").data("room-uid")
- $("#create-room-name").val($(this).closest("tbody").find("#room-name h4").text())
- $("#createRoomModal form").attr("action", room_block_uid + "/update_settings")
-
- //show all elements & their children with a update-only class
- $(".update-only").each(function() {
- $(this).show()
- if($(this).children().length > 0) { $(this).children().show() }
- })
-
- //hide all elements & their children with a create-only class
- $(".create-only").each(function() {
- $(this).attr('style',"display:none !important")
- if($(this).children().length > 0) { $(this).children().attr('style',"display:none !important") }
- })
-
- updateCurrentSettings($(this).closest("#room-block").data("room-settings"))
-
- accessCode = $(this).closest("#room-block").data("room-access-code")
-
- if(accessCode){
- $("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code") + ": " + accessCode)
- $("#room_access_code").val(accessCode)
- } else{
- $("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code_placeholder"))
- $("#room_access_code").val(null)
- }
- })
-
- //Update the createRoomModal to show the correct current settings
- function updateCurrentSettings(settings){
- //set checkbox
- if(settings.muteOnStart){
- $("#room_mute_on_join").prop("checked", true)
- } else { //default option
- $("#room_mute_on_join").prop("checked", false)
- }
-
- if(settings.requireModeratorApproval){
- $("#room_require_moderator_approval").prop("checked", true)
- } else { //default option
- $("#room_require_moderator_approval").prop("checked", false)
- }
-
- if(settings.anyoneCanStart){
- $("#room_anyone_can_start").prop("checked", true)
- } else { //default option
- $("#room_anyone_can_start").prop("checked", false)
- }
-
- if(settings.joinModerator){
- $("#room_all_join_moderator").prop("checked", true)
- } else { //default option
- $("#room_all_join_moderator").prop("checked", false)
- }
}
});
+function showCreateRoom() {
+ $("#create-room-name").val("")
+ $("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code_placeholder"))
+ $("#room_access_code").val(null)
+
+ $("#createRoomModal form").attr("action", $("body").data('relative-root'))
+ $("#room_mute_on_join").prop("checked", false)
+ $("#room_require_moderator_approval").prop("checked", false)
+ $("#room_anyone_can_start").prop("checked", false)
+ $("#room_all_join_moderator").prop("checked", false)
+
+ //show all elements & their children with a create-only class
+ $(".create-only").each(function() {
+ $(this).show()
+ if($(this).children().length > 0) { $(this).children().show() }
+ })
+
+ //hide all elements & their children with a update-only class
+ $(".update-only").each(function() {
+ $(this).attr('style',"display:none !important")
+ if($(this).children().length > 0) { $(this).children().attr('style',"display:none !important") }
+ })
+}
+
+function showUpdateRoom() {
+ var room_block_uid = $(this).closest("#room-block").data("room-uid")
+ $("#create-room-name").val($(this).closest("tbody").find("#room-name h4").text())
+ $("#createRoomModal form").attr("action", room_block_uid + "/update_settings")
+
+ //show all elements & their children with a update-only class
+ $(".update-only").each(function() {
+ $(this).show()
+ if($(this).children().length > 0) { $(this).children().show() }
+ })
+
+ //hide all elements & their children with a create-only class
+ $(".create-only").each(function() {
+ $(this).attr('style',"display:none !important")
+ if($(this).children().length > 0) { $(this).children().attr('style',"display:none !important") }
+ })
+
+ updateCurrentSettings($(this).closest("#room-block").data("room-settings"))
+
+ var accessCode = $(this).closest("#room-block").data("room-access-code")
+
+ if(accessCode){
+ $("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code") + ": " + accessCode)
+ $("#room_access_code").val(accessCode)
+ } else {
+ $("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code_placeholder"))
+ $("#room_access_code").val(null)
+ }
+}
+
+//Update the createRoomModal to show the correct current settings
+function updateCurrentSettings(settings){
+ //set checkbox
+ $("#room_mute_on_join").prop("checked", settings.muteOnStart)
+ $("#room_require_moderator_approval").prop("checked", settings.requireModeratorApproval)
+ $("#room_anyone_can_start").prop("checked", settings.anyoneCanStart)
+ $("#room_all_join_moderator").prop("checked", settings.joinModerator)
+}
+
function generateAccessCode(){
const accessCodeLength = 6
var validCharacters = "0123456789"
diff --git a/app/assets/javascripts/search.js b/app/assets/javascripts/search.js
index 6869ebb5..9c8e0c5c 100644
--- a/app/assets/javascripts/search.js
+++ b/app/assets/javascripts/search.js
@@ -26,8 +26,7 @@ $(document).on('turbolinks:load', function(){
(controller == "admins" && action == "server_recordings")) {
// Submit search if the user hits enter
$("#search-input").keypress(function(key) {
- var keyPressed = key.which
- if (keyPressed == 13) {
+ if (key.which == 13) {
searchPage()
}
})
@@ -35,8 +34,6 @@ $(document).on('turbolinks:load', function(){
// Add listeners for sort
$("th[data-order]").click(function(data){
var header_elem = $(data.target)
- var controller = $("body").data('controller');
- var action = $("body").data('action');
if(header_elem.data('order') === 'asc'){ // asc
header_elem.data('order', 'desc');
@@ -50,15 +47,10 @@ $(document).on('turbolinks:load', function(){
var search = $("#search-input").val();
- if(controller === "rooms" && action === "show"){
- window.location.replace(window.location.pathname + "?page=1&search=" + search +
- "&column=" + header_elem.data("header") + "&direction="+ header_elem.data('order') +
- "#recordings-table");
- }
- else{
- window.location.replace(window.location.pathname + "?page=1&search=" + search +
- "&column=" + header_elem.data("header") + "&direction="+ header_elem.data('order'));
- }
+ var url = window.location.pathname + "?page=1&search=" + search + "&column=" + header_elem.data("header") +
+ "&direction=" + header_elem.data('order')
+
+ window.location.replace(addRecordingTable(url))
})
if(controller === "rooms" && action === "show"){
@@ -75,42 +67,30 @@ $(document).on('turbolinks:load', function(){
function searchPage() {
var search = $("#search-input").val();
- var controller = $("body").data('controller');
- var action = $("body").data('action');
-
// Check if the user filtered by role
var role = new URL(location.href).searchParams.get('role')
var url = window.location.pathname + "?page=1&search=" + search
- if (role) {
- url += "&role=" + role
- }
+ if (role) { url += "&role=" + role }
- if(controller === "rooms" && action === "show"){
- window.location.replace(url + "#recordings-table");
- } else{
- window.location.replace(url);
- }
-
+ window.location.replace(addRecordingTable(url));
}
// Clears the search bar
function clearSearch() {
- var controller = $("body").data('controller');
- var action = $("body").data('action');
-
var role = new URL(location.href).searchParams.get('role')
var url = window.location.pathname + "?page=1"
- if (role) {
- url += "&role=" + role
- }
-
- if(controller === "rooms" && action === "show"){
- window.location.replace(url + "#recordings-table");
- } else{
- window.location.replace(url);
- }
+ if (role) { url += "&role=" + role }
+
+ window.location.replace(addRecordingTable(url));
+}
+
+function addRecordingTable(url) {
+ if($("body").data('controller') === "rooms" && $("body").data('action') === "show") {
+ url += "#recordings-table"
+ }
+ return url
}
diff --git a/app/controllers/account_activations_controller.rb b/app/controllers/account_activations_controller.rb
index fd7450c3..cc859f09 100644
--- a/app/controllers/account_activations_controller.rb
+++ b/app/controllers/account_activations_controller.rb
@@ -24,46 +24,45 @@ class AccountActivationsController < ApplicationController
# GET /account_activations
def show
- render :verify
end
# GET /account_activations/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])
+ # Verify user
@user.activate
# Redirect user to root with account pending flash if account is still pending
return redirect_to root_path,
flash: { success: I18n.t("registration.approval.signup") } if @user.has_role?(:pending)
- flash[:success] = I18n.t("verify.activated") + " " + I18n.t("verify.signin")
- redirect_to signin_path
+ # Redirect user to sign in path with success flash
+ redirect_to signin_path, flash: { success: I18n.t("verify.activated") + " " + I18n.t("verify.signin") }
else
- flash[:alert] = I18n.t("verify.invalid")
- redirect_to root_path
+ redirect_to root_path, flash: { alert: I18n.t("verify.invalid") }
end
end
# GET /account_activations/resend
def resend
if @user.activated?
+ # User is already verified
flash[:alert] = I18n.t("verify.already_verified")
else
- 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
+ # Resend
+ send_activation_email(@user)
end
- redirect_to(root_path)
+ redirect_to root_path
end
private
+ def find_user
+ @user = User.find_by!(email: params[:email], provider: @user_domain)
+ end
+
def ensure_unauthenticated
redirect_to current_user.main_room if current_user
end
@@ -71,8 +70,4 @@ class AccountActivationsController < ApplicationController
def email_params
params.require(:email).permit(:email, :token)
end
-
- def find_user
- @user = User.find_by!(email: params[:email], provider: @user_domain)
- end
end
diff --git a/app/controllers/admins_controller.rb b/app/controllers/admins_controller.rb
index b1c9d48b..41e7e9f8 100644
--- a/app/controllers/admins_controller.rb
+++ b/app/controllers/admins_controller.rb
@@ -21,18 +21,17 @@ class AdminsController < ApplicationController
include Themer
include Emailer
include Recorder
+ include Rolify
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
before_action :find_user, only: manage_users
before_action :verify_admin_of_user, only: manage_users
- before_action :find_setting, only: site_settings
# GET /admins
def index
+ # Initializa the data manipulation variables
@search = params[:search] || ""
@order_column = params[:column] && params[:direction] != "none" ? params[:column] : "created_at"
@order_direction = params[:direction] && params[:direction] != "none" ? params[:direction] : "DESC"
@@ -49,13 +48,14 @@ class AdminsController < ApplicationController
# GET /admins/server_recordings
def server_recordings
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
Room.pluck(:bbb_id)
end
@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)
end
@@ -92,17 +92,10 @@ class AdminsController < ApplicationController
def invite
emails = params[:invite_user][:email].split(",")
- begin
- emails.each do |email|
- invitation = create_or_update_invite(email)
+ emails.each do |email|
+ invitation = create_or_update_invite(email)
- send_invitation_email(current_user.name, email, invitation.invite_token)
- 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(', '))
+ send_invitation_email(current_user.name, email, invitation.invite_token)
end
redirect_to admins_path
@@ -118,39 +111,30 @@ class AdminsController < ApplicationController
end
# SITE SETTINGS
- # POST /admins/branding
- def branding
- @settings.update_value("Branding Image", params[:url])
- redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
+ # POST /admins/update_settings
+ def update_settings
+ @settings.update_value(params[:setting], params[:value])
+
+ 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
# POST /admins/color
def coloring
- @settings.update_value("Primary Color", params[:color])
- @settings.update_value("Primary Color Lighten", color_lighten(params[:color]))
- @settings.update_value("Primary Color Darken", color_darken(params[:color]))
- 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])
+ @settings.update_value("Primary Color", params[:value])
+ @settings.update_value("Primary Color Lighten", color_lighten(params[:value]))
+ @settings.update_value("Primary Color Darken", color_darken(params[:value]))
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
end
# POST /admins/registration_method/: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
if !Rails.configuration.enable_email_verification && new_method == Rails.configuration.registration_methods[:invite]
@@ -163,67 +147,19 @@ class AdminsController < ApplicationController
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
# GET /admins/roles
def roles
- @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 params[:selected_role].nil?
- @roles.find_by(name: 'user')
- else
- @roles.find(params[:selected_role])
- end
+ @roles = all_roles(params[:selected_role])
end
- # POST /admin/role
- # This method creates a new role scope to the users provider
+ # POST /admins/role
+ # This method creates a new role scoped to the users provider
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
- 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)
+ return redirect_to admin_roles_path, flash: { alert: I18n.t("administrator.roles.invalid_create") } if new_role.nil?
redirect_to admin_roles_path(selected_role: new_role.id)
end
@@ -232,82 +168,16 @@ class AdminsController < ApplicationController
# This updates the priority of a site's roles
# Note: A lower priority role will always get used before a higher priority one
def change_role_order
- 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
- 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
+ unless update_priority(params[:role])
+ redirect_to admin_roles_path, flash: { alert: I18n.t("administrator.roles.invalid_order") }
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
# POST /admin/role/:role_id
# This method updates the permissions assigned to a role
def update_role
role = Role.find(params[:role_id])
- current_user_role = current_user.highest_priority_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!
-
+ flash[:alert] = I18n.t("administrator.roles.invalid_update") unless update_permissions(role)
redirect_to admin_roles_path(selected_role: role.id)
end
@@ -325,6 +195,7 @@ class AdminsController < ApplicationController
role.priority <= current_user.highest_priority_role.priority
return redirect_to admin_roles_path(selected_role: role.id)
else
+ role.role_permissions.delete_all
role.delete
end
@@ -337,10 +208,7 @@ class AdminsController < ApplicationController
@user = User.where(uid: params[:user_uid]).includes(:roles).first
end
- def find_setting
- @settings = Setting.find_or_create_by!(provider: user_settings_provider)
- end
-
+ # Verifies that admin is an administrator of the user in the action
def verify_admin_of_user
redirect_to admins_path,
flash: { alert: I18n.t("administrator.flash.unauthorized") } unless current_user.admin_of?(@user)
@@ -355,7 +223,7 @@ class AdminsController < ApplicationController
end
if Rails.configuration.loadbalanced_configuration
- initial_list.where(provider: user_settings_provider)
+ initial_list.where(provider: @user_domain)
.admins_search(@search, @role)
.admins_order(@order_column, @order_direction)
else
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 1c2f857b..96cd481f 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -16,44 +16,63 @@
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see .
-require 'bigbluebutton_api'
-
class ApplicationController < ActionController::Base
- include ApplicationHelper
- include SessionsHelper
- include ThemingHelper
+ include BbbServer
- # Force SSL for loadbalancer configurations.
- before_action :redirect_to_https
-
- before_action :set_user_domain
- before_action :maintenance_mode?
- before_action :migration_error?
- before_action :set_locale
- before_action :check_admin_password
- before_action :check_user_role
+ before_action :redirect_to_https, :set_user_domain, :set_user_settings, :maintenance_mode?, :migration_error?,
+ :user_locale, :check_admin_password, :check_user_role
# Manually handle BigBlueButton errors
rescue_from BigBlueButton::BigBlueButtonException, with: :handle_bigbluebutton_error
- protect_from_forgery with: :exception
+ protect_from_forgery with: :exceptions
- MEETING_NAME_LIMIT = 90
- USER_NAME_LIMIT = 32
+ # Retrieves the current user.
+ def current_user
+ @current_user ||= User.where(id: session[:user_id]).includes(:roles).first
- # Include user domain in lograge logs
- def append_info_to_payload(payload)
- super
- payload[:host] = @user_domain
+ 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
+ helper_method :current_user
+
+ def bbb_server
+ @bbb_server ||= Rails.configuration.loadbalanced_configuration ? bbb(@user_domain) : bbb("greenlight")
end
- # Show an information page when migration fails and there is a version error.
- def migration_error?
- render :migration_error, status: 500 unless ENV["DB_MIGRATE_FAILED"].blank?
+ # 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
+
+ # Redirects the user to a Maintenance page if turned on
def maintenance_mode?
- if Rails.configuration.maintenance_mode
+ if ENV["MAINTENANCE_MODE"] == "true"
render "errors/greenlight_error", status: 503, formats: :html,
locals: {
status_code: 503,
@@ -68,29 +87,48 @@ class ApplicationController < ActionController::Base
end
end
- # Sets the appropriate locale.
- def set_locale
- update_locale(current_user)
+ # Show an information page when migration fails and there is a version error.
+ def migration_error?
+ render :migration_error, status: 500 unless ENV["DB_MIGRATE_FAILED"].blank?
end
- def update_locale(user)
+ # 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?
+
+ begin
+ I18n.locale = locale.tr('-', '_') unless locale.nil?
+ rescue
+ # Default to English if there are any issues in language
+ logger.error("Support: User locale is not supported (#{locale}")
+ I18n.locale = "en"
+ end
end
- def meeting_name_limit
- MEETING_NAME_LIMIT
- end
- helper_method :meeting_name_limit
+ # 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)
- def user_name_limit
- USER_NAME_LIMIT
+ 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
- helper_method :user_name_limit
# Relative root helper (when deploying to subdirectory).
def relative_root
@@ -105,34 +143,53 @@ class ApplicationController < ActionController::Base
end
helper_method :bigbluebutton_endpoint_default?
- def recording_thumbnails?
- Rails.configuration.recording_thumbnails
+ 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.error "Error in checking if greenlight accounts are allowed: #{e}"
+ false
+ end
end
- helper_method :recording_thumbnails?
+ helper_method :allow_greenlight_accounts?
- def allow_greenlight_users?
- allow_greenlight_accounts?
+ # Determine if Greenlight is configured to allow user signups.
+ def allow_user_signup?
+ Rails.configuration.allow_user_signup
end
- helper_method :allow_greenlight_users?
+ helper_method :allow_user_signup?
- # Determines if a form field needs the is-invalid class.
- def form_is_invalid?(obj, key)
- 'is-invalid' unless obj.errors.messages[key].empty?
+ # Gets all configured omniauth providers.
+ def configured_providers
+ Rails.configuration.providers.select do |provider|
+ Rails.configuration.send("omniauth_#{provider}")
+ end
end
- helper_method :form_is_invalid?
+ helper_method :configured_providers
- # 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: Setting.find_or_create_by!(provider: user_settings_provider)
- .get_value("Default Recording Visibility") == "public"
- }
+ # 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
+
+ # 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
# Manually deal with 401 errors
@@ -140,50 +197,6 @@ class ApplicationController < ActionController::Base
render "errors/greenlight_error"
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
def check_provider_exists
@@ -198,6 +211,7 @@ class ApplicationController < ActionController::Base
# Add a session variable if the provider exists
session[:provider_exists] = @user_domain
rescue => e
+ logger.error "Error in retrieve provider info: #{e}"
# Use the default site settings
@user_domain = "greenlight"
diff --git a/app/helpers/sessions_helper.rb b/app/controllers/concerns/authenticator.rb
similarity index 55%
rename from app/helpers/sessions_helper.rb
rename to app/controllers/concerns/authenticator.rb
index e0183be6..2fd6ded0 100644
--- a/app/helpers/sessions_helper.rb
+++ b/app/controllers/concerns/authenticator.rb
@@ -16,7 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see .
-module SessionsHelper
+module Authenticator
+ extend ActiveSupport::Concern
+
# Logs a user into GreenLight.
def login(user)
migrate_twitter_user(user)
@@ -56,74 +58,18 @@ module SessionsHelper
end
end
+ def ensure_unauthenticated_except_twitter
+ redirect_to current_user.main_room if current_user && params[:old_twitter_user_id].nil?
+ end
+
# Logs current user out of GreenLight.
def logout
session.delete(:user_id) if current_user
end
- # Retrieves the current user.
- 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
+ private
+ # Migrates all of the twitter users rooms to the new account
def migrate_twitter_user(user)
if !session["old_twitter_user_id"].nil? && user.provider != "twitter"
old_user = User.find(session["old_twitter_user_id"])
diff --git a/app/controllers/concerns/bbb_server.rb b/app/controllers/concerns/bbb_server.rb
new file mode 100644
index 00000000..02b3fde7
--- /dev/null
+++ b/app/controllers/concerns/bbb_server.rb
@@ -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 .
+
+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
diff --git a/app/controllers/concerns/emailer.rb b/app/controllers/concerns/emailer.rb
index 9146bb00..39ee1ea3 100644
--- a/app/controllers/concerns/emailer.rb
+++ b/app/controllers/concerns/emailer.rb
@@ -21,91 +21,132 @@ module Emailer
# Sends account activation email.
def send_activation_email(user)
- return unless Rails.configuration.enable_email_verification
+ begin
+ return unless Rails.configuration.enable_email_verification
- @user = user
- UserMailer.verify_email(@user, user_verification_link, logo_image, user_color).deliver
+ UserMailer.verify_email(user, user_verification_link(user), @settings).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
# Sends password reset email.
def send_password_reset_email(user)
- return unless Rails.configuration.enable_email_verification
+ begin
+ return unless Rails.configuration.enable_email_verification
- @user = user
- UserMailer.password_reset(@user, reset_link, logo_image, user_color).deliver_now
+ UserMailer.password_reset(user, reset_link(user), @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("reset_password.subtitle"))
+ end
end
def send_user_promoted_email(user, role)
- return unless Rails.configuration.enable_email_verification
+ begin
+ 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
def send_user_demoted_email(user, role)
- return unless Rails.configuration.enable_email_verification
+ begin
+ 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
# Sends inivitation to join
def send_invitation_email(name, email, token)
- return unless Rails.configuration.enable_email_verification
+ begin
+ return unless Rails.configuration.enable_email_verification
- @token = token
- UserMailer.invite_email(name, email, invitation_link, logo_image, user_color).deliver_now
+ UserMailer.invite_email(name, email, invitation_link(token), @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("administrator.flash.invite", email: email)
+ end
end
def send_user_approved_email(user)
- return unless Rails.configuration.enable_email_verification
+ begin
+ 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
def send_approval_user_signup_email(user)
- return unless Rails.configuration.enable_email_verification
+ begin
+ return unless Rails.configuration.enable_email_verification
- admin_emails = admin_emails()
- unless admin_emails.empty?
- UserMailer.approval_user_signup(user, admins_url, logo_image, user_color, admin_emails).deliver_now
+ admin_emails = admin_emails()
+ UserMailer.approval_user_signup(user, admins_url, admin_emails, @settings).deliver_now unless admin_emails.empty?
+ rescue => e
+ logger.error "Support: Error in email delivery: #{e}"
+ flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
end
end
def send_invite_user_signup_email(user)
- return unless Rails.configuration.enable_email_verification
+ begin
+ return unless Rails.configuration.enable_email_verification
- admin_emails = admin_emails()
- unless admin_emails.empty?
- UserMailer.invite_user_signup(user, admins_url, logo_image, user_color, admin_emails).deliver_now
+ admin_emails = admin_emails()
+ UserMailer.invite_user_signup(user, admins_url, admin_emails, @settings).deliver_now unless admin_emails.empty?
+ rescue => e
+ logger.error "Support: Error in email delivery: #{e}"
+ flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
end
end
private
# Returns the link the user needs to click to verify their account
- def user_verification_link
- edit_account_activation_url(token: @user.activation_token, email: @user.email)
+ def user_verification_link(user)
+ edit_account_activation_url(token: user.activation_token, email: user.email)
end
def admin_emails
- admins = User.all_users_with_roles.where(roles: { can_manage_users: true })
+ admins = User.all_users_with_roles.where(roles: { role_permissions: { name: "can_manage_users", value: "true" } })
if Rails.configuration.loadbalanced_configuration
admins = admins.without_role(:super_admin)
- .where(provider: user_settings_provider)
+ .where(provider: @user_domain)
end
admins.collect(&:email).join(",")
end
- def reset_link
- edit_password_reset_url(@user.reset_token, email: @user.email)
+ def reset_link(user)
+ edit_password_reset_url(user.reset_token, email: user.email)
end
- def invitation_link
- if allow_greenlight_users?
- signup_url(invite_token: @token)
+ def invitation_link(token)
+ if allow_greenlight_accounts?
+ signup_url(invite_token: token)
else
- root_url(invite_token: @token)
+ root_url(invite_token: token)
end
end
end
diff --git a/app/controllers/concerns/joiner.rb b/app/controllers/concerns/joiner.rb
new file mode 100644
index 00000000..e554d631
--- /dev/null
+++ b/app/controllers/concerns/joiner.rb
@@ -0,0 +1,94 @@
+# 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 .
+
+module Joiner
+ extend ActiveSupport::Concern
+
+ # Displays the join room page to the user
+ def show_user_join
+ # Get users name
+ @name = if current_user
+ current_user.name
+ elsif cookies.encrypted[:greenlight_name]
+ cookies.encrypted[:greenlight_name]
+ else
+ ""
+ end
+
+ @search, @order_column, @order_direction, pub_recs =
+ public_recordings(@room.bbb_id, params.permit(:search, :column, :direction), true)
+
+ @pagy, @public_recordings = pagy_array(pub_recs)
+
+ render :join
+ end
+
+ # create or update cookie to track the three most recent rooms a user joined
+ def save_recent_rooms
+ if current_user
+ 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).uniq[0..2]
+ end
+ end
+
+ def join_room(opts)
+ room_settings = JSON.parse(@room[:room_settings])
+
+ if room_running?(@room.bbb_id) || @room.owned_by?(current_user) || room_settings["anyoneCanStart"]
+
+ # Determine if the user needs to join as a moderator.
+ opts[:user_is_moderator] = @room.owned_by?(current_user) || room_settings["joinModerator"]
+
+ opts[:require_moderator_approval] = room_settings["requireModeratorApproval"]
+
+ if current_user
+ redirect_to join_path(@room, current_user.name, opts, current_user.uid)
+ else
+ join_name = params[:join_name] || params[@room.invite_path][:join_name]
+ redirect_to join_path(@room, join_name, opts)
+ end
+ else
+ search_params = params[@room.invite_path] || params
+ @search, @order_column, @order_direction, pub_recs =
+ public_recordings(@room.bbb_id, search_params.permit(:search, :column, :direction), true)
+
+ @pagy, @public_recordings = pagy_array(pub_recs)
+
+ # They need to wait until the meeting begins.
+ render :wait
+ end
+ end
+
+ def incorrect_user_domain
+ Rails.configuration.loadbalanced_configuration && @room.owner.provider != @user_domain
+ 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
diff --git a/app/controllers/concerns/recorder.rb b/app/controllers/concerns/recorder.rb
index 53e777e4..30a2dff2 100644
--- a/app/controllers/concerns/recorder.rb
+++ b/app/controllers/concerns/recorder.rb
@@ -18,29 +18,29 @@
module Recorder
extend ActiveSupport::Concern
- include ::BbbApi
+ include RecordingsHelper
# Fetches all recordings for a room.
- def recordings(room_bbb_id, provider, search_params = {}, ret_search_params = false)
- res = bbb(provider).get_recordings(meetingID: room_bbb_id)
+ def recordings(room_bbb_id, search_params = {}, ret_search_params = false)
+ res = get_recordings(room_bbb_id)
format_recordings(res, search_params, ret_search_params)
end
# Fetches a rooms public recordings.
- def public_recordings(room_bbb_id, provider, search_params = {}, ret_search_params = false)
- search, order_col, order_dir, recs = recordings(room_bbb_id, provider, search_params, ret_search_params)
+ def public_recordings(room_bbb_id, search_params = {}, ret_search_params = false)
+ 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" }]
end
# 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: [] }
until room_bbb_ids.empty?
# bbb.get_recordings returns an object
# 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])
end
diff --git a/app/controllers/concerns/registrar.rb b/app/controllers/concerns/registrar.rb
index 79c0a622..98c38a08 100644
--- a/app/controllers/concerns/registrar.rb
+++ b/app/controllers/concerns/registrar.rb
@@ -19,20 +19,12 @@
module Registrar
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
- registration_method == Rails.configuration.registration_methods[:approval]
+ @settings.get_value("Registration Method") == Rails.configuration.registration_methods[:approval]
end
def invite_registration
- registration_method == Rails.configuration.registration_methods[:invite]
+ @settings.get_value("Registration Method") == Rails.configuration.registration_methods[:invite]
end
# Returns a hash containing whether the user has been invited and if they
@@ -51,4 +43,33 @@ module Registrar
{ present: false, verified: false }
end
end
+
+ # Checks if the user passes the requirements to be invited
+ def passes_invite_reqs
+ # check if user needs to be invited and IS invited
+ invitation = check_user_invited(@user.email, session[:invite_token], @user_domain)
+
+ @user.email_verified = true if invitation[:verified]
+
+ invitation[:present]
+ end
+
+ # Add validation errors to model if they exist
+ def valid_user_or_captcha
+ valid_user = @user.valid?
+ valid_captcha = Rails.configuration.recaptcha_enabled ? verify_recaptcha(model: @user) : true
+
+ logger.error("Support: #{@user.email} creation failed: User params are not valid.") unless valid_user
+
+ valid_user && valid_captcha
+ end
+
+ # Checks if the user trying to sign in with twitter account
+ def check_if_twitter_account(log_out = false)
+ unless params[:old_twitter_user_id].nil? && session[:old_twitter_user_id].nil?
+ logout if log_out
+ flash.now[:alert] = I18n.t("registration.deprecated.new_signin")
+ session[:old_twitter_user_id] = params[:old_twitter_user_id] unless params[:old_twitter_user_id].nil?
+ end
+ end
end
diff --git a/app/controllers/concerns/rolify.rb b/app/controllers/concerns/rolify.rb
new file mode 100644
index 00000000..1fab4bc5
--- /dev/null
+++ b/app/controllers/concerns/rolify.rb
@@ -0,0 +1,172 @@
+# 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 .
+
+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.get_permission("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.get_permission("send_promoted_email") }
+ removed_roles.each { |role| send_user_demoted_email(@user, role) if role.get_permission("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)
+
+ permission_params.transform_values! do |v|
+ if v == "0"
+ "false"
+ elsif v == "1"
+ "true"
+ else
+ v
+ end
+ end
+
+ # 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(colour: permission_params[:colour])
+ role.update_all_role_permissions(permission_params)
+
+ role.save!
+ end
+end
diff --git a/app/controllers/concerns/themer.rb b/app/controllers/concerns/themer.rb
index 2893ea27..132e3bbf 100644
--- a/app/controllers/concerns/themer.rb
+++ b/app/controllers/concerns/themer.rb
@@ -22,22 +22,20 @@ module Themer
# Lightens a color by 40%
def color_lighten(color)
# Uses the built in Sass Engine to lighten the color
-
- dummy_scss = "h1 { color: $lighten; }"
- compiled = SassC::Engine.new("$lighten:lighten(#{color}, 40%);" + dummy_scss, syntax: :scss).render
-
- string_locater = 'color: '
- color_start = compiled.index(string_locater) + string_locater.length
-
- compiled[color_start..color_start + 6]
+ generate_sass("lighten", color, "40%")
end
# Darkens a color by 10%
def color_darken(color)
# Uses the built in Sass Engine to darken the color
+ generate_sass("darken", color, "10%")
+ end
- dummy_scss = "h1 { color: $darken; }"
- compiled = SassC::Engine.new("$darken:darken(#{color}, 10%);" + dummy_scss, syntax: :scss).render
+ private
+
+ def generate_sass(action, color, percentage)
+ dummy_scss = "h1 { color: $#{action}; }"
+ compiled = SassC::Engine.new("$#{action}:#{action}(#{color}, #{percentage});" + dummy_scss, syntax: :scss).render
string_locater = 'color: '
color_start = compiled.index(string_locater) + string_locater.length
diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb
index 3bea0915..365955d3 100644
--- a/app/controllers/errors_controller.rb
+++ b/app/controllers/errors_controller.rb
@@ -27,7 +27,8 @@ class ErrorsController < ApplicationController
status_code: 500,
message: I18n.t("errors.internal.message"),
help: I18n.t("errors.internal.help"),
- display_back: true
+ display_back: true,
+ report_issue: true
}
end
diff --git a/app/controllers/password_resets_controller.rb b/app/controllers/password_resets_controller.rb
index 84ccb389..3c22a43e 100644
--- a/app/controllers/password_resets_controller.rb
+++ b/app/controllers/password_resets_controller.rb
@@ -20,45 +20,47 @@ class PasswordResetsController < ApplicationController
include Emailer
before_action :disable_password_reset, unless: -> { Rails.configuration.enable_email_verification }
- before_action :find_user, only: [:edit, :update]
+ before_action :find_user, only: [:edit, :update]
before_action :valid_user, only: [:edit, :update]
before_action :check_expiration, only: [:edit, :update]
- def index
+ # POST /password_resets/new
+ def new
end
+ # POST /password_resets
def create
- @user = User.find_by(email: params[:password_reset][:email].downcase)
- if @user
+ begin
+ # 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
send_password_reset_email(@user)
- flash[:success] = I18n.t("email_sent", email_type: t("reset_password.subtitle"))
redirect_to root_path
- else
- flash[:alert] = I18n.t("no_user_email_exists")
- redirect_to new_password_reset_path
+ rescue
+ # User doesn't exist
+ redirect_to root_path, flash: { success: I18n.t("email_sent", email_type: t("reset_password.subtitle")) }
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
+ # GET /password_resets/:id/edit
def edit
end
+ # PATCH /password_resets/:id
def update
+ # Check if password is valid
if params[:user][:password].empty?
flash.now[:alert] = I18n.t("password_empty_notice")
- render 'edit'
elsif params[:user][:password] != params[:user][:password_confirmation]
+ # Password does not match password confirmation
flash.now[:alert] = I18n.t("password_different_notice")
- render 'edit'
elsif @user.update_attributes(user_params)
- flash[:success] = I18n.t("password_reset_success")
- redirect_to root_path
- else
- render 'edit'
+ # Successfully reset password
+ return redirect_to root_path, flash: { success: I18n.t("password_reset_success") }
end
+
+ render 'edit'
end
private
@@ -84,6 +86,7 @@ class PasswordResetsController < ApplicationController
end
end
+ # Redirects to 404 if emails are not enabled
def disable_password_reset
redirect_to '/404'
end
diff --git a/app/controllers/recordings_controller.rb b/app/controllers/recordings_controller.rb
index ad1c2806..d5d3c80f 100644
--- a/app/controllers/recordings_controller.rb
+++ b/app/controllers/recordings_controller.rb
@@ -23,23 +23,30 @@ class RecordingsController < ApplicationController
META_LISTED = "gl-listed"
# POST /:meetingID/:record_id
- def update_recording
+ def update
meta = {
"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
- redirect_to request.referrer if res[:updated]
+ redirect_back fallback_location: root_path if res[:updated]
+ end
+
+ # PATCH /:meetingID/:record_id
+ def rename
+ update_recording(params[:record_id], "meta_name" => params[:record_name])
+
+ redirect_back fallback_location: room_path(@room)
end
# DELETE /:meetingID/:record_id
- def delete_recording
- @room.delete_recording(params[:record_id])
+ def delete
+ delete_recording(params[:record_id])
# Redirects to the page that made the initial request
- redirect_to request.referrer
+ redirect_back fallback_location: root_path
end
private
@@ -51,7 +58,7 @@ class RecordingsController < ApplicationController
# Ensure the user is logged into the room they are accessing.
def verify_room_ownership
if !current_user || (!@room.owned_by?(current_user) &&
- !current_user.highest_priority_role.can_edit_site_settings &&
+ !current_user.highest_priority_role.get_permission("can_edit_site_settings") &&
!current_user.has_role?(:super_admin))
redirect_to root_path
end
diff --git a/app/controllers/rooms_controller.rb b/app/controllers/rooms_controller.rb
index 4771d7de..f4322537 100644
--- a/app/controllers/rooms_controller.rb
+++ b/app/controllers/rooms_controller.rb
@@ -17,96 +17,67 @@
# with BigBlueButton; if not, see .
class RoomsController < ApplicationController
- include RecordingsHelper
include Pagy::Backend
include Recorder
+ include Joiner
before_action :validate_accepted_terms, unless: -> { !Rails.configuration.terms }
before_action :validate_verified_email, except: [:show, :join],
unless: -> { !Rails.configuration.enable_email_verification }
before_action :find_room, except: [:create, :join_specific_room]
- before_action :verify_room_ownership, except: [:create, :show, :join, :logout, :login, :join_specific_room]
+ before_action :verify_room_ownership, only: [:destroy, :start, :update_settings]
before_action :verify_room_owner_verified, only: [:show, :join],
unless: -> { !Rails.configuration.enable_email_verification }
before_action :verify_user_not_admin, only: [:show]
# POST /
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
+ # Create room
@room = Room.new(name: room_params[:name], access_code: room_params[:access_code])
@room.owner = current_user
- @room.room_settings = create_room_settings_string(room_params[:mute_on_join],
- room_params[:require_moderator_approval], room_params[:anyone_can_start], room_params[:all_join_moderator])
+ @room.room_settings = create_room_settings_string(room_params)
- if @room.save
- logger.info("Support: #{current_user.email} has created a new room #{@room.uid}.")
+ # Save the room and redirect if it fails
+ return redirect_to current_user.main_room, flash: { alert: I18n.t("room.create_room_error") } unless @room.save
- if room_params[:auto_join] == "1"
- start
- else
- flash[:success] = I18n.t("room.create_room_success")
- redirect_to @room
- end
- else
- flash[:alert] = I18n.t("room.create_room_error")
- redirect_to current_user.main_room
- end
+ logger.info "Support: #{current_user.email} has created a new room #{@room.uid}."
+
+ # Redirect to room is auto join was not turned on
+ return redirect_to @room,
+ flash: { success: I18n.t("room.create_room_success") } unless room_params[:auto_join] == "1"
+
+ # Start the room if auto join was turned on
+ start
end
# GET /:room_uid
def show
- @is_running = @room.running?
@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.highest_priority_role.can_create_rooms
+ if current_user.highest_priority_role.get_permission("can_create_rooms")
+ # User is allowed to have rooms
@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)
else
+ # Render view for users that cant create rooms
@recent_rooms = Room.where(id: cookies.encrypted["#{current_user.uid}_recently_joined_rooms"])
render :cant_create_rooms
end
else
return redirect_to root_path, flash: { alert: I18n.t("room.invalid_provider") } if incorrect_user_domain
- # Get users name
- @name = if current_user
- current_user.name
- elsif cookies.encrypted[:greenlight_name]
- cookies.encrypted[:greenlight_name]
- else
- ""
- end
-
- @search, @order_column, @order_direction, pub_recs =
- public_recordings(@room.bbb_id, @user_domain, params.permit(:search, :column, :direction), true)
-
- @pagy, @public_recordings = pagy_array(pub_recs)
-
- render :join
- end
- end
-
- # PATCH /:room_uid
- def update
- if params[:setting] == "rename_block"
- @room = Room.find_by!(uid: params[:room_block_uid])
- update_room_attributes("name")
- elsif params[:setting] == "rename_header"
- update_room_attributes("name")
- elsif params[:setting] == "rename_recording"
- @room.update_recording(params[:record_id], "meta_name" => params[:record_name])
- end
-
- if request.referrer
- redirect_to request.referrer
- else
- redirect_to room_path
+ show_user_join
end
end
@@ -115,10 +86,8 @@ class RoomsController < ApplicationController
return redirect_to root_path,
flash: { alert: I18n.t("administrator.site_settings.authentication.user-info") } if auth_required
- opts = default_meeting_options
unless @room.owned_by?(current_user)
- # Don't allow users to join unless they have a valid access code or the room doesn't
- # have an access code
+ # Don't allow users to join unless they have a valid access code or the room doesn't have an 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") }
end
@@ -128,23 +97,17 @@ class RoomsController < ApplicationController
@join_name = params[@room.invite_path][:join_name]
elsif !params[:join_name]
# Join name not passed.
- return
+ return redirect_to root_path
end
end
# create or update cookie with join name
cookies.encrypted[:greenlight_name] = @join_name unless cookies.encrypted[:greenlight_name] == @join_name
- if current_user
- # 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
- cookies.encrypted["#{current_user.uid}_recently_joined_rooms"] = recently_joined_rooms.prepend(@room.id)
- .uniq[0..2]
- end
+ save_recent_rooms
- logger.info("Support: #{current_user.present? ? current_user.email : @join_name} is joining room #{@room.uid}")
-
- join_room(opts)
+ logger.info "Support: #{current_user.present? ? current_user.email : @join_name} is joining room #{@room.uid}"
+ join_room(default_meeting_options)
end
# DELETE /:room_uid
@@ -155,24 +118,22 @@ class RoomsController < ApplicationController
redirect_to current_user.main_room
end
- # POST room/join
+ # POST /room/join
def join_specific_room
room_uid = params[:join_room][:url].split('/').last
begin
- @room = Room.find_by(uid: room_uid)
+ @room = Room.find_by!(uid: room_uid)
rescue ActiveRecord::RecordNotFound
return redirect_to current_user.main_room, alert: I18n.t("room.no_room.invalid_room_uid")
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)
end
# POST /:room_uid/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.
opts = default_meeting_options
@@ -180,11 +141,11 @@ class RoomsController < ApplicationController
# Include the user's choices for the room settings
room_settings = JSON.parse(@room[:room_settings])
- opts[:mute_on_start] = room_settings["muteOnStart"] if room_settings["muteOnStart"]
+ opts[:mute_on_start] = room_settings["muteOnStart"]
opts[:require_moderator_approval] = room_settings["requireModeratorApproval"]
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
logger.error("Support: #{@room.uid} start failed: #{e}")
@@ -199,26 +160,31 @@ class RoomsController < ApplicationController
# POST /:room_uid/update_settings
def update_settings
begin
- raise "Room name can't be blank" if room_params[:name].empty?
+ options = params[:room].nil? ? params : params[:room]
+ raise "Room name can't be blank" if options[:name].blank?
+ raise "Unauthorized Request" if !@room.owned_by?(current_user) || @room == current_user.main_room
+
+ # Update the rooms values
+ room_settings_string = create_room_settings_string(options)
+
+ @room.update_attributes(
+ name: options[:name],
+ room_settings: room_settings_string,
+ access_code: options[:access_code]
+ )
- @room = Room.find_by!(uid: params[:room_uid])
- # Update the rooms settings
- update_room_attributes("settings")
- # Update the rooms name if it has been changed
- update_room_attributes("name") if @room.name != room_params[:name]
- # Update the room's access code if it has changed
- update_room_attributes("access_code") if @room.access_code != room_params[:access_code]
- rescue StandardError
- flash[:alert] = I18n.t("room.update_settings_error")
- else
flash[:success] = I18n.t("room.update_settings_success")
+ rescue => e
+ logger.error "Support: Error in updating room settings: #{e}"
+ flash[:alert] = I18n.t("room.update_settings_error")
end
+
redirect_to room_path
end
# GET /:room_uid/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_to @room
@@ -235,29 +201,13 @@ class RoomsController < ApplicationController
private
- def update_room_attributes(update_type)
- if @room.owned_by?(current_user) && @room != current_user.main_room
- if update_type.eql? "name"
- @room.update_attributes(name: params[:room_name] || room_params[:name])
- elsif update_type.eql? "settings"
- room_settings_string = create_room_settings_string(room_params[:mute_on_join],
- room_params[:require_moderator_approval], room_params[:anyone_can_start], room_params[:all_join_moderator])
- @room.update_attributes(room_settings: room_settings_string)
- elsif update_type.eql? "access_code"
- @room.update_attributes(access_code: room_params[:access_code])
- end
- end
- end
-
- def create_room_settings_string(mute_res, require_approval_res, start_res, join_mod)
- room_settings = {}
- room_settings["muteOnStart"] = mute_res == "1"
-
- room_settings["requireModeratorApproval"] = require_approval_res == "1"
-
- room_settings["anyoneCanStart"] = start_res == "1"
-
- room_settings["joinModerator"] = join_mod == "1"
+ def create_room_settings_string(options)
+ room_settings = {
+ "muteOnStart": options[:mute_on_join] == "1",
+ "requireModeratorApproval": options[:require_moderator_approval] == "1",
+ "anyoneCanStart": options[:anyone_can_start] == "1",
+ "joinModerator": options[:all_join_moderator] == "1",
+ }
room_settings.to_json
end
@@ -274,92 +224,40 @@ class RoomsController < ApplicationController
# Ensure the user is logged into the room they are accessing.
def verify_room_ownership
- bring_to_room unless @room.owned_by?(current_user)
- end
-
- # Redirects a user to their room.
- def bring_to_room
- if current_user
- # Redirect authenticated users to their room.
- redirect_to room_path(current_user.main_room)
- else
- # Redirect unauthenticated users to root.
- redirect_to root_path
- end
+ return redirect_to root_path unless @room.owned_by?(current_user)
end
def validate_accepted_terms
- if current_user
- redirect_to terms_path unless current_user.accepted_terms
- end
+ redirect_to terms_path if current_user && !current_user&.accepted_terms
end
def validate_verified_email
- if current_user
- redirect_to account_activation_path(current_user) unless current_user.activated?
- end
+ redirect_to account_activation_path(current_user) if current_user && !current_user&.activated?
end
def verify_room_owner_verified
unless @room.owner.activated?
flash[:alert] = t("room.unavailable")
-
- if current_user && !@room.owned_by?(current_user)
- redirect_to current_user.main_room
- else
- redirect_to root_path
- end
+ redirect_to root_path
end
end
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
def auth_required
- Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Authentication") == "true" &&
- current_user.nil?
+ @settings.get_value("Room Authentication") == "true" && current_user.nil?
end
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
return false if current_user&.has_role?(:admin) || limit == 15
- current_user.rooms.count >= limit
- end
-
- def join_room(opts)
- room_settings = JSON.parse(@room[:room_settings])
-
- if @room.running? || @room.owned_by?(current_user) || room_settings["anyoneCanStart"]
-
- # Determine if the user needs to join as a moderator.
- opts[:user_is_moderator] = @room.owned_by?(current_user) || room_settings["joinModerator"]
-
- opts[:require_moderator_approval] = room_settings["requireModeratorApproval"]
-
- if current_user
- redirect_to @room.join_path(current_user.name, opts, current_user.uid)
- else
- join_name = params[:join_name] || params[@room.invite_path][:join_name]
- redirect_to @room.join_path(join_name, opts)
- end
- else
- search_params = params[@room.invite_path] || params
- @search, @order_column, @order_direction, pub_recs =
- public_recordings(@room.bbb_id, @user_domain, search_params.permit(:search, :column, :direction), true)
-
- @pagy, @public_recordings = pagy_array(pub_recs)
-
- # They need to wait until the meeting begins.
- render :wait
- end
- end
-
- def incorrect_user_domain
- Rails.configuration.loadbalanced_configuration && @room.owner.provider != @user_domain
+ current_user.rooms.length >= limit
end
+ helper_method :room_limit_exceeded
end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index cde24e24..05a79fca 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -17,21 +17,51 @@
# with BigBlueButton; if not, see .
class SessionsController < ApplicationController
+ include Authenticator
include Registrar
include Emailer
include LdapAuthenticator
skip_before_action :verify_authenticity_token, only: [:omniauth, :fail]
+ before_action :check_user_signup_allowed, only: [:new]
+ before_action :ensure_unauthenticated_except_twitter, only: [:new, :signin]
- # GET /users/logout
- def destroy
- logout
- redirect_to root_path
+ # GET /signin
+ def signin
+ check_if_twitter_account
+
+ if one_provider
+ provider_path = if Rails.configuration.omniauth_ldap
+ ldap_signin_path
+ else
+ "#{Rails.configuration.relative_url_root}/auth/#{providers.first}"
+ end
+
+ return redirect_to provider_path
+ end
+ end
+
+ # GET /ldap_signin
+ def ldap_signin
+ end
+
+ # GET /signup
+ def new
+ # Check if the user needs to be invited
+ if invite_registration
+ redirect_to root_path, flash: { alert: I18n.t("registration.invite.no_invite") } unless params[:invite_token]
+
+ session[:invite_token] = params[:invite_token]
+ end
+
+ check_if_twitter_account(true)
+
+ @user = User.new
end
# POST /users/login
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])
if admin&.has_role? :super_admin
@@ -48,11 +78,22 @@ class SessionsController < ApplicationController
login(user)
end
+ # GET /users/logout
+ def destroy
+ logout
+ redirect_to root_path
+ end
+
# GET/POST /auth/:provider/callback
def omniauth
@auth = request.env['omniauth.auth']
- process_signin
+ begin
+ process_signin
+ rescue => e
+ logger.error "Error authenticating via omniauth: #{e}"
+ omniauth_fail
+ end
end
# POST /auth/failure
@@ -81,23 +122,36 @@ class SessionsController < ApplicationController
result = send_ldap_request(params[:session], ldap_config)
- if result
- result = result.first
- else
- return redirect_to(ldap_signin_path, alert: I18n.t("invalid_credentials"))
+ return redirect_to(ldap_signin_path, alert: I18n.t("invalid_credentials")) unless result
+
+ @auth = parse_auth(result.first, ENV['LDAP_ROLE_FIELD'])
+
+ begin
+ process_signin
+ rescue => e
+ logger.error "Support: Error authenticating via omniauth: #{e}"
+ omniauth_fail
end
-
- @auth = parse_auth(result, ENV['LDAP_ROLE_FIELD'])
-
- process_signin
end
private
+ # Verify that GreenLight is configured to allow user signup.
+ def check_user_signup_allowed
+ redirect_to root_path unless Rails.configuration.allow_user_signup
+ end
+
def session_params
params.require(:session).permit(:email, :password)
end
+ def one_provider
+ providers = configured_providers
+
+ (!allow_user_signup? || !allow_greenlight_accounts?) && providers.count == 1 &&
+ !Rails.configuration.loadbalanced_configuration
+ end
+
def check_user_exists
provider = @auth['provider'] == "bn_launcher" ? @auth['info']['customer'] : @auth['provider']
User.exists?(social_uid: @auth['uid'], provider: provider)
@@ -112,47 +166,39 @@ class SessionsController < ApplicationController
end
def process_signin
- begin
- @user_exists = check_user_exists
+ @user_exists = check_user_exists
- if !@user_exists && @auth['provider'] == "twitter"
- return redirect_to root_path, flash: { alert: I18n.t("registration.deprecated.twitter_signup") }
+ if !@user_exists && @auth['provider'] == "twitter"
+ return redirect_to root_path, flash: { alert: I18n.t("registration.deprecated.twitter_signup") }
+ end
+
+ # If using invitation registration method, make sure user is invited
+ return redirect_to root_path, flash: { alert: I18n.t("registration.invite.no_invite") } unless passes_invite_reqs
+
+ user = User.from_omniauth(@auth)
+
+ logger.info "Support: Auth user #{user.email} is attempting to login."
+
+ # Add pending role if approval method and is a new user
+ if approval_registration && !@user_exists
+ user.add_role :pending
+
+ # Inform admins that a user signed up if emails are turned on
+ send_approval_user_signup_email(user)
+
+ return redirect_to root_path, flash: { success: I18n.t("registration.approval.signup") }
+ end
+
+ send_invite_user_signup_email(user) if invite_registration && !@user_exists
+
+ login(user)
+
+ if @auth['provider'] == "twitter"
+ flash[:alert] = if allow_user_signup? && allow_greenlight_accounts?
+ I18n.t("registration.deprecated.twitter_signin", link: signup_path(old_twitter_user_id: user.id))
+ else
+ I18n.t("registration.deprecated.twitter_signin", link: signin_path(old_twitter_user_id: user.id))
end
-
- # If using invitation registration method, make sure user is invited
- return redirect_to root_path, flash: { alert: I18n.t("registration.invite.no_invite") } unless passes_invite_reqs
-
- user = User.from_omniauth(@auth)
-
- logger.info("Support: Auth user #{user.email} is attempting to login.")
-
- # Add pending role if approval method and is a new user
- if approval_registration && !@user_exists
- user.add_role :pending
-
- # Inform admins that a user signed up if emails are turned on
- send_approval_user_signup_email(user) if Rails.configuration.enable_email_verification
-
- return redirect_to root_path, flash: { success: I18n.t("registration.approval.signup") }
- end
-
- send_invite_user_signup_email(user) if Rails.configuration.enable_email_verification &&
- invite_registration && !@user_exists
-
- login(user)
-
- if @auth['provider'] == "twitter"
- flash[:alert] = if allow_user_signup? && allow_greenlight_accounts?
- I18n.t("registration.deprecated.twitter_signin",
- link: signup_path(old_twitter_user_id: user.id))
- else
- I18n.t("registration.deprecated.twitter_signin",
- link: signin_path(old_twitter_user_id: user.id))
- end
- end
- rescue => e
- logger.error "Support: Error authenticating via omniauth: #{e}"
- omniauth_fail
end
end
end
diff --git a/app/controllers/themes_controller.rb b/app/controllers/themes_controller.rb
index d10521ca..f5c32eb2 100644
--- a/app/controllers/themes_controller.rb
+++ b/app/controllers/themes_controller.rb
@@ -17,8 +17,8 @@
# with BigBlueButton; if not, see .
class ThemesController < ApplicationController
- skip_before_action :maintenance_mode?
- before_action :provider_settings
+ skip_before_action :redirect_to_https, :maintenance_mode?, :migration_error?, :user_locale,
+ :check_admin_password, :check_user_role
# GET /primary
def index
@@ -39,10 +39,4 @@ class ThemesController < ApplicationController
format.css { render body: @compiled }
end
end
-
- private
-
- def provider_settings
- @settings = Setting.find_or_create_by(provider: user_settings_provider)
- end
end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 527c381a..6bffe8ad 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -17,25 +17,25 @@
# with BigBlueButton; if not, see .
class UsersController < ApplicationController
- include RecordingsHelper
include Pagy::Backend
+ include Authenticator
include Emailer
include Registrar
include Recorder
+ include Rolify
- before_action :find_user, only: [:edit, :update, :destroy]
- before_action :ensure_unauthenticated, only: [:new, :create, :signin]
+ before_action :find_user, only: [:edit, :change_password, :delete_account, :update, :destroy]
+ before_action :ensure_unauthenticated_except_twitter, only: [:create]
+ before_action :check_user_signup_allowed, only: [:create]
+ before_action :check_admin_of, only: [:edit, :change_password, :delete_account]
# POST /u
def create
- # Verify that GreenLight is configured to allow user signup.
- return unless Rails.configuration.allow_user_signup
-
@user = User.new(user_params)
@user.provider = @user_domain
# User or recpatcha is not valid
- render(:new) && return unless valid_user_or_captcha
+ render("sessions/new") && return unless valid_user_or_captcha
# Redirect to root if user token is either invalid or expired
return redirect_to root_path, flash: { alert: I18n.t("registration.invite.fail") } unless passes_invite_reqs
@@ -43,7 +43,7 @@ class UsersController < ApplicationController
# User has passed all validations required
@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
if approval_registration
@@ -53,76 +53,37 @@ class UsersController < ApplicationController
flash: { success: I18n.t("registration.approval.signup") } unless Rails.configuration.enable_email_verification
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.
login(@user) && return if !Rails.configuration.enable_email_verification || @user.email_verified
- send_verification
+ send_activation_email(@user)
redirect_to root_path
end
- # GET /signin
- def signin
- unless params[:old_twitter_user_id].nil? && session[:old_twitter_user_id].nil?
- flash[:alert] = I18n.t("registration.deprecated.new_signin")
- session[:old_twitter_user_id] = params[:old_twitter_user_id] unless params[:old_twitter_user_id].nil?
- end
-
- providers = configured_providers
- if (!allow_user_signup? || !allow_greenlight_accounts?) && providers.count == 1 &&
- !Rails.configuration.loadbalanced_configuration
- provider_path = if Rails.configuration.omniauth_ldap
- ldap_signin_path
- else
- "#{Rails.configuration.relative_url_root}/auth/#{providers.first}"
- end
-
- return redirect_to provider_path
- end
- end
-
- # GET /ldap_signin
- def ldap_signin
- end
-
- # GET /signup
- def new
- return redirect_to root_path unless Rails.configuration.allow_user_signup
-
- # Check if the user needs to be invited
- if invite_registration
- redirect_to root_path, flash: { alert: I18n.t("registration.invite.no_invite") } unless params[:invite_token]
-
- session[:invite_token] = params[:invite_token]
- end
-
- unless params[:old_twitter_user_id].nil? && session[:old_twitter_user_id].nil?
- logout
- flash.now[:alert] = I18n.t("registration.deprecated.new_signin")
- session[:old_twitter_user_id] = params[:old_twitter_user_id] unless params[:old_twitter_user_id].nil?
- end
-
- @user = User.new
- end
-
# GET /u/:user_uid/edit
def edit
- if current_user
- redirect_to current_user.main_room if @user != current_user && !current_user.admin_of?(@user)
- else
- redirect_to root_path
- end
+ redirect_to root_path unless current_user
+ end
+
+ # GET /u/:user_uid/change_password
+ def change_password
+ redirect_to edit_user_path unless current_user.greenlight_account?
+ end
+
+ # GET /u/:user_uid/delete_account
+ def delete_account
end
# PATCH /u/:user_uid/edit
def update
- redirect_path = current_user.admin_of?(@user) ? admins_path : edit_user_path(@user)
+ profile = params[:setting] == "password" ? change_password_path(@user) : edit_user_path(@user)
+ redirect_path = current_user.admin_of?(@user) ? admins_path : profile
if params[:setting] == "password"
# Update the users password.
- errors = {}
if @user.authenticate(user_params[:password])
# Verify that the new passwords match.
@@ -130,55 +91,52 @@ class UsersController < ApplicationController
@user.password = user_params[:new_password]
else
# New passwords don't match.
- errors[:password_confirmation] = "doesn't match"
+ @user.errors.add(:password_confirmation, "doesn't match")
end
else
# Original password is incorrect, can't update.
- errors[:password] = "is incorrect"
+ @user.errors.add(:password, "is incorrect")
end
- if errors.empty? && @user.save
- # Notify the user that their account has been updated.
- flash[:success] = I18n.t("info_update_success")
- redirect_to redirect_path
- else
- # Append custom errors.
- errors.each { |k, v| @user.errors.add(k, v) }
- render :edit, params: { settings: params[:settings] }
- end
- elsif user_params[:email] != @user.email && @user.update_attributes(user_params) && update_roles
- @user.update_attributes(email_verified: false)
+ # Notify the user that their account has been updated.
+ return redirect_to redirect_path,
+ flash: { success: I18n.t("info_update_success") } if @user.errors.empty? && @user.save
- 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
+ render :change_password
else
- render :edit, params: { settings: params[:settings] }
+ 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
end
end
# DELETE /u/:user_uid
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
- @user.destroy
- session.delete(:user_id)
- elsif current_user.admin_of?(@user)
- begin
+ self_delete = current_user == @user
+ begin
+ if current_user && (self_delete || current_user.admin_of?(@user))
@user.destroy
- rescue => e
- logger.error "Support: Error in user deletion: #{e}"
- flash[:alert] = I18n.t(params[:message], default: I18n.t("administrator.flash.delete_fail"))
- else
- flash[:success] = I18n.t("administrator.flash.delete")
+ session.delete(:user_id) if self_delete
+
+ return redirect_to admins_path, flash: { success: I18n.t("administrator.flash.delete") } unless self_delete
end
- redirect_to(admins_path) && return
+ rescue => e
+ logger.error "Support: Error in user deletion: #{e}"
+ flash[:alert] = I18n.t(params[:message], default: I18n.t("administrator.flash.delete_fail"))
end
+
redirect_to root_path
end
@@ -186,8 +144,7 @@ class UsersController < ApplicationController
def recordings
if current_user && current_user.uid == params[:user_uid]
@search, @order_column, @order_direction, recs =
- all_recordings(current_user.rooms.pluck(:bbb_id), current_user.provider,
- params.permit(:search, :column, :direction), true)
+ all_recordings(current_user.rooms.pluck(:bbb_id), params.permit(:search, :column, :direction), true)
@pagy, @recordings = pagy_array(recs)
else
redirect_to root_path
@@ -210,8 +167,9 @@ class UsersController < ApplicationController
@user = User.where(uid: params[:user_uid]).includes(:roles).first
end
- def ensure_unauthenticated
- redirect_to current_user.main_room if current_user && params[:old_twitter_user_id].nil?
+ # Verify that GreenLight is configured to allow user signup.
+ def check_user_signup_allowed
+ redirect_to root_path unless Rails.configuration.allow_user_signup
end
def user_params
@@ -219,109 +177,16 @@ class UsersController < ApplicationController
:new_password, :provider, :accepted_terms, :language)
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
- begin
- if invite_registration
- send_invite_user_signup_email(@user)
- elsif approval_registration
- send_approval_user_signup_email(@user)
- end
- rescue => e
- logger.error "Support: Error in email delivery: #{e}"
- flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
+ if invite_registration
+ send_invite_user_signup_email(@user)
+ elsif approval_registration
+ send_approval_user_signup_email(@user)
end
end
- # Add validation errors to model if they exist
- def valid_user_or_captcha
- valid_user = @user.valid?
- valid_captcha = Rails.configuration.recaptcha_enabled ? verify_recaptcha(model: @user) : true
-
- logger.error("Support: #{@user.email} creation failed: User params are not valid.") unless valid_user
-
- valid_user && valid_captcha
- end
-
- # Checks if the user passes the requirements to be invited
- def passes_invite_reqs
- # check if user needs to be invited and IS invited
- invitation = check_user_invited(@user.email, session[:invite_token], @user_domain)
-
- @user.email_verified = true if invitation[:verified]
-
- invitation[:present]
- end
-
- # Updates as user's roles
- def update_roles
- # Check that the user can manage users
- 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
+ # Checks that the user is allowed to edit this user
+ def check_admin_of
+ redirect_to current_user.main_room if current_user && @user != current_user && !current_user.admin_of?(@user)
end
end
diff --git a/app/helpers/admins_helper.rb b/app/helpers/admins_helper.rb
index c517c9f6..aff41f2a 100644
--- a/app/helpers/admins_helper.rb
+++ b/app/helpers/admins_helper.rb
@@ -19,36 +19,18 @@
module AdminsHelper
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
def recording_owner_email(room_id)
Room.find_by(bbb_id: room_id).owner.email
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
- registration_method == Rails.configuration.registration_methods[:invite]
- end
-
- def approval_registration
- registration_method == Rails.configuration.registration_methods[:approval]
+ def admin_invite_registration
+ controller_name == "admins" && action_name == "index" &&
+ @settings.get_value("Registration Method") == Rails.configuration.registration_methods[:invite]
end
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")
else
I18n.t("administrator.site_settings.authentication.disabled")
@@ -56,8 +38,7 @@ module AdminsHelper
end
def recording_default_visibility_string
- if Setting.find_or_create_by!(provider: user_settings_provider)
- .get_value("Default Recording Visibility") == "public"
+ if @settings.get_value("Default Recording Visibility") == "public"
I18n.t("recording.visibility.public")
else
I18n.t("recording.visibility.unlisted")
@@ -65,7 +46,7 @@ module AdminsHelper
end
def registration_method_string
- case registration_method
+ case @settings.get_value("Registration Method")
when Rails.configuration.registration_methods[:open]
I18n.t("administrator.site_settings.registration.methods.open")
when Rails.configuration.registration_methods[:invite]
@@ -76,7 +57,7 @@ module AdminsHelper
end
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
def edit_disabled
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 7ae53282..155335cf 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -18,20 +18,8 @@
require 'bbb_api'
require 'uri'
-require 'i18n/language/mapping'
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.
def iconset_providers
providers = configured_providers & [:google, :twitter, :office365, :ldap]
@@ -50,53 +38,9 @@ module ApplicationHelper
end
end
- # Determine if Greenlight is configured to allow user signups.
- def allow_user_signup?
- Rails.configuration.allow_user_signup
- 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
+ # Determines if a form field needs the is-invalid class.
+ def form_is_invalid?(obj, key)
+ 'is-invalid' unless obj.errors.messages[key].empty?
end
# Return all the translations available in the client side through javascript
@@ -118,6 +62,13 @@ module ApplicationHelper
current_user.main_room
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)
role.colour || Rails.configuration.primary_color_default
end
diff --git a/app/helpers/errors_helper.rb b/app/helpers/errors_helper.rb
deleted file mode 100644
index 955cbf7a..00000000
--- a/app/helpers/errors_helper.rb
+++ /dev/null
@@ -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 .
-
-module ErrorsHelper
-end
diff --git a/app/helpers/main_helper.rb b/app/helpers/main_helper.rb
deleted file mode 100644
index 2ae4ce75..00000000
--- a/app/helpers/main_helper.rb
+++ /dev/null
@@ -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 .
-
-module MainHelper
-end
diff --git a/app/helpers/meetings_helper.rb b/app/helpers/meetings_helper.rb
deleted file mode 100644
index ca691815..00000000
--- a/app/helpers/meetings_helper.rb
+++ /dev/null
@@ -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 .
-
-module MeetingsHelper
-end
diff --git a/app/helpers/password_resets_helper.rb b/app/helpers/password_resets_helper.rb
deleted file mode 100644
index bfc3d834..00000000
--- a/app/helpers/password_resets_helper.rb
+++ /dev/null
@@ -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 .
-
-module PasswordResetsHelper
-end
diff --git a/app/helpers/recordings_helper.rb b/app/helpers/recordings_helper.rb
index 0ab14306..06296457 100644
--- a/app/helpers/recordings_helper.rb
+++ b/app/helpers/recordings_helper.rb
@@ -17,8 +17,6 @@
# with BigBlueButton; if not, see .
module RecordingsHelper
- include Pagy::Frontend
-
# Helper for converting BigBlueButton dates into the desired format.
def recording_date(date)
I18n.l date, format: "%B %d, %Y"
@@ -48,4 +46,9 @@ module RecordingsHelper
def room_uid_from_bbb(bbb_id)
Room.find_by(bbb_id: bbb_id)[:uid]
end
+
+ # returns whether recording thumbnails are enabled on the server
+ def recording_thumbnails?
+ Rails.configuration.recording_thumbnails
+ end
end
diff --git a/app/helpers/rooms_helper.rb b/app/helpers/rooms_helper.rb
index 009fd77d..d98f772f 100644
--- a/app/helpers/rooms_helper.rb
+++ b/app/helpers/rooms_helper.rb
@@ -24,27 +24,13 @@ module RoomsHelper
end
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?
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)
# 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
diff --git a/app/helpers/theming_helper.rb b/app/helpers/theming_helper.rb
index e3f073fb..bb725f12 100644
--- a/app/helpers/theming_helper.rb
+++ b/app/helpers/theming_helper.rb
@@ -19,24 +19,11 @@
module ThemingHelper
# Returns the logo based on user's provider
def logo_image
- Setting.find_or_create_by(provider: user_settings_provider)
- .get_value("Branding Image") || Rails.configuration.branding_image_default
+ @settings.get_value("Branding Image") || Rails.configuration.branding_image_default
end
# Returns the primary color based on user's provider
def user_color
- Setting.find_or_create_by(provider: user_settings_provider)
- .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
+ @settings.get_value("Primary Color") || Rails.configuration.primary_color_default
end
end
diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
index c62f3d7e..c92ce09b 100644
--- a/app/helpers/users_helper.rb
+++ b/app/helpers/users_helper.rb
@@ -16,7 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see .
+require 'i18n/language/mapping'
+
module UsersHelper
+ include I18n::Language::Mapping
+
def recaptcha_enabled?
Rails.configuration.recaptcha_enabled
end
@@ -36,4 +40,29 @@ module UsersHelper
user.roles.by_priority.pluck(:id) | disallowed_roles
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
diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb
index 3e0743e9..0fe7b991 100644
--- a/app/mailers/application_mailer.rb
+++ b/app/mailers/application_mailer.rb
@@ -17,7 +17,6 @@
# with BigBlueButton; if not, see .
class ApplicationMailer < ActionMailer::Base
- add_template_helper(ThemingHelper)
default from: 'from@example.com'
layout 'mailer'
end
diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb
index d05734cf..a28ef222 100644
--- a/app/mailers/user_mailer.rb
+++ b/app/mailers/user_mailer.rb
@@ -18,74 +18,83 @@
class UserMailer < ApplicationMailer
include ApplicationHelper
+ include ThemingHelper
default from: Rails.configuration.smtp_sender
- def verify_email(user, url, image, color)
+ def verify_email(user, url, settings)
+ @settings = settings
@user = user
@url = url
- @image = image
- @color = color
+ @image = logo_image
+ @color = user_color
mail(to: @user.email, subject: t('landing.welcome'))
end
- def password_reset(user, url, image, color)
+ def password_reset(user, url, settings)
+ @settings = settings
@user = user
@url = url
- @image = image
- @color = color
+ @image = logo_image
+ @color = user_color
mail to: user.email, subject: t('reset_password.subtitle')
end
- def user_promoted(user, role, url, image, color)
+ def user_promoted(user, role, url, settings)
+ @settings = settings
@url = url
@admin_url = url + "admins"
- @image = image
- @color = color
+ @image = logo_image
+ @color = user_color
@role = translated_role_name(role)
mail to: user.email, subject: t('mailer.user.promoted.subtitle', role: translated_role_name(role))
end
- def user_demoted(user, role, url, image, color)
+ def user_demoted(user, role, url, settings)
+ @settings = settings
@url = url
@root_url = url
- @image = image
- @color = color
+ @image = logo_image
+ @color = user_color
@role = translated_role_name(role)
mail to: user.email, subject: t('mailer.user.demoted.subtitle', role: translated_role_name(role))
end
- def invite_email(name, email, url, image, color)
+ def invite_email(name, email, url, settings)
+ @settings = settings
@name = name
@email = email
@url = url
- @image = image
- @color = color
+ @image = logo_image
+ @color = user_color
mail to: email, subject: t('mailer.user.invite.subject')
end
- def approve_user(user, url, image, color)
+ def approve_user(user, url, settings)
+ @settings = settings
@user = user
@url = url
- @image = image
- @color = color
+ @image = logo_image
+ @color = user_color
mail to: user.email, subject: t('mailer.user.approve.subject')
end
- def approval_user_signup(user, url, image, color, admin_emails)
+ def approval_user_signup(user, url, admin_emails, settings)
+ @settings = settings
@user = user
@url = url
- @image = image
- @color = color
+ @image = logo_image
+ @color = user_color
mail to: admin_emails, subject: t('mailer.user.approve.signup.subject')
end
- def invite_user_signup(user, url, image, color, admin_emails)
+ def invite_user_signup(user, url, admin_emails, settings)
+ @settings = settings
@user = user
@url = url
- @image = image
- @color = color
+ @image = logo_image
+ @color = user_color
mail to: admin_emails, subject: t('mailer.user.invite.signup.subject')
end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index eb9732e2..8be21b91 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -26,21 +26,21 @@ class Ability
can :manage, :all
else
highest_role = user.highest_priority_role
- if highest_role.can_edit_site_settings
- can [:index, :site_settings, :server_recordings, :branding, :coloring, :coloring_lighten, :coloring_darken,
- :room_authentication, :registration_method, :room_limit, :default_recording_visibility], :admin
+ if highest_role.get_permission("can_edit_site_settings")
+ can [:index, :site_settings, :server_recordings, :update_settings, :coloring, :registration_method], :admin
end
- if highest_role.can_edit_roles
+ if highest_role.get_permission("can_edit_roles")
can [:index, :roles, :new_role, :change_role_order, :update_role, :delete_role], :admin
end
- if highest_role.can_manage_users
+ if highest_role.get_permission("can_manage_users")
can [:index, :roles, :edit_user, :promote, :demote, :ban_user, :unban_user,
:approve, :invite, :reset], :admin
end
- if !highest_role.can_edit_site_settings && !highest_role.can_edit_roles && !highest_role.can_manage_users
+ if !highest_role.get_permission("can_edit_site_settings") && !highest_role.get_permission("can_edit_roles") &&
+ !highest_role.get_permission("can_manage_users")
cannot :manage, AdminsController
end
end
diff --git a/app/models/concerns/auth_values.rb b/app/models/concerns/auth_values.rb
new file mode 100644
index 00000000..06681f9d
--- /dev/null
+++ b/app/models/concerns/auth_values.rb
@@ -0,0 +1,67 @@
+# 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 .
+
+module AuthValues
+ extend ActiveSupport::Concern
+
+ # Provider attributes.
+ def auth_name(auth)
+ case auth['provider']
+ when :office365
+ auth['info']['display_name']
+ else
+ auth['info']['name']
+ end
+ end
+
+ def auth_username(auth)
+ case auth['provider']
+ when :google
+ auth['info']['email'].split('@').first
+ when :bn_launcher
+ auth['info']['username']
+ else
+ auth['info']['nickname']
+ end
+ end
+
+ def auth_email(auth)
+ auth['info']['email']
+ end
+
+ def auth_image(auth)
+ case auth['provider']
+ when :twitter
+ auth['info']['image'].gsub("http", "https").gsub("_normal", "")
+ else
+ auth['info']['image']
+ end
+ end
+
+ def auth_roles(user, auth)
+ unless auth['info']['roles'].nil?
+ roles = auth['info']['roles'].split(',')
+
+ role_provider = auth['provider'] == "bn_launcher" ? auth['info']['customer'] : "greenlight"
+ roles.each do |role_name|
+ role = Role.where(provider: role_provider, name: role_name).first
+ user.roles << role unless role.nil?
+ end
+ end
+ end
+end
diff --git a/app/helpers/account_activations_helper.rb b/app/models/concerns/deleteable.rb
similarity index 62%
rename from app/helpers/account_activations_helper.rb
rename to app/models/concerns/deleteable.rb
index 4cddbd77..a13985c9 100644
--- a/app/helpers/account_activations_helper.rb
+++ b/app/models/concerns/deleteable.rb
@@ -16,5 +16,30 @@
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see .
-module AccountActivationsHelper
+module Deleteable
+ extend ActiveSupport::Concern
+
+ included do
+ # By default don't include deleted
+ default_scope { where(deleted: false) }
+ scope :include_deleted, -> { unscope(where: :deleted) }
+ scope :deleted, -> { include_deleted.where(deleted: true) }
+ end
+
+ def destroy
+ run_callbacks :destroy
+ update_attribute(:deleted, true)
+ end
+
+ def delete
+ destroy
+ end
+
+ def undelete
+ assign_attributes(deleted: false)
+ end
+
+ def undelete!
+ update_attribute(:deleted, false)
+ end
end
diff --git a/app/models/role.rb b/app/models/role.rb
index 6f0e932d..a4b1331f 100644
--- a/app/models/role.rb
+++ b/app/models/role.rb
@@ -18,6 +18,7 @@
class Role < ApplicationRecord
has_and_belongs_to_many :users, join_table: :users_roles
+ has_many :role_permissions
default_scope { order(:priority) }
scope :by_priority, -> { order(:priority) }
@@ -30,15 +31,18 @@ class Role < ApplicationRecord
end
def self.create_default_roles(provider)
- Role.create(name: "user", provider: provider, priority: 1, can_create_rooms: true, colour: "#868e96")
- Role.create(name: "admin", provider: provider, priority: 0, can_create_rooms: true, send_promoted_email: true,
+ Role.create(name: "user", provider: provider, priority: 1, colour: "#868e96")
+ .update_all_role_permissions(can_create_rooms: true)
+ Role.create(name: "admin", provider: provider, priority: 0, colour: "#f1c40f")
+ .update_all_role_permissions(can_create_rooms: true, send_promoted_email: true,
send_demoted_email: true, can_edit_site_settings: true,
- can_edit_roles: true, can_manage_users: true, colour: "#f1c40f")
- Role.create(name: "pending", provider: provider, priority: -1, colour: "#17a2b8")
- Role.create(name: "denied", provider: provider, priority: -1, colour: "#343a40")
- Role.create(name: "super_admin", provider: provider, priority: -2, can_create_rooms: true,
+ can_edit_roles: true, can_manage_users: true)
+ Role.create(name: "pending", provider: provider, priority: -1, colour: "#17a2b8").update_all_role_permissions
+ Role.create(name: "denied", provider: provider, priority: -1, colour: "#343a40").update_all_role_permissions
+ Role.create(name: "super_admin", provider: provider, priority: -2, colour: "#cd201f")
+ .update_all_role_permissions(can_create_rooms: true,
send_promoted_email: true, send_demoted_email: true, can_edit_site_settings: true,
- can_edit_roles: true, can_manage_users: true, colour: "#cd201f")
+ can_edit_roles: true, can_manage_users: true)
end
def self.create_new_role(role_name, provider)
@@ -56,4 +60,37 @@ class Role < ApplicationRecord
role
end
+
+ def update_all_role_permissions(permissions = {})
+ update_permission("can_create_rooms", permissions[:can_create_rooms].to_s)
+ update_permission("send_promoted_email", permissions[:send_promoted_email].to_s)
+ update_permission("send_demoted_email", permissions[:send_demoted_email].to_s)
+ update_permission("can_edit_site_settings", permissions[:can_edit_site_settings].to_s)
+ update_permission("can_edit_roles", permissions[:can_edit_roles].to_s)
+ update_permission("can_manage_users", permissions[:can_manage_users].to_s)
+ end
+
+ # Updates the value of the permission and enables it
+ def update_permission(name, value)
+ permission = role_permissions.find_or_create_by!(name: name)
+
+ permission.update_attributes(value: value, enabled: true)
+ end
+
+ # Returns the value if enabled or the default if not enabled
+ def get_permission(name, return_boolean = true)
+ permission = role_permissions.find_or_create_by!(name: name)
+
+ value = if permission[:enabled]
+ permission[:value]
+ else
+ "false"
+ end
+
+ if return_boolean
+ value == "true"
+ else
+ value
+ end
+ end
end
diff --git a/app/models/role_permission.rb b/app/models/role_permission.rb
new file mode 100644
index 00000000..058b900c
--- /dev/null
+++ b/app/models/role_permission.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+class RolePermission < ApplicationRecord
+ belongs_to :role
+end
diff --git a/app/models/room.rb b/app/models/room.rb
index 2de7bc1c..0e61fa7e 100644
--- a/app/models/room.rb
+++ b/app/models/room.rb
@@ -19,128 +19,30 @@
require 'bbb_api'
class Room < ApplicationRecord
- include ::BbbApi
+ include Deleteable
before_create :setup
- before_destroy :delete_all_recordings
-
validates :name, presence: true
belongs_to :owner, class_name: 'User', foreign_key: :user_id
- META_LISTED = "gl-listed"
-
# Determines if a user owns a room.
def owned_by?(user)
return false if user.nil?
user.rooms.include?(self)
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.
def invite_path
"#{Rails.configuration.relative_url_root}/#{CGI.escape(uid)}"
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.
def notify_waiting
ActionCable.server.broadcast("#{uid}_waiting_channel", action: "started")
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
# Generates a uid for the room and BigBlueButton.
@@ -151,12 +53,6 @@ class Room < ApplicationRecord
self.attendee_pw = RandomPassword.generate(length: 12)
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.
def uid_chunk
charset = ("a".."z").to_a - %w(b i l o s) + ("2".."9").to_a - %w(5 8)
diff --git a/app/models/user.rb b/app/models/user.rb
index 92ed8c74..3ab10b23 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -19,11 +19,10 @@
require 'bbb_api'
class User < ApplicationRecord
- include ::BbbApi
+ include Deleteable
attr_accessor :reset_token
- after_create :assign_default_role
- after_create :initialize_main_room
+ after_create :setup_user
before_save { email.try(:downcase!) }
@@ -32,7 +31,7 @@ class User < ApplicationRecord
has_many :rooms
belongs_to :main_room, class_name: 'Room', foreign_key: :room_id, required: false
- has_and_belongs_to_many :roles, join_table: :users_roles
+ has_and_belongs_to_many :roles, -> { includes :role_permissions }, join_table: :users_roles
validates :name, length: { maximum: 256 }, presence: true
validates :provider, presence: true
@@ -51,6 +50,8 @@ class User < ApplicationRecord
has_secure_password(validations: false)
class << self
+ include AuthValues
+
# Generates a user from omniauth.
def from_omniauth(auth)
# Provider is the customer name if in loadbalanced config mode
@@ -65,54 +66,6 @@ class User < ApplicationRecord
u.save!
end
end
-
- private
-
- # Provider attributes.
- def auth_name(auth)
- case auth['provider']
- when :office365
- auth['info']['display_name']
- else
- auth['info']['name']
- end
- end
-
- def auth_username(auth)
- case auth['provider']
- when :google
- auth['info']['email'].split('@').first
- when :bn_launcher
- auth['info']['username']
- else
- auth['info']['nickname']
- end
- end
-
- def auth_email(auth)
- auth['info']['email']
- end
-
- def auth_image(auth)
- case auth['provider']
- when :twitter
- auth['info']['image'].gsub("http", "https").gsub("_normal", "")
- else
- auth['info']['image']
- end
- end
-
- def auth_roles(user, auth)
- unless auth['info']['roles'].nil?
- roles = auth['info']['roles'].split(',')
-
- role_provider = auth['provider'] == "bn_launcher" ? auth['info']['customer'] : "greenlight"
- roles.each do |role_name|
- role = Role.where(provider: role_provider, name: role_name).first
- user.roles << role unless role.nil?
- end
- end
- end
end
def self.admins_search(string, role)
@@ -151,21 +104,17 @@ class User < ApplicationRecord
# Activates an account and initialize a users main room
def activate
- update_attribute(:email_verified, true)
- update_attribute(:activated_at, Time.zone.now)
- save
+ update_attributes(email_verified: true, activated_at: Time.zone.now)
end
def activated?
- return true unless Rails.configuration.enable_email_verification
- email_verified
+ Rails.configuration.enable_email_verification ? email_verified : true
end
# Sets the password reset attributes.
def create_reset_digest
self.reset_token = User.new_token
- update_attribute(:reset_digest, User.digest(reset_token))
- update_attribute(:reset_sent_at, Time.zone.now)
+ update_attributes(reset_digest: User.digest(reset_token), reset_sent_at: Time.zone.now)
end
# Returns true if the given token matches the digest.
@@ -203,12 +152,7 @@ class User < ApplicationRecord
end
def greenlight_account?
- return true unless provider # For testing cases when provider is set to null
- 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'
+ social_uid.nil?
end
def activation_token
@@ -221,11 +165,11 @@ class User < ApplicationRecord
if has_role? :super_admin
id != user.id
else
- highest_priority_role.can_manage_users && (id != user.id) && (provider == user.provider) &&
+ highest_priority_role.get_permission("can_manage_users") && (id != user.id) && (provider == user.provider) &&
(!user.has_role? :super_admin)
end
else
- (highest_priority_role.can_manage_users || (has_role? :super_admin)) && (id != user.id)
+ (highest_priority_role.get_permission("can_manage_users") || (has_role? :super_admin)) && (id != user.id)
end
end
@@ -288,15 +232,14 @@ class User < ApplicationRecord
def self.all_users_with_roles
User.joins("INNER JOIN users_roles ON users_roles.user_id = users.id INNER JOIN roles " \
- "ON roles.id = users_roles.role_id")
+ "ON roles.id = users_roles.role_id INNER JOIN role_permissions ON roles.id = role_permissions.role_id").distinct
end
private
def create_reset_activation_digest(token)
# Create the digest and persist it.
- self.activation_digest = User.digest(token)
- save
+ update_attribute(:activation_digest, User.digest(token))
token
end
@@ -305,19 +248,17 @@ class User < ApplicationRecord
rooms.destroy_all
end
- # Initializes a room for the user and assign a BigBlueButton user id.
- def initialize_main_room
- self.uid = "gl-#{(0...12).map { rand(65..90).chr }.join.downcase}"
- self.main_room = Room.create!(owner: self, name: I18n.t("home_room"))
- save
- end
+ def setup_user
+ # Initializes a room for the user and assign a BigBlueButton user id.
+ id = "gl-#{(0...12).map { rand(65..90).chr }.join.downcase}"
+ room = Room.create!(owner: self, name: I18n.t("home_room"))
- # Initialize the user to use the default user role
- def assign_default_role
+ update_attributes(uid: id, main_room: room)
+
+ # Initialize the user to use the default user role
role_provider = Rails.configuration.loadbalanced_configuration ? provider : "greenlight"
Role.create_default_roles(role_provider) if Role.where(provider: role_provider).count.zero?
-
add_role(:user) if roles.blank?
end
diff --git a/app/views/account_activations/verify.html.erb b/app/views/account_activations/show.html.erb
similarity index 83%
rename from app/views/account_activations/verify.html.erb
rename to app/views/account_activations/show.html.erb
index 3fc03ff2..1098255f 100644
--- a/app/views/account_activations/verify.html.erb
+++ b/app/views/account_activations/show.html.erb
@@ -21,7 +21,9 @@
<%= t("verify.not_verified") %>
- <%= render "/shared/components/resend_button" %>
+
+ <%= button_to t("verify.resend"), resend_email_path, params: { email: params['email'], email_verified: false }, class: "btn btn-primary btn-space" %>
+
diff --git a/app/views/shared/components/_admins_role.html.erb b/app/views/admins/components/_admins_role.html.erb
similarity index 100%
rename from app/views/shared/components/_admins_role.html.erb
rename to app/views/admins/components/_admins_role.html.erb
diff --git a/app/views/shared/components/_admins_tags.html.erb b/app/views/admins/components/_admins_tags.html.erb
similarity index 100%
rename from app/views/shared/components/_admins_tags.html.erb
rename to app/views/admins/components/_admins_tags.html.erb
diff --git a/app/views/admins/components/_menu_buttons.html.erb b/app/views/admins/components/_menu_buttons.html.erb
index 395cc3d4..17bbc460 100644
--- a/app/views/admins/components/_menu_buttons.html.erb
+++ b/app/views/admins/components/_menu_buttons.html.erb
@@ -16,12 +16,12 @@
<% highest_role = current_user.highest_priority_role %>
<% highest_role.name %>
- <% if highest_role.can_manage_users || highest_role.name == "super_admin" %>
+ <% if highest_role.get_permission("can_manage_users") || highest_role.name == "super_admin" %>
<%= link_to admins_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "index"}" do %>
<%= t("administrator.users.title") %>
<% end %>
<% end %>
- <% if highest_role.can_edit_site_settings || highest_role.name == "super_admin" %>
+ <% if highest_role.get_permission("can_edit_site_settings") || highest_role.name == "super_admin" %>
<%= link_to admin_recordings_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "server_recordings"}" do %>
<%= t("administrator.recordings.title") %>
<% end %>
@@ -29,7 +29,7 @@
<%= t("administrator.site_settings.title") %>
<% end %>
<% end %>
- <% if highest_role.can_edit_roles || highest_role.name == "super_admin" %>
+ <% if highest_role.get_permission("can_edit_roles") || highest_role.name == "super_admin" %>
<%= link_to admin_roles_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "roles"}" do %>
<%= t("administrator.roles.title") %>
<% end %>
diff --git a/app/views/admins/components/_roles.html.erb b/app/views/admins/components/_roles.html.erb
index 9d8cf77b..51f5cf14 100644
--- a/app/views/admins/components/_roles.html.erb
+++ b/app/views/admins/components/_roles.html.erb
@@ -33,7 +33,7 @@
">
- <%= form_for(@selected_role, url: admin_update_role_path(@selected_role.id), method: :post) do |f| %>
+ <%= form_with model: @selected_role, url: admin_update_role_path(@selected_role.id), method: :post do |f| %>
<%= f.label t('administrator.roles.name'), class: "form-label" %>
<%= f.text_field :name, class: 'form-control mb-3', value: translated_role_name(@selected_role), readonly: edit_disabled || @selected_role.name == "user" || @selected_role.name == "admin", required: true %>
@@ -48,34 +48,34 @@
-