From cc2ca6429508eae19879107c238cb59bb2487294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Meny?= Date: Thu, 10 Mar 2022 12:03:24 +0000 Subject: [PATCH] Add support for admin lockout --- .../20220310120127_add_lockable_fields2.rb | 10 ++++++++ db/schema.rb | 4 ++++ spec/features/auth/user_lockout_spec.rb | 23 ++++++++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20220310120127_add_lockable_fields2.rb diff --git a/db/migrate/20220310120127_add_lockable_fields2.rb b/db/migrate/20220310120127_add_lockable_fields2.rb new file mode 100644 index 000000000..6d1315689 --- /dev/null +++ b/db/migrate/20220310120127_add_lockable_fields2.rb @@ -0,0 +1,10 @@ +class AddLockableFields2 < ActiveRecord::Migration[7.0] + def change + change_table :admin_users, bulk: true do |t| + t.column :failed_attempts, :integer, default: 0 + t.column :unlock_token, :string + t.column :locked_at, :datetime + end + add_index :admin_users, :unlock_token, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 0243ebae1..747e4db7f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -36,7 +36,11 @@ ActiveRecord::Schema[7.0].define(version: 202202071123100) do t.datetime "last_sign_in_at", precision: nil t.string "current_sign_in_ip" t.string "last_sign_in_ip" + t.integer "failed_attempts", default: 0 + t.string "unlock_token" + t.datetime "locked_at", precision: nil t.index ["encrypted_otp_secret_key"], name: "index_admin_users_on_encrypted_otp_secret_key", unique: true + t.index ["unlock_token"], name: "index_admin_users_on_unlock_token", unique: true end create_table "case_logs", force: :cascade do |t| diff --git a/spec/features/auth/user_lockout_spec.rb b/spec/features/auth/user_lockout_spec.rb index c483973a7..c4c7d17c4 100644 --- a/spec/features/auth/user_lockout_spec.rb +++ b/spec/features/auth/user_lockout_spec.rb @@ -2,9 +2,10 @@ require "rails_helper" RSpec.describe "User Lockout" do let(:user) { FactoryBot.create(:user) } + let(:admin) { FactoryBot.create(:admin_user) } let(:attempt_number) { Devise.maximum_attempts } - context "when login-in with the wrong password up to a maximum number of attempts" do + context "when login-in with the wrong user password up to a maximum number of attempts" do before do attempt_number.times do visit("/users/sign-in") @@ -23,4 +24,24 @@ RSpec.describe "User Lockout" do expect(page).to have_content("Your account is locked.") end end + + context "when login-in with the wrong admin password up to a maximum number of attempts" do + before do + attempt_number.times do + visit("/admin/sign-in") + fill_in("admin_user[email]", with: admin.email) + fill_in("admin_user[password]", with: "wrong_password") + click_button("Sign in") + end + end + + it "locks the admin account" do + visit("/admin/sign-in") + fill_in("admin_user[email]", with: admin.email) + fill_in("admin_user[password]", with: admin.password) + click_button("Sign in") + expect(page).to have_http_status(:unprocessable_entity) + expect(page).to have_content("Your account is locked.") + end + end end