Merge branch 'v2.2.1-alpha' into master

This commit is contained in:
Jesus Federico
2019-07-23 15:57:08 -04:00
committed by GitHub
77 changed files with 1740 additions and 921 deletions

View File

@ -20,10 +20,11 @@ class AdminsController < ApplicationController
include Pagy::Backend
include Themer
include Emailer
include Recorder
manage_users = [:edit_user, :promote, :demote, :ban_user, :unban_user, :approve]
site_settings = [:branding, :coloring, :coloring_lighten, :coloring_darken,
:registration_method, :room_authentication, :room_limit]
:registration_method, :room_authentication, :room_limit, :default_recording_visibility]
authorize_resource class: false
before_action :find_user, only: manage_users
@ -40,11 +41,27 @@ class AdminsController < ApplicationController
@pagy, @users = pagy(user_list)
end
# GET /admins/site_settings
def site_settings
end
# GET /admins/server_recordings
def server_recordings
server_rooms = if Rails.configuration.loadbalanced_configuration
Room.includes(:owner).where(users: { provider: user_settings_provider }).pluck(:bbb_id)
else
Room.pluck(:bbb_id)
end
@search, @order_column, @order_direction, recs =
all_recordings(server_rooms, @user_domain, params.permit(:search, :column, :direction), true, true)
@pagy, @recordings = pagy_array(recs)
end
# MANAGE USERS
# GET /admins/edit/:user_uid
def edit_user
render "admins/index", locals: { setting_id: "account" }
end
# POST /admins/promote/:user_uid
@ -111,7 +128,7 @@ class AdminsController < ApplicationController
# POST /admins/branding
def branding
@settings.update_value("Branding Image", params[:url])
redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") }
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
end
# POST /admins/color
@ -119,23 +136,23 @@ class AdminsController < ApplicationController
@settings.update_value("Primary Color", params[:color])
@settings.update_value("Primary Color Lighten", color_lighten(params[:color]))
@settings.update_value("Primary Color Darken", color_darken(params[:color]))
redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") }
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 admins_path, flash: { success: I18n.t("administrator.flash.settings") }
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 admins_path, flash: { success: I18n.t("administrator.flash.settings") }
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 admins_path, flash: { success: I18n.t("administrator.flash.settings") }
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
end
# POST /admins/registration_method/:method
@ -144,11 +161,11 @@ class AdminsController < ApplicationController
# 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]
redirect_to admins_path,
redirect_to admin_site_settings_path,
flash: { alert: I18n.t("administrator.flash.invite_email_verification") }
else
@settings.update_value("Registration Method", new_method)
redirect_to admins_path,
redirect_to admin_site_settings_path,
flash: { success: I18n.t("administrator.flash.registration_method_updated") }
end
end
@ -156,13 +173,20 @@ class AdminsController < ApplicationController
# POST /admins/room_limit
def room_limit
@settings.update_value("Room Limit", params[:limit])
redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") }
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 admins_path, flash: { success: I18n.t("administrator.flash.settings") + ". " +
I18n.t("administrator.site_settings.recording_visibility.warning") }
end
private
def find_user
@user = User.find_by!(uid: params[:user_uid])
@user = User.where(uid: params[:user_uid]).includes(:roles).first
end
def find_setting
@ -176,21 +200,19 @@ class AdminsController < ApplicationController
# Gets the list of users based on your configuration
def user_list
initial_list = if current_user.has_role? :super_admin
User.where.not(id: current_user.id)
initial_list = if current_user.has_cached_role? :super_admin
User.where.not(id: current_user.id).includes(:roles)
else
User.without_role(:super_admin).where.not(id: current_user.id)
User.without_role(:super_admin).where.not(id: current_user.id).includes(:roles)
end
list = @role.present? ? initial_list.with_role(@role.to_sym) : initial_list
if Rails.configuration.loadbalanced_configuration
list.where(provider: user_settings_provider)
.admins_search(@search)
.admins_order(@order_column, @order_direction)
initial_list.where(provider: user_settings_provider)
.admins_search(@search, @role)
.admins_order(@order_column, @order_direction)
else
list.admins_search(@search)
.admins_order(@order_column, @order_direction)
initial_list.admins_search(@search, @role)
.admins_order(@order_column, @order_direction)
end
end

View File

@ -121,6 +121,9 @@ class ApplicationController < ActionController::Base
meeting_logout_url: request.base_url + logout_room_path(@room),
meeting_recorded: true,
moderator_message: "#{invite_msg}\n\n#{request.base_url + room_path(@room)}",
host: request.host,
recording_default_visibility: Setting.find_or_create_by!(provider: user_settings_provider)
.get_value("Default Recording Visibility") == "public"
}
end
@ -131,7 +134,7 @@ class ApplicationController < ActionController::Base
# 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&.greenlight_account? &&
if current_user&.has_cached_role?(:admin) && current_user&.greenlight_account? &&
current_user&.authenticate(Rails.configuration.admin_password_default)
flash.now[:alert] = I18n.t("default_admin",
@ -179,10 +182,10 @@ class ApplicationController < ActionController::Base
# Checks if the user is banned and logs him out if he is
def check_user_role
if current_user&.has_role? :denied
if current_user&.has_cached_role? :denied
session.delete(:user_id)
redirect_to root_path, flash: { alert: I18n.t("registration.banned.fail") }
elsif current_user&.has_role? :pending
elsif current_user&.has_cached_role? :pending
session.delete(:user_id)
redirect_to root_path, flash: { alert: I18n.t("registration.approval.fail") }
end

View File

@ -64,13 +64,19 @@ module Emailer
def send_approval_user_signup_email(user)
return unless Rails.configuration.enable_email_verification
UserMailer.approval_user_signup(user, admins_url, logo_image, user_color, admin_emails).deliver_now
admin_emails = admin_emails()
unless admin_emails.empty?
UserMailer.approval_user_signup(user, admins_url, logo_image, user_color, admin_emails).deliver_now
end
end
def send_invite_user_signup_email(user)
return unless Rails.configuration.enable_email_verification
UserMailer.invite_user_signup(user, admins_url, logo_image, user_color, admin_emails).deliver_now
admin_emails = admin_emails()
unless admin_emails.empty?
UserMailer.invite_user_signup(user, admins_url, logo_image, user_color, admin_emails).deliver_now
end
end
private

View File

@ -0,0 +1,136 @@
# 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 Recorder
extend ActiveSupport::Concern
include ::BbbApi
# Fetches all recordings for a room.
def recordings(room_bbb_id, provider, search_params = {}, ret_search_params = false)
res = bbb(provider).get_recordings(meetingID: room_bbb_id)
format_recordings(res, search_params, ret_search_params)
end
# Fetches a rooms public recordings.
def public_recordings(room_bbb_id, provider, search_params = {}, ret_search_params = false)
search, order_col, order_dir, recs = recordings(room_bbb_id, provider, search_params, ret_search_params)
[search, order_col, order_dir, recs.select { |r| r[:metadata][:"gl-listed"] == "true" }]
end
# Makes paginated API calls to get recordings
def all_recordings(room_bbb_ids, provider, search_params = {}, ret_search_params = false, search_name = false)
pag_num = Rails.configuration.pagination_number
pag_loops = room_bbb_ids.length / pag_num - 1
res = { recordings: [] }
(0..pag_loops).each do |i|
pag_rooms = room_bbb_ids[pag_num * i, pag_num]
# bbb.get_recordings returns an object
# take only the array portion of the object that is returned
full_res = bbb(provider).get_recordings(meetingID: pag_rooms)
res[:recordings].push(*full_res[:recordings])
end
last_pag_room = room_bbb_ids[pag_num * (pag_loops + 1), room_bbb_ids.length % pag_num]
full_res = bbb(provider).get_recordings(meetingID: last_pag_room)
res[:recordings].push(*full_res[:recordings])
format_recordings(res, search_params, ret_search_params, search_name)
end
# Format, filter, and sort recordings to match their current use in the app
def format_recordings(api_res, search_params, ret_search_params, search_name = false)
search = search_params[:search] || ""
order_col = search_params[:column] && search_params[:direction] != "none" ? search_params[:column] : "end_time"
order_dir = search_params[:column] && search_params[:direction] != "none" ? search_params[:direction] : "desc"
search = search.downcase
api_res[:recordings].each do |r|
next if r.key?(:error)
# Format playbacks in a more pleasant way.
r[:playbacks] = if !r[:playback] || !r[:playback][:format]
[]
elsif r[:playback][:format].is_a?(Array)
r[:playback][:format]
else
[r[:playback][:format]]
end
r.delete(:playback)
end
recs = filter_recordings(api_res, search, search_name)
recs = sort_recordings(recs, order_col, order_dir)
if ret_search_params
[search, order_col, order_dir, recs]
else
recs
end
end
def filter_recordings(api_res, search, search_name = false)
api_res[:recordings].select do |r|
(!r[:metadata].nil? && ((!r[:metadata][:name].nil? &&
r[:metadata][:name].downcase.include?(search)) ||
(r[:metadata][:"gl-listed"] == "true" && search == "public") ||
(r[:metadata][:"gl-listed"] == "false" && search == "unlisted"))) ||
((r[:metadata].nil? || r[:metadata][:name].nil?) &&
r[:name].downcase.include?(search)) ||
r[:participants].include?(search) ||
!r[:playbacks].select { |p| p[:type].downcase.include?(search) }.empty? ||
(search_name && Room.find_by(bbb_id: r[:meetingID]).owner.email.downcase.include?(search))
end
end
def sort_recordings(recs, order_col, order_dir)
recs = case order_col
when "end_time"
recs.sort_by { |r| r[:endTime] }
when "name"
recs.sort_by do |r|
if !r[:metadata].nil? && !r[:metadata][:name].nil?
r[:metadata][:name].downcase
else
r[:name].downcase
end
end
when "length"
recs.sort_by { |r| r[:playbacks].reject { |p| p[:type] == "statistics" }.first[:length] }
when "users"
recs.sort_by { |r| r[:participants] }
when "visibility"
recs.sort_by { |r| r[:metadata][:"gl-listed"] }
when "formats"
recs.sort_by { |r| r[:playbacks].first[:type].downcase }
else
recs.sort_by { |r| r[:endTime] }
end
if order_dir == 'asc'
recs
else
recs.reverse
end
end
end

View File

@ -24,7 +24,7 @@ module Themer
# Uses the built in Sass Engine to lighten the color
dummy_scss = "h1 { color: $lighten; }"
compiled = Sass::Engine.new("$lighten:lighten(#{color}, 40%);" + dummy_scss, syntax: :scss).render
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
@ -37,7 +37,7 @@ module Themer
# Uses the built in Sass Engine to darken the color
dummy_scss = "h1 { color: $darken; }"
compiled = Sass::Engine.new("$darken:darken(#{color}, 10%);" + dummy_scss, syntax: :scss).render
compiled = SassC::Engine.new("$darken:darken(#{color}, 10%);" + dummy_scss, syntax: :scss).render
string_locater = 'color: '
color_start = compiled.index(string_locater) + string_locater.length

View File

@ -50,6 +50,11 @@ class RecordingsController < ApplicationController
# Ensure the user is logged into the room they are accessing.
def verify_room_ownership
redirect_to root_path unless @room.owned_by?(current_user)
if !current_user ||
!@room.owned_by?(current_user) ||
!current_user.has_cached_role?(:admin) ||
!current_user.has_cached_role?(:super_admin)
redirect_to root_path
end
end
end

View File

@ -19,12 +19,13 @@
class RoomsController < ApplicationController
include RecordingsHelper
include Pagy::Backend
include Recorder
before_action :validate_accepted_terms, unless: -> { !Rails.configuration.terms }
before_action :validate_verified_email, except: [:show, :join],
unless: -> { !Rails.configuration.enable_email_verification }
before_action :find_room, except: :create
before_action :verify_room_ownership, except: [:create, :show, :join, :logout]
before_action :verify_room_ownership, except: [:create, :show, :join, :logout, :login]
before_action :verify_room_owner_verified, only: [:show, :join],
unless: -> { !Rails.configuration.enable_email_verification }
before_action :verify_user_not_admin, only: [:show]
@ -35,9 +36,10 @@ class RoomsController < ApplicationController
return redirect_to current_user.main_room, flash: { alert: I18n.t("room.room_limit") } if room_limit_exceeded
@room = Room.new(name: room_params[:name])
@room = Room.new(name: room_params[:name], access_code: room_params[:access_code])
@room.owner = current_user
@room.room_settings = create_room_settings_string(room_params[:mute_on_join], room_params[:client])
@room.room_settings = create_room_settings_string(room_params[:mute_on_join], room_params[:client],
room_params[:anyone_can_start])
if @room.save
if room_params[:auto_join] == "1"
@ -54,13 +56,15 @@ class RoomsController < ApplicationController
# GET /:room_uid
def show
@is_running = @room.running?
@anyone_can_start = JSON.parse(@room[:room_settings])["anyoneCanStart"]
if current_user && @room.owned_by?(current_user)
@search, @order_column, @order_direction, recs =
@room.recordings(params.permit(:search, :column, :direction), true)
recordings(@room.bbb_id, @user_domain, params.permit(:search, :column, :direction), true)
@pagy, @recordings = pagy_array(recs)
@is_running = @room.running?
else
# Get users name
@name = if current_user
@ -72,7 +76,7 @@ class RoomsController < ApplicationController
end
@search, @order_column, @order_direction, pub_recs =
@room.public_recordings(params.permit(:search, :column, :direction), true)
public_recordings(@room.bbb_id, @user_domain, params.permit(:search, :column, :direction), true)
@pagy, @public_recordings = pagy_array(pub_recs)
@ -105,6 +109,12 @@ class RoomsController < ApplicationController
opts = default_meeting_options
unless @room.owned_by?(current_user)
# Don't allow users to join unless they have a valid access code or the room doesn't
# have an access code
if @room.access_code && !@room.access_code.empty? && @room.access_code != session[:access_code]
return redirect_to room_path(room_uid: params[:room_uid]), flash: { alert: I18n.t("room.access_code_required") }
end
# Assign join name if passed.
if params[@room.invite_path]
@join_name = params[@room.invite_path][:join_name]
@ -117,31 +127,7 @@ class RoomsController < ApplicationController
# create or update cookie with join name
cookies.encrypted[:greenlight_name] = @join_name unless cookies.encrypted[:greenlight_name] == @join_name
if @room.running? || @room.owned_by?(current_user)
# Determine if the user needs to join as a moderator.
opts[:user_is_moderator] = @room.owned_by?(current_user)
# Check if the user has specified which client to use
room_settings = JSON.parse(@room[:room_settings])
opts[:join_via_html5] = room_settings["joinViaHtml5"] if room_settings["joinViaHtml5"]
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 =
@room.public_recordings(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
join_room(opts)
end
# DELETE /:room_uid
@ -184,6 +170,8 @@ class RoomsController < ApplicationController
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
@ -198,6 +186,15 @@ class RoomsController < ApplicationController
redirect_to @room
end
# POST /:room_uid/login
def login
session[:access_code] = room_params[:access_code]
flash[:alert] = I18n.t("room.access_code_required") if session[:access_code] != @room.access_code
redirect_to room_path(@room.uid)
end
private
def update_room_attributes(update_type)
@ -205,13 +202,16 @@ class RoomsController < ApplicationController
if update_type.eql? "name"
@room.update_attributes(name: params[:room_name] || room_params[:name])
elsif update_type.eql? "settings"
room_settings_string = create_room_settings_string(room_params[:mute_on_join], room_params[:client])
room_settings_string = create_room_settings_string(room_params[:mute_on_join], room_params[:client],
room_params[:anyone_can_start])
@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, client_res)
def create_room_settings_string(mute_res, client_res, start_res)
room_settings = {}
room_settings["muteOnStart"] = mute_res == "1"
@ -221,11 +221,13 @@ class RoomsController < ApplicationController
room_settings["joinViaHtml5"] = false
end
room_settings["anyoneCanStart"] = start_res == "1"
room_settings.to_json
end
def room_params
params.require(:room).permit(:name, :auto_join, :mute_on_join, :client)
params.require(:room).permit(:name, :auto_join, :mute_on_join, :client, :access_code, :anyone_can_start)
end
# Find the room from the uid.
@ -274,7 +276,7 @@ class RoomsController < ApplicationController
end
def verify_user_not_admin
redirect_to admins_path if current_user && current_user&.has_role?(:super_admin)
redirect_to admins_path if current_user && current_user&.has_cached_role?(:super_admin)
end
def auth_required
@ -287,8 +289,38 @@ class RoomsController < ApplicationController
# Does not apply to admin
# 15+ option is used as unlimited
return false if current_user&.has_role?(:admin) || limit == 15
return false if current_user&.has_cached_role?(:admin) || limit == 15
current_user.rooms.count >= limit
end
def join_room(opts)
room_settings = JSON.parse(@room[:room_settings])
if @room.running? || @room.owned_by?(current_user) || room_settings["anyoneCanStart"]
# Determine if the user needs to join as a moderator.
opts[:user_is_moderator] = @room.owned_by?(current_user) ||
(room_settings["anyoneCanStart"] && !@room.running?)
# Check if the user has specified which client to use
opts[:join_via_html5] = room_settings["joinViaHtml5"] if room_settings["joinViaHtml5"]
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
end

View File

@ -30,7 +30,7 @@ class ThemesController < ApplicationController
@file_contents = File.read(file_name)
# Include the variables and covert scss file to css
@compiled = Sass::Engine.new("$primary-color:#{color};" \
@compiled = SassC::Engine.new("$primary-color:#{color};" \
"$primary-color-lighten:#{lighten_color};" \
"$primary-color-darken:#{darken_color};" +
@file_contents, syntax: :scss).render

View File

@ -21,6 +21,7 @@ class UsersController < ApplicationController
include Pagy::Backend
include Emailer
include Registrar
include Recorder
before_action :find_user, only: [:edit, :update, :destroy]
before_action :ensure_unauthenticated, only: [:new, :create]
@ -66,6 +67,12 @@ class UsersController < ApplicationController
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
return redirect_to "#{Rails.configuration.relative_url_root}/auth/#{providers.first}"
end
end
# GET /ldap_signin
@ -103,6 +110,8 @@ class UsersController < ApplicationController
# PATCH /u/:user_uid/edit
def update
redirect_path = current_user.admin_of?(@user) ? admins_path : edit_user_path(@user)
if params[:setting] == "password"
# Update the users password.
errors = {}
@ -123,7 +132,7 @@ class UsersController < ApplicationController
if errors.empty? && @user.save
# Notify the user that their account has been updated.
flash[:success] = I18n.t("info_update_success")
redirect_to edit_user_path(@user)
redirect_to redirect_path
else
# Append custom errors.
errors.each { |k, v| @user.errors.add(k, v) }
@ -132,11 +141,11 @@ class UsersController < ApplicationController
elsif user_params[:email] != @user.email && @user.update_attributes(user_params)
@user.update_attributes(email_verified: false)
flash[:success] = I18n.t("info_update_success")
redirect_to edit_user_path(@user)
redirect_to redirect_path
elsif @user.update_attributes(user_params)
update_locale(@user)
flash[:success] = I18n.t("info_update_success")
redirect_to edit_user_path(@user)
redirect_to redirect_path
else
render :edit, params: { settings: params[:settings] }
end
@ -165,7 +174,8 @@ class UsersController < ApplicationController
def recordings
if current_user && current_user.uid == params[:user_uid]
@search, @order_column, @order_direction, recs =
current_user.all_recordings(params.permit(:search, :column, :direction), true)
all_recordings(current_user.rooms.pluck(:bbb_id), current_user.provider,
params.permit(:search, :column, :direction), true)
@pagy, @recordings = pagy_array(recs)
else
redirect_to root_path
@ -185,7 +195,7 @@ class UsersController < ApplicationController
private
def find_user
@user = User.find_by!(uid: params[:user_uid])
@user = User.where(uid: params[:user_uid]).includes(:roles).first
end
def ensure_unauthenticated