Module: Devise::Models::Lockable

Includes:
Activatable
Defined in:
lib/devise/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 it’s account. The second will unlock the user automatically after some configured time (ie 2.hours). It’s also possible to setup lockable to use both email and time strategies.

Configuration:

maximum_attempts: how many attempts should be accepted before blocking the user.
unlock_strategy: unlock the user account by :time, :email or :both.
unlock_in: the time you want to lock the user after to lock happens. Only
           available when unlock_strategy is :time or :both.

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



23
24
25
26
27
# File 'lib/devise/models/lockable.rb', line 23

def self.included(base)
  base.class_eval do
    extend ClassMethods
  end
end

Instance Method Details

#active?Boolean

Overwrites active? from Devise::Models::Activatable for locking purposes by verifying whether an user is active to sign in or not based on locked?

Returns:

  • (Boolean)


75
76
77
# File 'lib/devise/models/lockable.rb', line 75

def active?
  super && !locked?
end

#inactive_messageObject

Overwrites invalid_message from Devise::Models::Authenticatable to define the correct reason for blocking the sign in.



81
82
83
84
85
86
87
# File 'lib/devise/models/lockable.rb', line 81

def inactive_message
  if locked?
    :locked
  else
    super
  end
end

#lockObject

Lock an user setting it’s locked_at to actual time.



30
31
32
33
34
35
36
# File 'lib/devise/models/lockable.rb', line 30

def lock
  self.locked_at = Time.now
  if unlock_strategy_enabled?(:email)
    generate_unlock_token
    send_unlock_instructions
  end
end

#lock!Object

Lock an user also saving the record.



39
40
41
42
# File 'lib/devise/models/lockable.rb', line 39

def lock!
  lock
  save(false)
end

#locked?Boolean

Verifies whether a user is locked or not.

Returns:

  • (Boolean)


55
56
57
# File 'lib/devise/models/lockable.rb', line 55

def locked?
  locked_at && !lock_expired?
end

#resend_unlock!Object

Resend the unlock instructions if the user is locked.



65
66
67
68
69
70
71
# File 'lib/devise/models/lockable.rb', line 65

def resend_unlock!
  if_locked do
    generate_unlock_token unless unlock_token.present?
    save(false)
    send_unlock_instructions
  end
end

#send_unlock_instructionsObject

Send unlock instructions by email



60
61
62
# File 'lib/devise/models/lockable.rb', line 60

def send_unlock_instructions
  ::DeviseMailer.deliver_unlock_instructions(self)
end

#unlock!Object

Unlock an user by cleaning locket_at and failed_attempts.



45
46
47
48
49
50
51
52
# File 'lib/devise/models/lockable.rb', line 45

def unlock!
  if_locked do
    self.locked_at = nil
    self.failed_attempts = 0
    self.unlock_token = nil
    save(false)
  end
end

#valid_for_authentication?(attributes) ⇒ Boolean

Overwrites valid_for_authentication? from Devise::Models::Authenticatable for verifying whether an user is allowed to sign in or not. If the user is locked, it should never be allowed.

Returns:

  • (Boolean)


92
93
94
95
96
97
98
99
100
101
# File 'lib/devise/models/lockable.rb', line 92

def valid_for_authentication?(attributes)
  if result = super
    self.failed_attempts = 0
  else
    self.failed_attempts += 1
    lock if failed_attempts > self.class.maximum_attempts
  end
  save(false) if changed?
  result
end