forked from External/greenlight
Allow rooms to have an optional access code (#646)
This commit is contained in:
parent
a055b88eb7
commit
7d1c9e87a9
|
@ -44,6 +44,9 @@ $(document).on('turbolinks:load', function(){
|
|||
// Display and update all fields related to creating a room in the createRoomModal
|
||||
$("#create-room-block").click(function(){
|
||||
$("#create-room-name").val("")
|
||||
$("#create-room-access-code").text("<%= I18n.t("modal.create_room.access_code_placeholder") %>")
|
||||
$("#room_access_code").val(null)
|
||||
|
||||
$("#createRoomModal form").attr("action", $("body").data('relative-root'))
|
||||
updateDropdown($(".dropdown-item[value='default']"))
|
||||
$("#room_mute_on_join").prop("checked", false)
|
||||
|
@ -80,6 +83,16 @@ $(document).on('turbolinks:load', function(){
|
|||
})
|
||||
|
||||
updateCurrentSettings($(this).closest("#room-block").data("room-settings"))
|
||||
|
||||
accessCode = $(this).closest("#room-block").data("room-access-code")
|
||||
|
||||
if(accessCode){
|
||||
$("#create-room-access-code").text("<%= I18n.t("modal.create_room.access_code") %>: " + accessCode)
|
||||
$("#room_access_code").val(accessCode)
|
||||
} else{
|
||||
$("#create-room-access-code").text("<%= I18n.t("modal.create_room.access_code_placeholder") %>")
|
||||
$("#room_access_code").val(null)
|
||||
}
|
||||
})
|
||||
|
||||
//Update the createRoomModal to show the correct current settings
|
||||
|
@ -107,3 +120,21 @@ function updateDropdown(element) {
|
|||
$("#dropdown-trigger").text(element.text())
|
||||
$("#room_client").val(element.val())
|
||||
}
|
||||
|
||||
function generateAccessCode(){
|
||||
const accessCodeLength = 6
|
||||
var validCharacters = "0123456789"
|
||||
var accessCode = ""
|
||||
|
||||
for( var i = 0; i < accessCodeLength; i++){
|
||||
accessCode += validCharacters.charAt(Math.floor(Math.random() * validCharacters.length));
|
||||
}
|
||||
|
||||
$("#create-room-access-code").text("<%= I18n.t("modal.create_room.access_code") %>: " + accessCode)
|
||||
$("#room_access_code").val(accessCode)
|
||||
}
|
||||
|
||||
function ResetAccessCode(){
|
||||
$("#create-room-access-code").text("<%= I18n.t("modal.create_room.access_code_placeholder") %>")
|
||||
$("#room_access_code").val(null)
|
||||
}
|
||||
|
|
|
@ -65,3 +65,7 @@
|
|||
background-color: rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
}
|
||||
|
||||
.allow-icon-click{
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ class RoomsController < ApplicationController
|
|||
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]
|
||||
|
@ -36,7 +36,7 @@ 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])
|
||||
|
||||
|
@ -106,6 +106,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]
|
||||
|
@ -118,31 +124,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 =
|
||||
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
|
||||
join_room(opts)
|
||||
end
|
||||
|
||||
# DELETE /:room_uid
|
||||
|
@ -185,6 +167,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
|
||||
|
@ -199,6 +183,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)
|
||||
|
@ -208,6 +201,8 @@ class RoomsController < ApplicationController
|
|||
elsif update_type.eql? "settings"
|
||||
room_settings_string = create_room_settings_string(room_params[:mute_on_join], room_params[:client])
|
||||
@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
|
||||
|
@ -226,7 +221,7 @@ class RoomsController < ApplicationController
|
|||
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)
|
||||
end
|
||||
|
||||
# Find the room from the uid.
|
||||
|
@ -292,4 +287,31 @@ class RoomsController < ApplicationController
|
|||
|
||||
current_user.rooms.count >= limit
|
||||
end
|
||||
|
||||
def join_room(opts)
|
||||
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 =
|
||||
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
|
||||
|
|
|
@ -13,9 +13,21 @@
|
|||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
%>
|
||||
|
||||
<%= render 'shared/room_event' do %>
|
||||
<% 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 %>
|
||||
<% if room_authentication_required %>
|
||||
<h2><%= t("administrator.site_settings.authentication.user-info") %></h2>
|
||||
<% elsif !valid_access_code %>
|
||||
<%= form_for :room, url: login_room_path(@room.uid) do |f| %>
|
||||
<div class="input-group join-input">
|
||||
<%= f.text_field :access_code,
|
||||
required: true,
|
||||
class: "form-control join-form",
|
||||
placeholder: t("room.enter_the_access_code"),
|
||||
value: "" %>
|
||||
<%= f.submit t("room.login"), class: "btn btn-primary btn-sm col-sm-3 form-control join-form" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= form_for room_path(@room), method: :post do |f| %>
|
||||
<div class="input-group join-input">
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
%>
|
||||
|
||||
<%= render 'shared/room_event' do %>
|
||||
<%= render 'shared/room_event', render_recordings: true do %>
|
||||
<div class="row">
|
||||
<div class="col-9">
|
||||
<h3><%= t("room.wait.message") %></h3>
|
||||
|
|
|
@ -40,4 +40,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<% if render_recordings %>
|
||||
<%= render "shared/sessions", recordings: @public_recordings, pagy: @pagy, only_public: true, user_recordings: false, title: t("room.recordings") %>
|
||||
<% end %>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
%>
|
||||
|
||||
<div id="<%= if room == current_user.main_room then 'home_room_block' else 'room-block' end %>" data-room-uid="<%= room.uid %>" data-room-settings=<%= room.room_settings %> class="card">
|
||||
<div id="<%= if room == current_user.main_room then 'home_room_block' else 'room-block' end %>" data-room-uid="<%= room.uid %>" data-room-settings=<%= room.room_settings %> data-room-access-code="<%= room.access_code %>" class="card">
|
||||
<div class="card-body p-1">
|
||||
<table class="table table-hover table-vcenter text-wrap table-no-border">
|
||||
<tbody class="no-border-top">
|
||||
|
|
|
@ -28,10 +28,21 @@
|
|||
<span class="input-icon-addon">
|
||||
<i class="fas fa-chalkboard-teacher"></i>
|
||||
</span>
|
||||
<%= f.text_field :name, id: "create-room-name", class: "form-control", value: "", placeholder: t("modal.create_room.name_placeholder"), autocomplete: :off %>
|
||||
<%= f.text_field :name, id: "create-room-name", class: "form-control text-center", value: "", placeholder: t("modal.create_room.name_placeholder"), autocomplete: :off %>
|
||||
<div class="invalid-feedback text-left"><%= t("modal.create_room.not_blank") %></div>
|
||||
</div>
|
||||
|
||||
<div class="input-icon mb-2">
|
||||
<span onclick="generateAccessCode()" class="input-icon-addon allow-icon-click">
|
||||
<i class="fas fa-dice"></i>
|
||||
</span>
|
||||
<%= f.label :access_code, t("modal.create_room.access_code_placeholder"), id: "create-room-access-code", class: "form-control" %>
|
||||
<%= f.hidden_field :access_code %>
|
||||
<span onclick="ResetAccessCode()" class="input-icon-addon allow-icon-click">
|
||||
<i class="far fa-trash-alt"></i>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<% if Rails.configuration.room_features.include? "default-client" %>
|
||||
<label class="mt-3 mb-3 w-100 text-left d-inline-block">
|
||||
<input type="hidden" name="room[client]" id="room_client">
|
||||
|
|
|
@ -252,6 +252,8 @@ en:
|
|||
max_concurrent: The maximum number of concurrent sessions allowed has been reached!
|
||||
modal:
|
||||
create_room:
|
||||
access_code: Access Code
|
||||
access_code_placeholder: Generate an optional room access code
|
||||
auto_join: Automatically join me into the room
|
||||
create: Create Room
|
||||
free_delete: You will be free to delete this room at any time.
|
||||
|
@ -357,13 +359,16 @@ en:
|
|||
super_admin: Super Admin
|
||||
user: User
|
||||
room:
|
||||
access_code_required: Please enter a valid access code to join the room
|
||||
create_room: Create a Room
|
||||
create_room_error: There was an error creating the room
|
||||
create_room_success: Room created successfully
|
||||
enter_the_access_code: Enter the room's access code
|
||||
invited: You have been invited to join
|
||||
invite_participants: Invite Participants
|
||||
join: Join
|
||||
last_session: Last session on %{session}
|
||||
login: Login
|
||||
owner: Owner
|
||||
no_sessions: This room has no sessions, yet!
|
||||
recordings: Room Recordings
|
||||
|
|
|
@ -102,6 +102,7 @@ Rails.application.routes.draw do
|
|||
post '/update_settings', to: 'rooms#update_settings'
|
||||
post '/start', to: 'rooms#start', as: :start_room
|
||||
get '/logout', to: 'rooms#logout', as: :logout_room
|
||||
post '/login', to: 'rooms#login', as: :login_room
|
||||
end
|
||||
|
||||
# Recording operations routes
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddPasswordDigestToRooms < ActiveRecord::Migration[5.0]
|
||||
def change
|
||||
add_column :rooms, :access_code, :string, null: true, default: nil
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20190522195242) do
|
||||
ActiveRecord::Schema.define(version: 20190711192033) do
|
||||
|
||||
create_table "features", force: :cascade do |t|
|
||||
t.integer "setting_id"
|
||||
|
@ -56,6 +56,7 @@ ActiveRecord::Schema.define(version: 20190522195242) do
|
|||
t.string "room_settings", default: "{ }"
|
||||
t.string "moderator_pw"
|
||||
t.string "attendee_pw"
|
||||
t.string "access_code"
|
||||
t.index ["bbb_id"], name: "index_rooms_on_bbb_id"
|
||||
t.index ["last_session"], name: "index_rooms_on_last_session"
|
||||
t.index ["name"], name: "index_rooms_on_name"
|
||||
|
|
|
@ -203,6 +203,32 @@ describe RoomsController, type: :controller do
|
|||
expect(response).to render_template(:wait)
|
||||
end
|
||||
|
||||
it "should render wait if the correct access code is supplied" do
|
||||
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(false)
|
||||
|
||||
protected_room = Room.new(name: 'test', access_code: "123456")
|
||||
protected_room.owner = @owner
|
||||
protected_room.save
|
||||
|
||||
@request.session[:user_id] = @user.id
|
||||
post :join, params: { room_uid: protected_room, join_name: @user.name }, session: { access_code: "123456" }
|
||||
|
||||
expect(response).to render_template(:wait)
|
||||
end
|
||||
|
||||
it "should redirect to login if the correct access code isn't supplied" do
|
||||
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(false)
|
||||
|
||||
protected_room = Room.new(name: 'test', access_code: "123456")
|
||||
protected_room.owner = @owner
|
||||
protected_room.save
|
||||
|
||||
@request.session[:user_id] = @user.id
|
||||
post :join, params: { room_uid: protected_room, join_name: @user.name }, session: { access_code: "123455" }
|
||||
|
||||
expect(response).to redirect_to room_path(protected_room.uid)
|
||||
end
|
||||
|
||||
it "should join owner as moderator if meeting running" do
|
||||
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(true)
|
||||
|
||||
|
@ -374,4 +400,27 @@ describe RoomsController, type: :controller do
|
|||
expect(response).to redirect_to(@room)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST #login" do
|
||||
before do
|
||||
@user = create(:user)
|
||||
@room = @user.main_room
|
||||
@room.access_code = "123456"
|
||||
@room.save
|
||||
end
|
||||
|
||||
it "should redirect to show with valid access code" do
|
||||
post :login, params: { room_uid: @room.uid, room: { access_code: "123456" } }
|
||||
|
||||
expect(response).to redirect_to room_path(@room.uid)
|
||||
expect(flash[:alert]).to be_nil
|
||||
end
|
||||
|
||||
it "should redirect to show with and notify user of invalid access code" do
|
||||
post :login, params: { room_uid: @room.uid, room: { access_code: "123455" } }
|
||||
|
||||
expect(response).to redirect_to room_path(@room.uid)
|
||||
expect(flash[:alert]).to eq(I18n.t("room.access_code_required"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue