Module: Negroni::Models::Lockable
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/negroni/models/lockable.rb
Overview
Handles blocking a user access after a certain number of attempts. Lockable accepts two different strategies to unlock a user after it’s blocked: email and time. The former will send an email to the user when the lock happens, containing a link to unlock its account. The second will unlock the user automatically after some configured time (ie 2.hours). It’s also possible to set up lockable to use both email and time strategies.
## Options
Lockable adds the following options to ‘negroni`:
* `maximum_attempts`: how many attempts should be accepted before
blocking the user.
* `lock_strategy`: lock the user account by :failed_attempts or :none.
* `unlock_strategy`: unlock the user account by :time, :email, :both or
:none.
* `unlock_in`: the time you want to lock the user after to lock happens.
Only available when unlock_strategy is :time or :both.
* `unlock_keys`: the keys you want to use when locking and unlocking.
Defined Under Namespace
Modules: ClassMethods
Class Method Summary collapse
-
.required_fields(klass) ⇒ Object
Required fields.
Instance Method Summary collapse
-
#access_locked? ⇒ Boolean
Returns true if the user has access locked.
-
#active_for_auth? ⇒ Boolean
Override active_for_auth? for locking purposes.
-
#inactive_message ⇒ Object
Override for locking purposes.
-
#lock_access!(opts = {}) ⇒ Object
Lock a user setting its locked_at to actual time.
-
#lock_strategy_enabled?(strategy) ⇒ Boolean
If the passed strategy is enabled.
-
#resend_unlock_instructions ⇒ Object
Resend instructions if the user is locked.
-
#send_unlock_instructions ⇒ Object
send instructions to unlock.
-
#unauthenticated_message ⇒ Object
Override for locking.
-
#unlock_access! ⇒ Object
Unlock a user, clearing ‘locked_at` and `failed_attempts`.
-
#valid_for_auth? ⇒ Boolean
Override for locking purposes.
Class Method Details
.required_fields(klass) ⇒ Object
Required fields
36 37 38 39 40 41 42 |
# File 'lib/negroni/models/lockable.rb', line 36 def self.required_fields(klass) att = [] att << :failed_attempts if klass.lock_strategy_enabled? :failed_attempts att << :locked_at if klass.unlock_strategy_enabled? :time att << :unlock_token if klass.unlock_strategy_enabled? :email att end |
Instance Method Details
#access_locked? ⇒ Boolean
Returns true if the user has access locked
70 71 72 |
# File 'lib/negroni/models/lockable.rb', line 70 def access_locked? locked_at && !lock_expired? end |
#active_for_auth? ⇒ Boolean
Override active_for_auth? for locking purposes
90 91 92 |
# File 'lib/negroni/models/lockable.rb', line 90 def active_for_auth? super && !access_locked? end |
#inactive_message ⇒ Object
Override for locking purposes
95 96 97 |
# File 'lib/negroni/models/lockable.rb', line 95 def access_locked? ? :locked : super end |
#lock_access!(opts = {}) ⇒ Object
Lock a user setting its locked_at to actual time.
49 50 51 52 53 54 55 56 57 58 |
# File 'lib/negroni/models/lockable.rb', line 49 def lock_access!(opts = {}) self.locked_at = Time.now.utc if unlock_strategy_enabled?(:email) && opts.fetch(:send_instructions, true) send_unlock_instructions else save(validate: false) end end |
#lock_strategy_enabled?(strategy) ⇒ Boolean
Returns if the passed strategy is enabled.
31 32 33 |
# File 'lib/negroni/models/lockable.rb', line 31 delegate :lock_strategy_enabled?, :unlock_strategy_enabled?, to: 'self.class' |
#resend_unlock_instructions ⇒ Object
Resend instructions if the user is locked
85 86 87 |
# File 'lib/negroni/models/lockable.rb', line 85 def resend_unlock_instructions if_access_locked { send_unlock_instructions } end |
#send_unlock_instructions ⇒ Object
send instructions to unlock
75 76 77 78 79 80 81 82 |
# File 'lib/negroni/models/lockable.rb', line 75 def send_unlock_instructions raw, enc = Negroni.token_generator.generate(self.class, :unlock_token) self.unlock_token = enc save(validate: false) # rubocop:disable Rails/SaveBang send_auth_notification(:unlock_instructions, raw, {}) raw end |
#unauthenticated_message ⇒ Object
Override for locking
123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/negroni/models/lockable.rb', line 123 def if Negroni.paranoid super elsif access_locked? || (lock_strategy_enabled?(:failed_attempts) && attempts_exceeded?) :locked elsif lock_strategy_enabled?(:failed_attempts) && last_attempt? && self.class.last_attempt_warning :last_attempt else super end end |
#unlock_access! ⇒ Object
Unlock a user, clearing ‘locked_at` and `failed_attempts`.
61 62 63 64 65 66 |
# File 'lib/negroni/models/lockable.rb', line 61 def unlock_access! self.locked_at = nil self.failed_attempts = 0 if respond_to?(:failed_attempts=) self.unlock_token = nil if respond_to?(:unlock_token=) save(validate: false) end |
#valid_for_auth? ⇒ Boolean
Override for locking purposes
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/negroni/models/lockable.rb', line 102 def valid_for_auth? return super unless persisted? && lock_strategy_enabled?(:failed_attempts) unlock_access! if lock_expired? return true if super && !access_locked? self.failed_attempts ||= 0 self.failed_attempts += 1 if attempts_exceeded? lock_access! unless access_locked? else save(validate: false) end false end |