diff --git a/app/controllers/account_sessions_controller.rb b/app/controllers/account_sessions_controller.rb index dc9b4ca..3e83657 100644 --- a/app/controllers/account_sessions_controller.rb +++ b/app/controllers/account_sessions_controller.rb @@ -1,4 +1,5 @@ class AccountSessionsController < ApplicationController + skip_before_action :redirect_locked_accounts def update authorize :account_session, :update? session[:active_account] = account_session_params[:account_id] diff --git a/app/controllers/admin/account_locks_controller.rb b/app/controllers/admin/account_locks_controller.rb new file mode 100644 index 0000000..21aa3bd --- /dev/null +++ b/app/controllers/admin/account_locks_controller.rb @@ -0,0 +1,31 @@ +class Admin::AccountLocksController < Admin::ApplicationController + before_action :set_account + + def create + authorize :account_lock, :create? + @account.update(locked: true) + redirect_to admin_accounts_path, notice: 'Account locked' + end + + def destroy + authorize :account_lock, :destroy? + @account.update(locked: false) + redirect_to admin_accounts_path, notice: 'Account unlocked' + end + + private + + def set_account + if params[:account_id].present? + @account = Account.find_by(slug: params[:account_id]) + else + failure_redirect + end + rescue ActiveRecord::RecordNotFound + failure_redirect + end + + def failure_redirect + redirect_to admin_accounts_path, alert: 'Failed to find the account' + end +end \ No newline at end of file diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 6f6b302..ef1dce4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -13,6 +13,7 @@ class ApplicationController < ActionController::Base include SetCurrentRequestDetails before_action :redirect_accountless + before_action :redirect_locked_accounts private @@ -29,6 +30,12 @@ class ApplicationController < ActionController::Base end end + def redirect_locked_accounts + if Current.user && !Current.user.admin? && Current.account.present? && Current.account.locked? + redirect_to locked_account_path + end + end + def signed_in_as_admin? signed_in? && current_user.admin? end diff --git a/app/controllers/locked_accounts_controller.rb b/app/controllers/locked_accounts_controller.rb new file mode 100644 index 0000000..90a0618 --- /dev/null +++ b/app/controllers/locked_accounts_controller.rb @@ -0,0 +1,10 @@ +class LockedAccountsController < ApplicationController + skip_before_action :redirect_locked_accounts + skip_after_action :verify_policy_scoped + + def index + unless Current.account.locked? + redirect_to projects_path + end + end +end diff --git a/app/policies/account_lock_policy.rb b/app/policies/account_lock_policy.rb new file mode 100644 index 0000000..f14f1f6 --- /dev/null +++ b/app/policies/account_lock_policy.rb @@ -0,0 +1,9 @@ +class AccountLockPolicy < ApplicationPolicy + def create? + user.admin? + end + + def destroy? + user.admin? + end +end diff --git a/app/views/admin/accounts/_account.html.erb b/app/views/admin/accounts/_account.html.erb index e418727..bc761b7 100644 --- a/app/views/admin/accounts/_account.html.erb +++ b/app/views/admin/accounts/_account.html.erb @@ -30,6 +30,11 @@ <%= link_to fa_icon("arrow-right", text: "Overview"), admin_account_path(account), class: "dropdown-item" %> <%= link_to fa_icon("pencil", text: "Edit"), edit_admin_account_path(account), class: "dropdown-item" %> <%= link_to fa_icon("arrow-right", text: "Account Managers"), account_auths_path({ account_id: account.id}), class: "dropdown-item" %> + <% if account.locked? %> + <%= link_to fa_icon("unlock", text: "Unlock Account"), [:admin, account, :lock], method: :delete, class: "dropdown-item" %> + <% else %> + <%= link_to fa_icon("lock", text: "Lock Account"), [:admin, account, :lock], method: :post, class: "dropdown-item" %> + <% end %> diff --git a/app/views/locked_accounts/index.html.erb b/app/views/locked_accounts/index.html.erb new file mode 100644 index 0000000..521868f --- /dev/null +++ b/app/views/locked_accounts/index.html.erb @@ -0,0 +1 @@ +

<%= t '.account_locked_message' %>

\ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 7413d44..f7aa204 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1651,3 +1651,6 @@ en: edit: Edit report: Report generating: Generating... + locked_accounts: + index: + account_locked_message: This account is locked. Please contact a BIG admin. diff --git a/config/locales/es.yml b/config/locales/es.yml index 3383633..78f4ccc 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -705,3 +705,6 @@ es: production_elements_logs: Production Elements Logs, and more (ES) reduces_labor_cost: Reduces labor costs (ES) simplifies_cue_sheets: Simplifies Music Cue Sheets, Graphic Cue Sheets (ES) + locked_accounts: + index: + account_locked_message: This account is locked. Please contact a BIG admin. (ES) diff --git a/config/routes.rb b/config/routes.rb index 147e3ce..4ef5dbe 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -30,7 +30,9 @@ Rails.application.routes.draw do namespace :admin do mount Sidekiq::Web => '/background_queue', as: :background_queue - resources :accounts, only: [:index, :new, :create, :edit, :update, :show] + resources :accounts, only: [:index, :new, :create, :edit, :update, :show] do + resource :account_lock, path: :lock, as: :lock, only: [:create, :destroy] + end resources :users, only: [:index, :new, :create, :edit, :update, :destroy] do resource :masquerade, only: :create end @@ -48,7 +50,9 @@ Rails.application.routes.draw do scope "(:locale)", locale: AVAILABLE_LOCALES_REGEX do resource :account_session, only: [:update] resource :session, only: [:destroy] - resource :account, only: [:new, :create, :update] + resource :account, only: [:new, :create, :update] do + get 'locked' => 'locked_accounts#index' + end resources :account_auths, only: [:index, :create, :update, :destroy] resources :projects, shallow: true do resources :acquired_media_releases, except: [:show], concerns: [:contractable, :notable, :file_uploadable] diff --git a/db/migrate/20200908085319_add_locked_to_accounts.rb b/db/migrate/20200908085319_add_locked_to_accounts.rb new file mode 100644 index 0000000..7ef0855 --- /dev/null +++ b/db/migrate/20200908085319_add_locked_to_accounts.rb @@ -0,0 +1,5 @@ +class AddLockedToAccounts < ActiveRecord::Migration[6.0] + def change + add_column :accounts, :locked, :boolean, default: false + end +end diff --git a/db/structure.sql b/db/structure.sql index 23b141d..a48aad1 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -95,7 +95,8 @@ CREATE TABLE public.accounts ( slug character varying, plan_uid character varying, created_at timestamp without time zone NOT NULL, - updated_at timestamp without time zone NOT NULL + updated_at timestamp without time zone NOT NULL, + locked boolean DEFAULT false ); @@ -4027,6 +4028,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20200812060406'), ('20200819070738'), ('20200820082501'), -('20200824171649'); +('20200824171649'), +('20200908085319'); diff --git a/spec/features/admin_managing_accounts_spec.rb b/spec/features/admin_managing_accounts_spec.rb index 417e4f4..116e2e9 100644 --- a/spec/features/admin_managing_accounts_spec.rb +++ b/spec/features/admin_managing_accounts_spec.rb @@ -30,6 +30,24 @@ feature "Admin managing accounts" do expect(page).to have_content "Created at less than a minute ago" end + scenario "locks and unlocks account" do + sign_in current_user + visit admin_signed_in_root_path + expect(Account.last.locked?).to eq false + + click_button "Manage" + expect(page).not_to have_content "Unlock Account" + click_link "Lock Account" + + expect(Account.last.locked?).to eq true + + click_button "Manage" + expect(page).not_to have_content "Lock Account" + click_link "Unlock Account" + + expect(Account.last.locked?).to eq false + end + scenario "sees videos for an account in the system" do visit_account_overview_page diff --git a/spec/features/user_managing_locked_account_spec.rb b/spec/features/user_managing_locked_account_spec.rb new file mode 100644 index 0000000..8c6192e --- /dev/null +++ b/spec/features/user_managing_locked_account_spec.rb @@ -0,0 +1,34 @@ +require "rails_helper" + +feature "User managing locked account" do + let(:user) { create(:user, :account_manager) } + let(:project) { create(:project) } + + before do + sign_in(user) + user.accounts.first.update(locked: true) + end + + scenario "user is redirected to custom landing page when opens projects index page" do + paths = [ + projects_path, + project_path(project), + project_task_requests_path(project), + project_contract_templates_path(project), + project_broadcasts_path(project), + project_videos_path(project), + ] + + paths.each do |path| + visit path + + expect(page).to have_content locked_account_warning + end + end + + private + + def locked_account_warning + t 'locked_accounts.index.account_locked_message' + end +end