greenlight/app/controllers/rooms_controller.rb
Ahmad Farhat 51824ad84b
Merge v2.6-alpha (#1672)
* GRN2-xx: Switch the relation between users and roles to make queries cleaner and faster (#1299)

* First steps

* Fixes in account creation flow

* Fixed most testcases

* more test fixes

* Fixed more test cases

* Passing tests and rubocop

* Added rake task to remove rooms

* Adding translation (#1510)

* Update _account.html.erb

* Update en.yml

* Fix "for" attribute for label elements (#1488)

Co-authored-by: Ahmad Farhat <ahmad.af.farhat@gmail.com>

* Fix some issues reported by LGTM (#1478)

* Declare local JavaScript variables (reported by LGTM)

Signed-off-by: Stefan Weil <sw@weilnetz.de>

* Remove unused local JavaScript variable (reported by LGTM)

Signed-off-by: Stefan Weil <sw@weilnetz.de>

* Puma Worker Configuration (#1332)

We noticed that the current default settings perform very poorly under
load. We managed to literally take down Greenlight during a larger event
when people where accessing the landing page for rooms and when doing
some tests, I was more or less able to DoS Greenlight on my own.

This patch adds a default worker configuration which significantly
improves the situation. The small, 4 core machine I was testing on could
handle about thrice the amount of requests.

While the new default configuration should be reasonably well suited for
most deployments, this patch further allows users to easily configure
the worker pool on their own in the environment file.

* Made name and email readonly for no greenlight accounts (#1534)

* Fixed hardcoded string (#1532)

* fixed spelling error that was bugging me :) - sep a rat e (#1535)

Co-authored-by: Dave Lane <dave@oerfoundation.org>

* Improve Server Rooms View (#1524)

* Order rooms by status

* Cleaned up order function

* Now displays Started/Created/Ended

* Added participant count to rooms list

* Fix rake task user:create so that users can be created when terms are present (#1565)

* Changed user create task to always accept terms

* clean up

* More secure room ID (#1451)

* Legal and privpolicy link (#1421)

* add customizable Links to Imprint and Privacy Policy

* fix copy&paste error in spec

* replace "imprint" with "legal" since that is the correct term

* remove german translation of new strings, transifex will take care of them later

* GRN2-295:Refactored update profile and update password (#1591)

* Refactored update profile and update password

* Relowered rubocop settings

* Fixed email sending when not supposed to (#1592)

* Design changes for small screens  (#1580)

* now rap for pagination

* Update _subtitle.html.erb

* Update _rooms.html.erb

* Update _recordings.html.erb

* Update _rooms.html.erb

* Update _users.html.erb

* Update cant_create_rooms.html.erb

* Update room.js

* Update edit.html.erb

* Update new.html.erb

* Update cant_create_rooms.html.erb

* Update _sessions.html.erb

* Update _account.html.erb

* Make Greenlight work with Ruby 2.7 (#1560)

Greenlight's failure to start up with Ruby 2.7 seems to be caused by [an
issue in bootsnap](https://github.com/Shopify/bootsnap/issues/258).
Updating that library makes Greenlight work again.

However, there are still a lot of deprecation warnings. But that's
something to deal with separately.

This fixes #1558

* use email input for sign in (#1199)

* use email input for sign in

* use email input for registration

* use email input for invitation

* use email input for account settings

Co-authored-by: Ahmad Farhat <ahmad.af.farhat@gmail.com>

* Fix Gemfile (#1593)

* Fixed invalid token for password reset (#1632)

* HELP_URL env variable now works as expected (#1636)

* #1372 Fix for long Text in Table + Remove invalid HTML Tag (#1403)

* removed invalid HTML Tag

* removed invalid HTML Tag

* Update _public_recording_row.html.erb

* Update _recording_row.html.erb

* Update _server_recording_row.html.erb

form-inline replaced by own css

* Update _server_room_row.html.erb

* Update _public_recording_row.html.erb

* Update _recording_row.html.erb

* Update _public_recording_row.html.erb

* Update _recordings.html.erb

* Update _rooms.html.erb

* Update main.scss

fix for long text

* Update main.scss

* Update _public_recording_row.html.erb

* Added more validation on profile image (#1644)

* Users who can't create rooms but have shared rooms now have a different view (#1649)

* Revert "Puma Worker Configuration (#1332)" (#1667)

This reverts commit 78ed8d74601b613af3fd96ccf75a6bada24deddd.

* Removed html safe from all flash messages (#1668)

* Remove hardcoded guest=true if require mod approval is set (#1669)

* Change random generation for room uid (#1670)

* GRN2-290: Update gems and update to Rails 5.2.4.3 (#1671)

* Update gems and update to Rails 5.2.4.3

* remove gemfile error

Co-authored-by: MrKeksi <mrkeksi@users.noreply.github.com>
Co-authored-by: Florian Weber <fnwbr@users.noreply.github.com>
Co-authored-by: Stefan Weil <sw@weilnetz.de>
Co-authored-by: Lars Kiesow <lkiesow@uos.de>
Co-authored-by: Dave Lane <dave@lane.net.nz>
Co-authored-by: Dave Lane <dave@oerfoundation.org>
Co-authored-by: Henning <hng@users.noreply.github.com>
Co-authored-by: Marcel Waldvogel <marcel@waldvogel.family>
Co-authored-by: Christian Marg <marg@rz.tu-clausthal.de>
Co-authored-by: Klaus <klaus@jsxc.org>
2020-05-26 17:37:23 -04:00

368 lines
13 KiB
Ruby

# 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/>.
class RoomsController < ApplicationController
include Pagy::Backend
include Recorder
include Joiner
include Populator
before_action :validate_accepted_terms, unless: -> { !Rails.configuration.terms }
before_action :validate_verified_email, except: [:show, :join],
unless: -> { !Rails.configuration.enable_email_verification }
before_action :find_room, except: [:create, :join_specific_room, :cant_create_rooms]
before_action :verify_room_ownership_or_admin_or_shared, only: [:start, :shared_access]
before_action :verify_room_ownership_or_admin, only: [:update_settings, :destroy]
before_action :verify_room_ownership_or_shared, only: [:remove_shared_access]
before_action :verify_room_owner_verified, only: [:show, :join],
unless: -> { !Rails.configuration.enable_email_verification }
before_action :verify_room_owner_valid, only: [:show, :join]
before_action :verify_user_not_admin, only: [:show]
# POST /
def create
# Return to root if user is not signed in
return redirect_to root_path unless current_user
# Check if the user has not exceeded the room limit
return redirect_to current_user.main_room, flash: { alert: I18n.t("room.room_limit") } if room_limit_exceeded
# Create room
@room = Room.new(name: room_params[:name], access_code: room_params[:access_code])
@room.owner = current_user
@room.room_settings = create_room_settings_string(room_params)
# Save the room and redirect if it fails
return redirect_to current_user.main_room, flash: { alert: I18n.t("room.create_room_error") } unless @room.save
logger.info "Support: #{current_user.email} has created a new room #{@room.uid}."
# Redirect to room is auto join was not turned on
return redirect_to @room,
flash: { success: I18n.t("room.create_room_success") } unless room_params[:auto_join] == "1"
# Start the room if auto join was turned on
start
end
# GET /:room_uid
def show
@room_settings = @room[:room_settings]
@anyone_can_start = room_setting_with_config("anyoneCanStart")
@room_running = room_running?(@room.bbb_id)
@shared_room = room_shared_with_user
# If its the current user's room
if current_user && (@room.owned_by?(current_user) || @shared_room)
# User is allowed to have rooms
@search, @order_column, @order_direction, recs =
recordings(@room.bbb_id, params.permit(:search, :column, :direction), true)
@user_list = shared_user_list if shared_access_allowed
@pagy, @recordings = pagy_array(recs)
else
return redirect_to root_path, flash: { alert: I18n.t("room.invalid_provider") } if incorrect_user_domain
show_user_join
end
end
# GET /rooms
def cant_create_rooms
shared_rooms = current_user.shared_rooms
if current_user.shared_rooms.empty?
# Render view for users that cant create rooms
@recent_rooms = Room.where(id: cookies.encrypted["#{current_user.uid}_recently_joined_rooms"])
render :cant_create_rooms
else
redirect_to shared_rooms[0]
end
end
# POST /:room_uid
def join
return redirect_to root_path,
flash: { alert: I18n.t("administrator.site_settings.authentication.user-info") } if auth_required
@shared_room = room_shared_with_user
unless @room.owned_by?(current_user) || @shared_room
# 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]
elsif !params[:join_name]
# Join name not passed.
return redirect_to root_path
end
end
# create or update cookie with join name
cookies.encrypted[:greenlight_name] = @join_name unless cookies.encrypted[:greenlight_name] == @join_name
save_recent_rooms
logger.info "Support: #{current_user.present? ? current_user.email : @join_name} is joining room #{@room.uid}"
join_room(default_meeting_options)
end
# DELETE /:room_uid
def destroy
begin
# Don't delete the users home room.
raise I18n.t("room.delete.home_room") if @room == @room.owner.main_room
@room.destroy
rescue => e
flash[:alert] = I18n.t("room.delete.fail", error: e)
else
flash[:success] = I18n.t("room.delete.success")
end
# Redirect to home room if the redirect_back location is the deleted room
return redirect_to @current_user.main_room if request.referer == room_url(@room)
# Redirect to the location that the user deleted the room from
redirect_back fallback_location: current_user.main_room
end
# POST /room/join
def join_specific_room
room_uid = params[:join_room][:url].split('/').last
begin
@room = Room.find_by!(uid: room_uid)
rescue ActiveRecord::RecordNotFound
return redirect_to current_user.main_room, alert: I18n.t("room.no_room.invalid_room_uid")
end
redirect_to room_path(@room)
end
# POST /:room_uid/start
def start
logger.info "Support: #{current_user.email} is starting room #{@room.uid}"
# Join the user in and start the meeting.
opts = default_meeting_options
opts[:user_is_moderator] = true
# Include the user's choices for the room settings
@room_settings = JSON.parse(@room[:room_settings])
opts[:mute_on_start] = room_setting_with_config("muteOnStart")
opts[:require_moderator_approval] = room_setting_with_config("requireModeratorApproval")
begin
redirect_to join_path(@room, current_user.name, opts, current_user.uid)
rescue BigBlueButton::BigBlueButtonException => e
logger.error("Support: #{@room.uid} start failed: #{e}")
redirect_to room_path, alert: I18n.t(e.key.to_s.underscore, default: I18n.t("bigbluebutton_exception"))
end
# Notify users that the room has started.
# Delay 5 seconds to allow for server start, although the request will retry until it succeeds.
NotifyUserWaitingJob.set(wait: 5.seconds).perform_later(@room)
end
# POST /:room_uid/update_settings
def update_settings
begin
options = params[:room].nil? ? params : params[:room]
raise "Room name can't be blank" if options[:name].blank?
# 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]
)
flash[:success] = I18n.t("room.update_settings_success")
rescue => e
logger.error "Support: Error in updating room settings: #{e}"
flash[:alert] = I18n.t("room.update_settings_error")
end
redirect_back fallback_location: room_path(@room)
end
# POST /:room_uid/update_shared_access
def shared_access
begin
current_list = @room.shared_users.pluck(:id)
new_list = User.where(uid: params[:add]).pluck(:id)
# Get the list of users that used to be in the list but were removed
users_to_remove = current_list - new_list
# Get the list of users that are in the new list but not in the current list
users_to_add = new_list - current_list
# Remove users that are removed
SharedAccess.where(room_id: @room.id, user_id: users_to_remove).delete_all unless users_to_remove.empty?
# Add users that are added
users_to_add.each do |id|
SharedAccess.create(room_id: @room.id, user_id: id)
end
flash[:success] = I18n.t("room.shared_access_success")
rescue => e
logger.error "Support: Error in updating room shared access: #{e}"
flash[:alert] = I18n.t("room.shared_access_error")
end
redirect_back fallback_location: room_path
end
# POST /:room_uid/remove_shared_access
def remove_shared_access
begin
SharedAccess.find_by!(room_id: @room.id, user_id: params[:user_id]).destroy
flash[:success] = I18n.t("room.remove_shared_access_success")
rescue => e
logger.error "Support: Error in removing room shared access: #{e}"
flash[:alert] = I18n.t("room.remove_shared_access_error")
end
redirect_to current_user.main_room
end
# GET /:room_uid/shared_users
def shared_users
# Respond with JSON object of users that have access to the room
respond_to do |format|
format.json { render body: @room.shared_users.to_json }
end
end
# GET /:room_uid/room_settings
def room_settings
# Respond with JSON object of the room_settings
respond_to do |format|
format.json { render body: @room.room_settings.to_json }
end
end
# GET /:room_uid/logout
def logout
logger.info "Support: #{current_user.present? ? current_user.email : 'Guest'} has left room #{@room.uid}"
# Redirect the correct page.
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 create_room_settings_string(options)
room_settings = {
"muteOnStart": options[:mute_on_join] == "1",
"requireModeratorApproval": options[:require_moderator_approval] == "1",
"anyoneCanStart": options[:anyone_can_start] == "1",
"joinModerator": options[:all_join_moderator] == "1",
}
room_settings.to_json
end
def room_params
params.require(:room).permit(:name, :auto_join, :mute_on_join, :access_code,
:require_moderator_approval, :anyone_can_start, :all_join_moderator)
end
# Find the room from the uid.
def find_room
@room = Room.includes(:owner).find_by!(uid: params[:room_uid])
end
# Ensure the user either owns the room or is an admin of the room owner or the room is shared with him
def verify_room_ownership_or_admin_or_shared
return redirect_to root_path unless @room.owned_by?(current_user) ||
room_shared_with_user ||
current_user&.admin_of?(@room.owner, "can_manage_rooms_recordings")
end
# Ensure the user either owns the room or is an admin of the room owner
def verify_room_ownership_or_admin
return redirect_to root_path if !@room.owned_by?(current_user) &&
!current_user&.admin_of?(@room.owner, "can_manage_rooms_recordings")
end
# Ensure the user owns the room or is allowed to start it
def verify_room_ownership_or_shared
return redirect_to root_path unless @room.owned_by?(current_user) || room_shared_with_user
end
def validate_accepted_terms
redirect_to terms_path if current_user && !current_user&.accepted_terms
end
def validate_verified_email
redirect_to account_activation_path(current_user) if current_user && !current_user&.activated?
end
def verify_room_owner_verified
redirect_to root_path, alert: t("room.unavailable") unless @room.owner.activated?
end
# Check to make sure the room owner is not pending or banned
def verify_room_owner_valid
redirect_to root_path, alert: t("room.owner_banned") if @room.owner.has_role?(:pending) || @room.owner.has_role?(:denied)
end
def verify_user_not_admin
redirect_to admins_path if current_user&.has_role?(:super_admin)
end
def auth_required
@settings.get_value("Room Authentication") == "true" && current_user.nil?
end
# Checks if the room is shared with the user and room sharing is enabled
def room_shared_with_user
shared_access_allowed ? @room.shared_with?(current_user) : false
end
def room_limit_exceeded
limit = @settings.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
helper_method :room_limit_exceeded
end