Skip to content

Commit

Permalink
Add validation password (#1153)
Browse files Browse the repository at this point in the history
  • Loading branch information
yasirazgar authored and julianguyen committed Oct 27, 2018
1 parent 2087ad3 commit a1d7844
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 15 deletions.
20 changes: 20 additions & 0 deletions app/models/concerns/password_validator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module PasswordValidator
extend ActiveSupport::Concern

PASSWORD_REGEX = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).*$/

private

def password_complexity
return if good_password?

error_message = I18n.t('devise.registrations.password_complexity_error')
errors.add(:password, error_message)
end

def good_password?
google_oauth2_enabled? || password.blank? || (password =~ PASSWORD_REGEX)
end
end
13 changes: 8 additions & 5 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
#

class User < ApplicationRecord
include PasswordValidator

ALLY_STATUS = {
accepted: 0,
pending_from_user: 1,
Expand Down Expand Up @@ -83,6 +85,7 @@ class User < ApplicationRecord
validates :locale, inclusion: {
in: Rails.application.config.i18n.available_locales.map(&:to_s).push(nil)
}
validate :password_complexity

def ally?(user)
allies_by_status(:accepted).include?(user)
Expand All @@ -108,11 +111,7 @@ def self.find_for_google_oauth2(access_token)
end

def google_access_token
if !access_expires_at || Time.zone.now > access_expires_at
update_access_token
else
token
end
google_access_token_expired? ? update_access_token : token
end

def google_oauth2_enabled?
Expand Down Expand Up @@ -161,6 +160,10 @@ def update_access_token

private

def google_access_token_expired?
!access_expires_at || Time.zone.now > access_expires_at
end

def accepted_ally_ids
allyships.where(status: ALLY_STATUS[:accepted]).pluck(:ally_id)
end
Expand Down
1 change: 1 addition & 0 deletions config/locales/de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,7 @@ de:
meeting_notify_text: Meeting-Updates
google_auth1: 'If you no longer want to be authenticated with Google, please enter a new email and password.'
google_auth2: 'Da du mit Google angemeldet bist, brauchst du kein Passwort eingeen.<br>Wenn du dies ändern möchtest, gib bitte eine E-Mail und ein Passwort ein.'
password_complexity_error: 'sollte 8 bis 128 Zeichen enthalten, einschließlich 1 Großbuchstaben, 1 Kleinbuchstaben, 1 Ziffer und 1 Sonderzeichen.'
placeholders:
repeat_password: 'Passwort wiederholen'
edit:
Expand Down
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,7 @@ en:
meeting_notify_text: 'Meeting updates'
google_auth1: 'If you no longer want to be authenticated with Google, please enter a new email and password.'
google_auth2: 'Since you are authenticated with Google, you do not need to enter your password.<br>If you want to change this, please enter a new email and password.'
password_complexity_error: 'should contain 8 to 128 characters, including 1 uppercase, 1 lowercase, 1 digit, and 1 special character.'
placeholders:
repeat_password: 'Repeat Password'
edit:
Expand Down
1 change: 1 addition & 0 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,7 @@ es:
meeting_notify_text: 'Actualizaciones de reuniones'
google_auth1: 'Si ya no deseas verificar tu identidad a través de Google, por favor ingresa un nuevo correo electrónico y contraseña.'
google_auth2: 'Debido a que tu identidad ha sido confirmada a través de Google, no necesitas ingresar tu contraseña.<br>Si deseas modificar esto, por favor ingresa un nuevo correo electrónico y contraseña.'
password_complexity_error: 'debe contener de 8 a 128 caracteres, incluyendo 1 mayúscula, 1 minúscula, 1 dígito y 1 carácter especial.'
placeholders:
repeat_password: 'Repetir contraseña'
edit:
Expand Down
1 change: 1 addition & 0 deletions config/locales/it.yml
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,7 @@ it:
meeting_notify_text: 'Aggiornamenti sui raduni'
google_auth1: 'Se non vuoi più effettuare l’autenticazione tramite Google, per favore inserisci una nuova EMail e password.'
google_auth2: 'Avendo effettuato l’autenticazione tramite Google, non devi inserire la password.<br>Se non vuoi che sia così, per favore specifica una nuova EMail e password.'
password_complexity_error: 'dovrebbe contenere da 8 a 128 caratteri, inclusi 1 maiuscolo, 1 minuscolo, 1 carattere e 1 carattere speciale.'
placeholders:
repeat_password: 'Ripeti la password'
edit:
Expand Down
1 change: 1 addition & 0 deletions config/locales/nb.yml
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,7 @@ nb:
meeting_notify_text: Møteoppdateringer
google_auth1: 'Hvis du ikke lenger ønsker å bli autorisert med Google, vennligst fyll inn en ny e-post og passord.'
google_auth2: 'Siden du ikke er autorisert med Google trenger du ikke å taste inn passordet ditt.<br>Hvis du ønsker å forandre dette, vennligst fyll inn e-post og passord på nytt.'
password_complexity_error: 'bør inneholde 8 til 128 tegn, inkludert 1 stor, 1 liten, 1 siffer og 1 spesialtegn.'
placeholders:
repeat_password: 'Gjenta passord'
edit:
Expand Down
1 change: 1 addition & 0 deletions config/locales/nl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,7 @@ nl:
meeting_notify_text: 'Samenkomstupdates'
google_auth1: 'Als je niet langer via Google wilt inloggen, geef dan een nieuw e-mailadres en wachtwoord op.'
google_auth2: 'Omdat je via Google inlogt, hoef je geen wachtwoord op te geven.<br>Als je deze wilt wijzigen, geef dan een nieuw e-mailadres en wachtwoord op.'
password_complexity_error: 'moet 8 tot 128 tekens bevatten, inclusief 1 hoofdletter, 1 kleine letter, 1 cijfer en 1 speciaal teken.'
placeholders:
repeat_password: 'Herhaal Wachtwoord'
edit:
Expand Down
1 change: 1 addition & 0 deletions config/locales/pt-BR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,7 @@ pt-BR:
meeting_notify_text: 'Atualizações de reuniões'
google_auth1: 'Caso você não queira mais fazer login com sua conta Google, por favor digite um novo email e uma nova senha.'
google_auth2: 'Com a sua conta Google, você não precisa digitar sua senha.<br> Caso você queira mudar isso, por favor cadastre-se com um novo email e uma nova senha.'
password_complexity_error: 'deve conter 8 a 128 caracteres, incluindo 1 maiúsculo, 1 minúsculo, 1 dígito e 1 caractere especial.'
placeholders:
repeat_password: 'Digite novamente sua senha'
edit:
Expand Down
1 change: 1 addition & 0 deletions config/locales/sv.yml
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,7 @@ sv:
meeting_notify_text: Mötesuppdateringar
google_auth1: 'Om du inte längre vill verifieras med Google anger du ett nytt e-post och lösenord.'
google_auth2: 'Eftersom du är autentiserad med Google behöver du inte ange ditt lösenord. <br> Om du vill ändra detta anger du en ny e-postadress och lösenord.'
password_complexity_error: 'bör innehålla 8 till 128 tecken, inklusive 1 versal, 1 små bokstav, 1 siffra och 1 specialtecken.'
placeholders:
repeat_password: 'Repetera lösenord'
edit:
Expand Down
1 change: 1 addition & 0 deletions config/locales/vi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,7 @@ vi:
meeting_notify_text: 'Cập nhật họp nhóm'
google_auth1: 'Nếu bạn không muốn xác minh tài khoản thông qua Google, xin vui lòng đăng nhập bằng một email và mật khẩu mới.'
google_auth2: 'Bởi vì bạn xác minh tài khoản thông quan Google, bạn không cần phải điền mật khẩu.<br>Nếu bạn muốn thay đổi xin vui lòng đăng nhập bằng một email và mật khẩu mới.'
password_complexity_error: 'nên chứa 8 đến 128 ký tự, bao gồm 1 chữ hoa, 1 chữ thường, 1 chữ số và 1 ký tự đặc biệt.'
placeholders:
repeat_password: 'Lập lại mật khẩu lần nữa'
edit:
Expand Down
6 changes: 3 additions & 3 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
# Mayor.create(name: 'Emanuel', city: cities.first)

# Users
user1 = User.create(name: 'Test1 Lastname', email: '[email protected]', password: 'password99', location: 'Toronto, ON, Canada', about: 'Hi my name is Test1! I want to use the site so that I can improve the way I handle my anxiety.')
user2 = User.create(name: 'Test2 Lastname', email: '[email protected]', password: 'password99', location: 'Toronto, ON, Canada')
user3 = User.create(name: 'Test3 Two-Lastnames', email: '[email protected]', password: 'password99', location: 'San Francisco, CA, United States')
user1 = User.create(name: 'Test1 Lastname', email: '[email protected]', password: 'passworD@99', location: 'Toronto, ON, Canada', about: 'Hi my name is Test1! I want to use the site so that I can improve the way I handle my anxiety.')
user2 = User.create(name: 'Test2 Lastname', email: '[email protected]', password: 'passworD@99', location: 'Toronto, ON, Canada')
user3 = User.create(name: 'Test3 Two-Lastnames', email: '[email protected]', password: 'passworD@99', location: 'San Francisco, CA, United States')

# Allies
Allyship.create(user_id: user1.id, ally_id: user2.id, status: :accepted)
Expand Down
10 changes: 5 additions & 5 deletions spec/factories/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,20 @@
factory :user, class: 'User' do
sequence(:email) { |n| "some-email#{n}@ifme.org" }
sequence(:name) { |n| "Some Person#{n}" }
password { 'password' }
password { 'passworD%1' }
end

factory :user1, class: User do
name { 'Oprah Chang' }
sequence(:email) { |n| "oprah.chang#{n}@example.com" }
password { 'password' }
password { 'passworD%1' }
location { 'Toronto, ON, Canada' }
end

factory :user2, class: User do
name { 'Plum Blossom' }
email { '[email protected]' }
password { 'password' }
password { 'passworD%1' }
location { 'Toronto, ON, Canada' }

trait :with_allies do
Expand All @@ -80,14 +80,14 @@
factory :user3, class: User do
name { 'Gentle Breezy' }
email { '[email protected]' }
password { 'password' }
password { 'passworD%1' }
location { 'Toronto, ON, Canada' }
end

factory :user_oauth, class: User do
name { 'Orange Southland' }
email { '[email protected]' }
password { 'password' }
password { 'passworD%1' }
location { 'Toronto, ON, Canada' }
token { 'has_a_token' }
access_expires_at { Time.zone.now + 600 }
Expand Down
45 changes: 43 additions & 2 deletions spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
end

context 'an existing user' do
let!(:user) { User.create(name: 'some name', email: '[email protected]', password: 'asdfasdf') }
let!(:user) { User.create(name: 'some name', email: '[email protected]', password: 'asdfaS1!df') }

it 'updates token information' do
User.find_for_google_oauth2(access_token)
Expand Down Expand Up @@ -93,7 +93,7 @@
let!(:user) do
User.create(name: 'some name',
email: '[email protected]',
password: 'asdfasdf',
password: 'asdfasdF!1',
token: 'some token')
end

Expand Down Expand Up @@ -135,6 +135,47 @@
end
end

describe '#validations' do
context 'password' do
let(:user) { build(:user, password: nil) }

context 'when password is blank' do
it 'throws password error only from devise' do
expect(user.valid?).to be false

expect(user).to have(1).error_on(:password)
expect(user.errors[:password]).not_to include(I18n.t('devise.registrations.password_complexity_error'))
end
end

context 'when oauth is enabled' do
it 'doesnt throw any errors even if the password strength is less' do
user.password = 'warsdasdf'
user.token = 'access token'
expect(user.valid?).to be true
end
end

context 'when password is valid' do
it 'doesnt throw any errors' do
user.password = 'waspAr$0'
expect(user.valid?).to be true
end
end

context 'when password is invalid' do
it 'returns respective error message' do
['waspar$0', 'waspaRs0', 'waspar$o', 'WASPAR$0', 'Was$0'].each do |password|
user.password = password
expect(user.valid?).to be false

expect(user).to have(1).error_on(:password)
end
end
end
end
end

describe '#available_groups' do
it "returns the groups that allys belong to and the user doesn't" do
user = create :user1
Expand Down

0 comments on commit a1d7844

Please sign in to comment.