diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5020faf7b6..9c22277244 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -39,6 +39,7 @@ class ApplicationController < ActionController::Base include Spree::Core::ControllerHelpers::Common before_action :set_cache_headers # prevent cart emptying via cache when using back button #1213 + before_action :check_disabled_user, if: :spree_user_signed_in? before_action :set_after_login_url include RawParams @@ -159,6 +160,14 @@ class ApplicationController < ActionController::Base response.headers["Pragma"] = "no-cache" response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT" end + + def check_disabled_user + return unless current_spree_user.disabled + + flash[:success] = nil + flash.now[:error] = I18n.t("devise.failure.disabled") + sign_out current_spree_user + end end require 'spree/i18n/initializer' diff --git a/app/models/spree/user.rb b/app/models/spree/user.rb index 542e43a0b9..3ff88d8fa9 100644 --- a/app/models/spree/user.rb +++ b/app/models/spree/user.rb @@ -144,6 +144,14 @@ module Spree "#{self.class.name};#{id}" end + def disabled + disabled_at.present? + end + + def disabled=(value) + self.disabled_at = value == '1' ? Time.zone.now : nil + end + protected def password_required? diff --git a/app/services/permitted_attributes/user.rb b/app/services/permitted_attributes/user.rb index 4efbf0e3b5..0b511bab21 100644 --- a/app/services/permitted_attributes/user.rb +++ b/app/services/permitted_attributes/user.rb @@ -15,7 +15,7 @@ module PermittedAttributes private def permitted_attributes - [:email, :password, :password_confirmation] + [:email, :password, :password_confirmation, :disabled] end end end diff --git a/app/views/spree/admin/users/_form.html.haml b/app/views/spree/admin/users/_form.html.haml index 47bf167151..5262ca05df 100644 --- a/app/views/spree/admin/users/_form.html.haml +++ b/app/views/spree/admin/users/_form.html.haml @@ -23,4 +23,8 @@ = f.field_container :password do = f.label :password_confirmation, t(".confirm_password") = f.password_field :password_confirmation, class: "fullwidth" - = f.error_message_on :password_confirmation \ No newline at end of file + = f.error_message_on :password_confirmation + = f.field_container :disabled do + = f.label :disabled, t(".disabled") + = f.check_box :disabled + = f.error_message_on :disabled diff --git a/config/locales/en.yml b/config/locales/en.yml index 3820f0c536..8aae021b39 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -207,6 +207,7 @@ en: signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please open the link to activate your account." unknown_error: "Something went wrong while creating your account. Check your email address and try again." failure: + disabled: "Your account has been disabled. Please contact an administrator to solve this issue." invalid: | Invalid email or password. Were you a guest last time? Perhaps you need to create an account or reset your password. @@ -3965,6 +3966,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using back_to_users_list: "Back To Users List" general_settings: "General Settings" form: + disabled: "Disabled?" email: "Email" roles: "Roles" enterprise_limit: "Enterprise Limit" diff --git a/db/migrate/20220425230907_add_disabled_at_to_spree_users.rb b/db/migrate/20220425230907_add_disabled_at_to_spree_users.rb new file mode 100644 index 0000000000..a9b4b55d62 --- /dev/null +++ b/db/migrate/20220425230907_add_disabled_at_to_spree_users.rb @@ -0,0 +1,5 @@ +class AddDisabledAtToSpreeUsers < ActiveRecord::Migration[6.1] + def change + add_column :spree_users, :disabled_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index edfd135051..96cab7ce42 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_06_02_013938) do +ActiveRecord::Schema.define(version: 2022_06_21_230907) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -1055,6 +1055,7 @@ ActiveRecord::Schema.define(version: 2022_06_02_013938) do t.datetime "confirmed_at" t.datetime "confirmation_sent_at" t.string "unconfirmed_email", limit: 255 + t.datetime "disabled_at" t.index ["confirmation_token"], name: "index_spree_users_on_confirmation_token", unique: true t.index ["email"], name: "email_idx_unique", unique: true t.index ["persistence_token"], name: "index_users_on_persistence_token" diff --git a/spec/models/spree/user_spec.rb b/spec/models/spree/user_spec.rb index 0730a050c9..d29cd3d038 100644 --- a/spec/models/spree/user_spec.rb +++ b/spec/models/spree/user_spec.rb @@ -201,4 +201,38 @@ describe Spree::User do expect(user.flipper_id).to eq "Spree::User;42" end end + + describe "#disabled=" do + context 'when the value is truthy' do + it "sets disabled datetime" do + user = Spree::User.new + expect(user.disabled_at).to be_nil + user.disabled = '1' + expect(user.disabled_at).not_to be_nil + end + end + + context 'when the value is falsey' do + it "clears disabled datetime" do + user = Spree::User.new(disabled_at: Time.zone.now) + expect(user.disabled_at).not_to be_nil + user.disabled = '0' + expect(user.disabled_at).to be_nil + end + end + end + + describe "#disabled" do + it "returns true with a disabled datetime" do + user = Spree::User.new + user.disabled = '1' + expect(user.disabled).to be_truthy + end + + it "returns false without a disabled datetime" do + user = Spree::User.new(disabled_at: Time.zone.now) + user.disabled = '0' + expect(user.disabled).to be_falsey + end + end end diff --git a/spec/system/admin/users_spec.rb b/spec/system/admin/users_spec.rb index e95b081066..8c558436bf 100644 --- a/spec/system/admin/users_spec.rb +++ b/spec/system/admin/users_spec.rb @@ -90,6 +90,20 @@ describe "Managing users" do click_button "Clear key" expect(page).to have_content "NO KEY" end + + it "should allow to disable the user and to enable it" do + expect(page).to have_unchecked_field "Disabled" + check "Disabled" + click_button "Update" + + expect(page).to have_content("Account updated") + expect(page).to have_checked_field "Disabled" + uncheck "Disabled" + click_button "Update" + + expect(page).to have_content("Account updated") + expect(page).to have_unchecked_field "Disabled" + end end end