forked from External/greenlight
		
	GRN2-176: Create a role editor that allows admins to specify what permissions each role has (#709)
* Add roles editor * Add colour selection ability to roles * Add ability to assign roles to users in the UI * Remove rolify and replace it with our own custom roles implemenation * - Fix all existing roles functionality - Fix super admins * Fix bugs with new customers not have default roles * Add can't create room setting * Code improvements * Fix migration * Add tests for new methods * Translate reserved role names * Pull roles from saml/ldap * Fix rspec * Fix scrutinizer issues * Fix email promoted/demoted tests * Apply comments * Redirect directly to the main room * Add comments
This commit is contained in:
		
				
					committed by
					
						 Jesus Federico
						Jesus Federico
					
				
			
			
				
	
			
			
			
						parent
						
							02b342b157
						
					
				
				
					commit
					4fc1714db8
				
			
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -32,6 +32,9 @@ vendor/bundle | |||||||
| .env | .env | ||||||
| env | env | ||||||
|  |  | ||||||
|  | # Ignore yarn configs | ||||||
|  | /node_modules | ||||||
|  |  | ||||||
| # IDEs | # IDEs | ||||||
| .idea | .idea | ||||||
| .idea/** | .idea/** | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								Gemfile
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								Gemfile
									
									
									
									
									
								
							| @@ -27,6 +27,7 @@ gem 'mini_racer', platforms: :ruby | |||||||
|  |  | ||||||
| # Use jquery as the JavaScript library | # Use jquery as the JavaScript library | ||||||
| gem 'jquery-rails', '~> 4.3.3' | gem 'jquery-rails', '~> 4.3.3' | ||||||
|  | gem 'jquery-ui-rails' | ||||||
|  |  | ||||||
| # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks | # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks | ||||||
| gem 'turbolinks', '~> 5' | gem 'turbolinks', '~> 5' | ||||||
| @@ -72,8 +73,6 @@ gem 'redcarpet' | |||||||
| # For health check endpoint | # For health check endpoint | ||||||
| gem "health_check" | gem "health_check" | ||||||
|  |  | ||||||
| # For providing user roles |  | ||||||
| gem "rolify" |  | ||||||
| # For limiting access based on user roles | # For limiting access based on user roles | ||||||
| gem 'cancancan', '~> 2.0' | gem 'cancancan', '~> 2.0' | ||||||
|  |  | ||||||
|   | |||||||
| @@ -149,6 +149,8 @@ GEM | |||||||
|       rails-dom-testing (>= 1, < 3) |       rails-dom-testing (>= 1, < 3) | ||||||
|       railties (>= 4.2.0) |       railties (>= 4.2.0) | ||||||
|       thor (>= 0.14, < 2.0) |       thor (>= 0.14, < 2.0) | ||||||
|  |     jquery-ui-rails (6.0.1) | ||||||
|  |       railties (>= 3.2.16) | ||||||
|     json (2.2.0) |     json (2.2.0) | ||||||
|     jwt (2.2.1) |     jwt (2.2.1) | ||||||
|     libv8 (7.3.492.27.1) |     libv8 (7.3.492.27.1) | ||||||
| @@ -257,7 +259,6 @@ GEM | |||||||
|       syslog_protocol |       syslog_protocol | ||||||
|     request_store (1.4.1) |     request_store (1.4.1) | ||||||
|       rack (>= 1.4) |       rack (>= 1.4) | ||||||
|     rolify (5.2.0) |  | ||||||
|     rspec-core (3.8.2) |     rspec-core (3.8.2) | ||||||
|       rspec-support (~> 3.8.0) |       rspec-support (~> 3.8.0) | ||||||
|     rspec-expectations (3.8.4) |     rspec-expectations (3.8.4) | ||||||
| @@ -363,6 +364,7 @@ DEPENDENCIES | |||||||
|   i18n-language-mapping (~> 0.1.0) |   i18n-language-mapping (~> 0.1.0) | ||||||
|   jbuilder (~> 2.5) |   jbuilder (~> 2.5) | ||||||
|   jquery-rails (~> 4.3.3) |   jquery-rails (~> 4.3.3) | ||||||
|  |   jquery-ui-rails | ||||||
|   listen (~> 3.0.5) |   listen (~> 3.0.5) | ||||||
|   lograge |   lograge | ||||||
|   mini_racer |   mini_racer | ||||||
| @@ -381,7 +383,6 @@ DEPENDENCIES | |||||||
|   recaptcha |   recaptcha | ||||||
|   redcarpet |   redcarpet | ||||||
|   remote_syslog_logger |   remote_syslog_logger | ||||||
|   rolify |  | ||||||
|   rspec-rails (~> 3.7) |   rspec-rails (~> 3.7) | ||||||
|   rubocop |   rubocop | ||||||
|   sassc-rails |   sassc-rails | ||||||
|   | |||||||
| @@ -19,47 +19,60 @@ $(document).on('turbolinks:load', function(){ | |||||||
|   var action = $("body").data('action'); |   var action = $("body").data('action'); | ||||||
|  |  | ||||||
|   // Only run on the admins page. |   // Only run on the admins page. | ||||||
|   if (controller == "admins" && action == "index") { |   if (controller == "admins") { | ||||||
|     // show the modal with the correct form action url |     if(action == "index") { | ||||||
|     $(".delete-user").click(function(data){ |       // show the modal with the correct form action url | ||||||
|       var uid = $(data.target).closest("tr").data("user-uid") |       $(".delete-user").click(function(data){ | ||||||
|       var url = $("body").data("relative-root") |         var uid = $(data.target).closest("tr").data("user-uid") | ||||||
|       if (!url.endsWith("/")) { |         var url = $("body").data("relative-root") | ||||||
|         url += "/" |         if (!url.endsWith("/")) { | ||||||
|       } |           url += "/" | ||||||
|       url += "u/" + uid |         } | ||||||
|       $("#delete-confirm").parent().attr("action", url) |         url += "u/" + uid | ||||||
|     }) |         $("#delete-confirm").parent().attr("action", url) | ||||||
|  |       }) | ||||||
|  |  | ||||||
|     //clear the role filter if user clicks on the x |       //clear the role filter if user clicks on the x | ||||||
|     $(".clear-role").click(function() { |       $(".clear-role").click(function() { | ||||||
|       var search = new URL(location.href).searchParams.get('search') |         var search = new URL(location.href).searchParams.get('search') | ||||||
|  |  | ||||||
|       var url = window.location.pathname + "?page=1" |         var url = window.location.pathname + "?page=1" | ||||||
|      |        | ||||||
|       if (search) { |         if (search) { | ||||||
|         url += "&search=" + search |           url += "&search=" + search | ||||||
|       }   |         }   | ||||||
|      |        | ||||||
|       window.location.replace(url); |         window.location.replace(url); | ||||||
|     }) |       }) | ||||||
|   } |     } | ||||||
|  |     else if(action == "site_settings"){ | ||||||
|  |       loadColourSelectors() | ||||||
|  |     } | ||||||
|  |     else if (action == "roles"){ | ||||||
|  |       // Refreshes the new role modal | ||||||
|  |       $("#newRoleButton").click(function(){ | ||||||
|  |         $("#createRoleName").val("") | ||||||
|  |       }) | ||||||
|  |  | ||||||
|   if (controller == "admins" && action == "site_settings") { |       // Updates the colour picker to the correct colour | ||||||
|     loadColourSelectors() |       role_colour = $("#role-colorinput-regular").data("colour") | ||||||
|   } |       $("#role-colorinput-regular").css("background-color", role_colour); | ||||||
|  |       $("#role-colorinput-regular").css("border-color", role_colour); | ||||||
|  |  | ||||||
|   // Only run on the admins edit user page. |       loadRoleColourSelector(role_colour, $("#role-colorinput-regular").data("disabled")); | ||||||
|   if (controller == "admins" && action == "edit_user") { |  | ||||||
|     $(".setting-btn").click(function(data){ |  | ||||||
|       var url = $("body").data("relative-root") |  | ||||||
|       if (!url.endsWith("/")) { |  | ||||||
|         url += "/" |  | ||||||
|       } |  | ||||||
|       url += "admins?setting=" + data.target.id |  | ||||||
|  |  | ||||||
|       window.location.href = url |       // Loads the jquery sortable so users can manually sort roles | ||||||
|     }) |       $("#rolesSelect").sortable({ | ||||||
|  |         items: "a:not(.sort-disabled)", | ||||||
|  |         update: function() { | ||||||
|  |           $.ajax({ | ||||||
|  |             url: $(this).data("url"), | ||||||
|  |             type: 'PATCH', | ||||||
|  |             data: $(this).sortable('serialize') | ||||||
|  |           }); | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| }); | }); | ||||||
|  |  | ||||||
| @@ -160,4 +173,35 @@ function loadColourSelectors() { | |||||||
|       location.reload() |       location.reload() | ||||||
|     }); |     }); | ||||||
|   }) |   }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function loadRoleColourSelector(role_colour, disabled) {  | ||||||
|  |   if (!disabled) { | ||||||
|  |     const pickrRoleRegular = new Pickr({ | ||||||
|  |       el: '#role-colorinput-regular', | ||||||
|  |       theme: 'monolith', | ||||||
|  |       useAsButton: true, | ||||||
|  |       lockOpacity: true, | ||||||
|  |       defaultRepresentation: 'HEX', | ||||||
|  |       closeWithKey: 'Enter', | ||||||
|  |       default: role_colour, | ||||||
|  |    | ||||||
|  |       components: { | ||||||
|  |           palette: true, | ||||||
|  |           preview: true, | ||||||
|  |           hue: true, | ||||||
|  |           interaction: { | ||||||
|  |               input: true, | ||||||
|  |               save: true, | ||||||
|  |           }, | ||||||
|  |       }, | ||||||
|  |     }); | ||||||
|  |    | ||||||
|  |     // On save update the colour input's background colour and update the role colour input | ||||||
|  |     pickrRoleRegular.on("save", (color, instance) => { | ||||||
|  |       $("#role-colorinput-regular").css("background-color", color.toHEXA().toString()); | ||||||
|  |       $("#role-colorinput-regular").css("border-color", color.toHEXA().toString()); | ||||||
|  |       $("#role-colour").val(color.toHEXA().toString()); | ||||||
|  |     }); | ||||||
|  |   } | ||||||
| } | } | ||||||
| @@ -31,4 +31,6 @@ | |||||||
| //= require tabler | //= require tabler | ||||||
| //= require tabler.plugins | //= require tabler.plugins | ||||||
| //= require jquery_ujs | //= require jquery_ujs | ||||||
|  | //= require jquery-ui/widget | ||||||
|  | //= require jquery-ui/widgets/sortable | ||||||
| //= require_tree . | //= require_tree . | ||||||
|   | |||||||
| @@ -39,6 +39,11 @@ $(document).on('turbolinks:load', function(){ | |||||||
|         }, 2000) |         }, 2000) | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     // Forces the wrapper to take the entire screen height if the user can't create rooms | ||||||
|  |     if ($("#cant-create-room-wrapper").length){ | ||||||
|  |       $(".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 | ||||||
|   | |||||||
							
								
								
									
										88
									
								
								app/assets/javascripts/user_edit.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								app/assets/javascripts/user_edit.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | |||||||
|  | // 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/>. | ||||||
|  |  | ||||||
|  | $(document).on('turbolinks:load', function(){ | ||||||
|  |     var controller = $("body").data('controller'); | ||||||
|  |     var action = $("body").data('action'); | ||||||
|  |     if ((controller == "admins" && action == "edit_user") || (controller == "users" && action == "edit")) { | ||||||
|  |         $(".setting-btn").click(function(data){ | ||||||
|  |             var url = $("body").data("relative-root") | ||||||
|  |             if (!url.endsWith("/")) { | ||||||
|  |                 url += "/" | ||||||
|  |             } | ||||||
|  |             url += "admins?setting=" + data.target.id | ||||||
|  |  | ||||||
|  |             window.location.href = url | ||||||
|  |         }) | ||||||
|  |  | ||||||
|  |         // Clear the role when the user clicks the x | ||||||
|  |         $(".clear-role").click(clearRole) | ||||||
|  |  | ||||||
|  |         // When the user selects an item in the dropdown add the role to the user | ||||||
|  |         $("#role-select-dropdown").change(function(data){ | ||||||
|  |             var dropdown = $("#role-select-dropdown"); | ||||||
|  |             var select_role_id = dropdown.val(); | ||||||
|  |  | ||||||
|  |             if(select_role_id){ | ||||||
|  |                 // Disable the role in the dropdown | ||||||
|  |                 var selected_role = dropdown.find('[value=\"' + select_role_id + '\"]'); | ||||||
|  |                 selected_role.prop("disabled", true) | ||||||
|  |  | ||||||
|  |                 // Add the role tag | ||||||
|  |                 var tag_container = $("#role-tag-container"); | ||||||
|  |                 tag_container.append("<span id=\"user-role-tag_" + select_role_id + "\" style=\"background-color:" + selected_role.data("colour") + ";\" class=\"tag\">" +  | ||||||
|  |                     selected_role.text() + "<a data-role-id=\"" + select_role_id + "\" class=\"tag-addon clear-role\"><i data-role-id=\"" + select_role_id + "\" class=\"fas fa-times\"></i></a></span>"); | ||||||
|  |  | ||||||
|  |                 // Update the role ids input that gets submited on user update | ||||||
|  |                 var role_ids = $("#user_role_ids").val() | ||||||
|  |                 role_ids += " " + select_role_id | ||||||
|  |                 $("#user_role_ids").val(role_ids) | ||||||
|  |                  | ||||||
|  |                 // Add the clear role function to the tag | ||||||
|  |                 $("#user-role-tag_" + select_role_id).click(clearRole); | ||||||
|  |  | ||||||
|  |                 // Reset the dropdown | ||||||
|  |                 dropdown.val(null) | ||||||
|  |             } | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | // This function removes the specfied role from a user | ||||||
|  | function clearRole(data){ | ||||||
|  |     // Get the role id | ||||||
|  |     var role_id = $(data.target).data("role-id"); | ||||||
|  |     var role_tag = $("#user-role-tag_" + role_id); | ||||||
|  |  | ||||||
|  |     // Remove the role tag | ||||||
|  |     $(role_tag).remove() | ||||||
|  |    | ||||||
|  |     // Update the role ids input | ||||||
|  |     var role_ids = $("#user_role_ids").val() | ||||||
|  |     var parsed_ids = role_ids.split(' ') | ||||||
|  |    | ||||||
|  |     var index = parsed_ids.indexOf(role_id.toString()); | ||||||
|  |    | ||||||
|  |     if (index > -1) { | ||||||
|  |         parsed_ids.splice(index, 1); | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |     $("#user_role_ids").val(parsed_ids.join(' ')) | ||||||
|  |    | ||||||
|  |     // Enable the role in the role select dropdown | ||||||
|  |     var selected_role = $("#role-select-dropdown").find('[value=\"' + role_id + '\"]'); | ||||||
|  |     selected_role.prop("disabled", false) | ||||||
|  | } | ||||||
| @@ -54,4 +54,29 @@ | |||||||
|     height: 2rem; |     height: 2rem; | ||||||
|     width: 2rem; |     width: 2rem; | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .sort-disabled{ | ||||||
|  |   background: #e6e6e6 !important; | ||||||
|  |   color: rgb(110, 118, 135) !important; | ||||||
|  |   opacity: 0.75; | ||||||
|  |   &:hover{ | ||||||
|  |     opacity: 0.9; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .form-disable{ | ||||||
|  |   background-color: #e6e6e6; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .role-colour-picker{ | ||||||
|  |   color: white !important; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .custom-role-tag{ | ||||||
|  |   color: white !important; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .user-role-tag{ | ||||||
|  |   color: white !important; | ||||||
| } | } | ||||||
| @@ -32,6 +32,7 @@ | |||||||
|  |  | ||||||
| @import "tabler/variables"; | @import "tabler/variables"; | ||||||
| @import "bootstrap"; | @import "bootstrap"; | ||||||
|  | @import "jquery-ui/sortable"; | ||||||
| @import "tabler-custom"; | @import "tabler-custom"; | ||||||
|  |  | ||||||
| @import "utilities/variables"; | @import "utilities/variables"; | ||||||
|   | |||||||
| @@ -18,3 +18,7 @@ | |||||||
| // Place all the styles related to the Users controller here. | // Place all the styles related to the Users controller here. | ||||||
| // They will automatically be included in application.css. | // They will automatically be included in application.css. | ||||||
| // You can use Sass (SCSS) here: http://sass-lang.com/ | // You can use Sass (SCSS) here: http://sass-lang.com/ | ||||||
|  |  | ||||||
|  | .user-role-tag{ | ||||||
|  |     color: white !important; | ||||||
|  | } | ||||||
| @@ -85,6 +85,11 @@ a { | |||||||
|   &:hover { |   &:hover { | ||||||
|     color: $primary-color !important; |     color: $primary-color !important; | ||||||
|     background-color: $primary-color-lighten !important; |     background-color: $primary-color-lighten !important; | ||||||
|  |     &.sort-disabled { | ||||||
|  |       background: #e6e6e6 !important; | ||||||
|  |       color: rgb(110, 118, 135) !important; | ||||||
|  |       opacity: 0.9; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|   &:active { |   &:active { | ||||||
|     background-color: $primary-color-lighten !important; |     background-color: $primary-color-lighten !important; | ||||||
| @@ -102,6 +107,12 @@ input:focus, select:focus { | |||||||
|   &, .list-group-item.active * { |   &, .list-group-item.active * { | ||||||
|     color: $primary-color !important; |     color: $primary-color !important; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   &.sort-disabled { | ||||||
|  |     background: #e6e6e6 !important; | ||||||
|  |     color: rgb(110, 118, 135) !important; | ||||||
|  |     opacity: 0.9 !important; | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| .text-primary { | .text-primary { | ||||||
|   | |||||||
| @@ -36,7 +36,8 @@ class AdminsController < ApplicationController | |||||||
|     @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" | ||||||
|     @role = params[:role] || "" |  | ||||||
|  |     @role = params[:role] ? Role.find_by(name: params[:role], provider: @user_domain) : nil | ||||||
|  |  | ||||||
|     @pagy, @users = pagy(user_list) |     @pagy, @users = pagy(user_list) | ||||||
|   end |   end | ||||||
| @@ -64,24 +65,6 @@ class AdminsController < ApplicationController | |||||||
|   def edit_user |   def edit_user | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   # POST /admins/promote/:user_uid |  | ||||||
|   def promote |  | ||||||
|     @user.add_role :admin |  | ||||||
|  |  | ||||||
|     send_user_promoted_email(@user) |  | ||||||
|  |  | ||||||
|     redirect_to admins_path, flash: { success: I18n.t("administrator.flash.promoted") } |  | ||||||
|   end |  | ||||||
|  |  | ||||||
|   # POST /admins/demote/:user_uid |  | ||||||
|   def demote |  | ||||||
|     @user.remove_role :admin |  | ||||||
|  |  | ||||||
|     send_user_demoted_email(@user) |  | ||||||
|  |  | ||||||
|     redirect_to admins_path, flash: { success: I18n.t("administrator.flash.demoted") } |  | ||||||
|   end |  | ||||||
|  |  | ||||||
|   # POST /admins/ban/:user_uid |   # POST /admins/ban/:user_uid | ||||||
|   def ban_user |   def ban_user | ||||||
|     @user.roles = [] |     @user.roles = [] | ||||||
| @@ -185,6 +168,158 @@ class AdminsController < ApplicationController | |||||||
|     } |     } | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  |   # ROLES | ||||||
|  |  | ||||||
|  |   # GET /admins/roles | ||||||
|  |   def roles | ||||||
|  |     @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 params[:selected_role].nil? | ||||||
|  |                         @roles.find_by(name: 'user') | ||||||
|  |                       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 | ||||||
|  |     new_role_name = params[:role][:name] | ||||||
|  |  | ||||||
|  |     # Make sure that the role name isn't a duplicate or a reserved name like super_admin | ||||||
|  |     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 | ||||||
|  |  | ||||||
|  |     # Create the new role with the second highest priority | ||||||
|  |     # This means that it will only be more important than the user role | ||||||
|  |     # This also updates the user role to have the highest priority | ||||||
|  |     new_role = Role.create(name: new_role_name, provider: @user_domain) | ||||||
|  |     user_role = Role.find_by(name: 'user', provider: @user_domain) | ||||||
|  |  | ||||||
|  |     new_role.priority = user_role.priority | ||||||
|  |     user_role.priority += 1 | ||||||
|  |  | ||||||
|  |     new_role.save! | ||||||
|  |     user_role.save! | ||||||
|  |  | ||||||
|  |     redirect_to admin_roles_path(selected_role: new_role.id) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   # PATCH /admin/roles/order | ||||||
|  |   # This updates the priority of a site's roles | ||||||
|  |   # Note: A lower priority role will always get used before a higher priority one | ||||||
|  |   def change_role_order | ||||||
|  |     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 | ||||||
|  |     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 | ||||||
|  |  | ||||||
|  |     # 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 | ||||||
|  |  | ||||||
|  |   # POST /admin/role/:role_id | ||||||
|  |   # This method updates the permissions assigned to a role | ||||||
|  |   def update_role | ||||||
|  |     role = Role.find(params[:role_id]) | ||||||
|  |     current_user_role = current_user.highest_priority_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 | ||||||
|  |                               ) | ||||||
|  |  | ||||||
|  |     # 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) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   # DELETE admins/role/:role_id | ||||||
|  |   # This deletes a role | ||||||
|  |   def delete_role | ||||||
|  |     role = Role.find(params[:role_id]) | ||||||
|  |  | ||||||
|  |     # Make sure no users are assigned to the role and the role isn't a reserved role | ||||||
|  |     # before deleting | ||||||
|  |     if role.users.count.positive? | ||||||
|  |       flash[:alert] = I18n.t("administrator.roles.role_has_users", user_count: role.users.count) | ||||||
|  |       return redirect_to admin_roles_path(selected_role: role.id) | ||||||
|  |     elsif Role::RESERVED_ROLE_NAMES.include?(role) || role.provider != @user_domain || | ||||||
|  |           role.priority <= current_user.highest_priority_role.priority | ||||||
|  |       return redirect_to admin_roles_path(selected_role: role.id) | ||||||
|  |     else | ||||||
|  |       role.delete | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     redirect_to admin_roles_path | ||||||
|  |   end | ||||||
|  |  | ||||||
|   private |   private | ||||||
|  |  | ||||||
|   def find_user |   def find_user | ||||||
| @@ -202,10 +337,10 @@ class AdminsController < ApplicationController | |||||||
|  |  | ||||||
|   # Gets the list of users based on your configuration |   # Gets the list of users based on your configuration | ||||||
|   def user_list |   def user_list | ||||||
|     initial_list = if current_user.has_cached_role? :super_admin |     initial_list = if current_user.has_role? :super_admin | ||||||
|       User.where.not(id: current_user.id).includes(:roles) |       User.where.not(id: current_user.id) | ||||||
|     else |     else | ||||||
|       User.without_role(:super_admin).where.not(id: current_user.id).includes(:roles) |       User.without_role(:super_admin).where.not(id: current_user.id) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     if Rails.configuration.loadbalanced_configuration |     if Rails.configuration.loadbalanced_configuration | ||||||
|   | |||||||
| @@ -137,7 +137,7 @@ class ApplicationController < ActionController::Base | |||||||
|  |  | ||||||
|   # Checks to make sure that the admin has changed his password from the default |   # Checks to make sure that the admin has changed his password from the default | ||||||
|   def check_admin_password |   def check_admin_password | ||||||
|     if current_user&.has_cached_role?(:admin) && current_user&.greenlight_account? && |     if current_user&.has_role?(:admin) && current_user&.greenlight_account? && | ||||||
|        current_user&.authenticate(Rails.configuration.admin_password_default) |        current_user&.authenticate(Rails.configuration.admin_password_default) | ||||||
|  |  | ||||||
|       flash.now[:alert] = I18n.t("default_admin", |       flash.now[:alert] = I18n.t("default_admin", | ||||||
| @@ -185,10 +185,10 @@ class ApplicationController < ActionController::Base | |||||||
|  |  | ||||||
|   # Checks if the user is banned and logs him out if he is |   # Checks if the user is banned and logs him out if he is | ||||||
|   def check_user_role |   def check_user_role | ||||||
|     if current_user&.has_cached_role? :denied |     if current_user&.has_role? :denied | ||||||
|       session.delete(:user_id) |       session.delete(:user_id) | ||||||
|       redirect_to root_path, flash: { alert: I18n.t("registration.banned.fail") } |       redirect_to root_path, flash: { alert: I18n.t("registration.banned.fail") } | ||||||
|     elsif current_user&.has_cached_role? :pending |     elsif current_user&.has_role? :pending | ||||||
|       session.delete(:user_id) |       session.delete(:user_id) | ||||||
|       redirect_to root_path, flash: { alert: I18n.t("registration.approval.fail") } |       redirect_to root_path, flash: { alert: I18n.t("registration.approval.fail") } | ||||||
|     end |     end | ||||||
|   | |||||||
| @@ -35,16 +35,16 @@ module Emailer | |||||||
|     UserMailer.password_reset(@user, reset_link, logo_image, user_color).deliver_now |     UserMailer.password_reset(@user, reset_link, logo_image, user_color).deliver_now | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def send_user_promoted_email(user) |   def send_user_promoted_email(user, role) | ||||||
|     return unless Rails.configuration.enable_email_verification |     return unless Rails.configuration.enable_email_verification | ||||||
|  |  | ||||||
|     UserMailer.user_promoted(user, root_url, logo_image, user_color).deliver_now |     UserMailer.user_promoted(user, role, root_url, logo_image, user_color).deliver_now | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def send_user_demoted_email(user) |   def send_user_demoted_email(user, role) | ||||||
|     return unless Rails.configuration.enable_email_verification |     return unless Rails.configuration.enable_email_verification | ||||||
|  |  | ||||||
|     UserMailer.user_demoted(user, root_url, logo_image, user_color).deliver_now |     UserMailer.user_demoted(user, role, root_url, logo_image, user_color).deliver_now | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   # Sends inivitation to join |   # Sends inivitation to join | ||||||
| @@ -87,7 +87,7 @@ module Emailer | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   def admin_emails |   def admin_emails | ||||||
|     admins = User.with_role(:admin) |     admins = User.all_users_with_roles.where(roles: { can_manage_users: true }) | ||||||
|  |  | ||||||
|     if Rails.configuration.loadbalanced_configuration |     if Rails.configuration.loadbalanced_configuration | ||||||
|       admins = admins.without_role(:super_admin) |       admins = admins.without_role(:super_admin) | ||||||
|   | |||||||
| @@ -52,8 +52,8 @@ class RecordingsController < ApplicationController | |||||||
|   def verify_room_ownership |   def verify_room_ownership | ||||||
|     if !current_user || |     if !current_user || | ||||||
|        !@room.owned_by?(current_user) || |        !@room.owned_by?(current_user) || | ||||||
|        !current_user.has_cached_role?(:admin) || |        !current_user.has_role?(:admin) || | ||||||
|        !current_user.has_cached_role?(:super_admin) |        !current_user.has_role?(:super_admin) | ||||||
|       redirect_to root_path |       redirect_to root_path | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|   | |||||||
| @@ -24,8 +24,8 @@ class RoomsController < ApplicationController | |||||||
|   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 |   before_action :find_room, except: [:create, :join_specific_room] | ||||||
|   before_action :verify_room_ownership, except: [:create, :show, :join, :logout, :login] |   before_action :verify_room_ownership, except: [:create, :show, :join, :logout, :login, :join_specific_room] | ||||||
|   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] | ||||||
| @@ -60,11 +60,14 @@ class RoomsController < ApplicationController | |||||||
|     @anyone_can_start = JSON.parse(@room[:room_settings])["anyoneCanStart"] |     @anyone_can_start = JSON.parse(@room[:room_settings])["anyoneCanStart"] | ||||||
|  |  | ||||||
|     if current_user && @room.owned_by?(current_user) |     if current_user && @room.owned_by?(current_user) | ||||||
|       @search, @order_column, @order_direction, recs = |       if current_user.highest_priority_role.can_create_rooms | ||||||
|         recordings(@room.bbb_id, @user_domain, params.permit(:search, :column, :direction), true) |         @search, @order_column, @order_direction, recs = | ||||||
|  |           recordings(@room.bbb_id, @user_domain, params.permit(:search, :column, :direction), true) | ||||||
|       @pagy, @recordings = pagy_array(recs) |  | ||||||
|  |  | ||||||
|  |         @pagy, @recordings = pagy_array(recs) | ||||||
|  |       else | ||||||
|  |         render :cant_create_rooms | ||||||
|  |       end | ||||||
|     else |     else | ||||||
|       # Get users name |       # Get users name | ||||||
|       @name = if current_user |       @name = if current_user | ||||||
| @@ -138,6 +141,21 @@ class RoomsController < ApplicationController | |||||||
|     redirect_to current_user.main_room |     redirect_to current_user.main_room | ||||||
|   end |   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 | ||||||
|  |  | ||||||
|  |     return redirect_to current_user.main_room, alert: I18n.t("room.no_room.invalid_room_uid") if @room.nil? | ||||||
|  |  | ||||||
|  |     redirect_to room_path(@room) | ||||||
|  |   end | ||||||
|  |  | ||||||
|   # POST /:room_uid/start |   # POST /:room_uid/start | ||||||
|   def start |   def start | ||||||
|     # Join the user in and start the meeting. |     # Join the user in and start the meeting. | ||||||
| @@ -275,7 +293,7 @@ class RoomsController < ApplicationController | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   def verify_user_not_admin |   def verify_user_not_admin | ||||||
|     redirect_to admins_path if current_user && current_user&.has_cached_role?(:super_admin) |     redirect_to admins_path if current_user && current_user&.has_role?(:super_admin) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def auth_required |   def auth_required | ||||||
| @@ -288,7 +306,7 @@ class RoomsController < ApplicationController | |||||||
|  |  | ||||||
|     # Does not apply to admin |     # Does not apply to admin | ||||||
|     # 15+ option is used as unlimited |     # 15+ option is used as unlimited | ||||||
|     return false if current_user&.has_cached_role?(:admin) || limit == 15 |     return false if current_user&.has_role?(:admin) || limit == 15 | ||||||
|  |  | ||||||
|     current_user.rooms.count >= limit |     current_user.rooms.count >= limit | ||||||
|   end |   end | ||||||
|   | |||||||
| @@ -144,12 +144,14 @@ class UsersController < ApplicationController | |||||||
|         errors.each { |k, v| @user.errors.add(k, v) } |         errors.each { |k, v| @user.errors.add(k, v) } | ||||||
|         render :edit, params: { settings: params[:settings] } |         render :edit, params: { settings: params[:settings] } | ||||||
|       end |       end | ||||||
|     elsif user_params[:email] != @user.email && @user.update_attributes(user_params) |     elsif user_params[:email] != @user.email && @user.update_attributes(user_params) && update_roles | ||||||
|       @user.update_attributes(email_verified: false) |       @user.update_attributes(email_verified: false) | ||||||
|  |  | ||||||
|       flash[:success] = I18n.t("info_update_success") |       flash[:success] = I18n.t("info_update_success") | ||||||
|       redirect_to redirect_path |       redirect_to redirect_path | ||||||
|     elsif @user.update_attributes(user_params) |     elsif @user.update_attributes(user_params) && update_roles | ||||||
|       update_locale(@user) |       update_locale(@user) | ||||||
|  |  | ||||||
|       flash[:success] = I18n.t("info_update_success") |       flash[:success] = I18n.t("info_update_success") | ||||||
|       redirect_to redirect_path |       redirect_to redirect_path | ||||||
|     else |     else | ||||||
| @@ -255,4 +257,65 @@ class UsersController < ApplicationController | |||||||
|  |  | ||||||
|     invitation[:present] |     invitation[:present] | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  |   # Updates as user's roles | ||||||
|  |   def update_roles | ||||||
|  |     # Check that the user can edit roles | ||||||
|  |     if current_user.highest_priority_role.can_edit_roles | ||||||
|  |       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.name) if role.send_promoted_email } | ||||||
|  |       removed_roles.each { |role| send_user_demoted_email(@user, role.name) 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 | ||||||
|   | |||||||
| @@ -78,4 +78,8 @@ module AdminsHelper | |||||||
|   def room_limit_number |   def room_limit_number | ||||||
|     Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Limit").to_i |     Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Limit").to_i | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  |   def edit_disabled | ||||||
|  |     @edit_disabled ||= @selected_role.priority <= current_user.highest_priority_role.priority | ||||||
|  |   end | ||||||
| end | end | ||||||
|   | |||||||
| @@ -107,7 +107,25 @@ module ApplicationHelper | |||||||
|   # Returns the page that the logo redirects to when clicked on |   # Returns the page that the logo redirects to when clicked on | ||||||
|   def home_page |   def home_page | ||||||
|     return root_path unless current_user |     return root_path unless current_user | ||||||
|     return admins_path if current_user.has_cached_role? :super_admin |     return admins_path if current_user.has_role? :super_admin | ||||||
|     current_user.main_room |     current_user.main_room | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  |   def role_colour(role) | ||||||
|  |     role.colour || Rails.configuration.primary_color_default | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   def translated_role_name(role) | ||||||
|  |     if role.name == "denied" | ||||||
|  |       I18n.t("roles.banned") | ||||||
|  |     elsif role.name == "pending" | ||||||
|  |       I18n.t("roles.pending") | ||||||
|  |     elsif role.name == "admin" | ||||||
|  |       I18n.t("roles.admin") | ||||||
|  |     elsif role.name == "user" | ||||||
|  |       I18n.t("roles.user") | ||||||
|  |     else | ||||||
|  |       role.name | ||||||
|  |     end | ||||||
|  |   end | ||||||
| end | end | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ module RoomsHelper | |||||||
|  |  | ||||||
|     # Does not apply to admin or users that aren't signed in |     # 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_cached_role?(:admin) || limit == 15 |     return false if current_user&.has_role?(:admin) || limit == 15 | ||||||
|  |  | ||||||
|     current_user.rooms.length >= limit |     current_user.rooms.length >= limit | ||||||
|   end |   end | ||||||
| @@ -46,7 +46,7 @@ module RoomsHelper | |||||||
|     # 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 = Setting.find_or_create_by!(provider: user_settings_provider).get_value("Room Limit").to_i | ||||||
|  |  | ||||||
|     return false if current_user&.has_cached_role?(:admin) || limit == 15 |     return false if current_user&.has_role?(:admin) || limit == 15 | ||||||
|  |  | ||||||
|     @diff = current_user.rooms.count - limit |     @diff = current_user.rooms.count - limit | ||||||
|     @diff.positive? && current_user.rooms.pluck(:id).index(room.id) + 1 > limit |     @diff.positive? && current_user.rooms.pluck(:id).index(room.id) + 1 > limit | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ module ThemingHelper | |||||||
|  |  | ||||||
|   # Returns the user's provider in the settings context |   # Returns the user's provider in the settings context | ||||||
|   def user_settings_provider |   def user_settings_provider | ||||||
|     if Rails.configuration.loadbalanced_configuration && current_user && !current_user&.has_cached_role?(:super_admin) |     if Rails.configuration.loadbalanced_configuration && current_user && !current_user&.has_role?(:super_admin) | ||||||
|       current_user.provider |       current_user.provider | ||||||
|     elsif Rails.configuration.loadbalanced_configuration |     elsif Rails.configuration.loadbalanced_configuration | ||||||
|       @user_domain |       @user_domain | ||||||
|   | |||||||
| @@ -20,4 +20,20 @@ module UsersHelper | |||||||
|   def recaptcha_enabled? |   def recaptcha_enabled? | ||||||
|     Rails.configuration.recaptcha_enabled |     Rails.configuration.recaptcha_enabled | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  |   def disabled_roles(user) | ||||||
|  |     current_user_role = current_user.highest_priority_role | ||||||
|  |  | ||||||
|  |     # Admins are able to remove the admin role from other admins | ||||||
|  |     # For all other roles they can only add/remove roles with a higher priority | ||||||
|  |     disallowed_roles = if current_user_role.name == "admin" | ||||||
|  |                           Role.editable_roles(@user_domain).where("priority < #{current_user_role.priority}") | ||||||
|  |                               .pluck(:id) | ||||||
|  |                         else | ||||||
|  |                           Role.editable_roles(@user_domain).where("priority <= #{current_user_role.priority}") | ||||||
|  |                               .pluck(:id) | ||||||
|  |                        end | ||||||
|  |  | ||||||
|  |     user.roles.by_priority.pluck(:id) | disallowed_roles | ||||||
|  |   end | ||||||
| end | end | ||||||
|   | |||||||
| @@ -35,20 +35,22 @@ class UserMailer < ApplicationMailer | |||||||
|     mail to: user.email, subject: t('reset_password.subtitle') |     mail to: user.email, subject: t('reset_password.subtitle') | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def user_promoted(user, url, image, color) |   def user_promoted(user, role, url, image, color) | ||||||
|     @url = url |     @url = url | ||||||
|     @admin_url = url + "admins" |     @admin_url = url + "admins" | ||||||
|     @image = image |     @image = image | ||||||
|     @color = color |     @color = color | ||||||
|     mail to: user.email, subject: t('mailer.user.promoted.subtitle') |     @role = role | ||||||
|  |     mail to: user.email, subject: t('mailer.user.promoted.subtitle', role: role) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def user_demoted(user, url, image, color) |   def user_demoted(user, role, url, image, color) | ||||||
|     @url = url |     @url = url | ||||||
|     @root_url = url |     @root_url = url | ||||||
|     @image = image |     @image = image | ||||||
|     @color = color |     @color = color | ||||||
|     mail to: user.email, subject: t('mailer.user.demoted.subtitle') |     @role = role | ||||||
|  |     mail to: user.email, subject: t('mailer.user.demoted.subtitle', role: role) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def invite_email(name, email, url, image, color) |   def invite_email(name, email, url, image, color) | ||||||
|   | |||||||
| @@ -24,10 +24,25 @@ class Ability | |||||||
|       cannot :manage, AdminsController |       cannot :manage, AdminsController | ||||||
|     elsif user.has_role? :super_admin |     elsif user.has_role? :super_admin | ||||||
|       can :manage, :all |       can :manage, :all | ||||||
|     elsif user.has_role? :admin |     else | ||||||
|       can :manage, :all |       highest_role = user.highest_priority_role | ||||||
|     elsif user.has_role? :user |       if highest_role.can_edit_site_settings | ||||||
|       cannot :manage, AdminsController |         can [:index, :site_settings, :server_recordings, :branding, :coloring, :coloring_lighten, :coloring_darken, | ||||||
|  |              :room_authentication, :registration_method, :room_limit, :default_recording_visibility], :admin | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       if highest_role.can_edit_roles | ||||||
|  |         can [:index, :roles, :new_role, :change_role_order, :update_role, :delete_role], :admin | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       if highest_role.can_manage_users | ||||||
|  |         can [:index, :roles, :edit_user, :promote, :demote, :ban_user, :unban_user, | ||||||
|  |              :approve, :invite], :admin | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       if !highest_role.can_edit_site_settings && !highest_role.can_edit_roles && !highest_role.can_manage_users | ||||||
|  |         cannot :manage, AdminsController | ||||||
|  |       end | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| end | end | ||||||
|   | |||||||
| @@ -19,13 +19,25 @@ | |||||||
| 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 | ||||||
|  |  | ||||||
|   belongs_to :resource, |   default_scope { order(:priority) } | ||||||
|     polymorphic: true, |   scope :by_priority, -> { order(:priority) } | ||||||
|     optional: true |   scope :editable_roles, ->(provider) { where(provider: provider).where.not(name: %w[super_admin denied pending]) } | ||||||
|  |  | ||||||
|   validates :resource_type, |   RESERVED_ROLE_NAMES = %w[super_admin admin pending denied user] | ||||||
|     inclusion: { in: Rolify.resource_types }, |  | ||||||
|     allow_nil: true |  | ||||||
|  |  | ||||||
|   scopify |   def self.duplicate_name(name, provider) | ||||||
|  |     RESERVED_ROLE_NAMES.include?(name) || Role.exists?(name: name, provider: provider) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   def self.create_default_roles(provider) | ||||||
|  |     Role.create(name: "user", provider: provider, priority: 1, can_create_rooms: true, colour: "#868e96") | ||||||
|  |     Role.create(name: "admin", provider: provider, priority: 0, can_create_rooms: true, send_promoted_email: true, | ||||||
|  |       send_demoted_email: true, can_edit_site_settings: true, | ||||||
|  |       can_edit_roles: true, can_manage_users: true, colour: "#f1c40f") | ||||||
|  |     Role.create(name: "pending", provider: provider, priority: -1, colour: "#17a2b8") | ||||||
|  |     Role.create(name: "denied", provider: provider, priority: -1, colour: "#343a40") | ||||||
|  |     Role.create(name: "super_admin", provider: provider, priority: -2, can_create_rooms: true, | ||||||
|  |       send_promoted_email: true, send_demoted_email: true, can_edit_site_settings: true, | ||||||
|  |       can_edit_roles: true, can_manage_users: true, colour: "#cd201f") | ||||||
|  |   end | ||||||
| end | end | ||||||
|   | |||||||
| @@ -19,7 +19,6 @@ | |||||||
| require 'bbb_api' | require 'bbb_api' | ||||||
|  |  | ||||||
| class User < ApplicationRecord | class User < ApplicationRecord | ||||||
|   rolify |  | ||||||
|   include ::BbbApi |   include ::BbbApi | ||||||
|  |  | ||||||
|   attr_accessor :reset_token |   attr_accessor :reset_token | ||||||
| @@ -33,6 +32,8 @@ 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 | ||||||
|  |  | ||||||
|   validates :name, length: { maximum: 256 }, presence: true |   validates :name, length: { maximum: 256 }, presence: true | ||||||
|   validates :provider, presence: true |   validates :provider, presence: true | ||||||
|   validate :check_if_email_can_be_blank |   validate :check_if_email_can_be_blank | ||||||
| @@ -59,6 +60,7 @@ class User < ApplicationRecord | |||||||
|         u.username = auth_username(auth) unless u.username |         u.username = auth_username(auth) unless u.username | ||||||
|         u.email = auth_email(auth) |         u.email = auth_email(auth) | ||||||
|         u.image = auth_image(auth) unless u.image |         u.image = auth_image(auth) unless u.image | ||||||
|  |         auth_roles(u, auth) | ||||||
|         u.email_verified = true |         u.email_verified = true | ||||||
|         u.save! |         u.save! | ||||||
|       end |       end | ||||||
| @@ -99,6 +101,18 @@ class User < ApplicationRecord | |||||||
|         auth['info']['image'] |         auth['info']['image'] | ||||||
|       end |       end | ||||||
|     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) | ||||||
| @@ -112,16 +126,16 @@ class User < ApplicationRecord | |||||||
|  |  | ||||||
|     search_query = "" |     search_query = "" | ||||||
|     role_search_param = "" |     role_search_param = "" | ||||||
|     if role.present? |     if role.nil? | ||||||
|       search_query = "(users.name LIKE :search OR email LIKE :search OR username LIKE :search" \ |  | ||||||
|                     " OR users.#{created_at_query} LIKE :search OR provider LIKE :search)" \ |  | ||||||
|                     " AND roles.name = :roles_search" |  | ||||||
|       role_search_param = role |  | ||||||
|     else |  | ||||||
|       search_query = "users.name LIKE :search OR email LIKE :search OR username LIKE :search" \ |       search_query = "users.name LIKE :search OR email LIKE :search OR username LIKE :search" \ | ||||||
|                     " OR users.#{created_at_query} LIKE :search OR provider LIKE :search" \ |                     " OR users.#{created_at_query} LIKE :search OR users.provider LIKE :search" \ | ||||||
|                     " OR roles.name LIKE :roles_search" |                     " OR roles.name LIKE :roles_search" | ||||||
|       role_search_param = "%#{string}%".downcase |       role_search_param = "%#{string}%" | ||||||
|  |     else | ||||||
|  |       search_query = "(users.name LIKE :search OR email LIKE :search OR username LIKE :search" \ | ||||||
|  |                     " OR users.#{created_at_query} LIKE :search OR users.provider LIKE :search)" \ | ||||||
|  |                     " AND roles.name = :roles_search" | ||||||
|  |       role_search_param = role.name | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     search_param = "%#{string}%" |     search_param = "%#{string}%" | ||||||
| @@ -204,17 +218,14 @@ class User < ApplicationRecord | |||||||
|  |  | ||||||
|   def admin_of?(user) |   def admin_of?(user) | ||||||
|     if Rails.configuration.loadbalanced_configuration |     if Rails.configuration.loadbalanced_configuration | ||||||
|       # Pulls in the user roles if they weren't request in the original request |       if has_role? :super_admin | ||||||
|       # So the has_cached_role? doesn't always return false |  | ||||||
|       user.roles |  | ||||||
|       if has_cached_role? :super_admin |  | ||||||
|         id != user.id |         id != user.id | ||||||
|       else |       else | ||||||
|         (has_cached_role? :admin) && (id != user.id) && (provider == user.provider) && |         highest_priority_role.can_manage_users && (id != user.id) && (provider == user.provider) && | ||||||
|           (!user.has_cached_role? :super_admin) |           (!user.has_role? :super_admin) | ||||||
|       end |       end | ||||||
|     else |     else | ||||||
|       ((has_cached_role? :admin) || (has_cached_role? :super_admin)) && (id != user.id) |       (highest_priority_role.can_manage_users || (has_role? :super_admin)) && (id != user.id) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
| @@ -228,6 +239,50 @@ class User < ApplicationRecord | |||||||
|     SecureRandom.urlsafe_base64 |     SecureRandom.urlsafe_base64 | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  |   # role functions | ||||||
|  |   def highest_priority_role | ||||||
|  |     roles.by_priority.first | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   def add_role(role) | ||||||
|  |     unless has_role?(role) | ||||||
|  |       role_provider = Rails.configuration.loadbalanced_configuration ? provider : "greenlight" | ||||||
|  |  | ||||||
|  |       roles << Role.find_or_create_by(name: role, provider: role_provider) | ||||||
|  |  | ||||||
|  |       save! | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   def remove_role(role) | ||||||
|  |     if has_role?(role) | ||||||
|  |       role_provider = Rails.configuration.loadbalanced_configuration ? provider : "greenlight" | ||||||
|  |  | ||||||
|  |       roles.delete(Role.find_by(name: role, provider: role_provider)) | ||||||
|  |       save! | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   # This rule is disabled as the function name must be has_role? | ||||||
|  |   # rubocop:disable Naming/PredicateName | ||||||
|  |   def has_role?(role) | ||||||
|  |     # rubocop:enable Naming/PredicateName | ||||||
|  |     roles.exists?(name: role) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   def self.with_role(role) | ||||||
|  |     User.all_users_with_roles.where(roles: { name: role }) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   def self.without_role(role) | ||||||
|  |     User.where.not(id: with_role(role).pluck(:id)) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   def self.all_users_with_roles | ||||||
|  |     User.joins("INNER JOIN users_roles ON users_roles.user_id = users.id INNER JOIN roles " \ | ||||||
|  |       "ON roles.id = users_roles.role_id") | ||||||
|  |   end | ||||||
|  |  | ||||||
|   private |   private | ||||||
|  |  | ||||||
|   def create_reset_activation_digest(token) |   def create_reset_activation_digest(token) | ||||||
| @@ -251,6 +306,10 @@ class User < ApplicationRecord | |||||||
|  |  | ||||||
|   # Initialize the user to use the default user role |   # Initialize the user to use the default user role | ||||||
|   def assign_default_role |   def assign_default_role | ||||||
|  |     role_provider = Rails.configuration.loadbalanced_configuration ? provider : "greenlight" | ||||||
|  |  | ||||||
|  |     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 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,13 +14,24 @@ | |||||||
| %> | %> | ||||||
|  |  | ||||||
| <div class="list-group list-group-transparent mb-0"> | <div class="list-group list-group-transparent mb-0"> | ||||||
|   <%= link_to admins_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "index"}" do %> |   <% highest_role = current_user.highest_priority_role %> | ||||||
|     <span class="icon mr-3"><i class="fas fa-users"></i></span><%= t("administrator.users.title") %> |   <% highest_role.name %> | ||||||
|  |   <% if highest_role.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 %> | ||||||
|  |       <span class="icon mr-3"><i class="fas fa-users"></i></span><%= t("administrator.users.title") %> | ||||||
|  |     <% end %> | ||||||
|   <% end %> |   <% end %> | ||||||
|   <%= link_to admin_site_settings_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "site_settings"}" do %> |   <% if highest_role.can_edit_site_settings || highest_role.name == "super_admin" %> | ||||||
|     <span class="icon mr-4"><i class="fas fa-cogs"></i></span><%= t("administrator.site_settings.title") %> |     <%= 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") %> | ||||||
|  |     <% end %> | ||||||
|  |     <%= link_to admin_site_settings_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "site_settings"}" do %> | ||||||
|  |       <span class="icon mr-4"><i class="fas fa-cogs"></i></span><%= t("administrator.site_settings.title") %> | ||||||
|  |     <% end %> | ||||||
|   <% end %> |   <% end %> | ||||||
|   <%= link_to admin_recordings_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "server_recordings"}" do %> |   <% if highest_role.can_edit_roles  || highest_role.name == "super_admin" %> | ||||||
|     <span class="icon mr-4"><i class="fas fa-video"></i></i></span><%= t("administrator.recordings.title") %> |     <%= 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") %> | ||||||
|  |     <% end %> | ||||||
|   <% end %> |   <% end %> | ||||||
| </div> | </div> | ||||||
							
								
								
									
										94
									
								
								app/views/admins/components/_roles.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								app/views/admins/components/_roles.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | |||||||
|  | <% | ||||||
|  | # 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="container"> | ||||||
|  |   <div class="row"> | ||||||
|  |     <div class="col-lg-3 mb-4"> | ||||||
|  |         <div class="list-group list-group-transparent mb-0"> | ||||||
|  |             <div id="rolesSelect" data-url="<%= admin_roles_order_path %>"> | ||||||
|  |                 <% @roles.each do |role| %> | ||||||
|  |                     <%= link_to admin_roles_path(selected_role: role.id),  | ||||||
|  |                     class: "#{"sort-disabled" if role.name == "user" || role.name == "admin" || role.priority <= current_user.highest_priority_role.priority } dropdown-item list-group-item list-group-item-action #{"active" if @selected_role.id == role.id}",  | ||||||
|  |                     id: dom_id(role) do %> | ||||||
|  |                         <%= translated_role_name(role) %> | ||||||
|  |                     <% end %> | ||||||
|  |                 <% end %> | ||||||
|  |             </div> | ||||||
|  |             <%= link_to "#", id: "newRoleButton", class: "list-group-item list-group-item-action", "data-toggle" => "modal", "data-target" => '#createRoleModal' do %> | ||||||
|  |                 <span class="icon mr-4"><i class="fas fa-plus-circle"></i></span><%= t("administrator.roles.new_role") %> | ||||||
|  |             <% end %> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |     <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| %> | ||||||
|  |             <%= 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.hidden_field :colour, id: "role-colour", value: role_colour(@selected_role) %> | ||||||
|  |             <div class="form-group"> | ||||||
|  |                 <label class="form-label"><%= t("administrator.roles.colour.title") %></label> | ||||||
|  |                 <label class="form-label text-muted"><%= t("administrator.roles.colour.info") %></label> | ||||||
|  |                 <div class="color-inputs"> | ||||||
|  |                     <div id="role-colorinput-regular" class="btn role-colour-picker" data-disabled="<%= edit_disabled %>" data-colour="<%= role_colour(@selected_role) %>"> | ||||||
|  |                         <%= t("administrator.site_settings.color.regular") %> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |  | ||||||
|  |             <label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block"> | ||||||
|  |                 <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 %> | ||||||
|  |                 <span class="custom-switch-indicator float-right"></span> | ||||||
|  |             </label> | ||||||
|  |             <label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block"> | ||||||
|  |                 <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 %> | ||||||
|  |                 <span class="custom-switch-indicator float-right"></span> | ||||||
|  |             </label> | ||||||
|  |             <label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block"> | ||||||
|  |                 <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 %> | ||||||
|  |                 <span class="custom-switch-indicator float-right"></span> | ||||||
|  |             </label> | ||||||
|  |             <label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block"> | ||||||
|  |                 <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 %> | ||||||
|  |                 <span class="custom-switch-indicator float-right"></span> | ||||||
|  |             </label> | ||||||
|  |             <label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block"> | ||||||
|  |                 <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 %> | ||||||
|  |                 <span class="custom-switch-indicator float-right"></span> | ||||||
|  |             </label> | ||||||
|  |             <label class="custom-switch pl-0 mt-3 mb-3 w-100 text-left d-inline-block"> | ||||||
|  |                 <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 %> | ||||||
|  |                 <span class="custom-switch-indicator float-right"></span> | ||||||
|  |             </label> | ||||||
|  |  | ||||||
|  |             <div class="mt-4"> | ||||||
|  |                 <%= f.submit t("update"), class: "btn btn-primary float-right ml-2 mb-2", disabled: edit_disabled %> | ||||||
|  |                 <% if @selected_role.name != "user" && @selected_role.name != "admin" && !edit_disabled %> | ||||||
|  |                     <%= link_to admin_delete_role_path(@selected_role.id), method: :delete, class: "float-right btn btn-danger" do %> | ||||||
|  |                         <%= t("administrator.roles.delete") %> | ||||||
|  |                     <% end %> | ||||||
|  |                 <% end %> | ||||||
|  |             </div> | ||||||
|  |         <% end %> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  |  | ||||||
|  | <%= render "shared/modals/create_role_modal" %> | ||||||
| @@ -28,7 +28,7 @@ | |||||||
| # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. | # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. | ||||||
| %> | %> | ||||||
|  |  | ||||||
| <% if @role.present? %> | <% unless @role.nil? %> | ||||||
|   <%= render "shared/components/admins_tags" %> |   <%= render "shared/components/admins_tags" %> | ||||||
| <% end %> | <% end %> | ||||||
|  |  | ||||||
| @@ -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", roles: roles %> |                       <%= render "shared/components/admins_role", role: user.highest_priority_role %> | ||||||
|                     </td> |                     </td> | ||||||
|                     <td> |                     <td> | ||||||
|                       <% if roles.include?("pending") %> |                       <% if roles.include?("pending") %> | ||||||
| @@ -122,16 +122,6 @@ | |||||||
|                               <button class= "delete-user dropdown-item" data-toggle="modal" data-target="#deleteAccountModal"> |                               <button class= "delete-user dropdown-item" data-toggle="modal" data-target="#deleteAccountModal"> | ||||||
|                                 <i class="dropdown-icon fas fa-user-minus"></i> <%= t("administrator.users.settings.delete") %> |                                 <i class="dropdown-icon fas fa-user-minus"></i> <%= t("administrator.users.settings.delete") %> | ||||||
|                               </button> |                               </button> | ||||||
|  |  | ||||||
|                               <% if roles.include?("admin") %> |  | ||||||
|                                 <%= button_to admin_demote_path(user_uid: user.uid), class: "dropdown-item" do %> |  | ||||||
|                                   <i class="dropdown-icon fas fa-level-down-alt"></i> <%= t("administrator.users.settings.demote") %> |  | ||||||
|                                 <% end %> |  | ||||||
|                               <% elsif roles.include?("user") %> |  | ||||||
|                                 <%= button_to admin_promote_path(user_uid: user.uid), class: "dropdown-item" do %> |  | ||||||
|                                   <i class="dropdown-icon fas fa-level-up-alt"></i> <%= t("administrator.users.settings.promote") %> |  | ||||||
|                                 <% end %> |  | ||||||
|                               <% end %> |  | ||||||
|                               <%= button_to admin_ban_path(user_uid: user.uid), class: "dropdown-item" do %> |                               <%= button_to admin_ban_path(user_uid: user.uid), class: "dropdown-item" do %> | ||||||
|                                 <i class="dropdown-icon fas fa-lock"></i> <%= t("administrator.users.settings.ban") %> |                                 <i class="dropdown-icon fas fa-lock"></i> <%= t("administrator.users.settings.ban") %> | ||||||
|                               <% end %> |                               <% end %> | ||||||
|   | |||||||
							
								
								
									
										27
									
								
								app/views/admins/roles.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/views/admins/roles.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | <% | ||||||
|  | # 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="container pt-6"> | ||||||
|  |   <%= render "shared/components/subtitle", subtitle: t("administrator.title"), search: false %> | ||||||
|  |  | ||||||
|  |   <div class="row"> | ||||||
|  |     <div class="col-lg-3 mb-4"> | ||||||
|  |       <%= render "admins/components/menu_buttons" %> | ||||||
|  |     </div> | ||||||
|  |     <div class="col-lg-9"> | ||||||
|  |         <%= render "admins/components/setting_view", setting_id: "roles", setting_title: t("administrator.roles.title"), search: false %> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
							
								
								
									
										44
									
								
								app/views/rooms/cant_create_rooms.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/views/rooms/cant_create_rooms.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
|  | <% | ||||||
|  | # 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 id="cant-create-room-wrapper" class="background h-100 cant-create-room-wrapper"> | ||||||
|  |     <div class="container h-100"> | ||||||
|  |         <div class="row h-100 align-items-center"> | ||||||
|  |             <div class="offset-3 col-6 offset-3"> | ||||||
|  |                 <div class="card"> | ||||||
|  |                     <div class="card-status bg-primary"></div> | ||||||
|  |                     <div class="card-header"> | ||||||
|  |                         <h3 class="card-title"><%= t("room.no_room.title") %></h3> | ||||||
|  |                     </div> | ||||||
|  |                     <div class="card-body"> | ||||||
|  |                         <%= form_for(:join_room, url: join_room_path) do |f| %> | ||||||
|  |                             <div class="input-icon mb-2"> | ||||||
|  |                                 <span class="input-icon-addon"> | ||||||
|  |                                     <i class="fas fa-link"></i> | ||||||
|  |                                 </span> | ||||||
|  |                                 <%= f.text_field :url, class: "form-control", value: "", placeholder: t("room.no_room.placeholder"), required: "" %> | ||||||
|  |                             </div> | ||||||
|  |                             <div class="mt-4"> | ||||||
|  |                                 <%= f.submit t("room.join"), class:"btn btn-primary btn-block" %> | ||||||
|  |                             </div> | ||||||
|  |                         <% end %> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
| @@ -23,7 +23,7 @@ | |||||||
|       <div class="d-flex ml-auto"> |       <div class="d-flex ml-auto"> | ||||||
|         <% if current_user %> |         <% if current_user %> | ||||||
|  |  | ||||||
|           <% if current_user.has_cached_role? :super_admin %> |           <% if current_user.has_role? :super_admin %> | ||||||
|             <% admins_page = params[:controller] == "admins" && params[:action] == "index" ? "active" : "" %> |             <% admins_page = params[:controller] == "admins" && params[:action] == "index" ? "active" : "" %> | ||||||
|             <%= link_to admins_path, class: "px-3 mx-1 mt-1 header-nav #{admins_page}" do %> |             <%= link_to admins_path, class: "px-3 mx-1 mt-1 header-nav #{admins_page}" do %> | ||||||
|               <i class="fas fa-home pr-1 "></i> <%= t("header.dropdown.home") %> |               <i class="fas fa-home pr-1 "></i> <%= t("header.dropdown.home") %> | ||||||
| @@ -34,9 +34,11 @@ | |||||||
|               <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 %> | ||||||
|  |  | ||||||
|             <% all_rec_page = params[:controller] == "users" && params[:action] == "recordings" ? "active" : "" %> |             <% if current_user.highest_priority_role.can_create_rooms %> | ||||||
|             <%= link_to get_user_recordings_path(current_user), class: "px-3 mx-1 mt-1 header-nav #{all_rec_page}" do %> |               <% all_rec_page = params[:controller] == "users" && params[:action] == "recordings" ? "active" : "" %> | ||||||
|               <i class="fas fa-video pr-1"></i> <%= t("header.all_recordings") %> |               <%= 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") %> | ||||||
|  |               <% end %> | ||||||
|             <% end %> |             <% end %> | ||||||
|           <% end %> |           <% end %> | ||||||
|  |  | ||||||
| @@ -56,10 +58,19 @@ | |||||||
|               <%= link_to edit_user_path(current_user), class: "dropdown-item"  do %> |               <%= link_to edit_user_path(current_user), class: "dropdown-item"  do %> | ||||||
|                 <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 %> | ||||||
|               <% if current_user.has_cached_role? :admin %> |               <% highest_role = current_user.highest_priority_role %> | ||||||
|  |               <% if highest_role.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 %> | ||||||
|  |                 <%= 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") %> | ||||||
|  |                 <% end %> | ||||||
|  |               <% elsif highest_role.can_edit_roles%> | ||||||
|  |                 <%= 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") %> | ||||||
|  |                 <% end %> | ||||||
|               <% end %> |               <% end %> | ||||||
|               <div class="dropdown-divider"></div> |               <div class="dropdown-divider"></div> | ||||||
|               <a class="dropdown-item" href="http://docs.bigbluebutton.org/install/greenlight-v2.html" target="_blank"> |               <a class="dropdown-item" href="http://docs.bigbluebutton.org/install/greenlight-v2.html" target="_blank"> | ||||||
|   | |||||||
| @@ -13,24 +13,6 @@ | |||||||
| # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. | # with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. | ||||||
| %> | %> | ||||||
|  |  | ||||||
| <% if roles.include?("denied")%> | <button style="<%= "background-color: #{role_colour(role)};border-color: #{role_colour(role)}" %>" class="user-role btn btn-sm" onclick="filterRole('<%= role.name %>')"> | ||||||
|   <button class="user-role btn btn-sm btn-gray-dark" onclick="filterRole('denied')"> |   <%= translated_role_name(role) %> | ||||||
|     <%= t("roles.banned") %> | </button> | ||||||
|   </button> |  | ||||||
| <% elsif roles.include?("pending") %> |  | ||||||
|   <button class="user-role btn btn-sm btn-cyan" onclick="filterRole('pending')"> |  | ||||||
|     <%= t("roles.pending") %> |  | ||||||
|   </button> |  | ||||||
| <% elsif roles.include?("super_admin") %> |  | ||||||
|   <button class="user-role btn btn-sm btn-red" onclick="filterRole('super_admin')"> |  | ||||||
|     <%= t("roles.super_admin") %> |  | ||||||
|   </button> |  | ||||||
| <% elsif roles.include?("admin") %> |  | ||||||
|   <button class="user-role btn btn-sm btn-yellow" onclick="filterRole('admin')"> |  | ||||||
|     <%= t("roles.administrator") %> |  | ||||||
|   </button> |  | ||||||
| <% else %> |  | ||||||
|   <button class="user-role btn btn-sm btn-gray" onclick="filterRole('user')"> |  | ||||||
|     <%= t("roles.user") %> |  | ||||||
|   </button> |  | ||||||
| <% end %> |  | ||||||
| @@ -16,42 +16,12 @@ | |||||||
| <div class="form-group"> | <div class="form-group"> | ||||||
|   <div class="row"> |   <div class="row"> | ||||||
|     <div class="col-12 tags"> |     <div class="col-12 tags"> | ||||||
|       <% if @role == "denied"%> |       <span style="<%= "background-color: #{role_colour(@role)};border-color: #{role_colour(@role)};" %>" class="tag custom-role-tag"> | ||||||
|         <span class="tag tag-gray-dark"> |         <%= translated_role_name(@role) %> | ||||||
|           <%= t("roles.banned") %> |         <a class="tag-addon clear-role"> | ||||||
|           <a class="tag-addon clear-role"> |           <i class="fas fa-times"></i> | ||||||
|             <i class="fas fa-times"></i> |         </a> | ||||||
|           </a> |       </span> | ||||||
|         </span> |  | ||||||
|       <% elsif @role == "pending" %> |  | ||||||
|         <span class="tag tag-cyan"> |  | ||||||
|           <%= t("roles.pending") %> |  | ||||||
|           <a class="tag-addon clear-role"> |  | ||||||
|             <i class="fas fa-times"></i> |  | ||||||
|           </a> |  | ||||||
|         </span> |  | ||||||
|       <% elsif @role == "super_admin" %> |  | ||||||
|         <span class="tag tag-red"> |  | ||||||
|           <%= t("roles.super_admin") %> |  | ||||||
|           <a class="tag-addon clear-role"> |  | ||||||
|             <i class="fas fa-times"></i> |  | ||||||
|           </a> |  | ||||||
|         </span> |  | ||||||
|       <% elsif @role == "admin" %> |  | ||||||
|         <span class="tag tag-yellow"> |  | ||||||
|           <%= t("roles.administrator") %> |  | ||||||
|           <a class="tag-addon clear-role"> |  | ||||||
|             <i class="fas fa-times"></i> |  | ||||||
|           </a> |  | ||||||
|         </span> |  | ||||||
|       <% else %> |  | ||||||
|         <span class="tag tag-gray"> |  | ||||||
|           <%= t("roles.user") %> |  | ||||||
|           <a class="tag-addon clear-role"> |  | ||||||
|             <i class="fas fa-times"></i> |  | ||||||
|           </a> |  | ||||||
|         </span> |  | ||||||
|       <% end %> |  | ||||||
|     </div> |     </div> | ||||||
|   </div> |   </div> | ||||||
| </div> | </div> | ||||||
							
								
								
									
										44
									
								
								app/views/shared/modals/_create_role_modal.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/views/shared/modals/_create_role_modal.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | <% | ||||||
|  | # 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="modal fade" id="createRoleModal" tabindex="-1" role="dialog"> | ||||||
|  |   <div class="modal-dialog modal-dialog-centered" role="document"> | ||||||
|  |     <div class="modal-content text-center"> | ||||||
|  |       <div class="modal-body"> | ||||||
|  |         <div class="card-body p-6"> | ||||||
|  |           <div class="card-title"> | ||||||
|  |             <h3><%= t("modal.create_role.title") %></h3> | ||||||
|  |           </div> | ||||||
|  |  | ||||||
|  |           <%= form_for(:role, url: admin_new_role_path) do |f| %> | ||||||
|  |             <div class="input-icon mb-2"> | ||||||
|  |               <span class="input-icon-addon"> | ||||||
|  |                 <i class="fas fa-user-tag"></i> | ||||||
|  |               </span> | ||||||
|  |               <%= f.text_field :name, id: "createRoleName", class: "form-control text-center", placeholder: t("modal.create_role.name_placeholder"), autocomplete: :off, required: true %> | ||||||
|  |               <div class="invalid-feedback text-left"><%= t("modal.create_role.not_blank") %></div> | ||||||
|  |             </div> | ||||||
|  |             <div class="mt-4"> | ||||||
|  |                 <%= f.submit t("modal.create_role.create"), class: "btn btn-primary btn-block" %> | ||||||
|  |             </div> | ||||||
|  |           <% end %> | ||||||
|  |         </div> | ||||||
|  |         <div class="card-footer"> | ||||||
|  |           <p><%= t("modal.create_role.footer_text") %></p> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
| @@ -38,6 +38,28 @@ | |||||||
|     <%= f.label t("settings.account.language"), class: "form-label" %> |     <%= f.label t("settings.account.language"), class: "form-label" %> | ||||||
|     <%= f.select :language, language_options, {}, { class: "form-control custom-select" } %> |     <%= f.select :language, language_options, {}, { class: "form-control custom-select" } %> | ||||||
|  |  | ||||||
|  |     <% current_user_role = current_user.highest_priority_role %> | ||||||
|  |     <br> | ||||||
|  |     <br> | ||||||
|  |     <%= f.label t("settings.account.roles"), class: "form-label" %> | ||||||
|  |     <div id="role-tag-container" class="tags mb-1"> | ||||||
|  |       <% @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"> | ||||||
|  |           <%= translated_role_name(role) %> | ||||||
|  |           <% if (current_user_role.can_edit_roles || 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"> | ||||||
|  |               <i data-role-id="<%= role.id %>" class="fas fa-times"></i> | ||||||
|  |             </a> | ||||||
|  |           <% end %> | ||||||
|  |         </span> | ||||||
|  |       <% end %> | ||||||
|  |     </div> | ||||||
|  |     <% if current_user_role.can_edit_roles || current_user_role.name == "super_admin" %> | ||||||
|  |       <% 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" } %> | ||||||
|  |     <% end %> | ||||||
|  |     <%= f.hidden_field :role_ids, id: "user_role_ids", value: @user.roles.by_priority.pluck(:id) %> | ||||||
|  |  | ||||||
|     <%= 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"> | ||||||
|       <div class="col-2"> |       <div class="col-2"> | ||||||
|   | |||||||
| @@ -21,11 +21,11 @@ | |||||||
|     <%= image_tag(@image, height: '70') %> |     <%= image_tag(@image, height: '70') %> | ||||||
|  |  | ||||||
|     <h1 style="margin-bottom:30px"> |     <h1 style="margin-bottom:30px"> | ||||||
|       <%= t('mailer.user.demoted.subtitle') %> |       <%= t('mailer.user.demoted.subtitle', role: @role) %> | ||||||
|     </h1> |     </h1> | ||||||
|  |  | ||||||
|     <p> |     <p> | ||||||
|       <%= t('mailer.user.demoted.info', url: @url) %> |       <%= t('mailer.user.demoted.info', url: @url, role: @role) %> | ||||||
|     </p> |     </p> | ||||||
|  |  | ||||||
|     <p style="margin-bottom:45px;"> |     <p style="margin-bottom:45px;"> | ||||||
|   | |||||||
| @@ -17,9 +17,9 @@ | |||||||
| %> | %> | ||||||
|  |  | ||||||
|  |  | ||||||
| <%= t('mailer.user.demoted.subtitle') %> | <%= t('mailer.user.demoted.subtitle', role: @role) %> | ||||||
|  |  | ||||||
| <%= t('mailer.user.demoted.info', url: @url) %> | <%= t('mailer.user.demoted.info', url: @url, role: @role) %> | ||||||
|  |  | ||||||
| <%= t('mailer.user.demoted.more-info') %> | <%= t('mailer.user.demoted.more-info') %> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,15 +21,15 @@ | |||||||
|     <%= image_tag(@image, height: '70') %> |     <%= image_tag(@image, height: '70') %> | ||||||
|  |  | ||||||
|     <h1 style="margin-bottom:30px"> |     <h1 style="margin-bottom:30px"> | ||||||
|       <%= t('mailer.user.promoted.subtitle') %> |       <%= t('mailer.user.promoted.subtitle', role: @role) %> | ||||||
|     </h1> |     </h1> | ||||||
|  |  | ||||||
|     <p> |     <p> | ||||||
|       <%= t('mailer.user.promoted.info', url: @url) %> |       <%= t('mailer.user.promoted.info', url: @url, role: @role) %> | ||||||
|     </p> |     </p> | ||||||
|  |  | ||||||
|     <p style="margin-bottom:45px;"> |     <p style="margin-bottom:45px;"> | ||||||
|       <%= t('mailer.user.promoted.more-info') %> |       <%= t('mailer.user.promoted.more-info', url: @url) %> | ||||||
|     </p> |     </p> | ||||||
|  |  | ||||||
|     <a style="background: <%= @color %>;color: #ffffff; padding: 10px 15px; box-shadow: 0 2px 4px 0 rgba(0,0,0,.25);border: 1px solid transparent;text-decoration:none;" href="<%= @admin_url %>"> |     <a style="background: <%= @color %>;color: #ffffff; padding: 10px 15px; box-shadow: 0 2px 4px 0 rgba(0,0,0,.25);border: 1px solid transparent;text-decoration:none;" href="<%= @admin_url %>"> | ||||||
|   | |||||||
| @@ -17,10 +17,10 @@ | |||||||
| %> | %> | ||||||
|  |  | ||||||
|  |  | ||||||
| <%= t('mailer.user.promoted.subtitle') %> | <%= t('mailer.user.promoted.subtitle', role: @role) %> | ||||||
|  |  | ||||||
| <%= t('mailer.user.promoted.info', url: @url) %> | <%= t('mailer.user.promoted.info', url: @url, role: @role) %> | ||||||
|  |  | ||||||
| <%= t('mailer.user.promoted.more-info') %> | <%= t('mailer.user.promoted.more-info', url: @url) %> | ||||||
|  |  | ||||||
| <%= @admin_url %> | <%= @admin_url %> | ||||||
|   | |||||||
| @@ -1,12 +0,0 @@ | |||||||
| # frozen_string_literal: true |  | ||||||
|  |  | ||||||
| Rolify.configure do |config| |  | ||||||
|   # By default ORM adapter is ActiveRecord. uncomment to use mongoid |  | ||||||
|   # config.use_mongoid |  | ||||||
|  |  | ||||||
|   # Dynamic shortcuts for User class (user.is_admin? like methods). Default is: false |  | ||||||
|   # config.use_dynamic_shortcuts |  | ||||||
|  |  | ||||||
|   # Configuration to remove roles from database once the last resource is removed. Default is: true |  | ||||||
|   # config.remove_role_if_empty = false |  | ||||||
| end |  | ||||||
| @@ -80,6 +80,27 @@ en: | |||||||
|     recordings: |     recordings: | ||||||
|       title: Server Recordings |       title: Server Recordings | ||||||
|       no_recordings: This server has no recordings. |       no_recordings: This server has no recordings. | ||||||
|  |     roles: | ||||||
|  |       can_create_rooms: Can create rooms | ||||||
|  |       delete: Delete the role | ||||||
|  |       duplicate_name: The role name you provided was a duplicate. All role names must be unique | ||||||
|  |       empty_name: All roles must have a non empty name | ||||||
|  |       invalid_order: The user role must be the lowest priority role and the admin role must be the highest priority role | ||||||
|  |       invalid_update: You can't update a role with a higher priority than your own role | ||||||
|  |       name: Role Name | ||||||
|  |       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. | ||||||
|  |       title: Roles | ||||||
|  |       promote_email: Send an email to users when they are assigned this role | ||||||
|  |       demote_email: Send an email to users when they are removed from this role | ||||||
|  |       edit_site_settings: Allow users with this role to edit site settings | ||||||
|  |       edit_roles: Allow users with this role to edit other roles | ||||||
|  |       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_removal: You can't remove a role with a higher priority than your own | ||||||
|  |       colour: | ||||||
|  |         title: Role Colour | ||||||
|  |         info: Set the colour that will be associated with the role | ||||||
|     title: Organization Settings |     title: Organization Settings | ||||||
|     users: |     users: | ||||||
|       invite: Invite User |       invite: Invite User | ||||||
| @@ -90,9 +111,8 @@ en: | |||||||
|         decline: Decline |         decline: Decline | ||||||
|         ban: Ban User |         ban: Ban User | ||||||
|         delete: Delete |         delete: Delete | ||||||
|         demote: Demote to User |  | ||||||
|         edit: Edit |         edit: Edit | ||||||
|         promote: Promote to Admin |         edit_roles: Edit the user roles | ||||||
|         unban: Unban User |         unban: Unban User | ||||||
|       table: |       table: | ||||||
|         authenticator: Authenticator |         authenticator: Authenticator | ||||||
| @@ -226,10 +246,10 @@ en: | |||||||
|         subject: Account Approved |         subject: Account Approved | ||||||
|         username: Your username is %{email}. |         username: Your username is %{email}. | ||||||
|       demoted: |       demoted: | ||||||
|         info: You are no longer an administrator on %{url}. |         info: You are no longer an %{role} on %{url}. | ||||||
|         more-info: You now have the same privileges as a regular user and will no longer be able to access any of the Administrator settings. |         more-info: You now have the same privileges as a regular user. | ||||||
|         root_link: Sign In |         root_link: Sign In | ||||||
|         subtitle: Administrator Rights Rescinded |         subtitle: "%{role} Rights Rescinded" | ||||||
|       invite: |       invite: | ||||||
|         info: You have been invited to your own personal space by %{name} |         info: You have been invited to your own personal space by %{name} | ||||||
|         signup_info: To signup using your email, click the button below and follow the steps. |         signup_info: To signup using your email, click the button below and follow the steps. | ||||||
| @@ -250,9 +270,9 @@ en: | |||||||
|         ignore: You can safely ignore this email if you did not request a password reset. |         ignore: You can safely ignore this email if you did not request a password reset. | ||||||
|       promoted: |       promoted: | ||||||
|         admins_link: Visit the Organization Page |         admins_link: Visit the Organization Page | ||||||
|         info: You are now an administrator on %{url}. |         info: You are now an %{role} on %{url}. | ||||||
|         more-info: As an administrator, you can manage users, their role and configure your site settings by changing the logo and brand colour. |         more-info: To view your new abilities please visit %{url}. | ||||||
|         subtitle: Administrator Rights Granted |         subtitle: "%{role} Rights Granted" | ||||||
|       verify_email: |       verify_email: | ||||||
|         welcome: Welcome to your personal space, %{name}! |         welcome: Welcome to your personal space, %{name}! | ||||||
|         success: Leveraging %{bigbluebutton}, you can create your own rooms to host sessions and collaborate with others. |         success: Leveraging %{bigbluebutton}, you can create your own rooms to host sessions and collaborate with others. | ||||||
| @@ -263,6 +283,12 @@ en: | |||||||
|         thanks: Thanks for joining and have a great day! |         thanks: Thanks for joining and have a great day! | ||||||
|   max_concurrent: The maximum number of concurrent sessions allowed has been reached! |   max_concurrent: The maximum number of concurrent sessions allowed has been reached! | ||||||
|   modal: |   modal: | ||||||
|  |     create_role: | ||||||
|  |       create: Create a new Role | ||||||
|  |       footer_text: You can edit the individual permissions for this role after you've created it | ||||||
|  |       name_placeholder: Enter a role name... | ||||||
|  |       not_blank: Role name cannot be blank. | ||||||
|  |       title: Create New Role | ||||||
|     create_room: |     create_room: | ||||||
|       access_code: Access Code |       access_code: Access Code | ||||||
|       access_code_placeholder: Generate an optional room access code |       access_code_placeholder: Generate an optional room access code | ||||||
| @@ -369,10 +395,9 @@ en: | |||||||
|     confirm: New Password Confirmation |     confirm: New Password Confirmation | ||||||
|     update: Update Password |     update: Update Password | ||||||
|   roles: |   roles: | ||||||
|     administrator: Admin |     admin: Admin | ||||||
|     banned: Banned |     banned: Banned | ||||||
|     pending: Pending |     pending: Pending | ||||||
|     super_admin: Super Admin |  | ||||||
|     user: User |     user: User | ||||||
|   room: |   room: | ||||||
|     access_code_required: Please enter a valid access code to join the room |     access_code_required: Please enter a valid access code to join the room | ||||||
| @@ -386,6 +411,10 @@ en: | |||||||
|     last_session: Last session on %{session} |     last_session: Last session on %{session} | ||||||
|     login: Enter |     login: Enter | ||||||
|     owner: Owner |     owner: Owner | ||||||
|  |     no_room: | ||||||
|  |       title: Join a Room | ||||||
|  |       placeholder: Enter the room url or the room id for the room you want to join. | ||||||
|  |       invalid_room_uid: The room url/uid you entered was invalid. | ||||||
|     no_sessions: This room has no sessions, yet! |     no_sessions: This room has no sessions, yet! | ||||||
|     recordings: Room Recordings |     recordings: Room Recordings | ||||||
|     room_limit: You have reached the maximum number of rooms allowed |     room_limit: You have reached the maximum number of rooms allowed | ||||||
| @@ -406,6 +435,7 @@ en: | |||||||
|       provider: Provider |       provider: Provider | ||||||
|       image: Image |       image: Image | ||||||
|       image_url: Profile Image URL |       image_url: Profile Image URL | ||||||
|  |       roles: User Roles | ||||||
|       subtitle: Update your Account Info |       subtitle: Update your Account Info | ||||||
|       title: Account Info |       title: Account Info | ||||||
|     delete: |     delete: | ||||||
|   | |||||||
| @@ -46,8 +46,6 @@ Rails.application.routes.draw do | |||||||
|     post '/coloring_darken', to: 'admins#coloring_darken', as: :admin_coloring_darken |     post '/coloring_darken', to: 'admins#coloring_darken', as: :admin_coloring_darken | ||||||
|     post '/signup', to: 'admins#signup', as: :admin_signup |     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 '/promote/:user_uid', to: 'admins#promote', as: :admin_promote |  | ||||||
|     post '/demote/:user_uid', to: 'admins#demote', as: :admin_demote |  | ||||||
|     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 | ||||||
| @@ -55,6 +53,11 @@ Rails.application.routes.draw do | |||||||
|     post '/approve/:user_uid', to: 'admins#approve', as: :admin_approve |     post '/approve/:user_uid', to: 'admins#approve', as: :admin_approve | ||||||
|     post '/room_limit', to: 'admins#room_limit', as: :admin_room_limit |     post '/room_limit', to: 'admins#room_limit', as: :admin_room_limit | ||||||
|     post '/default_recording_visibility', to: 'admins#default_recording_visibility', as: :admin_recording_visibility |     post '/default_recording_visibility', to: 'admins#default_recording_visibility', as: :admin_recording_visibility | ||||||
|  |     get '/roles', to: 'admins#roles', as: :admin_roles | ||||||
|  |     post '/role', to: 'admins#new_role', as: :admin_new_role | ||||||
|  |     patch 'roles/order', to: 'admins#change_role_order', as: :admin_roles_order | ||||||
|  |     post '/role/:role_id', to: 'admins#update_role', as: :admin_update_role | ||||||
|  |     delete 'role/:role_id', to: 'admins#delete_role', as: :admin_delete_role | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   scope '/themes' do |   scope '/themes' do | ||||||
| @@ -96,6 +99,9 @@ Rails.application.routes.draw do | |||||||
|   # Room resources. |   # Room resources. | ||||||
|   resources :rooms, only: [:create, :show, :destroy], param: :room_uid, path: '/' |   resources :rooms, only: [:create, :show, :destroy], param: :room_uid, path: '/' | ||||||
|  |  | ||||||
|  |   # Join a room by UID | ||||||
|  |   post '/room/join', to: 'rooms#join_specific_room', as: :join_room | ||||||
|  |  | ||||||
|   # Extended room routes. |   # Extended room routes. | ||||||
|   scope '/:room_uid' do |   scope '/:room_uid' do | ||||||
|     post '/', to: 'rooms#join' |     post '/', to: 'rooms#join' | ||||||
|   | |||||||
							
								
								
									
										110
									
								
								db/migrate/20190726153012_add_custom_roles.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								db/migrate/20190726153012_add_custom_roles.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | |||||||
|  | # frozen_string_literal: true | ||||||
|  |  | ||||||
|  | class AddCustomRoles < ActiveRecord::Migration[5.2] | ||||||
|  |   def up | ||||||
|  |     super_admin_id = -1 | ||||||
|  |     user_id = -1 | ||||||
|  |     admin_id = -1 | ||||||
|  |     denied_id = -1 | ||||||
|  |     pending_id = -1 | ||||||
|  |  | ||||||
|  |     old_roles = ActiveRecord::Base.connection.execute("select * from roles") | ||||||
|  |  | ||||||
|  |     # Determine what ids corresponded to what roles in the old table | ||||||
|  |     old_roles.each do |role| | ||||||
|  |       if role["name"] == "super_admin" | ||||||
|  |         super_admin_id = role["id"] | ||||||
|  |       elsif role["name"] == "user" | ||||||
|  |         user_id = role["id"] | ||||||
|  |       elsif role["name"] == "admin" | ||||||
|  |         admin_id = role["id"] | ||||||
|  |       elsif role["name"] == "denied" | ||||||
|  |         denied_id = role["id"] | ||||||
|  |       elsif role["name"] == "pending" | ||||||
|  |         pending_id = role["id"] | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     # Replace Rolify's table with our own | ||||||
|  |     drop_table :roles | ||||||
|  |  | ||||||
|  |     create_table(:roles) do |t| | ||||||
|  |       t.string :name | ||||||
|  |       t.integer :priority, default: 9999 | ||||||
|  |       t.boolean :can_create_rooms, default: false | ||||||
|  |       t.boolean :send_promoted_email, default: false | ||||||
|  |       t.boolean :send_demoted_email, default: false | ||||||
|  |       t.boolean :can_edit_site_settings, default: false | ||||||
|  |       t.boolean :can_edit_roles, default: false | ||||||
|  |       t.boolean :can_manage_users, default: false | ||||||
|  |       t.string  :colour | ||||||
|  |       t.string :provider | ||||||
|  |  | ||||||
|  |       t.timestamps | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     add_index(:roles, :name) | ||||||
|  |     add_index(:roles, [:name, :provider], unique: true) | ||||||
|  |  | ||||||
|  |     # Look at all the old role assignments and and for each role create a new role | ||||||
|  |     # that is scoped to the provider | ||||||
|  |     old_assignments = ActiveRecord::Base.connection.execute("select * from users_roles") | ||||||
|  |     new_assignments = [] | ||||||
|  |  | ||||||
|  |     old_assignments.each do |assignment| | ||||||
|  |       user = User.find(assignment["user_id"]) | ||||||
|  |       new_assignment = { "user_id" => assignment["user_id"] } | ||||||
|  |       if assignment["role_id"] == super_admin_id | ||||||
|  |         new_assignment["new_role_id"] = generate_scoped_role(user, "super_admin") | ||||||
|  |       elsif assignment["role_id"] == user_id | ||||||
|  |         new_assignment["new_role_id"] = generate_scoped_role(user, "user") | ||||||
|  |       elsif assignment["role_id"] == admin_id | ||||||
|  |         new_assignment["new_role_id"] = generate_scoped_role(user, "admin") | ||||||
|  |       elsif assignment["role_id"] == denied_id | ||||||
|  |         new_assignment["new_role_id"] = generate_scoped_role(user, "denied") | ||||||
|  |       elsif assignment["role_id"] == pending_id | ||||||
|  |         new_assignment["new_role_id"] = generate_scoped_role(user, "pending") | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       new_assignments << new_assignment | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     assign_new_users(new_assignments) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   def generate_scoped_role(user, role_name) | ||||||
|  |     provider = Rails.configuration.loadbalanced_configuration ? user.provider : 'greenlight' | ||||||
|  |     new_role = Role.find_by(name: role_name, provider: provider) | ||||||
|  |  | ||||||
|  |     if new_role.nil? | ||||||
|  |       Role.create_default_roles(provider) | ||||||
|  |  | ||||||
|  |       new_role = Role.find_by(name: role_name, provider: provider) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     new_role.id | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   def assign_new_users(new_assignments) | ||||||
|  |     # Delete the old assignments | ||||||
|  |     ActiveRecord::Base.connection.execute("DELETE FROM users_roles") | ||||||
|  |     # Add the role assignments to the new roles | ||||||
|  |     new_assignments.each do |assignment| | ||||||
|  |       if assignment['new_role_id'] | ||||||
|  |         ActiveRecord::Base.connection.execute("INSERT INTO users_roles (user_id, role_id)" \ | ||||||
|  |           " VALUES (#{assignment['user_id']}, #{assignment['new_role_id']})") | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   def down | ||||||
|  |     drop_table :roles | ||||||
|  |  | ||||||
|  |     create_table(:roles) do |t| | ||||||
|  |       t.string :name | ||||||
|  |       t.references :resource, polymorphic: true | ||||||
|  |  | ||||||
|  |       t.timestamps | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
							
								
								
									
										100
									
								
								db/schema.rb
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								db/schema.rb
									
									
									
									
									
								
							| @@ -10,53 +10,59 @@ | |||||||
| # | # | ||||||
| # 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: 20190711192033) do | ActiveRecord::Schema.define(version: 2019_07_26_153012) do | ||||||
|  |  | ||||||
|   create_table "features", force: :cascade do |t| |   create_table "features", force: :cascade do |t| | ||||||
|     t.integer  "setting_id" |     t.integer "setting_id" | ||||||
|     t.string   "name",                       null: false |     t.string "name", null: false | ||||||
|     t.string   "value" |     t.string "value" | ||||||
|     t.boolean  "enabled",    default: false |     t.boolean "enabled", default: false | ||||||
|     t.datetime "created_at",                 null: false |     t.datetime "created_at", null: false | ||||||
|     t.datetime "updated_at",                 null: false |     t.datetime "updated_at", null: false | ||||||
|     t.index ["name"], name: "index_features_on_name" |     t.index ["name"], name: "index_features_on_name" | ||||||
|     t.index ["setting_id"], name: "index_features_on_setting_id" |     t.index ["setting_id"], name: "index_features_on_setting_id" | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   create_table "invitations", force: :cascade do |t| |   create_table "invitations", force: :cascade do |t| | ||||||
|     t.string   "email",        null: false |     t.string "email", null: false | ||||||
|     t.string   "provider",     null: false |     t.string "provider", null: false | ||||||
|     t.string   "invite_token" |     t.string "invite_token" | ||||||
|     t.datetime "created_at",   null: false |     t.datetime "created_at", null: false | ||||||
|     t.datetime "updated_at",   null: false |     t.datetime "updated_at", null: false | ||||||
|     t.index ["invite_token"], name: "index_invitations_on_invite_token" |     t.index ["invite_token"], name: "index_invitations_on_invite_token" | ||||||
|     t.index ["provider"], name: "index_invitations_on_provider" |     t.index ["provider"], name: "index_invitations_on_provider" | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   create_table "roles", force: :cascade do |t| |   create_table "roles", force: :cascade do |t| | ||||||
|     t.string   "name" |     t.string "name" | ||||||
|     t.string   "resource_type" |     t.integer "priority", default: 9999 | ||||||
|     t.integer  "resource_id" |     t.boolean "can_create_rooms", default: false | ||||||
|     t.datetime "created_at",    null: false |     t.boolean "send_promoted_email", default: false | ||||||
|     t.datetime "updated_at",    null: false |     t.boolean "send_demoted_email", default: false | ||||||
|     t.index ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id" |     t.boolean "can_edit_site_settings", default: false | ||||||
|  |     t.boolean "can_edit_roles", default: false | ||||||
|  |     t.boolean "can_manage_users", default: false | ||||||
|  |     t.string "colour" | ||||||
|  |     t.string "provider" | ||||||
|  |     t.datetime "created_at", null: false | ||||||
|  |     t.datetime "updated_at", null: false | ||||||
|  |     t.index ["name", "provider"], name: "index_roles_on_name_and_provider", unique: true | ||||||
|     t.index ["name"], name: "index_roles_on_name" |     t.index ["name"], name: "index_roles_on_name" | ||||||
|     t.index ["resource_type", "resource_id"], name: "index_roles_on_resource_type_and_resource_id" |  | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   create_table "rooms", force: :cascade do |t| |   create_table "rooms", force: :cascade do |t| | ||||||
|     t.integer  "user_id" |     t.integer "user_id" | ||||||
|     t.string   "name" |     t.string "name" | ||||||
|     t.string   "uid" |     t.string "uid" | ||||||
|     t.string   "bbb_id" |     t.string "bbb_id" | ||||||
|     t.integer  "sessions",              default: 0 |     t.integer "sessions", default: 0 | ||||||
|     t.datetime "last_session" |     t.datetime "last_session" | ||||||
|     t.datetime "created_at",                            null: false |     t.datetime "created_at", null: false | ||||||
|     t.datetime "updated_at",                            null: false |     t.datetime "updated_at", null: false | ||||||
|     t.string   "room_settings",         default: "{ }" |     t.string "room_settings", default: "{ }" | ||||||
|     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.index ["bbb_id"], name: "index_rooms_on_bbb_id" |     t.index ["bbb_id"], name: "index_rooms_on_bbb_id" | ||||||
|     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" | ||||||
| @@ -66,30 +72,30 @@ ActiveRecord::Schema.define(version: 20190711192033) do | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   create_table "settings", force: :cascade do |t| |   create_table "settings", force: :cascade do |t| | ||||||
|     t.string   "provider",   null: false |     t.string "provider", null: false | ||||||
|     t.datetime "created_at", null: false |     t.datetime "created_at", null: false | ||||||
|     t.datetime "updated_at", null: false |     t.datetime "updated_at", null: false | ||||||
|     t.index ["provider"], name: "index_settings_on_provider" |     t.index ["provider"], name: "index_settings_on_provider" | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   create_table "users", force: :cascade do |t| |   create_table "users", force: :cascade do |t| | ||||||
|     t.integer  "room_id" |     t.integer "room_id" | ||||||
|     t.string   "provider" |     t.string "provider" | ||||||
|     t.string   "uid" |     t.string "uid" | ||||||
|     t.string   "name" |     t.string "name" | ||||||
|     t.string   "username" |     t.string "username" | ||||||
|     t.string   "email" |     t.string "email" | ||||||
|     t.string   "social_uid" |     t.string "social_uid" | ||||||
|     t.string   "image" |     t.string "image" | ||||||
|     t.string   "password_digest" |     t.string "password_digest" | ||||||
|     t.boolean  "accepted_terms",    default: false |     t.boolean "accepted_terms", default: false | ||||||
|     t.datetime "created_at",                              null: false |     t.datetime "created_at", null: false | ||||||
|     t.datetime "updated_at",                              null: false |     t.datetime "updated_at", null: false | ||||||
|     t.boolean  "email_verified",    default: false |     t.boolean "email_verified", default: false | ||||||
|     t.string   "language",          default: "default" |     t.string "language", default: "default" | ||||||
|     t.string   "reset_digest" |     t.string "reset_digest" | ||||||
|     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.index ["created_at"], name: "index_users_on_created_at" |     t.index ["created_at"], name: "index_users_on_created_at" | ||||||
|     t.index ["email"], name: "index_users_on_email" |     t.index ["email"], name: "index_users_on_email" | ||||||
|   | |||||||
| @@ -8,4 +8,5 @@ | |||||||
| #   movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) | #   movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) | ||||||
| #   Character.create(name: 'Luke', movie: movies.first) | #   Character.create(name: 'Luke', movie: movies.first) | ||||||
|  |  | ||||||
|  | Role.create_default_roles("greenlight") | ||||||
| Rake::Task['admin:create'].invoke | Rake::Task['admin:create'].invoke | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ describe AdminsController, type: :controller do | |||||||
|   before do |   before do | ||||||
|     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") | ||||||
|  |  | ||||||
|     @user = create(:user, provider: "provider1") |     @user = create(:user, provider: "provider1") | ||||||
|     @admin = create(:user, provider: "provider1") |     @admin = create(:user, provider: "provider1") | ||||||
|     @admin.add_role :admin |     @admin.add_role :admin | ||||||
| @@ -58,53 +59,6 @@ describe AdminsController, type: :controller do | |||||||
|       end |       end | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     context "POST #promote" do |  | ||||||
|       it "promotes a user to admin" do |  | ||||||
|         @request.session[:user_id] = @admin.id |  | ||||||
|  |  | ||||||
|         expect(@user.has_role?(:admin)).to eq(false) |  | ||||||
|  |  | ||||||
|         post :promote, params: { user_uid: @user.uid } |  | ||||||
|  |  | ||||||
|         expect(@user.has_role?(:admin)).to eq(true) |  | ||||||
|         expect(flash[:success]).to be_present |  | ||||||
|         expect(response).to redirect_to(admins_path) |  | ||||||
|       end |  | ||||||
|  |  | ||||||
|       it "sends an email to the user being promoted" do |  | ||||||
|         @request.session[:user_id] = @admin.id |  | ||||||
|  |  | ||||||
|         params = { user_uid: @user.uid } |  | ||||||
|  |  | ||||||
|         expect { post :promote, params: params }.to change { ActionMailer::Base.deliveries.count }.by(1) |  | ||||||
|       end |  | ||||||
|     end |  | ||||||
|  |  | ||||||
|     context "POST #demote" do |  | ||||||
|       it "demotes an admin to user" do |  | ||||||
|         @request.session[:user_id] = @admin.id |  | ||||||
|  |  | ||||||
|         @user.add_role :admin |  | ||||||
|         expect(@user.has_role?(:admin)).to eq(true) |  | ||||||
|  |  | ||||||
|         post :demote, params: { user_uid: @user.uid } |  | ||||||
|  |  | ||||||
|         expect(@user.has_role?(:admin)).to eq(false) |  | ||||||
|         expect(flash[:success]).to be_present |  | ||||||
|         expect(response).to redirect_to(admins_path) |  | ||||||
|       end |  | ||||||
|  |  | ||||||
|       it "sends an email to the user being demoted" do |  | ||||||
|         @request.session[:user_id] = @admin.id |  | ||||||
|  |  | ||||||
|         @user.add_role :admin |  | ||||||
|  |  | ||||||
|         params = { user_uid: @user.uid } |  | ||||||
|  |  | ||||||
|         expect { post :demote, params: params }.to change { ActionMailer::Base.deliveries.count }.by(1) |  | ||||||
|       end |  | ||||||
|     end |  | ||||||
|  |  | ||||||
|     context "POST #ban" do |     context "POST #ban" do | ||||||
|       it "bans a user from the application" do |       it "bans a user from the application" do | ||||||
|         @request.session[:user_id] = @admin.id |         @request.session[:user_id] = @admin.id | ||||||
| @@ -331,4 +285,239 @@ describe AdminsController, type: :controller do | |||||||
|       end |       end | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  |   describe "Roles" do | ||||||
|  |     context "GET #roles" do | ||||||
|  |       it "should render the roles editor with the user role selected" do | ||||||
|  |         @request.session[:user_id] = @admin.id | ||||||
|  |  | ||||||
|  |         get :roles | ||||||
|  |  | ||||||
|  |         expect(response).to render_template :roles | ||||||
|  |         expect(assigns(:roles).count).to eq(2) | ||||||
|  |         expect(assigns(:selected_role).name).to eq("user") | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       it "should render the roles editor with the request role selected" do | ||||||
|  |         Role.create_default_roles("provider1") | ||||||
|  |  | ||||||
|  |         new_role = Role.create(name: "test", provider: "provider1") | ||||||
|  |  | ||||||
|  |         @request.session[:user_id] = @admin.id | ||||||
|  |  | ||||||
|  |         get :roles, params: { selected_role: new_role.id } | ||||||
|  |  | ||||||
|  |         expect(response).to render_template :roles | ||||||
|  |         expect(assigns(:roles).count).to eq(3) | ||||||
|  |         expect(assigns(:selected_role).name).to eq(new_role.name) | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     context "POST #new_role" do | ||||||
|  |       before do | ||||||
|  |         Role.create_default_roles("provider1") | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       it "should fail with duplicate role name" do | ||||||
|  |         @request.session[:user_id] = @admin.id | ||||||
|  |  | ||||||
|  |         post :new_role, params: { role: { name: "admin" } } | ||||||
|  |  | ||||||
|  |         expect(response).to redirect_to admin_roles_path | ||||||
|  |         expect(flash[:alert]).to eq(I18n.t("administrator.roles.duplicate_name")) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       it "should fail with empty role name" do | ||||||
|  |         @request.session[:user_id] = @admin.id | ||||||
|  |  | ||||||
|  |         post :new_role, params: { role: { name: "    " } } | ||||||
|  |  | ||||||
|  |         expect(response).to redirect_to admin_roles_path | ||||||
|  |         expect(flash[:alert]).to eq(I18n.t("administrator.roles.empty_name")) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       it "should create new role and increase user role priority" do | ||||||
|  |         @request.session[:user_id] = @admin.id | ||||||
|  |  | ||||||
|  |         post :new_role, params: { role: { name: "test" } } | ||||||
|  |  | ||||||
|  |         new_role = Role.find_by(name: "test", provider: "provider1") | ||||||
|  |         user_role = Role.find_by(name: "user", provider: "provider1") | ||||||
|  |  | ||||||
|  |         expect(new_role.priority).to eq(1) | ||||||
|  |         expect(user_role.priority).to eq(2) | ||||||
|  |         expect(response).to redirect_to admin_roles_path(selected_role: new_role.id) | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     context "PATCH #change_role_order" do | ||||||
|  |       before do | ||||||
|  |         Role.create_default_roles("provider1") | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       it "should fail if user attempts to change the order of the admin or user roles" do | ||||||
|  |         @request.session[:user_id] = @admin.id | ||||||
|  |  | ||||||
|  |         user_role = Role.find_by(name: "user", provider: "provider1") | ||||||
|  |         admin_role = Role.find_by(name: "admin", provider: "provider1") | ||||||
|  |  | ||||||
|  |         patch :change_role_order, params: { role: [user_role.id, admin_role.id] } | ||||||
|  |  | ||||||
|  |         expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_order")) | ||||||
|  |         expect(response).to redirect_to admin_roles_path | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       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") | ||||||
|  |         new_role2 = Role.create(name: "test2", priority: 2, provider: "greenlight", can_edit_roles: true) | ||||||
|  |         new_role3 = Role.create(name: "test3", priority: 3, provider: "greenlight") | ||||||
|  |         user_role = Role.find_by(name: "user", provider: "greenlight") | ||||||
|  |  | ||||||
|  |         user_role.priority = 4 | ||||||
|  |         user_role.save! | ||||||
|  |  | ||||||
|  |         @user.roles << new_role2 | ||||||
|  |         @user.save! | ||||||
|  |  | ||||||
|  |         @request.session[:user_id] = @user.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(response).to redirect_to admin_roles_path | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       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") | ||||||
|  |         new_role2 = Role.create(name: "test2", priority: 2, provider: "greenlight", can_edit_roles: true) | ||||||
|  |         new_role3 = Role.create(name: "test3", priority: 3, provider: "greenlight") | ||||||
|  |         user_role = Role.find_by(name: "user", provider: "greenlight") | ||||||
|  |  | ||||||
|  |         user_role.priority = 4 | ||||||
|  |         user_role.save! | ||||||
|  |  | ||||||
|  |         @user.roles << new_role2 | ||||||
|  |         @user.save! | ||||||
|  |  | ||||||
|  |         @request.session[:user_id] = @user.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(response).to redirect_to admin_roles_path | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       it "should update the role order" do | ||||||
|  |         new_role1 = Role.create(name: "test1", priority: 1, provider: "provider1") | ||||||
|  |         new_role2 = Role.create(name: "test2", priority: 2, provider: "provider1") | ||||||
|  |         new_role3 = Role.create(name: "test3", priority: 3, provider: "provider1") | ||||||
|  |         user_role = Role.find_by(name: "user", provider: "provider1") | ||||||
|  |  | ||||||
|  |         @request.session[:user_id] = @admin.id | ||||||
|  |  | ||||||
|  |         patch :change_role_order, params: { role: [new_role3.id, new_role2.id, new_role1.id] } | ||||||
|  |  | ||||||
|  |         new_role1.reload | ||||||
|  |         new_role2.reload | ||||||
|  |         new_role3.reload | ||||||
|  |         user_role.reload | ||||||
|  |  | ||||||
|  |         expect(new_role3.priority).to eq(1) | ||||||
|  |         expect(new_role2.priority).to eq(2) | ||||||
|  |         expect(new_role1.priority).to eq(3) | ||||||
|  |         expect(user_role.priority).to eq(4) | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     context 'POST #update_role' do | ||||||
|  |       before do | ||||||
|  |         Role.create_default_roles("provider1") | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       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_role2 = Role.create(name: "test2", priority: 2, provider: "provider1", can_edit_roles: true) | ||||||
|  |         user_role = Role.find_by(name: "user", provider: "greenlight") | ||||||
|  |  | ||||||
|  |         user_role.priority = 3 | ||||||
|  |         user_role.save! | ||||||
|  |  | ||||||
|  |         @user.roles << new_role2 | ||||||
|  |         @user.save! | ||||||
|  |  | ||||||
|  |         @request.session[:user_id] = @user.id | ||||||
|  |  | ||||||
|  |         patch :update_role, params: { role_id: new_role1.id } | ||||||
|  |  | ||||||
|  |         expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_update")) | ||||||
|  |         expect(response).to redirect_to admin_roles_path(selected_role: new_role1.id) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       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) | ||||||
|  |  | ||||||
|  |         @request.session[:user_id] = @admin.id | ||||||
|  |  | ||||||
|  |         patch :update_role, params: { role_id: new_role.id, role: { name: "admin" } } | ||||||
|  |  | ||||||
|  |         expect(flash[:alert]).to eq(I18n.t("administrator.roles.duplicate_name")) | ||||||
|  |         expect(response).to redirect_to admin_roles_path(selected_role: new_role.id) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       it "should update role permisions" do | ||||||
|  |         new_role = Role.create(name: "test2", priority: 1, provider: "provider1", can_edit_roles: true) | ||||||
|  |  | ||||||
|  |         @request.session[:user_id] = @admin.id | ||||||
|  |  | ||||||
|  |         patch :update_role, params: { role_id: new_role.id, role: { name: "test", can_edit_roles: false, | ||||||
|  |           colour: "#45434", can_manage_users: true } } | ||||||
|  |  | ||||||
|  |         new_role.reload | ||||||
|  |         expect(new_role.name).to eq("test") | ||||||
|  |         expect(new_role.can_edit_roles).to eq(false) | ||||||
|  |         expect(new_role.colour).to eq("#45434") | ||||||
|  |         expect(new_role.can_manage_users).to eq(true) | ||||||
|  |         expect(new_role.send_promoted_email).to eq(false) | ||||||
|  |         expect(response).to redirect_to admin_roles_path(selected_role: new_role.id) | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     context "DELETE delete_role" do | ||||||
|  |       before do | ||||||
|  |         Role.create_default_roles("provider1") | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       it "should fail to delete the role if it has users assigned to it" do | ||||||
|  |         admin_role = Role.find_by(name: "admin", provider: "greenlight") | ||||||
|  |  | ||||||
|  |         @request.session[:user_id] = @admin.id | ||||||
|  |  | ||||||
|  |         delete :delete_role, params: { role_id: admin_role.id } | ||||||
|  |  | ||||||
|  |         expect(flash[:alert]).to eq(I18n.t("administrator.roles.role_has_users", user_count: 1)) | ||||||
|  |         expect(response).to redirect_to admin_roles_path(selected_role: admin_role.id) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       it "should fail to delete the role if it is a default role" do | ||||||
|  |         pending_role = Role.find_by(name: "pending", provider: "provider1") | ||||||
|  |  | ||||||
|  |         @request.session[:user_id] = @admin.id | ||||||
|  |  | ||||||
|  |         delete :delete_role, params: { role_id: pending_role.id } | ||||||
|  |  | ||||||
|  |         expect(response).to redirect_to admin_roles_path(selected_role: pending_role.id) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       it "should successfully delete the role" do | ||||||
|  |         new_role = Role.create(name: "test2", priority: 1, provider: "provider1", can_edit_roles: true) | ||||||
|  |  | ||||||
|  |         @request.session[:user_id] = @admin.id | ||||||
|  |  | ||||||
|  |         delete :delete_role, params: { role_id: new_role.id } | ||||||
|  |  | ||||||
|  |         expect(Role.where(name: "test2", provider: "provider1").count).to eq(0) | ||||||
|  |         expect(response).to redirect_to admin_roles_path | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |   end | ||||||
| end | end | ||||||
|   | |||||||
| @@ -61,6 +61,19 @@ describe RoomsController, type: :controller do | |||||||
|       expect(response).to render_template(:join) |       expect(response).to render_template(:join) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  |     it "should render cant_create_rooms if user doesn't have permission to create rooms" do | ||||||
|  |       user_role = @user.highest_priority_role | ||||||
|  |  | ||||||
|  |       user_role.can_create_rooms = false | ||||||
|  |       user_role.save! | ||||||
|  |  | ||||||
|  |       @request.session[:user_id] = @user.id | ||||||
|  |  | ||||||
|  |       get :show, params: { room_uid: @user.main_room } | ||||||
|  |  | ||||||
|  |       expect(response).to render_template(:cant_create_rooms) | ||||||
|  |     end | ||||||
|  |  | ||||||
|     it "should be able to search public recordings if user is not owner" do |     it "should be able to search public recordings if user is not owner" do | ||||||
|       @request.session[:user_id] = @user.id |       @request.session[:user_id] = @user.id | ||||||
|  |  | ||||||
| @@ -454,4 +467,32 @@ describe RoomsController, type: :controller do | |||||||
|       expect(flash[:alert]).to eq(I18n.t("room.access_code_required")) |       expect(flash[:alert]).to eq(I18n.t("room.access_code_required")) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  |   describe "POST join_specific_room" do | ||||||
|  |     before do | ||||||
|  |       @user = create(:user) | ||||||
|  |       @user1 = create(:user) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "should display flash if the user doesn't supply a valid uid" do | ||||||
|  |       @request.session[:user_id] = @user.id | ||||||
|  |  | ||||||
|  |       post :join_specific_room, params: { join_room: { url: "abc" } } | ||||||
|  |  | ||||||
|  |       expect(flash[:alert]).to eq(I18n.t("room.no_room.invalid_room_uid")) | ||||||
|  |       expect(response).to redirect_to room_path(@user.main_room) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "should redirect the user to the room uid they supplied" do | ||||||
|  |       post :join_specific_room, params: { join_room: { url: @user1.main_room } } | ||||||
|  |  | ||||||
|  |       expect(response).to redirect_to room_path(@user1.main_room) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "should redirect the user to the room join url they supplied" do | ||||||
|  |       post :join_specific_room, params: { join_room: { url: room_path(@user1.main_room) } } | ||||||
|  |  | ||||||
|  |       expect(response).to redirect_to room_path(@user1.main_room) | ||||||
|  |     end | ||||||
|  |   end | ||||||
| end | end | ||||||
|   | |||||||
| @@ -333,6 +333,95 @@ describe UsersController, type: :controller do | |||||||
|       patch :update, params: invalid_params.merge!(user_uid: @user) |       patch :update, params: invalid_params.merge!(user_uid: @user) | ||||||
|       expect(response).to render_template(:edit) |       expect(response).to render_template(:edit) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  |     context 'Roles updates' do | ||||||
|  |       it "should fail to update roles if users tries to add a role with a higher priority than their own" do | ||||||
|  |         user = create(:user) | ||||||
|  |         @request.session[:user_id] = user.id | ||||||
|  |  | ||||||
|  |         user_role = user.highest_priority_role | ||||||
|  |  | ||||||
|  |         user_role.can_edit_roles = true | ||||||
|  |  | ||||||
|  |         user_role.save! | ||||||
|  |  | ||||||
|  |         tmp_role = Role.create(name: "test", priority: -2, provider: "greenlight") | ||||||
|  |  | ||||||
|  |         params = random_valid_user_params | ||||||
|  |         patch :update, params: params.merge!(user_uid: user, user: { role_ids: tmp_role.id.to_s }) | ||||||
|  |  | ||||||
|  |         expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_assignment")) | ||||||
|  |         expect(response).to render_template(:edit) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       it "should fail to update roles if a user tries to remove a role with a higher priority than their own" do | ||||||
|  |         user = create(:user) | ||||||
|  |         admin = create(:user) | ||||||
|  |  | ||||||
|  |         admin.add_role :admin | ||||||
|  |  | ||||||
|  |         @request.session[:user_id] = user.id | ||||||
|  |  | ||||||
|  |         user_role = user.highest_priority_role | ||||||
|  |  | ||||||
|  |         user_role.can_edit_roles = true | ||||||
|  |  | ||||||
|  |         user_role.save! | ||||||
|  |  | ||||||
|  |         params = random_valid_user_params | ||||||
|  |         patch :update, params: params.merge!(user_uid: admin, user: { role_ids: "" }) | ||||||
|  |  | ||||||
|  |         user.reload | ||||||
|  |  | ||||||
|  |         expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_removal")) | ||||||
|  |         expect(response).to render_template(:edit) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       it "should successfuly add roles to the user" do | ||||||
|  |         allow(Rails.configuration).to receive(:enable_email_verification).and_return(true) | ||||||
|  |  | ||||||
|  |         user = create(:user) | ||||||
|  |         admin = create(:user) | ||||||
|  |  | ||||||
|  |         admin.add_role :admin | ||||||
|  |  | ||||||
|  |         @request.session[:user_id] = admin.id | ||||||
|  |  | ||||||
|  |         tmp_role1 = Role.create(name: "test1", priority: 1, provider: "greenlight", send_promoted_email: true) | ||||||
|  |         tmp_role2 = Role.create(name: "test2", priority: 2, provider: "greenlight") | ||||||
|  |  | ||||||
|  |         params = random_valid_user_params | ||||||
|  |         params = params.merge!(user_uid: user, user: { role_ids: "#{tmp_role1.id} #{tmp_role2.id}" }) | ||||||
|  |  | ||||||
|  |         expect { patch :update, params: params }.to change { ActionMailer::Base.deliveries.count }.by(1) | ||||||
|  |         expect(user.roles.count).to eq(2) | ||||||
|  |         expect(user.highest_priority_role.name).to eq("test1") | ||||||
|  |         expect(response).to redirect_to(admins_path) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       it "all users must at least have the user role" do | ||||||
|  |         allow(Rails.configuration).to receive(:enable_email_verification).and_return(true) | ||||||
|  |  | ||||||
|  |         user = create(:user) | ||||||
|  |         admin = create(:user) | ||||||
|  |  | ||||||
|  |         admin.add_role :admin | ||||||
|  |  | ||||||
|  |         tmp_role1 = Role.create(name: "test1", priority: 1, provider: "greenlight", send_demoted_email: true) | ||||||
|  |         user.roles << tmp_role1 | ||||||
|  |         user.save! | ||||||
|  |  | ||||||
|  |         @request.session[:user_id] = admin.id | ||||||
|  |  | ||||||
|  |         params = random_valid_user_params | ||||||
|  |         params = params.merge!(user_uid: user, user: { role_ids: "" }) | ||||||
|  |  | ||||||
|  |         expect { patch :update, params: params }.to change { ActionMailer::Base.deliveries.count }.by(1) | ||||||
|  |         expect(user.roles.count).to eq(1) | ||||||
|  |         expect(user.highest_priority_role.name).to eq("user") | ||||||
|  |         expect(response).to redirect_to(admins_path) | ||||||
|  |       end | ||||||
|  |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   describe "DELETE #user" do |   describe "DELETE #user" do | ||||||
|   | |||||||
							
								
								
									
										44
									
								
								spec/helpers/admins_helper_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								spec/helpers/admins_helper_spec.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | # 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 | ||||||
| @@ -85,4 +85,14 @@ describe ApplicationHelper do | |||||||
|       expect(helper.allow_greenlight_accounts?).to eql(false) |       expect(helper.allow_greenlight_accounts?).to eql(false) | ||||||
|     end |     end | ||||||
|   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) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "should use role colour if provided" do | ||||||
|  |       expect(helper.role_colour(Role.create(name: "test", colour: "#1234"))).to eq("#1234") | ||||||
|  |     end | ||||||
|  |   end | ||||||
| end | end | ||||||
|   | |||||||
							
								
								
									
										44
									
								
								spec/helpers/users_helper_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								spec/helpers/users_helper_spec.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | # 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 UsersHelper do | ||||||
|  |     describe "disabled roles" do | ||||||
|  |         it "should return roles with a less than or equal to priority for non admins" do | ||||||
|  |             user = create(:user) | ||||||
|  |             allow_any_instance_of(SessionsHelper).to receive(:current_user).and_return(user) | ||||||
|  |  | ||||||
|  |             disabled_roles = helper.disabled_roles(user) | ||||||
|  |  | ||||||
|  |             expect(disabled_roles.count).to eq(1) | ||||||
|  |         end | ||||||
|  |  | ||||||
|  |         it "should return roles with a lesser priority for admins" do | ||||||
|  |             admin = create(:user) | ||||||
|  |             admin.add_role :admin | ||||||
|  |             user = create(:user) | ||||||
|  |  | ||||||
|  |             allow_any_instance_of(SessionsHelper).to receive(:current_user).and_return(admin) | ||||||
|  |  | ||||||
|  |             disabled_roles = helper.disabled_roles(user) | ||||||
|  |  | ||||||
|  |             expect(disabled_roles.count).to eq(1) | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  | end | ||||||
							
								
								
									
										35
									
								
								spec/models/role_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								spec/models/role_spec.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | # 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 Role, type: :model do | ||||||
|  |     it "should return duplicate if role name is in reserved role names" do | ||||||
|  |         expect(Role.duplicate_name("admin", "greenlight")).to eq(true) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "should return duplicate if role name matched another" do | ||||||
|  |         Role.create(name: "test", provider: "greenlight") | ||||||
|  |         expect(Role.duplicate_name("test", "greenlight")).to eq(true) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "should return false role name doesn't exist" do | ||||||
|  |         Role.create(name: "test", provider: "greenlight") | ||||||
|  |         expect(Role.duplicate_name("test1", "greenlight")).to eq(false) | ||||||
|  |     end | ||||||
|  | end | ||||||
| @@ -158,6 +158,72 @@ describe User, type: :model do | |||||||
|  |  | ||||||
|       expect(@admin.admin_of?(@user)).to be false |       expect(@admin.admin_of?(@user)).to be false | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  |     it "should get the highest priority role" do | ||||||
|  |       @admin = create(:user, provider: @user.provider) | ||||||
|  |       @admin.add_role :admin | ||||||
|  |  | ||||||
|  |       expect(@admin.highest_priority_role.name).to eq("admin") | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "should skip adding the role if the user already has the role" do | ||||||
|  |       @admin = create(:user, provider: @user.provider) | ||||||
|  |       @admin.add_role :admin | ||||||
|  |       @admin.add_role :admin | ||||||
|  |  | ||||||
|  |       expect(@admin.roles.count).to eq(2) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "should add the role if the user doesn't already have the role" do | ||||||
|  |       @admin = create(:user, provider: @user.provider) | ||||||
|  |       @admin.add_role :admin | ||||||
|  |  | ||||||
|  |       expect(@admin.roles.count).to eq(2) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "should remove the role if the user has the role assigned to them" do | ||||||
|  |       @admin = create(:user, provider: @user.provider) | ||||||
|  |       @admin.add_role :admin | ||||||
|  |       @admin.remove_role :admin | ||||||
|  |  | ||||||
|  |       expect(@admin.roles.count).to eq(1) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "has_role? should return false if the user doesn't have the role" do | ||||||
|  |       expect(@user.has_role?(:admin)).to eq(false) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "has_role? should return true if the user has the role" do | ||||||
|  |       @admin = create(:user, provider: @user.provider) | ||||||
|  |       @admin.add_role :admin | ||||||
|  |  | ||||||
|  |       expect(@admin.has_role?(:admin)).to eq(true) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "with_role should return all users with the role" do | ||||||
|  |       @admin1 = create(:user, provider: @user.provider) | ||||||
|  |       @admin2 = create(:user, provider: @user.provider) | ||||||
|  |       @admin1.add_role :admin | ||||||
|  |       @admin2.add_role :admin | ||||||
|  |  | ||||||
|  |       expect(User.with_role(:admin).count).to eq(2) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "without_role should return all users without the role" do | ||||||
|  |       @admin1 = create(:user, provider: @user.provider) | ||||||
|  |       @admin2 = create(:user, provider: @user.provider) | ||||||
|  |       @admin1.add_role :admin | ||||||
|  |       @admin2.add_role :admin | ||||||
|  |  | ||||||
|  |       expect(User.without_role(:admin).count).to eq(1) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it "all_users_with_roles should return all users with at least one role" do | ||||||
|  |       @admin1 = create(:user, provider: @user.provider) | ||||||
|  |       @admin2 = create(:user, provider: @user.provider) | ||||||
|  |  | ||||||
|  |       expect(User.all_users_with_roles.count).to eq(3) | ||||||
|  |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   context 'blank email' do |   context 'blank email' do | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| # frozen_string_literal: true | # frozen_string_literal: true | ||||||
|  |  | ||||||
| class UserMailerPreview < ActionMailer::Preview | class UserMailerPreview < ActionMailer::Preview | ||||||
|   def initialize |   def initialize(_params) | ||||||
|     @logo = "https://raw.githubusercontent.com/bigbluebutton/greenlight/master/app/assets/images/logo_with_text.png" |     @logo = "https://raw.githubusercontent.com/bigbluebutton/greenlight/master/app/assets/images/logo_with_text.png" | ||||||
|     @color = "#467fcf" |     @color = "#467fcf" | ||||||
|   end |   end | ||||||
| @@ -53,19 +53,21 @@ class UserMailerPreview < ActionMailer::Preview | |||||||
|   # http://localhost:3000/rails/mailers/user_mailer/user_promoted |   # http://localhost:3000/rails/mailers/user_mailer/user_promoted | ||||||
|   def user_promoted |   def user_promoted | ||||||
|     user = User.first |     user = User.first | ||||||
|  |     role = Role.first.name | ||||||
|     url = "http://example.com" |     url = "http://example.com" | ||||||
|     logo_image = "https://raw.githubusercontent.com/bigbluebutton/greenlight/master/app/assets/images/logo_with_text.png" |     logo_image = "https://raw.githubusercontent.com/bigbluebutton/greenlight/master/app/assets/images/logo_with_text.png" | ||||||
|     user_color = "#467fcf" |     user_color = "#467fcf" | ||||||
|     UserMailer.user_promoted(user, url, logo_image, user_color) |     UserMailer.user_promoted(user, role, url, logo_image, user_color) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   # Preview this email at |   # Preview this email at | ||||||
|   # http://localhost:3000/rails/mailers/user_mailer/user_demoted |   # http://localhost:3000/rails/mailers/user_mailer/user_demoted | ||||||
|   def user_demoted |   def user_demoted | ||||||
|     user = User.first |     user = User.first | ||||||
|  |     role = Role.first.name | ||||||
|     url = "http://example.com" |     url = "http://example.com" | ||||||
|     logo_image = "https://raw.githubusercontent.com/bigbluebutton/greenlight/master/app/assets/images/logo_with_text.png" |     logo_image = "https://raw.githubusercontent.com/bigbluebutton/greenlight/master/app/assets/images/logo_with_text.png" | ||||||
|     user_color = "#467fcf" |     user_color = "#467fcf" | ||||||
|     UserMailer.user_demoted(user, url, logo_image, user_color) |     UserMailer.user_demoted(user, role, url, logo_image, user_color) | ||||||
|   end |   end | ||||||
| end | end | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user