Merge branch 'v2.4-beta'

This commit is contained in:
jfederico 2019-09-20 16:23:21 +00:00
commit b2f2e73bbc
102 changed files with 1914 additions and 1952 deletions

View File

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

View File

@ -33,7 +33,7 @@ function getLocalizedString(key) {
}) })
// If key is not found, search the fallback language for the key // If key is not found, search the fallback language for the key
if (translated == undefined) { if (translated === undefined) {
translated = I18nFallback translated = I18nFallback
keyArr.forEach(function(k) { keyArr.forEach(function(k) {

View File

@ -123,8 +123,8 @@ $(document).on('turbolinks:load', function(){
if(element.is('#room-title')){ if(element.is('#room-title')){
submit_update_request({ submit_update_request({
setting: "rename_header", setting: "rename_header",
room_name: element.find('#user-text').text(), name: element.find('#user-text').text(),
}, element.data('path')); }, element.data('path'), "POST");
} }
else if(element.is('#recording-title')){ else if(element.is('#recording-title')){
submit_update_request({ submit_update_request({
@ -132,16 +132,16 @@ $(document).on('turbolinks:load', function(){
record_id: element.data('recordid'), record_id: element.data('recordid'),
record_name: element.find('text').text(), record_name: element.find('text').text(),
room_uid: element.data('room-uid'), room_uid: element.data('room-uid'),
}, element.data('path')); }, element.data('path'), "PATCH");
} }
} }
// Helper for submitting ajax requests // 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 // Send ajax request for update
$.ajax({ $.ajax({
url: path, url: path,
type: "PATCH", type: action,
data: data, data: data,
}); });
} }

View File

@ -44,10 +44,20 @@ $(document).on('turbolinks:load', function(){
if ($("#cant-create-room-wrapper").length){ if ($("#cant-create-room-wrapper").length){
$(".wrapper").css('height', '100%').css('height', '-=130px'); $(".wrapper").css('height', '100%').css('height', '-=130px');
} }
}
// Display and update all fields related to creating a room in the createRoomModal // Display and update all fields related to creating a room in the createRoomModal
$("#create-room-block").click(function(){ $("#create-room-block").click(function(){
showCreateRoom()
})
// Display and update all fields related to creating a room in the createRoomModal
$(".update-room").click(function(){
showUpdateRoom()
})
}
});
function showCreateRoom() {
$("#create-room-name").val("") $("#create-room-name").val("")
$("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code_placeholder")) $("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code_placeholder"))
$("#room_access_code").val(null) $("#room_access_code").val(null)
@ -69,10 +79,9 @@ $(document).on('turbolinks:load', function(){
$(this).attr('style',"display:none !important") $(this).attr('style',"display:none !important")
if($(this).children().length > 0) { $(this).children().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 function showUpdateRoom() {
$(".update-room").click(function(){
var room_block_uid = $(this).closest("#room-block").data("room-uid") var room_block_uid = $(this).closest("#room-block").data("room-uid")
$("#create-room-name").val($(this).closest("tbody").find("#room-name h4").text()) $("#create-room-name").val($(this).closest("tbody").find("#room-name h4").text())
$("#createRoomModal form").attr("action", room_block_uid + "/update_settings") $("#createRoomModal form").attr("action", room_block_uid + "/update_settings")
@ -91,7 +100,7 @@ $(document).on('turbolinks:load', function(){
updateCurrentSettings($(this).closest("#room-block").data("room-settings")) updateCurrentSettings($(this).closest("#room-block").data("room-settings"))
accessCode = $(this).closest("#room-block").data("room-access-code") var accessCode = $(this).closest("#room-block").data("room-access-code")
if(accessCode){ if(accessCode){
$("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code") + ": " + accessCode) $("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code") + ": " + accessCode)
@ -100,37 +109,17 @@ $(document).on('turbolinks:load', function(){
$("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code_placeholder")) $("#create-room-access-code").text(getLocalizedString("modal.create_room.access_code_placeholder"))
$("#room_access_code").val(null) $("#room_access_code").val(null)
} }
}) }
//Update the createRoomModal to show the correct current settings //Update the createRoomModal to show the correct current settings
function updateCurrentSettings(settings){ function updateCurrentSettings(settings){
//set checkbox //set checkbox
if(settings.muteOnStart){ $("#room_mute_on_join").prop("checked", settings.muteOnStart)
$("#room_mute_on_join").prop("checked", true) $("#room_require_moderator_approval").prop("checked", settings.requireModeratorApproval)
} else { //default option $("#room_anyone_can_start").prop("checked", settings.anyoneCanStart)
$("#room_mute_on_join").prop("checked", false) $("#room_all_join_moderator").prop("checked", settings.joinModerator)
} }
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 generateAccessCode(){ function generateAccessCode(){
const accessCodeLength = 6 const accessCodeLength = 6
var validCharacters = "0123456789" var validCharacters = "0123456789"

View File

@ -26,8 +26,7 @@ $(document).on('turbolinks:load', function(){
(controller == "admins" && action == "server_recordings")) { (controller == "admins" && action == "server_recordings")) {
// Submit search if the user hits enter // Submit search if the user hits enter
$("#search-input").keypress(function(key) { $("#search-input").keypress(function(key) {
var keyPressed = key.which if (key.which == 13) {
if (keyPressed == 13) {
searchPage() searchPage()
} }
}) })
@ -35,8 +34,6 @@ $(document).on('turbolinks:load', function(){
// Add listeners for sort // Add listeners for sort
$("th[data-order]").click(function(data){ $("th[data-order]").click(function(data){
var header_elem = $(data.target) var header_elem = $(data.target)
var controller = $("body").data('controller');
var action = $("body").data('action');
if(header_elem.data('order') === 'asc'){ // asc if(header_elem.data('order') === 'asc'){ // asc
header_elem.data('order', 'desc'); header_elem.data('order', 'desc');
@ -50,15 +47,10 @@ $(document).on('turbolinks:load', function(){
var search = $("#search-input").val(); var search = $("#search-input").val();
if(controller === "rooms" && action === "show"){ var url = window.location.pathname + "?page=1&search=" + search + "&column=" + header_elem.data("header") +
window.location.replace(window.location.pathname + "?page=1&search=" + search + "&direction=" + header_elem.data('order')
"&column=" + header_elem.data("header") + "&direction="+ header_elem.data('order') +
"#recordings-table"); window.location.replace(addRecordingTable(url))
}
else{
window.location.replace(window.location.pathname + "?page=1&search=" + search +
"&column=" + header_elem.data("header") + "&direction="+ header_elem.data('order'));
}
}) })
if(controller === "rooms" && action === "show"){ if(controller === "rooms" && action === "show"){
@ -75,42 +67,30 @@ $(document).on('turbolinks:load', function(){
function searchPage() { function searchPage() {
var search = $("#search-input").val(); var search = $("#search-input").val();
var controller = $("body").data('controller');
var action = $("body").data('action');
// Check if the user filtered by role // Check if the user filtered by role
var role = new URL(location.href).searchParams.get('role') var role = new URL(location.href).searchParams.get('role')
var url = window.location.pathname + "?page=1&search=" + search var url = window.location.pathname + "?page=1&search=" + search
if (role) { if (role) { url += "&role=" + 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 // Clears the search bar
function clearSearch() { function clearSearch() {
var controller = $("body").data('controller');
var action = $("body").data('action');
var role = new URL(location.href).searchParams.get('role') var role = new URL(location.href).searchParams.get('role')
var url = window.location.pathname + "?page=1" var url = window.location.pathname + "?page=1"
if (role) { if (role) { url += "&role=" + role }
url += "&role=" + role
window.location.replace(addRecordingTable(url));
} }
if(controller === "rooms" && action === "show"){ function addRecordingTable(url) {
window.location.replace(url + "#recordings-table"); if($("body").data('controller') === "rooms" && $("body").data('action') === "show") {
} else{ url += "#recordings-table"
window.location.replace(url);
} }
return url
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 <http://www.gnu.org/licenses/>.
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

View File

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

View File

@ -19,20 +19,12 @@
module Registrar module Registrar
extend ActiveSupport::Concern extend ActiveSupport::Concern
def registration_method
Setting.find_or_create_by!(provider: user_settings_provider).get_value("Registration Method")
end
def open_registration
registration_method == Rails.configuration.registration_methods[:open]
end
def approval_registration def approval_registration
registration_method == Rails.configuration.registration_methods[:approval] @settings.get_value("Registration Method") == Rails.configuration.registration_methods[:approval]
end end
def invite_registration def invite_registration
registration_method == Rails.configuration.registration_methods[:invite] @settings.get_value("Registration Method") == Rails.configuration.registration_methods[:invite]
end end
# Returns a hash containing whether the user has been invited and if they # Returns a hash containing whether the user has been invited and if they
@ -51,4 +43,33 @@ module Registrar
{ present: false, verified: false } { present: false, verified: false }
end end
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 end

View File

@ -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 <http://www.gnu.org/licenses/>.
module Rolify
extend ActiveSupport::Concern
# Gets all roles
def all_roles(selected_role)
@roles = Role.editable_roles(@user_domain)
if @roles.count.zero?
Role.create_default_roles(@user_domain)
@roles = Role.editable_roles(@user_domain)
end
@selected_role = if selected_role.nil?
@roles.find_by(name: 'user')
else
@roles.find(selected_role)
end
@roles
end
# Creates a new role
def create_role(new_role_name)
# Make sure that the role name isn't a duplicate or a reserved name like super_admin or empty
return nil if Role.duplicate_name(new_role_name, @user_domain) || new_role_name.strip.empty?
Role.create_new_role(new_role_name, @user_domain)
end
# Updates a user's roles
def update_roles(roles)
# Check that the user can manage users
return true unless current_user.highest_priority_role.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

View File

@ -22,22 +22,20 @@ module Themer
# Lightens a color by 40% # Lightens a color by 40%
def color_lighten(color) def color_lighten(color)
# Uses the built in Sass Engine to lighten the color # Uses the built in Sass Engine to lighten the color
generate_sass("lighten", color, "40%")
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]
end end
# Darkens a color by 10% # Darkens a color by 10%
def color_darken(color) def color_darken(color)
# Uses the built in Sass Engine to darken the color # Uses the built in Sass Engine to darken the color
generate_sass("darken", color, "10%")
end
dummy_scss = "h1 { color: $darken; }" private
compiled = SassC::Engine.new("$darken:darken(#{color}, 10%);" + dummy_scss, syntax: :scss).render
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: ' string_locater = 'color: '
color_start = compiled.index(string_locater) + string_locater.length color_start = compiled.index(string_locater) + string_locater.length

View File

@ -27,7 +27,8 @@ class ErrorsController < ApplicationController
status_code: 500, status_code: 500,
message: I18n.t("errors.internal.message"), message: I18n.t("errors.internal.message"),
help: I18n.t("errors.internal.help"), help: I18n.t("errors.internal.help"),
display_back: true display_back: true,
report_issue: true
} }
end end

View File

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

View File

@ -23,23 +23,30 @@ class RecordingsController < ApplicationController
META_LISTED = "gl-listed" META_LISTED = "gl-listed"
# POST /:meetingID/:record_id # POST /:meetingID/:record_id
def update_recording def update
meta = { meta = {
"meta_#{META_LISTED}" => (params[:state] == "public"), "meta_#{META_LISTED}" => (params[:state] == "public"),
} }
res = @room.update_recording(params[:record_id], meta) res = update_recording(params[:record_id], meta)
# Redirects to the page that made the initial request # Redirects to the page that made the initial request
redirect_to request.referrer if res[:updated] redirect_back fallback_location: root_path if res[:updated]
end
# PATCH /:meetingID/:record_id
def rename
update_recording(params[:record_id], "meta_name" => params[:record_name])
redirect_back fallback_location: room_path(@room)
end end
# DELETE /:meetingID/:record_id # DELETE /:meetingID/:record_id
def delete_recording def delete
@room.delete_recording(params[:record_id]) delete_recording(params[:record_id])
# Redirects to the page that made the initial request # Redirects to the page that made the initial request
redirect_to request.referrer redirect_back fallback_location: root_path
end end
private private
@ -51,7 +58,7 @@ class RecordingsController < ApplicationController
# Ensure the user is logged into the room they are accessing. # Ensure the user is logged into the room they are accessing.
def verify_room_ownership def verify_room_ownership
if !current_user || (!@room.owned_by?(current_user) && 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)) !current_user.has_role?(:super_admin))
redirect_to root_path redirect_to root_path
end end

View File

@ -17,96 +17,67 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
class RoomsController < ApplicationController class RoomsController < ApplicationController
include RecordingsHelper
include Pagy::Backend include Pagy::Backend
include Recorder include Recorder
include Joiner
before_action :validate_accepted_terms, unless: -> { !Rails.configuration.terms } before_action :validate_accepted_terms, unless: -> { !Rails.configuration.terms }
before_action :validate_verified_email, except: [:show, :join], before_action :validate_verified_email, except: [:show, :join],
unless: -> { !Rails.configuration.enable_email_verification } unless: -> { !Rails.configuration.enable_email_verification }
before_action :find_room, except: [:create, :join_specific_room] 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], before_action :verify_room_owner_verified, only: [:show, :join],
unless: -> { !Rails.configuration.enable_email_verification } unless: -> { !Rails.configuration.enable_email_verification }
before_action :verify_user_not_admin, only: [:show] before_action :verify_user_not_admin, only: [:show]
# POST / # POST /
def create def create
redirect_to(root_path) && return unless current_user # Return to root if user is not signed in
return redirect_to root_path unless current_user
# Check if the user has not exceeded the room limit
return redirect_to current_user.main_room, flash: { alert: I18n.t("room.room_limit") } if room_limit_exceeded return redirect_to current_user.main_room, flash: { alert: I18n.t("room.room_limit") } if room_limit_exceeded
# Create room
@room = Room.new(name: room_params[:name], access_code: room_params[:access_code]) @room = Room.new(name: room_params[:name], access_code: room_params[:access_code])
@room.owner = current_user @room.owner = current_user
@room.room_settings = create_room_settings_string(room_params[:mute_on_join], @room.room_settings = create_room_settings_string(room_params)
room_params[:require_moderator_approval], room_params[:anyone_can_start], room_params[:all_join_moderator])
if @room.save # Save the room and redirect if it fails
logger.info("Support: #{current_user.email} has created a new room #{@room.uid}.") return redirect_to current_user.main_room, flash: { alert: I18n.t("room.create_room_error") } unless @room.save
if room_params[:auto_join] == "1" 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 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
end end
# GET /:room_uid # GET /:room_uid
def show def show
@is_running = @room.running?
@anyone_can_start = JSON.parse(@room[:room_settings])["anyoneCanStart"] @anyone_can_start = JSON.parse(@room[:room_settings])["anyoneCanStart"]
@room_running = room_running?(@room.bbb_id)
# If its the current user's room
if current_user && @room.owned_by?(current_user) if current_user && @room.owned_by?(current_user)
if current_user.highest_priority_role.can_create_rooms if current_user.highest_priority_role.get_permission("can_create_rooms")
# User is allowed to have rooms
@search, @order_column, @order_direction, recs = @search, @order_column, @order_direction, recs =
recordings(@room.bbb_id, @user_domain, params.permit(:search, :column, :direction), true) recordings(@room.bbb_id, params.permit(:search, :column, :direction), true)
@pagy, @recordings = pagy_array(recs) @pagy, @recordings = pagy_array(recs)
else else
# Render view for users that cant create rooms
@recent_rooms = Room.where(id: cookies.encrypted["#{current_user.uid}_recently_joined_rooms"]) @recent_rooms = Room.where(id: cookies.encrypted["#{current_user.uid}_recently_joined_rooms"])
render :cant_create_rooms render :cant_create_rooms
end end
else else
return redirect_to root_path, flash: { alert: I18n.t("room.invalid_provider") } if incorrect_user_domain return redirect_to root_path, flash: { alert: I18n.t("room.invalid_provider") } if incorrect_user_domain
# Get users name show_user_join
@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
end end
end end
@ -115,10 +86,8 @@ class RoomsController < ApplicationController
return redirect_to root_path, return redirect_to root_path,
flash: { alert: I18n.t("administrator.site_settings.authentication.user-info") } if auth_required flash: { alert: I18n.t("administrator.site_settings.authentication.user-info") } if auth_required
opts = default_meeting_options
unless @room.owned_by?(current_user) unless @room.owned_by?(current_user)
# Don't allow users to join unless they have a valid access code or the room doesn't # Don't allow users to join unless they have a valid access code or the room doesn't have an access code
# have an access code
if @room.access_code && !@room.access_code.empty? && @room.access_code != session[:access_code] if @room.access_code && !@room.access_code.empty? && @room.access_code != session[:access_code]
return redirect_to room_path(room_uid: params[:room_uid]), flash: { alert: I18n.t("room.access_code_required") } return redirect_to room_path(room_uid: params[:room_uid]), flash: { alert: I18n.t("room.access_code_required") }
end end
@ -128,23 +97,17 @@ class RoomsController < ApplicationController
@join_name = params[@room.invite_path][:join_name] @join_name = params[@room.invite_path][:join_name]
elsif !params[:join_name] elsif !params[:join_name]
# Join name not passed. # Join name not passed.
return return redirect_to root_path
end end
end end
# create or update cookie with join name # create or update cookie with join name
cookies.encrypted[:greenlight_name] = @join_name unless cookies.encrypted[:greenlight_name] == @join_name cookies.encrypted[:greenlight_name] = @join_name unless cookies.encrypted[:greenlight_name] == @join_name
if current_user save_recent_rooms
# 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
logger.info("Support: #{current_user.present? ? current_user.email : @join_name} is joining room #{@room.uid}") logger.info "Support: #{current_user.present? ? current_user.email : @join_name} is joining room #{@room.uid}"
join_room(default_meeting_options)
join_room(opts)
end end
# DELETE /:room_uid # DELETE /:room_uid
@ -155,24 +118,22 @@ class RoomsController < ApplicationController
redirect_to current_user.main_room redirect_to current_user.main_room
end end
# POST room/join # POST /room/join
def join_specific_room def join_specific_room
room_uid = params[:join_room][:url].split('/').last room_uid = params[:join_room][:url].split('/').last
begin begin
@room = Room.find_by(uid: room_uid) @room = Room.find_by!(uid: room_uid)
rescue ActiveRecord::RecordNotFound rescue ActiveRecord::RecordNotFound
return redirect_to current_user.main_room, alert: I18n.t("room.no_room.invalid_room_uid") return redirect_to current_user.main_room, alert: I18n.t("room.no_room.invalid_room_uid")
end end
return redirect_to current_user.main_room, alert: I18n.t("room.no_room.invalid_room_uid") if @room.nil?
redirect_to room_path(@room) redirect_to room_path(@room)
end end
# POST /:room_uid/start # POST /:room_uid/start
def start def start
logger.info("Support: #{current_user.email} is starting room #{@room.uid}") logger.info "Support: #{current_user.email} is starting room #{@room.uid}"
# Join the user in and start the meeting. # Join the user in and start the meeting.
opts = default_meeting_options opts = default_meeting_options
@ -180,11 +141,11 @@ class RoomsController < ApplicationController
# Include the user's choices for the room settings # Include the user's choices for the room settings
room_settings = JSON.parse(@room[: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"] opts[:require_moderator_approval] = room_settings["requireModeratorApproval"]
begin begin
redirect_to @room.join_path(current_user.name, opts, current_user.uid) redirect_to join_path(@room, current_user.name, opts, current_user.uid)
rescue BigBlueButton::BigBlueButtonException => e rescue BigBlueButton::BigBlueButtonException => e
logger.error("Support: #{@room.uid} start failed: #{e}") logger.error("Support: #{@room.uid} start failed: #{e}")
@ -199,26 +160,31 @@ class RoomsController < ApplicationController
# POST /:room_uid/update_settings # POST /:room_uid/update_settings
def update_settings def update_settings
begin 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") 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 end
redirect_to room_path redirect_to room_path
end end
# GET /:room_uid/logout # GET /:room_uid/logout
def logout def logout
logger.info("Support: #{current_user.present? ? current_user.email : 'Guest'} has left room #{@room.uid}") logger.info "Support: #{current_user.present? ? current_user.email : 'Guest'} has left room #{@room.uid}"
# Redirect the correct page. # Redirect the correct page.
redirect_to @room redirect_to @room
@ -235,29 +201,13 @@ class RoomsController < ApplicationController
private private
def update_room_attributes(update_type) def create_room_settings_string(options)
if @room.owned_by?(current_user) && @room != current_user.main_room room_settings = {
if update_type.eql? "name" "muteOnStart": options[:mute_on_join] == "1",
@room.update_attributes(name: params[:room_name] || room_params[:name]) "requireModeratorApproval": options[:require_moderator_approval] == "1",
elsif update_type.eql? "settings" "anyoneCanStart": options[:anyone_can_start] == "1",
room_settings_string = create_room_settings_string(room_params[:mute_on_join], "joinModerator": options[:all_join_moderator] == "1",
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"
room_settings.to_json room_settings.to_json
end end
@ -274,92 +224,40 @@ class RoomsController < ApplicationController
# Ensure the user is logged into the room they are accessing. # Ensure the user is logged into the room they are accessing.
def verify_room_ownership def verify_room_ownership
bring_to_room unless @room.owned_by?(current_user) return redirect_to root_path 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
end end
def validate_accepted_terms def validate_accepted_terms
if current_user redirect_to terms_path if current_user && !current_user&.accepted_terms
redirect_to terms_path unless current_user.accepted_terms
end
end end
def validate_verified_email def validate_verified_email
if current_user redirect_to account_activation_path(current_user) if current_user && !current_user&.activated?
redirect_to account_activation_path(current_user) unless current_user.activated?
end
end end
def verify_room_owner_verified def verify_room_owner_verified
unless @room.owner.activated? unless @room.owner.activated?
flash[:alert] = t("room.unavailable") flash[:alert] = t("room.unavailable")
if current_user && !@room.owned_by?(current_user)
redirect_to current_user.main_room
else
redirect_to root_path redirect_to root_path
end end
end end
end
def verify_user_not_admin def verify_user_not_admin
redirect_to admins_path if current_user && current_user&.has_role?(:super_admin) redirect_to admins_path if current_user&.has_role?(:super_admin)
end end
def auth_required def auth_required
Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Authentication") == "true" && @settings.get_value("Room Authentication") == "true" && current_user.nil?
current_user.nil?
end end
def room_limit_exceeded def room_limit_exceeded
limit = Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Limit").to_i limit = @settings.get_value("Room Limit").to_i
# Does not apply to admin # Does not apply to admin or users that aren't signed in
# 15+ option is used as unlimited # 15+ option is used as unlimited
return false if current_user&.has_role?(:admin) || limit == 15 return false if current_user&.has_role?(:admin) || limit == 15
current_user.rooms.count >= limit current_user.rooms.length >= limit
end
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
end end
helper_method :room_limit_exceeded
end end

View File

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

View File

@ -17,8 +17,8 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
class ThemesController < ApplicationController class ThemesController < ApplicationController
skip_before_action :maintenance_mode? skip_before_action :redirect_to_https, :maintenance_mode?, :migration_error?, :user_locale,
before_action :provider_settings :check_admin_password, :check_user_role
# GET /primary # GET /primary
def index def index
@ -39,10 +39,4 @@ class ThemesController < ApplicationController
format.css { render body: @compiled } format.css { render body: @compiled }
end end
end end
private
def provider_settings
@settings = Setting.find_or_create_by(provider: user_settings_provider)
end
end end

View File

@ -17,25 +17,25 @@
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
class UsersController < ApplicationController class UsersController < ApplicationController
include RecordingsHelper
include Pagy::Backend include Pagy::Backend
include Authenticator
include Emailer include Emailer
include Registrar include Registrar
include Recorder include Recorder
include Rolify
before_action :find_user, only: [:edit, :update, :destroy] before_action :find_user, only: [:edit, :change_password, :delete_account, :update, :destroy]
before_action :ensure_unauthenticated, only: [:new, :create, :signin] before_action :ensure_unauthenticated_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 # POST /u
def create def create
# Verify that GreenLight is configured to allow user signup.
return unless Rails.configuration.allow_user_signup
@user = User.new(user_params) @user = User.new(user_params)
@user.provider = @user_domain @user.provider = @user_domain
# User or recpatcha is not valid # 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 # 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 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 has passed all validations required
@user.save @user.save
logger.info("Support: #{@user.email} user has been created.") logger.info "Support: #{@user.email} user has been created."
# Set user to pending and redirect if Approval Registration is set # Set user to pending and redirect if Approval Registration is set
if approval_registration if approval_registration
@ -53,76 +53,37 @@ class UsersController < ApplicationController
flash: { success: I18n.t("registration.approval.signup") } unless Rails.configuration.enable_email_verification flash: { success: I18n.t("registration.approval.signup") } unless Rails.configuration.enable_email_verification
end end
send_registration_email if Rails.configuration.enable_email_verification send_registration_email
# Sign in automatically if email verification is disabled or if user is already verified. # Sign in automatically if email verification is disabled or if user is already verified.
login(@user) && return if !Rails.configuration.enable_email_verification || @user.email_verified login(@user) && return if !Rails.configuration.enable_email_verification || @user.email_verified
send_verification send_activation_email(@user)
redirect_to root_path redirect_to root_path
end end
# 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 # GET /u/:user_uid/edit
def edit def edit
if current_user redirect_to root_path unless current_user
redirect_to current_user.main_room if @user != current_user && !current_user.admin_of?(@user)
else
redirect_to root_path
end end
# GET /u/:user_uid/change_password
def change_password
redirect_to edit_user_path unless current_user.greenlight_account?
end
# GET /u/:user_uid/delete_account
def delete_account
end end
# PATCH /u/:user_uid/edit # PATCH /u/:user_uid/edit
def update 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" if params[:setting] == "password"
# Update the users password. # Update the users password.
errors = {}
if @user.authenticate(user_params[:password]) if @user.authenticate(user_params[:password])
# Verify that the new passwords match. # Verify that the new passwords match.
@ -130,55 +91,52 @@ class UsersController < ApplicationController
@user.password = user_params[:new_password] @user.password = user_params[:new_password]
else else
# New passwords don't match. # New passwords don't match.
errors[:password_confirmation] = "doesn't match" @user.errors.add(:password_confirmation, "doesn't match")
end end
else else
# Original password is incorrect, can't update. # Original password is incorrect, can't update.
errors[:password] = "is incorrect" @user.errors.add(:password, "is incorrect")
end end
if errors.empty? && @user.save
# Notify the user that their account has been updated. # Notify the user that their account has been updated.
flash[:success] = I18n.t("info_update_success") return redirect_to redirect_path,
redirect_to redirect_path flash: { success: I18n.t("info_update_success") } if @user.errors.empty? && @user.save
render :change_password
else else
# Append custom errors. if @user.update_attributes(user_params)
errors.each { |k, v| @user.errors.add(k, v) } @user.update_attributes(email_verified: false) if user_params[:email] != @user.email
render :edit, params: { settings: params[:settings] }
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 end
elsif user_params[:email] != @user.email && @user.update_attributes(user_params) && update_roles
@user.update_attributes(email_verified: false)
flash[:success] = I18n.t("info_update_success") render :edit
redirect_to redirect_path
elsif @user.update_attributes(user_params) && update_roles
update_locale(@user)
flash[:success] = I18n.t("info_update_success")
redirect_to redirect_path
else
render :edit, params: { settings: params[:settings] }
end end
end end
# DELETE /u/:user_uid # DELETE /u/:user_uid
def destroy def destroy
logger.info("Support: #{current_user.email} is deleting #{@user.email}.") logger.info "Support: #{current_user.email} is deleting #{@user.email}."
if current_user && current_user == @user self_delete = current_user == @user
@user.destroy
session.delete(:user_id)
elsif current_user.admin_of?(@user)
begin begin
if current_user && (self_delete || current_user.admin_of?(@user))
@user.destroy @user.destroy
session.delete(:user_id) if self_delete
return redirect_to admins_path, flash: { success: I18n.t("administrator.flash.delete") } unless self_delete
end
rescue => e rescue => e
logger.error "Support: Error in user deletion: #{e}" logger.error "Support: Error in user deletion: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("administrator.flash.delete_fail")) flash[:alert] = I18n.t(params[:message], default: I18n.t("administrator.flash.delete_fail"))
else
flash[:success] = I18n.t("administrator.flash.delete")
end
redirect_to(admins_path) && return
end end
redirect_to root_path redirect_to root_path
end end
@ -186,8 +144,7 @@ class UsersController < ApplicationController
def recordings def recordings
if current_user && current_user.uid == params[:user_uid] if current_user && current_user.uid == params[:user_uid]
@search, @order_column, @order_direction, recs = @search, @order_column, @order_direction, recs =
all_recordings(current_user.rooms.pluck(:bbb_id), current_user.provider, all_recordings(current_user.rooms.pluck(:bbb_id), params.permit(:search, :column, :direction), true)
params.permit(:search, :column, :direction), true)
@pagy, @recordings = pagy_array(recs) @pagy, @recordings = pagy_array(recs)
else else
redirect_to root_path redirect_to root_path
@ -210,8 +167,9 @@ class UsersController < ApplicationController
@user = User.where(uid: params[:user_uid]).includes(:roles).first @user = User.where(uid: params[:user_uid]).includes(:roles).first
end end
def ensure_unauthenticated # Verify that GreenLight is configured to allow user signup.
redirect_to current_user.main_room if current_user && params[:old_twitter_user_id].nil? def check_user_signup_allowed
redirect_to root_path unless Rails.configuration.allow_user_signup
end end
def user_params def user_params
@ -219,109 +177,16 @@ class UsersController < ApplicationController
:new_password, :provider, :accepted_terms, :language) :new_password, :provider, :accepted_terms, :language)
end end
def send_verification
# Start email verification and redirect to root.
begin
send_activation_email(@user)
rescue => e
logger.error "Support: Error in email delivery: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
else
flash[:success] = I18n.t("email_sent", email_type: t("verify.verification"))
end
end
def send_registration_email def send_registration_email
begin
if invite_registration if invite_registration
send_invite_user_signup_email(@user) send_invite_user_signup_email(@user)
elsif approval_registration elsif approval_registration
send_approval_user_signup_email(@user) send_approval_user_signup_email(@user)
end end
rescue => e
logger.error "Support: Error in email delivery: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
end
end end
# Add validation errors to model if they exist # Checks that the user is allowed to edit this user
def valid_user_or_captcha def check_admin_of
valid_user = @user.valid? redirect_to current_user.main_room if current_user && @user != current_user && !current_user.admin_of?(@user)
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
end end
end end

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -26,21 +26,21 @@ class Ability
can :manage, :all can :manage, :all
else else
highest_role = user.highest_priority_role highest_role = user.highest_priority_role
if highest_role.can_edit_site_settings if highest_role.get_permission("can_edit_site_settings")
can [:index, :site_settings, :server_recordings, :branding, :coloring, :coloring_lighten, :coloring_darken, can [:index, :site_settings, :server_recordings, :update_settings, :coloring, :registration_method], :admin
:room_authentication, :registration_method, :room_limit, :default_recording_visibility], :admin
end end
if highest_role.can_edit_roles if highest_role.get_permission("can_edit_roles")
can [:index, :roles, :new_role, :change_role_order, :update_role, :delete_role], :admin can [:index, :roles, :new_role, :change_role_order, :update_role, :delete_role], :admin
end 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, can [:index, :roles, :edit_user, :promote, :demote, :ban_user, :unban_user,
:approve, :invite, :reset], :admin :approve, :invite, :reset], :admin
end 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 cannot :manage, AdminsController
end end
end end

View File

@ -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 <http://www.gnu.org/licenses/>.
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

View File

@ -16,5 +16,30 @@
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
module 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 end

View File

@ -18,6 +18,7 @@
class Role < ApplicationRecord class Role < ApplicationRecord
has_and_belongs_to_many :users, join_table: :users_roles has_and_belongs_to_many :users, join_table: :users_roles
has_many :role_permissions
default_scope { order(:priority) } default_scope { order(:priority) }
scope :by_priority, -> { order(:priority) } scope :by_priority, -> { order(:priority) }
@ -30,15 +31,18 @@ class Role < ApplicationRecord
end end
def self.create_default_roles(provider) def self.create_default_roles(provider)
Role.create(name: "user", provider: provider, priority: 1, can_create_rooms: true, colour: "#868e96") Role.create(name: "user", provider: provider, priority: 1, colour: "#868e96")
Role.create(name: "admin", provider: provider, priority: 0, can_create_rooms: true, send_promoted_email: true, .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, send_demoted_email: true, can_edit_site_settings: true,
can_edit_roles: true, can_manage_users: true, colour: "#f1c40f") can_edit_roles: true, can_manage_users: true)
Role.create(name: "pending", provider: provider, priority: -1, colour: "#17a2b8") Role.create(name: "pending", provider: provider, priority: -1, colour: "#17a2b8").update_all_role_permissions
Role.create(name: "denied", provider: provider, priority: -1, colour: "#343a40") Role.create(name: "denied", provider: provider, priority: -1, colour: "#343a40").update_all_role_permissions
Role.create(name: "super_admin", provider: provider, priority: -2, can_create_rooms: true, 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, 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 end
def self.create_new_role(role_name, provider) def self.create_new_role(role_name, provider)
@ -56,4 +60,37 @@ class Role < ApplicationRecord
role role
end 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 end

View File

@ -0,0 +1,5 @@
# frozen_string_literal: true
class RolePermission < ApplicationRecord
belongs_to :role
end

View File

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

View File

@ -19,11 +19,10 @@
require 'bbb_api' require 'bbb_api'
class User < ApplicationRecord class User < ApplicationRecord
include ::BbbApi include Deleteable
attr_accessor :reset_token attr_accessor :reset_token
after_create :assign_default_role after_create :setup_user
after_create :initialize_main_room
before_save { email.try(:downcase!) } before_save { email.try(:downcase!) }
@ -32,7 +31,7 @@ class User < ApplicationRecord
has_many :rooms has_many :rooms
belongs_to :main_room, class_name: 'Room', foreign_key: :room_id, required: false 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 :name, length: { maximum: 256 }, presence: true
validates :provider, presence: true validates :provider, presence: true
@ -51,6 +50,8 @@ class User < ApplicationRecord
has_secure_password(validations: false) has_secure_password(validations: false)
class << self class << self
include AuthValues
# Generates a user from omniauth. # Generates a user from omniauth.
def from_omniauth(auth) def from_omniauth(auth)
# Provider is the customer name if in loadbalanced config mode # Provider is the customer name if in loadbalanced config mode
@ -65,54 +66,6 @@ class User < ApplicationRecord
u.save! u.save!
end end
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 end
def self.admins_search(string, role) def self.admins_search(string, role)
@ -151,21 +104,17 @@ class User < ApplicationRecord
# Activates an account and initialize a users main room # Activates an account and initialize a users main room
def activate def activate
update_attribute(:email_verified, true) update_attributes(email_verified: true, activated_at: Time.zone.now)
update_attribute(:activated_at, Time.zone.now)
save
end end
def activated? def activated?
return true unless Rails.configuration.enable_email_verification Rails.configuration.enable_email_verification ? email_verified : true
email_verified
end end
# Sets the password reset attributes. # Sets the password reset attributes.
def create_reset_digest def create_reset_digest
self.reset_token = User.new_token self.reset_token = User.new_token
update_attribute(:reset_digest, User.digest(reset_token)) update_attributes(reset_digest: User.digest(reset_token), reset_sent_at: Time.zone.now)
update_attribute(:reset_sent_at, Time.zone.now)
end end
# Returns true if the given token matches the digest. # Returns true if the given token matches the digest.
@ -203,12 +152,7 @@ class User < ApplicationRecord
end end
def greenlight_account? def greenlight_account?
return true unless provider # For testing cases when provider is set to null social_uid.nil?
return true if provider == "greenlight"
return false unless Rails.configuration.loadbalanced_configuration
# Proceed with fetching the provider info
provider_info = retrieve_provider_info(provider, 'api2', 'getUserGreenlightCredentials')
provider_info['provider'] == 'greenlight'
end end
def activation_token def activation_token
@ -221,11 +165,11 @@ class User < ApplicationRecord
if has_role? :super_admin if has_role? :super_admin
id != user.id id != user.id
else 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) (!user.has_role? :super_admin)
end end
else 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
end end
@ -288,15 +232,14 @@ class User < ApplicationRecord
def self.all_users_with_roles def self.all_users_with_roles
User.joins("INNER JOIN users_roles ON users_roles.user_id = users.id INNER JOIN 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 end
private private
def create_reset_activation_digest(token) def create_reset_activation_digest(token)
# Create the digest and persist it. # Create the digest and persist it.
self.activation_digest = User.digest(token) update_attribute(:activation_digest, User.digest(token))
save
token token
end end
@ -305,19 +248,17 @@ class User < ApplicationRecord
rooms.destroy_all rooms.destroy_all
end end
def setup_user
# Initializes a room for the user and assign a BigBlueButton user id. # Initializes a room for the user and assign a BigBlueButton user id.
def initialize_main_room id = "gl-#{(0...12).map { rand(65..90).chr }.join.downcase}"
self.uid = "gl-#{(0...12).map { rand(65..90).chr }.join.downcase}" room = Room.create!(owner: self, name: I18n.t("home_room"))
self.main_room = Room.create!(owner: self, name: I18n.t("home_room"))
save update_attributes(uid: id, main_room: room)
end
# Initialize the user to use the default user role # Initialize the user to use the default user role
def assign_default_role
role_provider = Rails.configuration.loadbalanced_configuration ? provider : "greenlight" role_provider = Rails.configuration.loadbalanced_configuration ? provider : "greenlight"
Role.create_default_roles(role_provider) if Role.where(provider: role_provider).count.zero? Role.create_default_roles(role_provider) if Role.where(provider: role_provider).count.zero?
add_role(:user) if roles.blank? add_role(:user) if roles.blank?
end end

View File

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

View File

@ -16,12 +16,12 @@
<div class="list-group list-group-transparent mb-0"> <div class="list-group list-group-transparent mb-0">
<% highest_role = current_user.highest_priority_role %> <% highest_role = current_user.highest_priority_role %>
<% highest_role.name %> <% 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 %> <%= link_to admins_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "index"}" do %>
<span class="icon mr-3"><i class="fas fa-users"></i></span><%= t("administrator.users.title") %> <span class="icon mr-3"><i class="fas fa-users"></i></span><%= t("administrator.users.title") %>
<% end %> <% end %>
<% 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 %> <%= link_to admin_recordings_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "server_recordings"}" do %>
<span class="icon mr-4"><i class="fas fa-video"></i></i></span><%= t("administrator.recordings.title") %> <span class="icon mr-4"><i class="fas fa-video"></i></i></span><%= t("administrator.recordings.title") %>
<% end %> <% end %>
@ -29,7 +29,7 @@
<span class="icon mr-4"><i class="fas fa-cogs"></i></span><%= t("administrator.site_settings.title") %> <span class="icon mr-4"><i class="fas fa-cogs"></i></span><%= t("administrator.site_settings.title") %>
<% end %> <% end %>
<% 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 %> <%= link_to admin_roles_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "roles"}" do %>
<span class="icon mr-4"><i class="fas fa-user-tag"></i></i></span><%= t("administrator.roles.title") %> <span class="icon mr-4"><i class="fas fa-user-tag"></i></i></span><%= t("administrator.roles.title") %>
<% end %> <% end %>

View File

@ -33,7 +33,7 @@
</div> </div>
</div> </div>
<div class="col-lg-9 <%="form-disable" if edit_disabled %>"> <div class="col-lg-9 <%="form-disable" if edit_disabled %>">
<%= 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.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 %> <%= 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 @@
</div> </div>
</div> </div>
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.can_create_rooms %>"> <label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.get_permission("can_create_rooms") %>">
<span class="ml-0 custom-switch-description"><%= t("administrator.roles.can_create_rooms")%></span> <span class="ml-0 custom-switch-description"><%= t("administrator.roles.can_create_rooms")%></span>
<%= f.check_box :can_create_rooms, class: "custom-switch-input", disabled: edit_disabled || !current_role.can_create_rooms %> <%= f.check_box :can_create_rooms, checked: @selected_role.get_permission("can_create_rooms"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("can_create_rooms") %>
<span class="custom-switch-indicator float-right"></span> <span class="custom-switch-indicator float-right"></span>
</label> </label>
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.send_promoted_email %>"> <label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.get_permission("send_promoted_email") %>">
<span class="ml-0 custom-switch-description"><%= t("administrator.roles.promote_email")%></span> <span class="ml-0 custom-switch-description"><%= t("administrator.roles.promote_email")%></span>
<%= f.check_box :send_promoted_email, class: "custom-switch-input", disabled: edit_disabled || !current_role.send_promoted_email %> <%= f.check_box :send_promoted_email, checked: @selected_role.get_permission("send_promoted_email"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("send_promoted_email") %>
<span class="custom-switch-indicator float-right"></span> <span class="custom-switch-indicator float-right"></span>
</label> </label>
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.send_demoted_email %>"> <label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.get_permission("send_demoted_email") %>">
<span class="ml-0 custom-switch-description"><%= t("administrator.roles.demote_email")%></span> <span class="ml-0 custom-switch-description"><%= t("administrator.roles.demote_email")%></span>
<%= f.check_box :send_demoted_email, class: "custom-switch-input", disabled: edit_disabled || !current_role.send_demoted_email %> <%= f.check_box :send_demoted_email, checked: @selected_role.get_permission("send_demoted_email"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("send_demoted_email") %>
<span class="custom-switch-indicator float-right"></span> <span class="custom-switch-indicator float-right"></span>
</label> </label>
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.can_edit_site_settings %>"> <label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.get_permission("can_edit_site_settings") %>">
<span class="ml-0 custom-switch-description"><%= t("administrator.roles.edit_site_settings")%></span> <span class="ml-0 custom-switch-description"><%= t("administrator.roles.edit_site_settings")%></span>
<%= f.check_box :can_edit_site_settings, class: "custom-switch-input", disabled: edit_disabled || !current_role.can_edit_site_settings %> <%= f.check_box :can_edit_site_settings, checked: @selected_role.get_permission("can_edit_site_settings"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("can_edit_site_settings") %>
<span class="custom-switch-indicator float-right"></span> <span class="custom-switch-indicator float-right"></span>
</label> </label>
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.can_edit_roles %>"> <label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.get_permission("can_edit_roles") %>">
<span class="ml-0 custom-switch-description"><%= t("administrator.roles.edit_roles")%></span> <span class="ml-0 custom-switch-description"><%= t("administrator.roles.edit_roles")%></span>
<%= f.check_box :can_edit_roles, class: "custom-switch-input", disabled: edit_disabled || !current_role.can_edit_roles %> <%= f.check_box :can_edit_roles, checked: @selected_role.get_permission("can_edit_roles"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("can_edit_roles") %>
<span class="custom-switch-indicator float-right"></span> <span class="custom-switch-indicator float-right"></span>
</label> </label>
<label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.can_manage_users %>"> <label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block <%="form-disable" if !current_role.get_permission("can_manage_users") %>">
<span class="ml-0 custom-switch-description"><%= t("administrator.roles.manage_users")%></span> <span class="ml-0 custom-switch-description"><%= t("administrator.roles.manage_users")%></span>
<%= f.check_box :can_manage_users, class: "custom-switch-input", disabled: edit_disabled || !current_role.can_manage_users %> <%= f.check_box :can_manage_users, checked: @selected_role.get_permission("can_manage_users"), class: "custom-switch-input", disabled: edit_disabled || !current_role.get_permission("can_manage_users") %>
<span class="custom-switch-indicator float-right"></span> <span class="custom-switch-indicator float-right"></span>
</label> </label>

View File

@ -15,7 +15,7 @@
<tr> <tr>
<td> <td>
<div id="recording-title" class="form-inline edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= update_room_path(room_uid: room_uid_from_bbb(recording[:meetingID])) %>"> <div id="recording-title" class="form-inline edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= rename_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]) %>">
<text id='recording-text'> <text id='recording-text'>
<% if recording[:metadata][:name] %> <% if recording[:metadata][:name] %>
<%= recording[:metadata][:name] %> <%= recording[:metadata][:name] %>

View File

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

View File

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

View File

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

View File

@ -29,6 +29,11 @@
<i class="fas fa-arrow-left mr-2"></i><%= t("go_back") %> <i class="fas fa-arrow-left mr-2"></i><%= t("go_back") %>
</a> </a>
<% end %> <% end %>
<% if defined?(report_issue) && report_issue && Rails.configuration.report_issue_url.present? %>
<a class="btn btn-primary ml-4" href="<%= Rails.configuration.report_issue_url %>" target="_blank" rel="noopener">
<i class="fas fa-exclamation mr-2"></i><%= t("errors.internal.report") %>
</a>
<% end %>
<% else %> <% else %>
<h1 class="h2 mb-3"><%= t("errors.not_found.message") %></h1> <h1 class="h2 mb-3"><%= t("errors.not_found.message") %></h1>
<p class="h4 text-muted font-weight-normal mb-7"><%= t("errors.not_found.help") %></p> <p class="h4 text-muted font-weight-normal mb-7"><%= t("errors.not_found.help") %></p>

View File

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

View File

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

View File

@ -23,7 +23,7 @@
<div class="container"> <div class="container">
<div class="row pt-9"> <div class="row pt-9">
<div class="col-lg-8 col-sm-12"> <div class="col-lg-8 col-sm-12">
<div id="room-title" class="display-3 form-inline <%= 'edit_hover_class' if current_user.main_room != @room %>"> <div id="room-title" class="display-3 form-inline <%= 'edit_hover_class' if current_user.main_room != @room %>" data-path="<%= update_settings_path(@room) %>">
<% if current_user.main_room == @room %> <% if current_user.main_room == @room %>
<h1 contenteditable=false id="user-text" class="display-3 text-left mb-3 font-weight-400"><%= t("home_room") %></h1> <h1 contenteditable=false id="user-text" class="display-3 text-left mb-3 font-weight-400"><%= t("home_room") %></h1>
<a class="disable-click"><i class="fas fa-home align-top home-indicator ml-2"></i></a> <a class="disable-click"><i class="fas fa-home align-top home-indicator ml-2"></i></a>
@ -66,7 +66,7 @@
<% end %> <% end %>
</div> </div>
<div class="offset-lg-1 col-lg-3 col-sm-12 force-bottom mt-5 pr-0"> <div class="offset-lg-1 col-lg-3 col-sm-12 force-bottom mt-5 pr-0">
<% if @is_running %> <% if @room_running %>
<%= button_to t("room.join"), room_path(@room), class: "btn btn-primary btn-block px-7 start-button float-right" %> <%= button_to t("room.join"), room_path(@room), class: "btn btn-primary btn-block px-7 start-button float-right" %>
<% else %> <% else %>
<% unless exceeds_limit %> <% unless exceeds_limit %>
@ -80,20 +80,20 @@
<% if current_user.rooms.length > 1 %> <% if current_user.rooms.length > 1 %>
<div class="col-lg-4 col-md-6 col-sm-12"> <div class="col-lg-4 col-md-6 col-sm-12">
<%= link_to current_user.main_room do %> <%= link_to current_user.main_room do %>
<%= render "shared/components/room_block", room: current_user.main_room %> <%= render "rooms/components/room_block", room: current_user.main_room %>
<% end %> <% end %>
</div> </div>
<% current_user.secondary_rooms.each do |room| %> <% current_user.secondary_rooms.each do |room| %>
<div class="col-lg-4 col-md-6 col-sm-12"> <div class="col-lg-4 col-md-6 col-sm-12">
<%= link_to room do %> <%= link_to room do %>
<%= render "shared/components/room_block", room: room %> <%= render "rooms/components/room_block", room: room %>
<% end %> <% end %>
</div> </div>
<%= render "shared/modals/delete_room_modal", recording_count: room.recording_count, room: room %> <%= render "shared/modals/delete_room_modal", room: room %>
<% end %> <% end %>
<% end %> <% end %>
<% unless room_limit_exceeded %> <% unless room_limit_exceeded %>
<%= render "shared/components/create_room_block"%> <%= render "rooms/components/create_room_block"%>
<% end %> <% end %>
</div> </div>
</div> </div>

View File

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

View File

@ -34,7 +34,7 @@
<i class="fas fa-home pr-1 "></i> <%= t("header.dropdown.home") %> <i class="fas fa-home pr-1 "></i> <%= t("header.dropdown.home") %>
<% end %> <% end %>
<% if current_user.highest_priority_role.can_create_rooms %> <% if current_user.highest_priority_role.get_permission("can_create_rooms") %>
<% all_rec_page = params[:controller] == "users" && params[:action] == "recordings" ? "active" : "" %> <% all_rec_page = params[:controller] == "users" && params[:action] == "recordings" ? "active" : "" %>
<%= link_to get_user_recordings_path(current_user), class: "px-3 mx-1 mt-1 header-nav #{all_rec_page}" do %> <%= link_to get_user_recordings_path(current_user), class: "px-3 mx-1 mt-1 header-nav #{all_rec_page}" do %>
<i class="fas fa-video pr-1"></i> <%= t("header.all_recordings") %> <i class="fas fa-video pr-1"></i> <%= t("header.all_recordings") %>
@ -59,15 +59,15 @@
<i class="dropdown-icon fas fa-id-card mr-3"></i><%= t("header.dropdown.settings") %> <i class="dropdown-icon fas fa-id-card mr-3"></i><%= t("header.dropdown.settings") %>
<% end %> <% end %>
<% highest_role = current_user.highest_priority_role %> <% highest_role = current_user.highest_priority_role %>
<% 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: "dropdown-item" do %> <%= link_to admins_path, class: "dropdown-item" do %>
<i class="dropdown-icon fas fa-user-tie mr-3"></i><%= t("header.dropdown.account_settings") %> <i class="dropdown-icon fas fa-user-tie mr-3"></i><%= t("header.dropdown.account_settings") %>
<% end %> <% end %>
<% elsif highest_role.can_edit_site_settings %> <% elsif highest_role.get_permission("can_edit_site_settings") %>
<%= link_to admin_site_settings_path, class: "dropdown-item" do %> <%= link_to admin_site_settings_path, class: "dropdown-item" do %>
<i class="dropdown-icon fas fa-user-tie mr-3"></i><%= t("header.dropdown.account_settings") %> <i class="dropdown-icon fas fa-user-tie mr-3"></i><%= t("header.dropdown.account_settings") %>
<% end %> <% end %>
<% elsif highest_role.can_edit_roles%> <% elsif highest_role.get_permission("can_edit_roles")%>
<%= link_to admin_roles_path, class: "dropdown-item" do %> <%= link_to admin_roles_path, class: "dropdown-item" do %>
<i class="dropdown-icon fas fa-user-tie mr-3"></i><%= t("header.dropdown.account_settings") %> <i class="dropdown-icon fas fa-user-tie mr-3"></i><%= t("header.dropdown.account_settings") %>
<% end %> <% end %>
@ -76,6 +76,11 @@
<a class="dropdown-item" href="http://docs.bigbluebutton.org/install/greenlight-v2.html" target="_blank" rel="noopener"> <a class="dropdown-item" href="http://docs.bigbluebutton.org/install/greenlight-v2.html" target="_blank" rel="noopener">
<i class="dropdown-icon far fa-question-circle"></i> <%= t("header.dropdown.help") %> <i class="dropdown-icon far fa-question-circle"></i> <%= t("header.dropdown.help") %>
</a> </a>
<% if Rails.configuration.report_issue_url.present? %>
<a class="dropdown-item" href="<%= Rails.configuration.report_issue_url %>" target="_blank" rel="noopener">
<i class="dropdown-icon fas fa-exclamation mr-3"></i><%= t("errors.internal.report") %>
</a>
<% end %>
<%= link_to logout_path, class: "dropdown-item" do %> <%= link_to logout_path, class: "dropdown-item" do %>
<i class="dropdown-icon fas fa-sign-out-alt"></i> <%= t("header.dropdown.signout") %> <i class="dropdown-icon fas fa-sign-out-alt"></i> <%= t("header.dropdown.signout") %>
<% end %> <% end %>

View File

@ -15,7 +15,7 @@
<tr> <tr>
<td> <td>
<div id="recording-title" class="form-inline edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= update_room_path(room_uid: room_uid_from_bbb(recording[:meetingID])) %>"> <div id="recording-title" class="form-inline edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= rename_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]) %>">
<text> <text>
<% if recording[:metadata][:name] %> <% if recording[:metadata][:name] %>
<%= recording[:metadata][:name] %> <%= recording[:metadata][:name] %>

View File

@ -15,7 +15,7 @@
<tr> <tr>
<td> <td>
<div id="recording-title" class="form-inline edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= update_room_path(room_uid: room_uid_from_bbb(recording[:meetingID])) %>"> <div id="recording-title" class="form-inline edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= rename_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]) %>">
<text id='recording-text'> <text id='recording-text'>
<% if recording[:metadata][:name] %> <% if recording[:metadata][:name] %>
<%= recording[:metadata][:name] %> <%= recording[:metadata][:name] %>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -46,7 +46,7 @@
<% @user.roles.by_priority.each do |role| %> <% @user.roles.by_priority.each do |role| %>
<span id="<%= "user-role-tag_#{role.id}" %>" style="<%= "background-color: #{role_colour(role)};border-color: #{role_colour(role)};" %>" class="tag user-role-tag"> <span id="<%= "user-role-tag_#{role.id}" %>" style="<%= "background-color: #{role_colour(role)};border-color: #{role_colour(role)};" %>" class="tag user-role-tag">
<%= translated_role_name(role) %> <%= translated_role_name(role) %>
<% if (current_user_role.can_manage_users || current_user_role.name == "super_admin") && (role.priority > current_user_role.priority || current_user_role.name == "admin") %> <% if (current_user_role.get_permission("can_manage_users") || current_user_role.name == "super_admin") && (role.priority > current_user_role.priority || current_user_role.name == "admin") %>
<a data-role-id="<%= role.id %>" class="tag-addon clear-role"> <a data-role-id="<%= role.id %>" class="tag-addon clear-role">
<i data-role-id="<%= role.id %>" class="fas fa-times"></i> <i data-role-id="<%= role.id %>" class="fas fa-times"></i>
</a> </a>
@ -54,11 +54,11 @@
</span> </span>
<% end %> <% end %>
</div> </div>
<% if current_user_role.can_manage_users || current_user_role.name == "super_admin" %> <% if current_user_role.get_permission("can_manage_users") || current_user_role.name == "super_admin" %>
<% provider = Rails.configuration.loadbalanced_configuration ? current_user.provider : "greenlight" %> <% provider = Rails.configuration.loadbalanced_configuration ? current_user.provider : "greenlight" %>
<%= f.select :roles, Role.editable_roles(@user_domain).map{|role| [translated_role_name(role), role.id, {'data-colour' => role_colour(role)}]}.unshift(["", nil, {'data-colour' => nil}]), {disabled: disabled_roles(@user)}, { class: "form-control custom-select", id: "role-select-dropdown" } %> <%= f.select :roles, Role.editable_roles(@user_domain).map{|role| [translated_role_name(role), role.id, {'data-colour' => role_colour(role)}]}.unshift(["", nil, {'data-colour' => nil}]), {disabled: disabled_roles(@user)}, { class: "form-control custom-select", id: "role-select-dropdown" } %>
<% end %> <% end %>
<%= f.hidden_field :role_ids, id: "user_role_ids", value: @user.roles.by_priority.pluck(:id) %> <%= f.hidden_field :role_ids, id: "user_role_ids", value: @user.roles.by_priority.pluck(:id).uniq %>
<%= f.label t("settings.account.image"), class: "form-label mt-5" %> <%= f.label t("settings.account.image"), class: "form-label mt-5" %>
<div class="row"> <div class="row">

View File

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

View File

@ -19,13 +19,13 @@
<div class="row"> <div class="row">
<div class="col-8"> <div class="col-8">
<%= f.label :password, t("settings.password.old"), class: "form-label" %> <%= f.label :password, t("settings.password.old"), class: "form-label" %>
<%= f.password_field :password, class: "form-control #{form_is_invalid?(@user, :password)}" %> <%= f.password_field :password, class: "form-control #{form_is_invalid?(@user, :password)}", autocomplete: :off, required: true %>
<br> <br>
<%= f.label :new_password, t("settings.password.new"), class: "form-label" %> <%= f.label :new_password, t("settings.password.new"), class: "form-label" %>
<%= f.password_field :new_password, class: "form-control #{form_is_invalid?(@user, :password)}" %> <%= f.password_field :new_password, class: "form-control #{form_is_invalid?(@user, :password)}", autocomplete: :off, required: true %>
<br> <br>
<%= f.label :password_confirmation, t("settings.password.confirmation"), class: "form-label" %> <%= f.label :password_confirmation, t("settings.password.confirmation"), class: "form-label" %>
<%= f.password_field :password_confirmation, class: "form-control #{form_is_invalid?(@user, :password_confirmation)}" %> <%= f.password_field :password_confirmation, class: "form-control #{form_is_invalid?(@user, :password_confirmation)}", autocomplete: :off, required: true %>
</div> </div>
</div> </div>
</div> </div>

View File

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

View File

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

View File

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

View File

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

View File

@ -125,6 +125,8 @@ module Greenlight
config.maintenance_window = ENV["MAINTENANCE_WINDOW"] config.maintenance_window = ENV["MAINTENANCE_WINDOW"]
config.maintenance_mode = ENV["MAINTENANCE_MODE"] == "true" config.maintenance_mode = ENV["MAINTENANCE_MODE"] == "true"
config.report_issue_url = ENV["REPORT_ISSUE_URL"]
# DEFAULTS # DEFAULTS
# Default branding image if the user does not specify one # Default branding image if the user does not specify one

View File

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

View File

@ -88,10 +88,9 @@ en:
roles: roles:
can_create_rooms: Can create rooms can_create_rooms: Can create rooms
delete: Delete the role delete: Delete the role
duplicate_name: The role name you provided was a duplicate. All role names must be unique invalid_create: There was a problem creating a new role. Please check the role values and try again
empty_name: All roles must have a non empty name invalid_order: There was a problem updating the priority of the role. Please check the values and try again
invalid_order: The user role must be the lowest priority role and the admin role must be the highest priority role invalid_update: There was a problem updating the permissions of the role. Please check the values and try again
invalid_update: You can't update a role with a higher priority than your own role
name: Role Name name: Role Name
new_role: Create a new role new_role: Create a new role
role_has_users: This role is assigned to %{user_count} accounts. Please remove all accounts from this role before deleting it. role_has_users: This role is assigned to %{user_count} accounts. Please remove all accounts from this role before deleting it.
@ -101,8 +100,7 @@ en:
edit_site_settings: Allow users with this role to edit site settings edit_site_settings: Allow users with this role to edit site settings
edit_roles: Allow users with this role to edit other roles edit_roles: Allow users with this role to edit other roles
manage_users: Allow users with this role to manage users manage_users: Allow users with this role to manage users
invalid_assignment: You can't assign a role with a higher priority than your own to a user invalid_assignment: There was a problem assigning the roles to the user. Please check the values and try again
invalid_removal: You can't remove a role with a higher priority than your own
colour: colour:
title: Role Colour title: Role Colour
info: Set the colour that will be associated with the role info: Set the colour that will be associated with the role
@ -155,6 +153,7 @@ en:
internal: internal:
message: Looks like something went wrong on our end. message: Looks like something went wrong on our end.
help: The error has been logged, we'll take a look! help: The error has been logged, we'll take a look!
report: Report Issue
maintenance: maintenance:
message: Sorry, we're down for maintenance. message: Sorry, we're down for maintenance.
help: We'll be back soon! help: We'll be back soon!

View File

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

View File

@ -0,0 +1,32 @@
# frozen_string_literal: true
class CreateRolePermissions < ActiveRecord::Migration[5.2]
def change
create_table :role_permissions do |t|
t.string :name
t.string :value, default: ""
t.boolean :enabled, default: false
t.references :role, foreign_key: true
t.timestamps
end
Role.all.each do |role|
role.role_permissions.create(name: "can_create_rooms", value: role.can_create_rooms.to_s, enabled: true)
role.role_permissions.create(name: "send_promoted_email", value: role.send_promoted_email.to_s, enabled: true)
role.role_permissions.create(name: "send_demoted_email", value: role.send_demoted_email.to_s, enabled: true)
role.role_permissions.create(name: "can_edit_site_settings", value: role.can_edit_site_settings.to_s,
enabled: true)
role.role_permissions.create(name: "can_edit_roles", value: role.can_edit_roles.to_s, enabled: true)
role.role_permissions.create(name: "can_manage_users", value: role.can_manage_users.to_s, enabled: true)
end
# Add these back in once the change to postgres is made
# remove_column :roles, :can_create_rooms
# remove_column :roles, :send_promoted_email
# remove_column :roles, :send_demoted_email
# remove_column :roles, :can_edit_site_settings
# remove_column :roles, :can_edit_roles
# remove_column :roles, :can_manage_users
end
end

View File

@ -0,0 +1,10 @@
# frozen_string_literal: true
class AddDeletedColumn < ActiveRecord::Migration[5.2]
def change
add_column :users, :deleted, :boolean, null: false, default: false
add_index :users, :deleted
add_column :rooms, :deleted, :boolean, null: false, default: false
add_index :rooms, :deleted
end
end

View File

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2019_07_26_153012) do ActiveRecord::Schema.define(version: 2019_08_28_153347) do
create_table "features", force: :cascade do |t| create_table "features", force: :cascade do |t|
t.integer "setting_id" t.integer "setting_id"
@ -33,6 +33,16 @@ ActiveRecord::Schema.define(version: 2019_07_26_153012) do
t.index ["provider"], name: "index_invitations_on_provider" t.index ["provider"], name: "index_invitations_on_provider"
end end
create_table "role_permissions", force: :cascade do |t|
t.string "name"
t.string "value", default: ""
t.boolean "enabled", default: false
t.integer "role_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["role_id"], name: "index_role_permissions_on_role_id"
end
create_table "roles", force: :cascade do |t| create_table "roles", force: :cascade do |t|
t.string "name" t.string "name"
t.integer "priority", default: 9999 t.integer "priority", default: 9999
@ -63,7 +73,9 @@ ActiveRecord::Schema.define(version: 2019_07_26_153012) do
t.string "moderator_pw" t.string "moderator_pw"
t.string "attendee_pw" t.string "attendee_pw"
t.string "access_code" t.string "access_code"
t.boolean "deleted", default: false, null: false
t.index ["bbb_id"], name: "index_rooms_on_bbb_id" t.index ["bbb_id"], name: "index_rooms_on_bbb_id"
t.index ["deleted"], name: "index_rooms_on_deleted"
t.index ["last_session"], name: "index_rooms_on_last_session" t.index ["last_session"], name: "index_rooms_on_last_session"
t.index ["name"], name: "index_rooms_on_name" t.index ["name"], name: "index_rooms_on_name"
t.index ["sessions"], name: "index_rooms_on_sessions" t.index ["sessions"], name: "index_rooms_on_sessions"
@ -97,7 +109,9 @@ ActiveRecord::Schema.define(version: 2019_07_26_153012) do
t.datetime "reset_sent_at" t.datetime "reset_sent_at"
t.string "activation_digest" t.string "activation_digest"
t.datetime "activated_at" t.datetime "activated_at"
t.boolean "deleted", default: false, null: false
t.index ["created_at"], name: "index_users_on_created_at" t.index ["created_at"], name: "index_users_on_created_at"
t.index ["deleted"], name: "index_users_on_deleted"
t.index ["email"], name: "index_users_on_email" t.index ["email"], name: "index_users_on_email"
t.index ["password_digest"], name: "index_users_on_password_digest", unique: true t.index ["password_digest"], name: "index_users_on_password_digest", unique: true
t.index ["provider"], name: "index_users_on_provider" t.index ["provider"], name: "index_users_on_provider"

71
lib/omniauth_options.rb Normal file
View File

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

View File

@ -162,6 +162,12 @@ MAINTENANCE_MODE=false
# Ex: MAINTENANCE_WINDOW=Friday August 18 6pm-10pm EST # Ex: MAINTENANCE_WINDOW=Friday August 18 6pm-10pm EST
MAINTENANCE_WINDOW= MAINTENANCE_WINDOW=
# The link to the Report an Issue button that appears on the 500 page and in the Account Dropdown
#
# Defaults to the Github Issues Page for Greenlight
# Button can be disabled by setting the value to blank
REPORT_ISSUE_URL=https://github.com/bigbluebutton/greenlight/issues/new
# Comment this out to send logs to STDOUT in production instead of log/production.log . # Comment this out to send logs to STDOUT in production instead of log/production.log .
# #
# RAILS_LOG_TO_STDOUT=true # RAILS_LOG_TO_STDOUT=true

View File

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

View File

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

View File

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

View File

@ -91,7 +91,7 @@ describe AdminsController, type: :controller do
context "POST #invite" do context "POST #invite" do
before do before do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true) allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow_any_instance_of(ApplicationController).to receive(:allow_greenlight_users?).and_return(true) allow_any_instance_of(ApplicationController).to receive(:allow_greenlight_accounts?).and_return(true)
allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true) allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
end end
@ -177,7 +177,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
fake_image_url = "example.com" fake_image_url = "example.com"
post :branding, params: { url: fake_image_url } post :update_settings, params: { setting: "Branding Image", value: fake_image_url }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Branding Image") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Branding Image")
@ -194,7 +194,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
primary_color = Faker::Color.hex_color primary_color = Faker::Color.hex_color
post :coloring, params: { color: primary_color } post :coloring, params: { value: primary_color }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color")
@ -209,7 +209,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
primary_color = Faker::Color.hex_color primary_color = Faker::Color.hex_color
post :coloring_lighten, params: { color: primary_color } post :update_settings, params: { setting: "Primary Color Lighten", value: primary_color }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Lighten") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Lighten")
@ -224,7 +224,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
primary_color = Faker::Color.hex_color primary_color = Faker::Color.hex_color
post :coloring_darken, params: { color: primary_color } post :update_settings, params: { setting: "Primary Color Darken", value: primary_color }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Darken") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Darken")
@ -243,7 +243,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
post :registration_method, params: { method: "invite" } post :registration_method, params: { value: "invite" }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Registration Method") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Registration Method")
@ -259,7 +259,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
post :registration_method, params: { method: "invite" } post :registration_method, params: { value: "invite" }
expect(flash[:alert]).to be_present expect(flash[:alert]).to be_present
expect(response).to redirect_to(admin_site_settings_path) expect(response).to redirect_to(admin_site_settings_path)
@ -273,7 +273,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
post :room_authentication, params: { value: "true" } post :update_settings, params: { setting: "Room Authentication", value: "true" }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Authentication") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Authentication")
@ -289,7 +289,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
post :room_limit, params: { limit: 5 } post :update_settings, params: { setting: "Room Limit", value: 5 }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Limit") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Limit")
@ -305,7 +305,7 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
post :default_recording_visibility, params: { visibility: "public" } post :update_settings, params: { setting: "Default Recording Visibility", value: "public" }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Default Recording Visibility") feature = Setting.find_by(provider: "provider1").features.find_by(name: "Default Recording Visibility")
@ -353,7 +353,7 @@ describe AdminsController, type: :controller do
post :new_role, params: { role: { name: "admin" } } post :new_role, params: { role: { name: "admin" } }
expect(response).to redirect_to admin_roles_path expect(response).to redirect_to admin_roles_path
expect(flash[:alert]).to eq(I18n.t("administrator.roles.duplicate_name")) expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_create"))
end end
it "should fail with empty role name" do it "should fail with empty role name" do
@ -362,7 +362,7 @@ describe AdminsController, type: :controller do
post :new_role, params: { role: { name: " " } } post :new_role, params: { role: { name: " " } }
expect(response).to redirect_to admin_roles_path expect(response).to redirect_to admin_roles_path
expect(flash[:alert]).to eq(I18n.t("administrator.roles.empty_name")) expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_create"))
end end
it "should create new role and increase user role priority" do it "should create new role and increase user role priority" do
@ -398,7 +398,8 @@ describe AdminsController, type: :controller do
it "should fail if a user attempts to edit a role with a higher priority than their own" do it "should fail if a user attempts to edit a role with a higher priority than their own" do
Role.create(name: "test1", priority: 1, provider: "greenlight") Role.create(name: "test1", priority: 1, provider: "greenlight")
new_role2 = Role.create(name: "test2", priority: 2, provider: "greenlight", can_edit_roles: true) new_role2 = Role.create(name: "test2", priority: 2, provider: "greenlight")
new_role2.update_permission("can_edit_roles", "true")
new_role3 = Role.create(name: "test3", priority: 3, provider: "greenlight") new_role3 = Role.create(name: "test3", priority: 3, provider: "greenlight")
user_role = Role.find_by(name: "user", provider: "greenlight") user_role = Role.find_by(name: "user", provider: "greenlight")
@ -412,13 +413,14 @@ describe AdminsController, type: :controller do
patch :change_role_order, params: { role: [new_role3.id, new_role2.id] } patch :change_role_order, params: { role: [new_role3.id, new_role2.id] }
expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_update")) expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_order"))
expect(response).to redirect_to admin_roles_path expect(response).to redirect_to admin_roles_path
end end
it "should fail if a user attempts to edit a role with a higher priority than their own" do it "should fail if a user attempts to edit a role with a higher priority than their own" do
Role.create(name: "test1", priority: 1, provider: "greenlight") Role.create(name: "test1", priority: 1, provider: "greenlight")
new_role2 = Role.create(name: "test2", priority: 2, provider: "greenlight", can_edit_roles: true) new_role2 = Role.create(name: "test2", priority: 2, provider: "greenlight")
new_role2.update_permission("can_edit_roles", "true")
new_role3 = Role.create(name: "test3", priority: 3, provider: "greenlight") new_role3 = Role.create(name: "test3", priority: 3, provider: "greenlight")
user_role = Role.find_by(name: "user", provider: "greenlight") user_role = Role.find_by(name: "user", provider: "greenlight")
@ -432,7 +434,7 @@ describe AdminsController, type: :controller do
patch :change_role_order, params: { role: [new_role3.id, new_role2.id] } patch :change_role_order, params: { role: [new_role3.id, new_role2.id] }
expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_update")) expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_order"))
expect(response).to redirect_to admin_roles_path expect(response).to redirect_to admin_roles_path
end end
@ -465,7 +467,8 @@ describe AdminsController, type: :controller do
it "should fail to update a role with a lower priority than the user" do it "should fail to update a role with a lower priority than the user" do
new_role1 = Role.create(name: "test1", priority: 1, provider: "provider1") new_role1 = Role.create(name: "test1", priority: 1, provider: "provider1")
new_role2 = Role.create(name: "test2", priority: 2, provider: "provider1", can_edit_roles: true) new_role2 = Role.create(name: "test2", priority: 2, provider: "provider1")
new_role2.update_permission("can_edit_roles", "true")
user_role = Role.find_by(name: "user", provider: "greenlight") user_role = Role.find_by(name: "user", provider: "greenlight")
user_role.priority = 3 user_role.priority = 3
@ -483,18 +486,20 @@ describe AdminsController, type: :controller do
end end
it "should fail to update if there is a duplicate name" do it "should fail to update if there is a duplicate name" do
new_role = Role.create(name: "test2", priority: 1, provider: "provider1", can_edit_roles: true) new_role = Role.create(name: "test2", priority: 1, provider: "provider1")
new_role.update_permission("can_edit_roles", "true")
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
patch :update_role, params: { role_id: new_role.id, role: { name: "admin" } } patch :update_role, params: { role_id: new_role.id, role: { name: "admin" } }
expect(flash[:alert]).to eq(I18n.t("administrator.roles.duplicate_name")) expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_update"))
expect(response).to redirect_to admin_roles_path(selected_role: new_role.id) expect(response).to redirect_to admin_roles_path(selected_role: new_role.id)
end end
it "should update role permisions" do it "should update role permisions" do
new_role = Role.create(name: "test2", priority: 1, provider: "provider1", can_edit_roles: true) new_role = Role.create(name: "test2", priority: 1, provider: "provider1")
new_role.update_permission("can_edit_roles", "true")
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id
@ -503,10 +508,10 @@ describe AdminsController, type: :controller do
new_role.reload new_role.reload
expect(new_role.name).to eq("test") expect(new_role.name).to eq("test")
expect(new_role.can_edit_roles).to eq(false) expect(new_role.get_permission("can_edit_roles")).to eq(false)
expect(new_role.colour).to eq("#45434") expect(new_role.colour).to eq("#45434")
expect(new_role.can_manage_users).to eq(true) expect(new_role.get_permission("can_manage_users")).to eq(true)
expect(new_role.send_promoted_email).to eq(false) expect(new_role.get_permission("send_promoted_email")).to eq(false)
expect(response).to redirect_to admin_roles_path(selected_role: new_role.id) expect(response).to redirect_to admin_roles_path(selected_role: new_role.id)
end end
end end
@ -538,7 +543,8 @@ describe AdminsController, type: :controller do
end end
it "should successfully delete the role" do it "should successfully delete the role" do
new_role = Role.create(name: "test2", priority: 1, provider: "provider1", can_edit_roles: true) new_role = Role.create(name: "test2", priority: 1, provider: "provider1")
new_role.update_permission("can_edit_roles", "true")
@request.session[:user_id] = @admin.id @request.session[:user_id] = @admin.id

View File

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

View File

@ -50,7 +50,7 @@ describe PasswordResetsController, type: :controller do
expect(response).to redirect_to(root_path) expect(response).to redirect_to(root_path)
end end
it "reloads the page if no email exists in the database" do it "redirects to root with success flash if email does not exists" do
params = { params = {
password_reset: { password_reset: {
email: nil, email: nil,
@ -58,7 +58,8 @@ describe PasswordResetsController, type: :controller do
} }
post :create, params: params post :create, params: params
expect(response).to redirect_to(new_password_reset_path) expect(flash[:success]).to be_present
expect(response).to redirect_to(root_path)
end end
end end
@ -73,7 +74,9 @@ describe PasswordResetsController, type: :controller do
end end
describe "PATCH #update" do describe "PATCH #update" do
before { allow(Rails.configuration).to receive(:enable_email_verification).and_return(true) } before do
allow(Rails.configuration).to receive(:enable_email_verification).and_return(true)
end
context "valid user" do context "valid user" do
it "reloads page with notice if password is empty" do it "reloads page with notice if password is empty" do
@ -120,7 +123,7 @@ describe PasswordResetsController, type: :controller do
allow(controller).to receive(:valid_user).and_return(nil) allow(controller).to receive(:valid_user).and_return(nil)
allow(controller).to receive(:check_expiration).and_return(nil) allow(controller).to receive(:check_expiration).and_return(nil)
allow(controller).to receive(:current_user).and_return(user) controller.instance_variable_set(:@user, user)
params = { params = {
id: token, id: token,

View File

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

View File

@ -28,8 +28,11 @@ def random_valid_room_params
end end
describe RoomsController, type: :controller do describe RoomsController, type: :controller do
it_behaves_like "recorder"
include Recorder include Recorder
include BbbServer
let(:bbb_server) { BigBlueButton::BigBlueButtonApi.new("http://bbb.example.com/bigbluebutton/api", "secret", "0.8") }
describe "GET #show" do describe "GET #show" do
before do before do
@user = create(:user) @user = create(:user)
@ -41,8 +44,7 @@ describe RoomsController, type: :controller do
get :show, params: { room_uid: @owner.main_room } get :show, params: { room_uid: @owner.main_room }
expect(assigns(:recordings)).to eql(recordings(@owner.main_room.bbb_id, @owner.provider)) expect(assigns(:recordings)).to eql(recordings(@owner.main_room.bbb_id))
expect(assigns(:is_running)).to eql(@owner.main_room.running?)
end end
it "should be able to search recordings if user is owner" do it "should be able to search recordings if user is owner" do
@ -64,7 +66,7 @@ describe RoomsController, type: :controller do
it "should render cant_create_rooms if user doesn't have permission to create rooms" do it "should render cant_create_rooms if user doesn't have permission to create rooms" do
user_role = @user.highest_priority_role user_role = @user.highest_priority_role
user_role.can_create_rooms = false user_role.update_permission("can_create_rooms", "false")
user_role.save! user_role.save!
@request.session[:user_id] = @user.id @request.session[:user_id] = @user.id
@ -124,7 +126,7 @@ describe RoomsController, type: :controller do
it "redirects to root if the providers dont match" do it "redirects to root if the providers dont match" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true) allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow_any_instance_of(Room).to receive(:running?).and_return(false) allow_any_instance_of(BbbServer).to receive(:room_running?).and_return(true)
@owner.update_attribute(:provider, "provider1") @owner.update_attribute(:provider, "provider1")
@user.update_attribute(:provider, "provider2") @user.update_attribute(:provider, "provider2")
@ -199,11 +201,6 @@ describe RoomsController, type: :controller do
@user = create(:user) @user = create(:user)
@owner = create(:user) @owner = create(:user)
@room = @owner.main_room @room = @owner.main_room
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_meeting_info).and_return(
moderatorPW: "modpass",
attendeePW: "attpass",
)
end end
it "should use account name if user is logged in and meeting running" do it "should use account name if user is logged in and meeting running" do
@ -212,7 +209,7 @@ describe RoomsController, type: :controller do
@request.session[:user_id] = @user.id @request.session[:user_id] = @user.id
post :join, params: { room_uid: @room, join_name: @user.name } post :join, params: { room_uid: @room, join_name: @user.name }
expect(response).to redirect_to(@owner.main_room.join_path(@user.name, {}, @user.uid)) expect(response).to redirect_to(join_path(@owner.main_room, @user.name, {}, @user.uid))
end end
it "should use join name if user is not logged in and meeting running" do it "should use join name if user is not logged in and meeting running" do
@ -220,7 +217,7 @@ describe RoomsController, type: :controller do
post :join, params: { room_uid: @room, join_name: "Join Name" } post :join, params: { room_uid: @room, join_name: "Join Name" }
expect(response).to redirect_to(@owner.main_room.join_path("Join Name", {})) expect(response).to redirect_to(join_path(@owner.main_room, "Join Name", {}))
end end
it "should render wait if meeting isn't running" do it "should render wait if meeting isn't running" do
@ -243,7 +240,7 @@ describe RoomsController, type: :controller do
@request.session[:user_id] = @user.id @request.session[:user_id] = @user.id
post :join, params: { room_uid: room, join_name: @user.name } post :join, params: { room_uid: room, join_name: @user.name }
expect(response).to redirect_to(room.join_path(@user.name, { user_is_moderator: false }, @user.uid)) expect(response).to redirect_to(join_path(room, @user.name, { user_is_moderator: false }, @user.uid))
end end
it "should join the room as moderator if room has the all_join_moderator setting" do it "should join the room as moderator if room has the all_join_moderator setting" do
@ -257,7 +254,7 @@ describe RoomsController, type: :controller do
@request.session[:user_id] = @user.id @request.session[:user_id] = @user.id
post :join, params: { room_uid: room, join_name: @user.name } post :join, params: { room_uid: room, join_name: @user.name }
expect(response).to redirect_to(room.join_path(@user.name, { user_is_moderator: true }, @user.uid)) expect(response).to redirect_to(join_path(room, @user.name, { user_is_moderator: true }, @user.uid))
end end
it "should render wait if the correct access code is supplied" do it "should render wait if the correct access code is supplied" do
@ -292,7 +289,7 @@ describe RoomsController, type: :controller do
@request.session[:user_id] = @owner.id @request.session[:user_id] = @owner.id
post :join, params: { room_uid: @room, join_name: @owner.name } post :join, params: { room_uid: @room, join_name: @owner.name }
expect(response).to redirect_to(@owner.main_room.join_path(@owner.name, { user_is_moderator: true }, @owner.uid)) expect(response).to redirect_to(join_path(@owner.main_room, @owner.name, { user_is_moderator: true }, @owner.uid))
end end
it "redirects to root if owner of room is not verified" do it "redirects to root if owner of room is not verified" do
@ -362,14 +359,14 @@ describe RoomsController, type: :controller do
@request.session[:user_id] = @user.id @request.session[:user_id] = @user.id
post :start, params: { room_uid: @user.main_room } post :start, params: { room_uid: @user.main_room }
expect(response).to redirect_to(@user.main_room.join_path(@user.name, { user_is_moderator: true }, @user.uid)) expect(response).to redirect_to(join_path(@user.main_room, @user.name, { user_is_moderator: true }, @user.uid))
end end
it "should bring to room if not owner" do it "should bring to room if not owner" do
@request.session[:user_id] = @user.id @request.session[:user_id] = @user.id
post :start, params: { room_uid: @other_room } post :start, params: { room_uid: @other_room }
expect(response).to redirect_to(@user.main_room) expect(response).to redirect_to(root_path)
end end
it "should bring to root if not authenticated" do it "should bring to root if not authenticated" do
@ -408,37 +405,11 @@ describe RoomsController, type: :controller do
.from(@secondary_room.room_settings).to(formatted_room_params) .from(@secondary_room.room_settings).to(formatted_room_params)
expect(response).to redirect_to(@secondary_room) expect(response).to redirect_to(@secondary_room)
end end
end
describe "PATCH #update" do
before do
@user = create(:user)
@secondary_room = create(:room, owner: @user)
@editable_room = create(:room, owner: @user)
end
it "properly updates room name through room block and redirects to current page" do
@request.session[:user_id] = @user.id
patch :update, params: { room_uid: @secondary_room, room_block_uid: @editable_room,
setting: :rename_block, room_name: :name }
expect(response).to redirect_to(@secondary_room)
end
it "properly updates room name through room header and redirects to current page" do it "properly updates room name through room header and redirects to current page" do
@request.session[:user_id] = @user.id @request.session[:user_id] = @user.id
patch :update, params: { room_uid: @secondary_room, setting: :rename_header, room_name: :name } patch :update_settings, params: { room_uid: @secondary_room, setting: :rename_header, room_name: :name }
expect(response).to redirect_to(@secondary_room)
end
it "properly updates recording name and redirects to current page" do
@request.session[:user_id] = @user.id
patch :update, params: { room_uid: @secondary_room, recordid: :recordid,
setting: :rename_recording, record_name: :name }
expect(response).to redirect_to(@secondary_room) expect(response).to redirect_to(@secondary_room)
end end

View File

@ -19,6 +19,50 @@
require "rails_helper" require "rails_helper"
describe SessionsController, type: :controller do describe SessionsController, type: :controller do
describe "GET #new" do
it "assigns a blank user to the view" do
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
get :new
expect(assigns(:user)).to be_a_new(User)
end
it "redirects to root if allow_user_signup is false" do
allow(Rails.configuration).to receive(:allow_user_signup).and_return(false)
get :new
expect(response).to redirect_to(root_path)
end
it "rejects the user if they are not invited" do
allow_any_instance_of(Registrar).to receive(:invite_registration).and_return(true)
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
get :new
expect(flash[:alert]).to be_present
expect(response).to redirect_to(root_path)
end
end
describe "GET #signin" do
it "redirects to main room if already authenticated" do
user = create(:user)
@request.session[:user_id] = user.id
post :signin
expect(response).to redirect_to(room_path(user.main_room))
end
end
describe 'GET #ldap_signin' do
it "should render the ldap signin page" do
get :ldap_signin
expect(response).to render_template(:ldap_signin)
end
end
describe "GET #destroy" do describe "GET #destroy" do
before(:each) do before(:each) do
user = create(:user, provider: "greenlight") user = create(:user, provider: "greenlight")

View File

@ -46,32 +46,6 @@ describe UsersController, type: :controller do
} }
end end
describe "GET #new" do
it "assigns a blank user to the view" do
allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
get :new
expect(assigns(:user)).to be_a_new(User)
end
it "redirects to root if allow_user_signup is false" do
allow(Rails.configuration).to receive(:allow_user_signup).and_return(false)
get :new
expect(response).to redirect_to(root_path)
end
end
describe "GET #signin" do
it "redirects to main room if already authenticated" do
user = create(:user)
@request.session[:user_id] = user.id
post :signin
expect(response).to redirect_to(room_path(user.main_room))
end
end
describe "GET #edit" do describe "GET #edit" do
it "renders the edit template" do it "renders the edit template" do
user = create(:user) user = create(:user)
@ -211,13 +185,6 @@ describe UsersController, type: :controller do
expect { post :create, params: params }.to change { ActionMailer::Base.deliveries.count }.by(1) expect { post :create, params: params }.to change { ActionMailer::Base.deliveries.count }.by(1)
end end
it "rejects the user if they are not invited" do
get :new
expect(flash[:alert]).to be_present
expect(response).to redirect_to(root_path)
end
it "allows the user to signup if they are invited" do it "allows the user to signup if they are invited" do
allow(Rails.configuration).to receive(:enable_email_verification).and_return(false) allow(Rails.configuration).to receive(:enable_email_verification).and_return(false)
@ -341,7 +308,7 @@ describe UsersController, type: :controller do
user_role = user.highest_priority_role user_role = user.highest_priority_role
user_role.can_manage_users = true user_role.update_permission("can_manage_users", "true")
user_role.save! user_role.save!
@ -364,7 +331,7 @@ describe UsersController, type: :controller do
user_role = user.highest_priority_role user_role = user.highest_priority_role
user_role.can_manage_users = true user_role.update_permission("can_manage_users", "true")
user_role.save! user_role.save!
@ -373,7 +340,7 @@ describe UsersController, type: :controller do
user.reload user.reload
expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_removal")) expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_assignment"))
expect(response).to render_template(:edit) expect(response).to render_template(:edit)
end end
@ -387,7 +354,8 @@ describe UsersController, type: :controller do
@request.session[:user_id] = admin.id @request.session[:user_id] = admin.id
tmp_role1 = Role.create(name: "test1", priority: 1, provider: "greenlight", send_promoted_email: true) tmp_role1 = Role.create(name: "test1", priority: 1, provider: "greenlight")
tmp_role1.update_permission("send_promoted_email", "true")
tmp_role2 = Role.create(name: "test2", priority: 2, provider: "greenlight") tmp_role2 = Role.create(name: "test2", priority: 2, provider: "greenlight")
params = random_valid_user_params params = random_valid_user_params
@ -407,7 +375,8 @@ describe UsersController, type: :controller do
admin.add_role :admin admin.add_role :admin
tmp_role1 = Role.create(name: "test1", priority: 1, provider: "greenlight", send_demoted_email: true) tmp_role1 = Role.create(name: "test1", priority: 1, provider: "greenlight")
tmp_role1.update_permission("send_demoted_email", "true")
user.roles << tmp_role1 user.roles << tmp_role1
user.save! user.save!
@ -439,7 +408,6 @@ describe UsersController, type: :controller do
it "allows admins to delete users" do it "allows admins to delete users" do
allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true) allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true) allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
allow_any_instance_of(Room).to receive(:delete_all_recordings).and_return('')
allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("provider1") allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("provider1")
controller.instance_variable_set(:@user_domain, "provider1") controller.instance_variable_set(:@user_domain, "provider1")
@ -494,12 +462,4 @@ describe UsersController, type: :controller do
expect(response).to redirect_to(root_path) expect(response).to redirect_to(root_path)
end end
end end
context 'GET #ldap_signin' do
it "should render the ldap signin page" do
get :ldap_signin
expect(response).to render_template(:ldap_signin)
end
end
end end

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More