diff --git a/app/assets/javascripts/admins.js b/app/assets/javascripts/admins.js index aff5ed47..abd34f26 100644 --- a/app/assets/javascripts/admins.js +++ b/app/assets/javascripts/admins.js @@ -74,12 +74,33 @@ $(document).on('turbolinks:load', function(){ $(".bootstrap-select").on("click", function() { $(".bs-searchbox").siblings().hide() }) + + $("#merge-user-select ~ button").on("click", function() { + $(".bs-searchbox").siblings().hide() + }) $(".bs-searchbox input").on("input", function() { if ($(".bs-searchbox input").val() == '' || $(".bs-searchbox input").val().length < 3) { + $(".select-options").remove() $(".bs-searchbox").siblings().hide() } else { - $(".bs-searchbox").siblings().show() + // Manually populate the dropdown + $.get($("#merge-user-select").data("path"), { search: $(".bs-searchbox input").val() }, function(users) { + $(".select-options").remove() + if (users.length > 0) { + users.forEach(function(user) { + let opt = document.createElement("option") + $(opt).val(JSON.stringify({uid: user.uid, email: user.email, name: user.name})) + $(opt).text(user.name) + $(opt).addClass("select-options") + $(opt).attr("data-subtext", user.email) + $("#merge-user-select").append(opt) + }) + // Only refresh the select dropdown if there are results to show + $('#merge-user-select').selectpicker('refresh'); + } + $(".bs-searchbox").siblings().show() + }) } }) diff --git a/app/assets/javascripts/room.js b/app/assets/javascripts/room.js index 1e09cad0..8ed1cddb 100644 --- a/app/assets/javascripts/room.js +++ b/app/assets/javascripts/room.js @@ -72,11 +72,32 @@ $(document).on('turbolinks:load', function(){ $(".bs-searchbox").siblings().hide() }) + $("#share-room-select ~ button").on("click", function() { + $(".bs-searchbox").siblings().hide() + }) + $(".bs-searchbox input").on("input", function() { if ($(".bs-searchbox input").val() == '' || $(".bs-searchbox input").val().length < 3) { + $(".select-options").remove() $(".bs-searchbox").siblings().hide() } else { - $(".bs-searchbox").siblings().show() + // Manually populate the dropdown + $.get($("#share-room-select").data("path"), { search: $(".bs-searchbox input").val() }, function(users) { + $(".select-options").remove() + if (users.length > 0) { + users.forEach(function(user) { + let opt = document.createElement("option") + $(opt).val(user.uid) + $(opt).text(user.name) + $(opt).addClass("select-options") + $(opt).attr("data-subtext", user.uid) + $("#share-room-select").append(opt) + }) + // Only refresh the select dropdown if there are results to show + $('#share-room-select').selectpicker('refresh'); + } + $(".bs-searchbox").siblings().show() + }) } }) diff --git a/app/controllers/admins_controller.rb b/app/controllers/admins_controller.rb index d0677e0d..5c4b106e 100644 --- a/app/controllers/admins_controller.rb +++ b/app/controllers/admins_controller.rb @@ -40,11 +40,10 @@ class AdminsController < ApplicationController @tab = params[:tab] || "active" @role = params[:role] ? Role.find_by(name: params[:role], provider: @user_domain) : nil - if @tab == "invited" - users = invited_users_list + users = if @tab == "invited" + invited_users_list else - users = manage_users_list - @user_list = merge_user_list + manage_users_list end @pagy, @users = pagy(users) @@ -86,8 +85,6 @@ class AdminsController < ApplicationController @participants_count[meet[:meetingID]] = meet[:participantCount] end - @user_list = shared_user_list if shared_access_allowed - @pagy, @rooms = pagy_array(server_rooms_list) end @@ -199,6 +196,22 @@ class AdminsController < ApplicationController redirect_back fallback_location: admins_path end + # GET /admins/merge_list + def merge_list + # Returns a list of users that can merged into another user + initial_list = User.select(:uid, :name, :email) + .without_role(:super_admin) + .where.not(uid: current_user.uid) + .merge_list_search(params[:search]) + + initial_list = initial_list.where(provider: @user_domain) if Rails.configuration.loadbalanced_configuration + + # Respond with JSON object of users + respond_to do |format| + format.json { render body: initial_list.to_json } + end + end + # SITE SETTINGS # POST /admins/update_settings diff --git a/app/controllers/concerns/populator.rb b/app/controllers/concerns/populator.rb index 59e2b9d7..b7865462 100644 --- a/app/controllers/concerns/populator.rb +++ b/app/controllers/concerns/populator.rb @@ -65,27 +65,6 @@ module Populator end end - # Returns a list of users that are in the same context of the current user - def shared_user_list - roles_can_appear = [] - Role.where(provider: @user_domain).each do |role| - roles_can_appear << role.name if role.get_permission("can_appear_in_share_list") && role.priority >= 0 - end - - initial_list = User.where.not(uid: current_user.uid).with_role(roles_can_appear) - - return initial_list unless Rails.configuration.loadbalanced_configuration - initial_list.where(provider: @user_domain) - end - - # Returns a list of users that can merged into another user - def merge_user_list - initial_list = User.without_role(:super_admin).where.not(uid: current_user.uid) - - return initial_list unless Rails.configuration.loadbalanced_configuration - initial_list.where(provider: @user_domain) - end - # Returns a list off all current invitations def invited_users_list list = if Rails.configuration.loadbalanced_configuration diff --git a/app/controllers/rooms_controller.rb b/app/controllers/rooms_controller.rb index 6bd35d6a..41b4144d 100644 --- a/app/controllers/rooms_controller.rb +++ b/app/controllers/rooms_controller.rb @@ -79,8 +79,6 @@ class RoomsController < ApplicationController @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 diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 34aea389..d1464e9d 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -197,6 +197,29 @@ class UsersController < ApplicationController end end + # GET /shared_access_list + def shared_access_list + # Don't allow searchs unless atleast 3 characters are passed + return redirect_to '/404' if params[:search].length < 3 + + roles_can_appear = [] + Role.where(provider: @user_domain).each do |role| + roles_can_appear << role.name if role.get_permission("can_appear_in_share_list") && role.priority >= 0 + end + + initial_list = User.select(:uid, :name) + .where.not(uid: current_user.uid) + .with_role(roles_can_appear) + .shared_list_search(params[:search]) + + initial_list = initial_list.where(provider: @user_domain) if Rails.configuration.loadbalanced_configuration + + # Respond with JSON object of users + respond_to do |format| + format.json { render body: initial_list.to_json } + end + end + private def find_user diff --git a/app/models/ability.rb b/app/models/ability.rb index 80a10900..b27bdc9c 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -37,7 +37,7 @@ class Ability if highest_role.get_permission("can_manage_users") can [:index, :edit_user, :promote, :demote, :ban_user, :unban_user, - :approve, :invite, :reset, :undelete, :merge_user], :admin + :approve, :invite, :reset, :undelete, :merge_user, :merge_list], :admin end can [:server_recordings, :server_rooms], :admin if highest_role.get_permission("can_manage_rooms_recordings") diff --git a/app/models/user.rb b/app/models/user.rb index 29c8b05f..cb5d3d8b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -95,6 +95,24 @@ class User < ApplicationRecord order(Arel.sql("users.#{column} #{direction}")) end + def self.shared_list_search(string) + return all if string.blank? + + search_query = "users.name LIKE :search OR users.uid LIKE :search" + + search_param = "%#{sanitize_sql_like(string)}%" + where(search_query, search: search_param) + end + + def self.merge_list_search(string) + return all if string.blank? + + search_query = "users.name LIKE :search OR users.email LIKE :search" + + search_param = "%#{sanitize_sql_like(string)}%" + where(search_query, search: search_param) + end + # Returns a list of rooms ordered by last session (with nil rooms last) def ordered_rooms return [] if main_room.nil? diff --git a/app/views/shared/modals/_merge_user_modal.html.erb b/app/views/shared/modals/_merge_user_modal.html.erb index e5c74bbc..80f67bd3 100644 --- a/app/views/shared/modals/_merge_user_modal.html.erb +++ b/app/views/shared/modals/_merge_user_modal.html.erb @@ -21,10 +21,7 @@

<%= t("modal.merge_user.title") %>

- " data-live-search="true" data-virtual-scroll="true" data-path="<%= merge_list_path %>">
diff --git a/app/views/shared/modals/_share_room_modal.html.erb b/app/views/shared/modals/_share_room_modal.html.erb index 5a06d9e4..5426b557 100644 --- a/app/views/shared/modals/_share_room_modal.html.erb +++ b/app/views/shared/modals/_share_room_modal.html.erb @@ -21,10 +21,7 @@

<%= t("modal.share_access.title") %>

- " data-live-search="true" data-virtual-scroll="true" data-path="<%= shared_access_list_path %>" >
diff --git a/config/routes.rb b/config/routes.rb index 8082da57..15ce2e7a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -52,6 +52,7 @@ Rails.application.routes.draw do get '/reset', to: 'admins#reset', as: :admin_reset post '/undelete', to: 'admins#undelete', as: :admin_undelete post '/merge/:user_uid', to: 'admins#merge_user', as: :merge_user + get '/merge_list', to: 'admins#merge_list', as: :merge_list # Site Settings post '/update_settings', to: 'admins#update_settings', as: :admin_update_settings post '/registration_method', to: 'admins#registration_method', as: :admin_change_registration @@ -110,6 +111,9 @@ Rails.application.routes.draw do # Users who can't create rooms get '/rooms', to: 'rooms#cant_create_rooms', as: :cant_create_rooms + # Returns a list of users for the shared access list + get '/shared_access_list', to: 'users#shared_access_list' + # Room resources. resources :rooms, only: [:create, :show, :destroy], param: :room_uid, path: '/'