Module: OmniAuth::Identity::SecurePassword::ClassMethods

Defined in:
lib/omniauth/identity/secure_password.rb

Overview

Class-level methods for secure password functionality.

Instance Method Summary collapse

Instance Method Details

#has_secure_password(attribute = :password, validations: true) ⇒ void

This method returns an undefined value.

Adds methods to set and authenticate against a BCrypt password.
This mechanism requires you to have a +XXX_digest+ attribute.
Where +XXX+ is the attribute name of your desired password.

For Supported ActiveModel-based ORMs:

  • ActiveRecord
  • CouchPotato
  • Mongoid
  • NoBrainer

the following validations are added automatically:

  • Password must be present on creation
  • Password length should be less than or equal to 72 bytes
  • Confirmation of password (using a +XXX_confirmation+ attribute)

If confirmation validation is not needed, simply leave out the
value for +XXX_confirmation+ (i.e. don’t provide a form field for
it). When this attribute has a +nil+ value, the validation will not be
triggered.

For Supported non-ActiveModel-based ORMs:

  • Sequel

validations are disabled by default.

It is possible to disable the default validations in any ORM
by passing validations: false as an argument.

Add bcrypt (~> 3.1.7) to Gemfile to use #has_secure_password:

gem ‘bcrypt’, ‘~> 3.1.7’

Example using Active Record (which automatically includes ActiveModel::SecurePassword):

# Schema: User(name:string, password_digest:string, recovery_password_digest:string)
class User < ActiveRecord::Base
has_secure_password
has_secure_password :recovery_password, validations: false
end

user = User.new(name: ‘david’, password: ‘’, password_confirmation: ‘nomatch’)
user.save # => false, password required
user.password = ‘mUc3m00RsqyRe’
user.save # => false, confirmation doesn’t match
user.password_confirmation = ‘mUc3m00RsqyRe’
user.save # => true
user.recovery_password = “42password”
user.recovery_password_digest # => “$2a$04$iOfhwahFymCs5weB3BNH/uXkTG65HR.qpW.bNhEjFP3ftli3o5DQC”
user.save # => true
user.authenticate(‘notright’) # => false
user.authenticate(‘mUc3m00RsqyRe’) # => user
user.authenticate_recovery_password(‘42password’) # => user
User.find_by(name: ‘david’)&.authenticate(‘notright’) # => false
User.find_by(name: ‘david’)&.authenticate(‘mUc3m00RsqyRe’) # => user

Parameters:

  • attribute (Symbol, String) (defaults to: :password)

    the attribute name for the password (default: :password)

  • validations (true, false) (defaults to: true)

    whether to add validations (default: true)



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/omniauth/identity/secure_password.rb', line 113

def has_secure_password(attribute = :password, validations: true)
  # Load bcrypt gem only when has_secure_password is used.
  # This is to avoid ActiveModel (and by extension the entire framework)
  # being dependent on a binary library.
  begin
    require "bcrypt"
  rescue LoadError
    warn("You don't have bcrypt installed in your application. Please add it to your Gemfile and run bundle install")
    raise
  end

  include(InstanceMethodsOnActivation.new(attribute))

  if validations
    if !defined?(ActiveModel)
      warn("[DEPRECATION][omniauth-identity v3.1][w/ Sequel ORM] has_secure_password(validations: true) is default, but incurs dependency on ActiveModel. v4 will default to `has_secure_password(validations: false)`.")
      begin
        require "active_model"
      rescue LoadError
        warn("You don't have active_model installed in your application. Please add it to your Gemfile and run bundle install")
        raise
      end
    end
    include(ActiveModel::Validations)

    # This ensures the model has a password by checking whether the password_digest
    # is present, so that this works with both new and existing records. However,
    # when there is an error, the message is added to the password attribute instead
    # so that the error message will make sense to the end-user.
    validate do |record|
      record.errors.add(attribute, :blank) unless record.public_send(:"#{attribute}_digest").present?
    end

    validates_length_of(attribute, maximum: MAX_PASSWORD_LENGTH_ALLOWED)
    validates_confirmation_of(attribute, allow_blank: true)
  end
end