0

I have researched a lot on this topic but due to some reason I am unable to perform password complexity implementation on my Ruby on Rails Web Application. I have installed the devise gem and followed Best flexible rails password security implementation and How to validate password strength with Devise in Ruby on Rails?.

My regex seems to be working when I check it online

/\A(?=.{8,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[[:^alnum:]])/x

but once I implement it inside my user.rb it just does not work.

My user.rb file:

#Active Record for Users
class User < ActiveRecord::Base
  belongs_to :entity
  has_and_belongs_to_many :groups, :join_table => "users_groups"
  has_many :surveys, inverse_of: :user
  has_many :results, inverse_of: :user

  validates :password, :firstName, :email, :salt, :role, :timezone, presence: true
  validates :email, :uniqueness => {:scope => :entity_id}
  validates_format_of :email, :with => /.+@.+\..+/i

  devise :database_authenticatable, :validatable
  validate :password_complexity

  #User Authentication
  def self.authenticate(email="", lpassword="")
    users = User.where(email: email)
    results = []
    users.each do |user|
      if user && user.match_password(lpassword)
      results.push(user)
      end
    end
    if(results.length == 0)
    return false
    else
    return results
    end
  end

  #Password Check
  def match_password(lpassword="")
        return (BCrypt::Password.new(password).is_password?(lpassword+salt))
    end

  #Password Authentication
  def password_complexity
      if password.present? and not password.match(/\A(?=.{8,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[[:^alnum:]])/x)
        errors.add :password, "must include at least one lowercase letter, one uppercase letter, and one digit"
      end
   end

end
4
  • 1
    What do you mean it "just does not work"? Please edit your question to include the steps you're taking to test this code, the result you expect and the result you're getting. Commented Jan 13, 2016 at 16:44
  • set pry breakpoint into #password_complexity method and try match manually as: /\A(?=.{8,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[[:^alnum:]])/x =~ password Commented Jan 13, 2016 at 17:33
  • It doesn't work meaning that if I enter the incorrect password which does not match the regex expression it still accepts it. Commented Jan 13, 2016 at 17:34
  • 1
    So, I was able to resolve the issue. It was quite a silly solution. The password that was being entered was first hashed using BCrypt and then undergoing validation. Thus, it would pass almost all the tests all the time (including the length and the matching of special characters). In any case, the following code works perfectly. Commented Jan 14, 2016 at 14:47

1 Answer 1

2

What you did should work, but why not do it simply like this

validates :password, format: { with: /\A(?=.{8,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[[:^alnum:]])/, message: "must include at least one lowercase letter, one uppercase letter, and one digit" }
Sign up to request clarification or add additional context in comments.

1 Comment

The only reason why I am doing it inside a function is because I want to later break it down so that the user can exactly know what he is missing and not just a general message.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.