module Sequel::Simple::OAuth2::ResourceOwner

ResourceOwner role mixin for Sequel. Includes all the required API, associations, validations and callbacks

Constants

MAX_PASSWORD_LENGTH_ALLOWED

BCrypt hash function can handle maximum 72 characters, and if we pass password of length more than 72 characters it ignores extra characters. Hence need to put a restriction on password length.

Public Class Methods

oauth_authenticate(_client, username, password) click to toggle source

Searches for ResourceOwner record with the specific params.

@param _client [Object] Client instance. @param username [String, to_s] username value (any object that responds to `#to_s`). @param password [String] password value.

@return [Object, nil] ResourceOwner object or nil if there is no record with such params.

@example

User.create(username: 'foo', password: 'foo')
user = User.oauth_authenticate(nil, 'foo', 'password')
user.username # => 'foo'
another_user = User.oauth_authenticate(nil, 'notfoo', 'password')
another_user # => nil
# File lib/sequel_simple_oauth2/mixins/resource_owner.rb, line 49
def self.oauth_authenticate(_client, username, password)
  resource_owner = first(username: username.to_s)
  resource_owner && resource_owner.authenticate(password)
end

Public Instance Methods

authenticate(pass) click to toggle source

Returns resource if the password is correct, otherwise false.

@param pass [String] Password value.

@return [Object, false] ResourceOwner object or false if password is incorrect.

@example

user = User.new(password: 'foo')
user.save
user.authenticate('notfoo') # => false
user.authenticate('foo')    # => user
# File lib/sequel_simple_oauth2/mixins/resource_owner.rb, line 66
def authenticate(pass)
  password.is_password?(pass) && self
end
min_cost?() click to toggle source

Allows to increase the amount of work required to hash a password as computers get faster. Old passwords will still work fine, but new passwords can keep up with the times. If true returns BCrypt::Engine::MIN_COST otherwise BCrypt::Engine.cost.

@example

user = User.new
user.min_cost? # => false
# File lib/sequel_simple_oauth2/mixins/resource_owner.rb, line 92
def min_cost?
  false
end
password() click to toggle source

Returns encrypted password if encrypted_password is not empty.

@return [String] Encrypted password.

@example

user = User.new
user.password = 'foo'
user.password          # => "$2a$10$4LEA7r4YmNHtvlAvHhsYAeZmk/xeUVtMTYqwIvYY76EW5GUqDiP4."
user.password == 'foo' # => true
# File lib/sequel_simple_oauth2/mixins/resource_owner.rb, line 80
def password
  @password ||= BCrypt::Password.new(encrypted_password) if encrypted_password
end
password=(pass) click to toggle source

Encrypts the password into the encrypted_password attribute, only if the new password is not empty.

@param pass [String] Password value.

@return [String] Encrypted password.

@example

user = User.new
user.password = nil
user.encrypted_password # => nil
user.password = 'foo'
user.encrypted_password # => "$2a$10$4LEA7r4YmNHtvlAvHhsYAeZmk/xeUVtMTYqwIvYY76EW5GUqDiP4."
# File lib/sequel_simple_oauth2/mixins/resource_owner.rb, line 109
def password=(pass)
  if pass.present? && pass.length >= MAX_PASSWORD_LENGTH_ALLOWED
    raise(ArgumentError, "Password is longer than #{MAX_PASSWORD_LENGTH_ALLOWED} characters")
  elsif pass.present?
    cost = min_cost? ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
    new_password = BCrypt::Password.create(pass, cost: cost)
  end

  self.encrypted_password = new_password
end
validate() click to toggle source

Required fields!

Calls superclass method
# File lib/sequel_simple_oauth2/mixins/resource_owner.rb, line 24
def validate
  super
  validates_presence :password
  validates_max_length MAX_PASSWORD_LENGTH_ALLOWED, :password_confirmation, allow_nil: true

  if password_confirmation.present? && password != password_confirmation
    errors.add(:password_confirmation, 'must match with password')
  end
end