Created
September 18, 2021 13:48
-
-
Save peimelo/b5ec31a30555439c6e575391e939b2c6 to your computer and use it in GitHub Desktop.
Devise: Password complexity
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/services/application_service.rb | |
class ApplicationService | |
def self.call(*args, &block) | |
new(*args, &block).call | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/services/check_password_complexity_service.rb | |
class CheckPasswordComplexityService < ApplicationService | |
attr_reader :password, :required_complexity | |
def initialize(password, required_complexity = 4) | |
@password = password | |
@required_complexity = required_complexity | |
end | |
def call | |
score = uppercase_letters? + digits? + extra_chars? + downcase_letters? | |
score >= required_complexity | |
end | |
private | |
def digits? | |
@password.match(/\d/) ? 1 : 0 | |
end | |
def downcase_letters? | |
@password.match(/[a-z]{1}/) ? 1 : 0 | |
end | |
def extra_chars? | |
@password.match(/[\W_]/) ? 1 : 0 | |
end | |
def uppercase_letters? | |
@password.match(/[A-Z]/) ? 1 : 0 | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config/locales/en.yml | |
en: | |
activerecord: | |
errors: | |
messages: | |
complexity: 'complexity requirement not met. Please use: 1 uppercase, 1 lowercase, 1 digit and 1 special character' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/user.rb | |
class User < ActiveRecord::Base | |
devise :confirmable, | |
:database_authenticatable, | |
:recoverable, | |
:registerable, | |
:rememberable, | |
:trackable, | |
:validatable | |
validate :password_complexity | |
private | |
def password_complexity | |
return if password.nil? | |
errors.add :password, :complexity unless CheckPasswordComplexityService.call(password) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# spec/models/user_spec.rb | |
require 'rails_helper' | |
RSpec.describe User, type: :model do | |
describe 'validations' do | |
it { should validate_presence_of(:email) } | |
it { should validate_length_of(:password).is_at_least(8) } | |
end | |
describe 'password_complexity' do | |
context 'valid' do | |
['`', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', | |
'-', '_', '=', '+', '[', ']', '{', '}', '\\', '|', ';', ':', | |
"'", '"', ',', '.', '<', '>', '/', '?'].each do |extra_char| | |
it { should allow_value("Password12#{extra_char}").for(:password) } | |
end | |
end | |
context 'invalid' do | |
%w(12345678 password =+[]{}\| PASSWORD password1 pa$$word Password1 password_1).each do |password| | |
it { should_not allow_value(password).for(:password) } | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment