Home > Mobile >  How to check a password against an array Ruby
How to check a password against an array Ruby

Time:09-11

I need to add a denylist to a Web application. It is working with a single string. Just not sure how to do it with multiple values

**Below is working fine **

def correct_password_format(password)
  (
    password.count('0-9').positive? &&
      !password.match(/[^A-Za-z0-9]/).nil? &&
      password.count('A-Z').positive? && password.count('a-z').positive? &&
      password.length >= 8 && password != 'P@ssword1'
end

I need to add more than one item but having a hard time :(

def correct_password_format(password)
  (
    password.count('0-9').positive? &&
      !password.match(/[^A-Za-z0-9]/).nil? &&
      password.count('A-Z').positive? && password.count('a-z').positive? &&
      password.length >= 8 && password != ['P@ssword1','shabixuege!@#','P@$$W0rd0123','P@ssw0rd5tgb','adminbigdata','Pa$$w0rdp!@#','adm1nistrator1','administrator!@#$'].include?
  )
end

CodePudding user response:

You can use include? to check if a string (the password) is included in an array.

require 'set'

FORBIDDEN_PASSWORDS = Set.new(
  ['P@ssword1', 'shabixuege!@#', 'P@$$W0rd0123', 'P@ssw0rd5tgb', 'adminbigdata', 'Pa$$w0rdp!@#', 'adm1nistrator1', 'administrator!@#$']
)

def correct_password_format(password)
  password.length >= 8              && 
    password.match?(/[0-9]/)        &&
    password.match?(/[A-Z]/)        && 
    password.match?(/[a-z]/)        &&
    password.match?(/[^A-Za-z0-9]/) &&
    !FORBIDDEN_PASSWORDS.include?(password)
end

I suggest using a Set to speed up the lookup if this method is used frequently.

CodePudding user response:

You can test that with a regular expression. I will express the regex in free-spacing mode to make it self-documenting.

FORBIDDEN = [
  "P@ssword1", "shabixuege!@#", "P@$$W0rd0123", "P@ssw0rd5tgb",
  "adminbigdata", "Pa$$w0rdp!@#", "adm1nistrator1", "administrator!@\#$"
]
RGX = /
      \A                # match beginning of string
      (?=               # begin positive lookahead
        .*              # match zero or more characters
        \d              # match a digit
      )                 # end positive lookahead
      (?=.*[A-Z])       # pos lookahead asserts there is an uppercase letter
      (?=.*[a-z])       # pos lookahead asserts there is an lowercase letter
      (?=.{8})          # pos lookahead asserts there are 8 (or more) chars
      (?=.*[^A-Za-z\d]) # pos lookahead asserts there is a char other than
                        # a letter or digit
      (?!               # begin a negative lookahead
        #{Regexp.union(*FORBIDDEN)}
       \z               # match end of string
      )                 # end neg lookahead
      /x                # free-spacing regex definition mode

(?=...) denotes a positive lookahead (search Positive lookahead and Negative lookahead at the link).

Here

#{Regexp.union(*FORBIDDEN)}

expands to

  (?-mix:P@ssword1|shabixuege!@\#|P@\$\$W0rd0123|P@ssw0rd5tgb|adminbigdata|Pa\$\$w0rdp!@\#|adm1nistrator1|administrator!@\#\$)

Note that Regexp::union escapes "#" and "$" as they are reserved characters in regular expressions.

We may now write

def correct_password_format(password)
  password.match?(RGX)
end
correct_password_format('aA#45678')        #=> true 
correct_password_format('aA#456789')       #=> true
correct_password_format('A0shabixuege!@#') #=> true
correct_password_format('aA#4567')         #=> false
correct_password_format('Aa345678')        #=> false
correct_password_format('a#345678')        #=> false
correct_password_format('a#BCDEFG')        #=> false
correct_password_format('adminbigdata')    #=> false

Demo. Notice that at the link I've changed the beginning and end of string anchors (\A and \z) to beginning and end of line anchors (^ and $) (and prevented newlines from being matched) so that multiple tests could be performed.

The regular expression could of course be expressed in conventional notation:

RGX = /\A(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.{8})(?=.*[^A-Za-z\d])(?!#{Regexp.union(*FORBIDDEN)}\z)/
  • Related