diff --git a/.rubocop.yml b/.rubocop.yml index b3e193c2..0f39657b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -9,6 +9,9 @@ AllCops: Bundler/OrderedGems: Enabled: false +Style/BlockDelimiters: + Enabled: false + # Checks if uses of quotes match the configured preference. Style/StringLiterals: Enabled: false @@ -97,6 +100,9 @@ Layout/AlignArguments: Layout/IndentationWidth: Enabled: false +Layout/CaseIndentation: + Enabled: false + # Checks for ambiguous block association with method when param passed without parentheses. Lint/AmbiguousBlockAssociation: Enabled: false diff --git a/app/assets/javascripts/admins.js b/app/assets/javascripts/admins.js index a7a4245e..13a64baf 100644 --- a/app/assets/javascripts/admins.js +++ b/app/assets/javascripts/admins.js @@ -21,17 +21,6 @@ $(document).on('turbolinks:load', function(){ // Only run on the admins page. if (controller == "admins") { if(action == "index") { - // show the modal with the correct form action url - $(".delete-user").click(function(data){ - var uid = $(data.target).closest("tr").data("user-uid") - var url = $("body").data("relative-root") - if (!url.endsWith("/")) { - url += "/" - } - url += "u/" + uid - $("#delete-confirm").parent().attr("action", url) - }) - //clear the role filter if user clicks on the x $(".clear-role").click(function() { var search = new URL(location.href).searchParams.get('search') @@ -44,6 +33,14 @@ $(document).on('turbolinks:load', function(){ window.location.replace(url); }) + + // Handle selected user tags + $(".manage-users-tab").click(function() { + $(".manage-users-tab").removeClass("selected") + $(this).addClass("selected") + + updateTabParams(this.id) + }) } else if(action == "site_settings"){ loadColourSelectors() @@ -95,6 +92,20 @@ function filterRole(role) { window.location.replace(url); } +function updateTabParams(tab) { + var search_params = new URLSearchParams(window.location.search) + + if (window.location.href.includes("tab=")) { + search_params.set("tab", tab) + } else { + search_params.append("tab", tab) + } + + search_params.delete("page") + + window.location.search = search_params.toString() +} + function loadColourSelectors() { const pickrRegular = new Pickr({ el: '#colorinput-regular', diff --git a/app/assets/javascripts/delete.js b/app/assets/javascripts/delete.js new file mode 100644 index 00000000..1b8ef556 --- /dev/null +++ b/app/assets/javascripts/delete.js @@ -0,0 +1,57 @@ +// 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 . + +$(document).on('turbolinks:load', function(){ + var controller = $("body").data('controller'); + var action = $("body").data('action'); + + // Only run on the admins page. + if (controller == "admins" && action == "index") { + // show the modal with the correct form action url + $(".delete-user").click(function(){ + $("#delete-confirm").parent().attr("action", $(this).data("path")) + + if ($(this).data("delete") == "temp-delete") { + $("#perm-delete").hide() + $("#delete-warning").show() + } else { + $("#perm-delete").show() + $("#delete-warning").hide() + } + }) + } + + $(".delete-user").click(function(data){ + document.getElementById("delete-checkbox").checked = false + $("#delete-confirm").prop("disabled", "disabled") + + if ($(data.target).data("delete") == "temp-delete") { + $("#perm-delete").hide() + $("#delete-warning").show() + } else { + $("#perm-delete").show() + $("#delete-warning").hide() + } + }) + + $("#delete-checkbox").click(function(data){ + if (document.getElementById("delete-checkbox").checked) { + $("#delete-confirm").removeAttr("disabled") + } else { + $("#delete-confirm").prop("disabled", "disabled") + } + }) +}) diff --git a/app/assets/javascripts/search.js b/app/assets/javascripts/search.js index 9c8e0c5c..f0da579c 100644 --- a/app/assets/javascripts/search.js +++ b/app/assets/javascripts/search.js @@ -69,10 +69,12 @@ function searchPage() { // Check if the user filtered by role var role = new URL(location.href).searchParams.get('role') + var tab = new URL(location.href).searchParams.get('tab') var url = window.location.pathname + "?page=1&search=" + search if (role) { url += "&role=" + role } + if (tab) { url += "&tab=" + tab } window.location.replace(addRecordingTable(url)); } @@ -80,12 +82,16 @@ function searchPage() { // Clears the search bar function clearSearch() { var role = new URL(location.href).searchParams.get('role') + var tab = new URL(location.href).searchParams.get('tab') var url = window.location.pathname + "?page=1" if (role) { url += "&role=" + role } + if (tab) { url += "&tab=" + tab } window.location.replace(addRecordingTable(url)); + + var search_params = new URLSearchParams(window.location.search) } function addRecordingTable(url) { diff --git a/app/assets/stylesheets/admins.scss b/app/assets/stylesheets/admins.scss index 6fe0260a..2265448d 100644 --- a/app/assets/stylesheets/admins.scss +++ b/app/assets/stylesheets/admins.scss @@ -75,8 +75,17 @@ .custom-role-tag{ color: white !important; + // Make it consistent with the manage users tab tags + padding-top: 1px; + padding-bottom: 1px; } .user-role-tag{ color: white !important; +} + +.manage-users-tab { + &:hover { + cursor: pointer; + } } \ No newline at end of file diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index d91d28c6..3f8df722 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -175,3 +175,7 @@ table { .cursor-pointer{ cursor: pointer; } + +#delete-confirm:disabled { + cursor: not-allowed; +} \ No newline at end of file diff --git a/app/assets/stylesheets/utilities/_primary_themes.scss b/app/assets/stylesheets/utilities/_primary_themes.scss index b23f6db4..6c8eb8f3 100644 --- a/app/assets/stylesheets/utilities/_primary_themes.scss +++ b/app/assets/stylesheets/utilities/_primary_themes.scss @@ -182,4 +182,14 @@ input:focus, select:focus { .custom-switch-input:focus ~ .custom-switch-indicator { box-shadow: 0 0 0 2px $primary-color-lighten; border-color: $primary-color-darken !important; +} + +.custom-control-label::before { + border-color: $primary-color-darken !important; +} + +.manage-users-tab { + &.selected { + @extend .btn-primary; + } } \ No newline at end of file diff --git a/app/controllers/admins_controller.rb b/app/controllers/admins_controller.rb index 41e7e9f8..24fd1843 100644 --- a/app/controllers/admins_controller.rb +++ b/app/controllers/admins_controller.rb @@ -24,10 +24,11 @@ class AdminsController < ApplicationController include Rolify manage_users = [:edit_user, :promote, :demote, :ban_user, :unban_user, :approve, :reset] - + manage_deleted_users = [:undelete] authorize_resource class: false before_action :find_user, only: manage_users - before_action :verify_admin_of_user, only: manage_users + before_action :find_deleted_user, only: manage_deleted_users + before_action :verify_admin_of_user, only: [manage_users, manage_deleted_users] # GET /admins def index @@ -37,6 +38,7 @@ class AdminsController < ApplicationController @order_direction = params[:direction] && params[:direction] != "none" ? params[:direction] : "DESC" @role = params[:role] ? Role.find_by(name: params[:role], provider: @user_domain) : nil + @tab = params[:tab] || "active" @pagy, @users = pagy(user_list) end @@ -88,6 +90,15 @@ class AdminsController < ApplicationController redirect_to admins_path, flash: { success: I18n.t("administrator.flash.approved") } end + # POST /admins/approve/:user_uid + def undelete + # Undelete the user and all of his rooms + @user.undelete! + @user.rooms.deleted.each(&:undelete!) + + redirect_to admins_path, flash: { success: I18n.t("administrator.flash.restored") } + end + # POST /admins/invite def invite emails = params[:invite_user][:email].split(",") @@ -208,6 +219,10 @@ class AdminsController < ApplicationController @user = User.where(uid: params[:user_uid]).includes(:roles).first end + def find_deleted_user + @user = User.deleted.where(uid: params[:user_uid]).includes(:roles).first + end + # Verifies that admin is an administrator of the user in the action def verify_admin_of_user redirect_to admins_path, @@ -216,18 +231,31 @@ class AdminsController < ApplicationController # Gets the list of users based on your configuration def user_list + current_role = @role + + initial_user = case @tab + when "active" + User.without_role(:pending).without_role(:denied) + when "deleted" + User.deleted + else + User + end + + current_role = Role.find_by(name: @tab, provider: @user_domain) if @tab == "pending" || @tab == "denied" + initial_list = if current_user.has_role? :super_admin - User.where.not(id: current_user.id) + initial_user.where.not(id: current_user.id) else - User.without_role(:super_admin).where.not(id: current_user.id) + initial_user.without_role(:super_admin).where.not(id: current_user.id) end if Rails.configuration.loadbalanced_configuration initial_list.where(provider: @user_domain) - .admins_search(@search, @role) + .admins_search(@search, current_role) .admins_order(@order_column, @order_direction) else - initial_list.admins_search(@search, @role) + initial_list.admins_search(@search, current_role) .admins_order(@order_column, @order_direction) end end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 05a79fca..9d713079 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -63,17 +63,22 @@ class SessionsController < ApplicationController def create logger.info "Support: #{session_params[:email]} is attempting to login." - admin = User.find_by(email: session_params[:email]) - if admin&.has_role? :super_admin - user = admin - else - user = User.find_by(email: session_params[:email], provider: @user_domain) - redirect_to(signin_path, alert: I18n.t("invalid_credentials")) && return unless user - redirect_to(root_path, alert: I18n.t("invalid_login_method")) && return unless user.greenlight_account? - redirect_to(account_activation_path(email: user.email)) && return unless user.activated? - end - redirect_to(signin_path, alert: I18n.t("invalid_credentials")) && return unless user.try(:authenticate, + user = User.include_deleted.find_by(email: session_params[:email], provider: @user_domain) + + # Check user with that email exists + return redirect_to(signin_path, alert: I18n.t("invalid_credentials")) unless user + # Check correct password was entered + return redirect_to(signin_path, alert: I18n.t("invalid_credentials")) unless user.try(:authenticate, session_params[:password]) + # Check that the user is not deleted + return redirect_to root_path, flash: { alert: I18n.t("registration.banned.fail") } if user.deleted? + + unless user.has_role? :super_admin + # Check that the user is a Greenlight account + return redirect_to(root_path, alert: I18n.t("invalid_login_method")) unless user.greenlight_account? + # Check that the user has verified their account + return redirect_to(account_activation_path(email: user.email)) unless user.activated? + end login(user) end @@ -153,8 +158,19 @@ class SessionsController < ApplicationController end def check_user_exists - provider = @auth['provider'] == "bn_launcher" ? @auth['info']['customer'] : @auth['provider'] - User.exists?(social_uid: @auth['uid'], provider: provider) + User.exists?(social_uid: @auth['uid'], provider: current_provider) + end + + def check_user_deleted(email) + User.deleted.exists?(email: email, provider: @user_domain) + end + + def check_auth_deleted + User.deleted.exists?(social_uid: @auth['uid'], provider: current_provider) + end + + def current_provider + @auth['provider'] == "bn_launcher" ? @auth['info']['customer'] : @auth['provider'] end # Check if the user already exists, if not then check for invitation @@ -172,6 +188,9 @@ class SessionsController < ApplicationController return redirect_to root_path, flash: { alert: I18n.t("registration.deprecated.twitter_signup") } end + # Check if user is deleted + return redirect_to root_path, flash: { alert: I18n.t("registration.banned.fail") } if check_auth_deleted + # If using invitation registration method, make sure user is invited return redirect_to root_path, flash: { alert: I18n.t("registration.invite.no_invite") } unless passes_invite_reqs diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 6bffe8ad..846c714d 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -24,7 +24,7 @@ class UsersController < ApplicationController include Recorder include Rolify - before_action :find_user, only: [:edit, :change_password, :delete_account, :update, :destroy] + before_action :find_user, only: [:edit, :change_password, :delete_account, :update] before_action :ensure_unauthenticated_except_twitter, only: [:create] before_action :check_user_signup_allowed, only: [:create] before_action :check_admin_of, only: [:edit, :change_password, :delete_account] @@ -122,22 +122,41 @@ class UsersController < ApplicationController # DELETE /u/:user_uid def destroy + # Include deleted users in the check + @user = User.include_deleted.find_by(uid: params[:user_uid]) + logger.info "Support: #{current_user.email} is deleting #{@user.email}." self_delete = current_user == @user + redirect_url = self_delete ? root_path : admins_path + begin if current_user && (self_delete || current_user.admin_of?(@user)) - @user.destroy + # Permanently delete if the user is deleting themself + perm_delete = self_delete || (params[:permanent].present? && params[:permanent] == "true") + + # Permanently delete the rooms under the user if they have not been reassigned + if perm_delete + @user.rooms.include_deleted.each do |room| + room.destroy(true) + end + end + + @user.destroy(perm_delete) + + # Log the user out if they are deleting themself session.delete(:user_id) if self_delete - return redirect_to admins_path, flash: { success: I18n.t("administrator.flash.delete") } unless self_delete + return redirect_to redirect_url, flash: { success: I18n.t("administrator.flash.delete") } unless self_delete + else + flash[:alert] = I18n.t("administrator.flash.delete_fail") end rescue => e logger.error "Support: Error in user deletion: #{e}" flash[:alert] = I18n.t(params[:message], default: I18n.t("administrator.flash.delete_fail")) end - redirect_to root_path + redirect_to redirect_url end # GET /u/:user_uid/recordings diff --git a/app/models/ability.rb b/app/models/ability.rb index 8be21b91..649bf02e 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -36,7 +36,7 @@ class Ability if highest_role.get_permission("can_manage_users") can [:index, :roles, :edit_user, :promote, :demote, :ban_user, :unban_user, - :approve, :invite, :reset], :admin + :approve, :invite, :reset, :undelete], :admin end if !highest_role.get_permission("can_edit_site_settings") && !highest_role.get_permission("can_edit_roles") && diff --git a/app/models/concerns/deleteable.rb b/app/models/concerns/deleteable.rb index c74a7aa1..0907ea1b 100644 --- a/app/models/concerns/deleteable.rb +++ b/app/models/concerns/deleteable.rb @@ -26,20 +26,28 @@ module Deleteable scope :deleted, -> { include_deleted.where(deleted: true) } end - def destroy - run_callbacks :destroy - update_attribute(:deleted, true) + def destroy(permanent = false) + if permanent + super() + else + run_callbacks :destroy do end + update_attribute(:deleted, true) + end end - def delete - destroy - end - - def undelete - assign_attributes(deleted: false) + def delete(permanent = false) + destroy(permanent) end def undelete! update_attribute(:deleted, false) end + + def permanent_delete + destroy(true) + end + + def deleted? + deleted + end end diff --git a/app/views/admins/components/_admins_tags.html.erb b/app/views/admins/components/_admins_tags.html.erb index 27f46b40..01b5fea4 100644 --- a/app/views/admins/components/_admins_tags.html.erb +++ b/app/views/admins/components/_admins_tags.html.erb @@ -13,7 +13,7 @@ # with BigBlueButton; if not, see . %> -
+
" class="tag custom-role-tag"> diff --git a/app/views/admins/components/_manage_users_tags.html.erb b/app/views/admins/components/_manage_users_tags.html.erb new file mode 100644 index 00000000..e622c867 --- /dev/null +++ b/app/views/admins/components/_manage_users_tags.html.erb @@ -0,0 +1,33 @@ +<% +# BigBlueButton open source conferencing system - http://www.bigbluespan.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 . +%> + +
+
+
+ + <%= t("roles.active") %> + + + <%= t("roles.pending") %> + + + <%= t("roles.banned") %> + + + <%= t("roles.deleted") %> + +
+
+
\ No newline at end of file diff --git a/app/views/admins/components/_users.html.erb b/app/views/admins/components/_users.html.erb index aa0a6a3c..e893b745 100644 --- a/app/views/admins/components/_users.html.erb +++ b/app/views/admins/components/_users.html.erb @@ -28,7 +28,9 @@ # with BigBlueButton; if not, see . %> -<% unless @role.nil? %> +<% if @role.nil? %> + <%= render "admins/components/manage_users_tags" %> +<% else %> <%= render "admins/components/admins_tags" %> <% end %> @@ -91,40 +93,43 @@ <%= render "admins/components/admins_role", role: user.highest_priority_role %> - <% if roles.include?("pending") %> + <% if !roles.include?("super_admin") %> - <% elsif !roles.include?("super_admin") %> - diff --git a/app/views/shared/modals/_delete_account_modal.html.erb b/app/views/shared/modals/_delete_account_modal.html.erb index da19d594..87b22300 100644 --- a/app/views/shared/modals/_delete_account_modal.html.erb +++ b/app/views/shared/modals/_delete_account_modal.html.erb @@ -26,13 +26,17 @@ <%= t("modal.delete_account.keep") %> - <%= button_to delete_location, method: :delete, id: "delete-confirm", class: "btn btn-danger my-1 btn-del-room" do %> + <%= button_to delete_location, method: :delete, id: "delete-confirm", class: "btn btn-danger my-1 btn-del-room", disabled:"" do %> <%= t("modal.delete_account.delete") %> <% end %>
diff --git a/app/views/users/components/_delete.html.erb b/app/views/users/components/_delete.html.erb index 2fd4c027..17808624 100644 --- a/app/views/users/components/_delete.html.erb +++ b/app/views/users/components/_delete.html.erb @@ -19,7 +19,7 @@
<%= t("settings.delete.disclaimer").html_safe %>
- + <%= t("settings.delete.button") %>
diff --git a/config/locales/en.yml b/config/locales/en.yml index 0088c051..c13114df 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -77,9 +77,11 @@ en: demoted: User has been successfully demoted invite: Invite successfully sent to %{email} invite_email_verification: Emails must be enabled in order to use this method. Please contact your system administrator. + perm_deleted: User has been permanently deleted promoted: User has been successfully promoted registration_method_updated: Registration method successfully updated reset_password: The user has been sent an email to reset their password. (Please ask them to check their spam folder if they haven't received it) + restored: User has been successfully restored settings: Site Settings successfully changed unauthorized: You are not authorized to perform actions on this user recordings: @@ -116,7 +118,9 @@ en: delete: Delete edit: Edit edit_roles: Edit the user roles + perm_delete: Permanently Delete unban: Unban User + undelete: Undelete table: authenticator: Authenticator created: Created @@ -307,6 +311,7 @@ en: confirm: Are you sure you want to delete this account? delete: I'm sure, delete this account. keep: Actually, I'll keep it. + delete_warning: This will deactivate the user's account. All deactived users can be found under the deleted tab. warning: This decision is final. You will not be able to recover associated data. delete_room: confirm: Are you sure you want to delete %{room}? @@ -401,8 +406,10 @@ en: confirm: New Password Confirmation update: Update Password roles: + active: Active admin: Admin banned: Banned + deleted: Deleted pending: Pending user: User room: diff --git a/config/routes.rb b/config/routes.rb index 17ea941b..dd7c07ec 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -48,6 +48,7 @@ Rails.application.routes.draw do post '/invite', to: 'admins#invite', as: :invite_user post '/approve/:user_uid', to: 'admins#approve', as: :admin_approve get '/reset', to: 'admins#reset', as: :admin_reset + post '/undelete', to: 'admins#undelete', as: :admin_undelete # Site Settings post '/update_settings', to: 'admins#update_settings', as: :admin_update_settings post '/registration_method', to: 'admins#registration_method', as: :admin_change_registration diff --git a/spec/controllers/admins_controller_spec.rb b/spec/controllers/admins_controller_spec.rb index 2b9a32ef..78069e69 100644 --- a/spec/controllers/admins_controller_spec.rb +++ b/spec/controllers/admins_controller_spec.rb @@ -166,6 +166,37 @@ describe AdminsController, type: :controller do expect { post :approve, params: params }.to change { ActionMailer::Base.deliveries.count }.by(1) end end + + context "POST #undelete" do + it "undeletes a user" do + @request.session[:user_id] = @admin.id + + @user.delete + + expect(User.find_by(uid: @user.uid)).to be_nil + + post :undelete, params: { user_uid: @user.uid } + + expect(User.find_by(uid: @user.uid)).to be_present + expect(flash[:success]).to be_present + expect(response).to redirect_to(admins_path) + end + + it "undeletes the users rooms" do + @request.session[:user_id] = @admin.id + + @user.main_room.delete + @user.delete + + expect(Room.find_by(uid: @user.main_room.uid)).to be_nil + + post :undelete, params: { user_uid: @user.uid } + + expect(Room.find_by(uid: @user.main_room.uid)).to be_present + expect(flash[:success]).to be_present + expect(response).to redirect_to(admins_path) + end + end end describe "User Design" do diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index d5e5c500..f1ef34eb 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -134,6 +134,26 @@ describe SessionsController, type: :controller do expect(response).to redirect_to(account_activation_path(email: @user3.email)) end + it "should not login user if account is deleted" do + user = create(:user, provider: "greenlight", + password: "example", password_confirmation: 'example') + + user.delete + user.reload + expect(user.deleted?).to be true + + post :create, params: { + session: { + email: user.email, + password: 'example', + }, + } + + expect(@request.session[:user_id]).to be_nil + expect(flash[:alert]).to eq(I18n.t("registration.banned.fail")) + expect(response).to redirect_to(root_path) + end + it "redirects the user to the page they clicked sign in from" do user = create(:user, provider: "greenlight", password: "example", password_confirmation: 'example') @@ -289,6 +309,27 @@ describe SessionsController, type: :controller do expect(@request.session[:user_id]).to eql(u.id) end + it "redirects a deleted user to the root page" do + # Create the user first + request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:bn_launcher] + get :omniauth, params: { provider: 'bn_launcher' } + + # Delete the user + user = User.find_by(social_uid: "bn-launcher-user") + + @request.session[:user_id] = nil + user.delete + user.reload + expect(user.deleted?).to be true + + # Try to sign back in + get :omniauth, params: { provider: 'bn_launcher' } + + expect(@request.session[:user_id]).to be_nil + expect(flash[:alert]).to eq(I18n.t("registration.banned.fail")) + expect(response).to redirect_to(root_path) + end + it "should redirect to root on invalid omniauth login" do request.env["omniauth.auth"] = :invalid_credentials get :omniauth, params: { provider: :google } diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 21025cce..c33daf74 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -396,16 +396,17 @@ describe UsersController, type: :controller do describe "DELETE #user" do before { allow(Rails.configuration).to receive(:allow_user_signup).and_return(true) } - it "properly deletes user" do + it "permanently deletes user" do user = create(:user) @request.session[:user_id] = user.id delete :destroy, params: { user_uid: user.uid } + expect(User.include_deleted.find_by(uid: user.uid)).to be_nil expect(response).to redirect_to(root_path) end - it "allows admins to delete users" do + it "allows admins to tombstone users" do allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true) allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true) allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("provider1") @@ -418,6 +419,46 @@ describe UsersController, type: :controller do delete :destroy, params: { user_uid: user.uid } + expect(User.deleted.find_by(uid: user.uid)).to be_present + expect(flash[:success]).to be_present + expect(response).to redirect_to(admins_path) + end + + it "allows admins to permanently delete users" do + allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true) + allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true) + allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("provider1") + controller.instance_variable_set(:@user_domain, "provider1") + + user = create(:user, provider: "provider1") + admin = create(:user, provider: "provider1") + admin.add_role :admin + @request.session[:user_id] = admin.id + + delete :destroy, params: { user_uid: user.uid, permanent: "true" } + + expect(User.include_deleted.find_by(uid: user.uid)).to be_nil + expect(flash[:success]).to be_present + expect(response).to redirect_to(admins_path) + end + + it "permanently deletes the users rooms if the user is permanently deleted" do + allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true) + allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true) + allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("provider1") + controller.instance_variable_set(:@user_domain, "provider1") + + user = create(:user, provider: "provider1") + admin = create(:user, provider: "provider1") + admin.add_role :admin + @request.session[:user_id] = admin.id + uid = user.main_room.uid + + expect(Room.find_by(uid: uid)).to be_present + + delete :destroy, params: { user_uid: user.uid, permanent: "true" } + + expect(Room.include_deleted.find_by(uid: uid)).to be_nil expect(flash[:success]).to be_present expect(response).to redirect_to(admins_path) end @@ -435,7 +476,8 @@ describe UsersController, type: :controller do delete :destroy, params: { user_uid: user.uid } - expect(response).to redirect_to(root_path) + expect(flash[:alert]).to be_present + expect(response).to redirect_to(admins_path) end end