66
77
88class PasswordValidator :
9+ ''' Class to generate schema of password definitions
10+
11+ Example:
12+ >>> schema = PasswordValidator()
13+ >>> schema.has().letters().has().digits().no().spaces()
14+ >>> schema.validate('testPassword123')
15+ True
16+ Returns:
17+ PasswordValidator: Schema object
18+ '''
919
1020 def __init__ (self ):
1121 self .properties = []
1222 self .positive = True
1323
24+
1425 def validate (self , pwd ):
26+ ''' Validates `pwd` against the schema and returns the result
27+
28+ Example:
29+ >>> PasswordValidator().letters().validate('123')
30+ False
31+ >>> PasswordValidator().letters().validate('abc')
32+ True
33+ Args:
34+ pwd (str): Password to validate against the schema
35+ Returns:
36+ boolean: Result of the validation
37+ '''
38+
1539 password = str (pwd )
1640 return all (self .__isPasswordValidFor (prop , password ) for prop in self .properties )
1741
18- def __registerProperty (self , func , args = []): # pylint: disable=dangerous-default-value
42+ def __registerProperty (self , func , args = []): # pylint: disable=dangerous-default-value
1943 self .properties .append ({
2044 'method' : func ,
2145 'positive' : self .positive ,
@@ -29,47 +53,171 @@ def __validateNum(self, num):
2953 assert (type (num ) == 'int' or num > 0 ), error ['length' ] # pylint: disable=unidiomatic-typecheck
3054
3155 def has (self , regexp = None ):
56+ ''' Inverts the effect of :func:`~no` and applies a :mod:`regex <python:re>` if provided
57+ to the schema. Works with:
58+ :func:`~letters`, :func:`~digits`, :func:`~uppercase`, :func:`~lowercase`,
59+ :func:`~symbols` and :func:`~spaces`.
60+
61+ Example:
62+ >>> PasswordValidator().no().letters().has().digits().validate('123')
63+ True
64+ >>> PasswordValidator().has(r'[a-z]+').validate('test')
65+ True
66+ Args:
67+ regexp (str, optional): The regular expression or string to mandate on the password
68+ Returns:
69+ PasswordValidator: Updated schema object
70+ '''
71+
3272 self .positive = True
3373 if regexp :
3474 self .__registerProperty (lib .applyRegexp , [re .compile (regexp )])
3575 return self
3676
3777 def no (self , regexp = None ):
78+ ''' Inverts the effect of all the next rules unless countered by a
79+ :func:`has` and applies a
80+ negative check of the regular expression provided. Works with:
81+ :func:`~letters`, :func:`~digits`, :func:`~uppercase`, :func:`~lowercase`,
82+ :func:`~symbols` and :func:`~spaces`.
83+
84+ Example:
85+ >>> PasswordValidator().no().letters().digits().validate('123')
86+ False
87+ >>> PasswordValidator().no().letters().has().digits().validate('123')
88+ True
89+ >>> PasswordValidator().no(r'[a-z]+').validate('test')
90+ False
91+
92+ Args:
93+ regexp (str, optional): The regex or str the password should not match to
94+ Returns:
95+ PasswordValidator: Updated schema object
96+ '''
3897 self .positive = not self .positive
3998 if regexp :
4099 self .__registerProperty (lib .applyRegexp , [re .compile (regexp )])
41100 return self
42101
43102 def uppercase (self ):
103+ ''' Mandates the presence/absense of uppercase letters.
104+
105+ Example:
106+ >>> PasswordValidator().uppercase().validate('Test')
107+ True
108+ >>> PasswordValidator().uppercase().validate('test')
109+ False
110+ Returns:
111+ PasswordValidator: Updated schema object
112+ '''
44113 self .__registerProperty (lib .uppercase )
45114 return self
46115
47116 def lowercase (self ):
117+ ''' Mandates the presence/absense of lowercase letters.
118+
119+ Example:
120+ >>> PasswordValidator().lowercase().validate('Test')
121+ True
122+ >>> PasswordValidator().lowercase().validate('TEST')
123+ False
124+ Returns:
125+ PasswordValidator: Updated schema object
126+ '''
127+
48128 self .__registerProperty (lib .lowercase )
49129 return self
50130
51131 def letters (self ):
132+ ''' Mandates the presence/absense of letters.
133+
134+ Example:
135+ >>> PasswordValidator().letters().validate('test')
136+ True
137+ >>> PasswordValidator().no().letters().validate('test')
138+ False
139+ Returns:
140+ PasswordValidator: Updated schema object
141+ '''
142+
52143 self .__registerProperty (lib .letters )
53144 return self
54145
55146 def digits (self ):
147+ ''' Mandates the presence/absense of digits.
148+
149+ Example:
150+ >>> PasswordValidator().digits().validate('test')
151+ False
152+ >>> PasswordValidator().no().digits().validate('test123')
153+ False
154+ Returns:
155+ PasswordValidator: Updated schema object
156+ '''
157+
56158 self .__registerProperty (lib .digits )
57159 return self
58160
59161 def min (self , length ):
162+ ''' Sets the minimum length allowed.
163+
164+ Example:
165+ >>> PasswordValidator().min(8).validate('testPassword')
166+ True
167+ >>> PasswordValidator().min(8).validate('test')
168+ False
169+ Args:
170+ length (int): Minimum length allowed
171+ Returns:
172+ PasswordValidator: Updated schema object
173+ '''
174+
60175 self .__validateNum (length )
61176 self .__registerProperty (lib .minimum , [length ])
62177 return self
63178
64179 def max (self , length ):
180+ ''' Sets the maximum length allowed.
181+
182+ Example:
183+ >>> PasswordValidator().max(8).validate('testPassword')
184+ False
185+ >>> PasswordValidator().max(8).validate('test')
186+ True
187+ Args:
188+ length (int): Maximum length allowed
189+ Returns:
190+ PasswordValidator: Updated schema object
191+ '''
65192 self .__validateNum (length )
66193 self .__registerProperty (lib .maximum , [length ])
67194 return self
68195
69196 def spaces (self ):
197+ ''' Mandates the presence/absense of whitespace.
198+
199+ Example:
200+ >>> PasswordValidator().spaces().validate('a bc')
201+ True
202+ >>> PasswordValidator().no().spaces().validate('a bc')
203+ False
204+ Returns:
205+ PasswordValidator: Updated schema object
206+ '''
70207 self .__registerProperty (lib .spaces )
71208 return self
72209
73210 def symbols (self ):
211+ ''' Mandates the presence/absense of special characters like `@`, `#`, `$`, etc.
212+
213+ Example:
214+ >>> PasswordValidator().symbols().validate('@bc')
215+ True
216+ >>> PasswordValidator().no().symbols().validate('@bc')
217+ False
218+
219+ Returns:
220+ PasswordValidator: Updated schema object
221+ '''
74222 self .__registerProperty (lib .symbols )
75223 return self
0 commit comments