Skip to content

Commit 3a3a6b8

Browse files
Merge pull request #18 from bandirevanth/main
Updated Password & Array Validator
2 parents 7097446 + 7e16d03 commit 3a3a6b8

File tree

2 files changed

+122
-95
lines changed

2 files changed

+122
-95
lines changed

sanatio/array_validator.py

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,55 @@
1+
from typing import Any, List, Optional
12
from sanatio.base_class import BaseValidator
23

34

45
class ArrayValidator(BaseValidator):
5-
6-
def isArray(self, value) -> bool:
7-
""" check if the string is array or not """
6+
def is_array(self, value: Any) -> bool:
7+
"""Check if the value is a list (array)."""
88
return isinstance(value, list)
99

10-
def isArrayLength(self, value, min: int = 0, max: int = None) -> bool:
11-
""" check if the array length is between min and max """
12-
return min <= len(value) <= max
13-
14-
def isContains(self, value, contains) -> bool:
15-
""" check if the array contains the element or not """
16-
return contains in value
17-
18-
def isUnique(self, value) -> bool:
19-
""" check if the array contains unique elements or not """
20-
return len(value) == len(set(value))
21-
22-
def isMultidimensional(self, value) -> bool:
23-
""" check if the array is multidimensional or not """
10+
def is_array_length(self, value: List[Any], min_length: int = 0, max_length: Optional[int] = None) -> bool:
11+
"""Check if the array length is between min_length and max_length (inclusive)."""
12+
if not self.is_array(value):
13+
return False
14+
if max_length is not None:
15+
return min_length <= len(value) <= max_length
16+
return len(value) >= min_length
17+
18+
def is_contains(self, value: List[Any], item: Any) -> bool:
19+
"""Check if the array contains a given element."""
20+
if not self.is_array(value):
21+
return False
22+
return item in value
23+
24+
def is_unique(self, value: List[Any]) -> bool:
25+
"""Check if all elements in the array are unique."""
26+
if not self.is_array(value):
27+
return False
28+
try:
29+
return len(value) == len(set(value))
30+
except TypeError:
31+
# Handles case where elements are unhashable (e.g., lists)
32+
seen = []
33+
for i in value:
34+
if i in seen:
35+
return False
36+
seen.append(i)
37+
return True
38+
39+
def is_multidimensional(self, value: List[Any]) -> bool:
40+
"""Check if the array is multidimensional (contains at least one list)."""
41+
if not self.is_array(value):
42+
return False
2443
return any(isinstance(i, list) for i in value)
2544

26-
def isMinlength(self, value, min: int) -> bool:
27-
""" check if the array length is greater than min """
28-
return len(value) > min
29-
30-
def isMaxlength(self, value, max: int) -> bool:
31-
""" check if the array length is less than max """
32-
return len(value) < max
45+
def is_min_length(self, value: List[Any], min_length: int) -> bool:
46+
"""Check if the array length is greater than or equal to min_length."""
47+
if not self.is_array(value):
48+
return False
49+
return len(value) >= min_length
50+
51+
def is_max_length(self, value: List[Any], max_length: int) -> bool:
52+
"""Check if the array length is less than or equal to max_length."""
53+
if not self.is_array(value):
54+
return False
55+
return len(value) <= max_length

sanatio/password_validator.py

Lines changed: 75 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,89 @@
11
import re
2+
from typing import List, Optional
23

34
from sanatio.base_class import BaseValidator
45

56

67
class PasswordValidator(BaseValidator):
78

8-
def isStrongPassword(self, value: str,
9-
min_length: int = 8,
10-
special_chars: bool = True,
11-
numbers: bool = True,
12-
uppercase: bool = True,
13-
lowercase: bool = True) -> bool:
14-
""" check if the string is strong password or not
15-
16-
requirements:
17-
1. At least 8 characters long
18-
2. At least one uppercase letter
19-
3. At least one lowercase letter
20-
4. At least one number
21-
5. At least one special character
9+
def is_strong_password(self, value: str,
10+
min_length: int = 8,
11+
special_chars: bool = True,
12+
numbers: bool = True,
13+
uppercase: bool = True,
14+
lowercase: bool = True) -> bool:
15+
"""Check if the string is a strong password.
16+
17+
Requirements:
18+
1. At least `min_length` characters
19+
2. At least one uppercase letter (optional)
20+
3. At least one lowercase letter (optional)
21+
4. At least one number (optional)
22+
5. At least one special character (optional)
2223
"""
23-
if not self.isPasswordLength(value, min_length) or \
24-
(special_chars and not self.isPasswordSpecialChar(value)) or \
25-
(numbers and not self.isPasswordNumber(value)) or \
26-
(uppercase and not self.isPasswordUppercase(value)) or \
27-
(lowercase and not self.isPasswordLowercase(value)):
24+
if not self.is_password_length(value, min_length):
25+
return False
26+
if special_chars and not self.is_password_special_char(value):
27+
return False
28+
if numbers and not self.is_password_number(value):
29+
return False
30+
if uppercase and not self.is_password_uppercase(value):
31+
return False
32+
if lowercase and not self.is_password_lowercase(value):
2833
return False
2934

3035
return True
3136

32-
def isPasswordUppercase(self, value: str, min_length: int = 1) -> bool:
33-
""" check if the string has uppercase letters """
34-
if len(re.findall(r'[A-Z]', value)) >= min_length:
35-
return True
36-
37-
def isPasswordLowercase(self, value: str, min_length: int = 1) -> bool:
38-
""" check if the string has lowercase letters """
39-
if len(re.findall(r'[a-z]', value)) >= min_length:
40-
return True
41-
42-
def isPasswordNumber(self, value: str, min_length: int = 1) -> bool:
43-
""" check if the string has numbers """
44-
if len(re.findall(r'[0-9]', value)) >= min_length:
45-
return True
46-
47-
def isPasswordLength(self, value: str, min_length: int = 8) -> bool:
48-
""" check if the string length is between min and max """
49-
if len(value) >= min_length:
50-
return True
51-
52-
def isPasswordSpecialChar(self, value: str, min_length: int = 1) -> bool:
53-
""" check if the string has special characters """
54-
if len(re.findall(r'[_@$]', value)) >= min_length:
55-
return True
56-
57-
def isPasswordMatch(self, value: str, match_value: str, ignore_case: bool = False) -> bool:
58-
""" check if the string matches the match_value """
59-
if ignore_case and value.lower() == match_value.lower():
60-
return True
61-
elif value == match_value:
62-
return True
63-
64-
def isPasswordNotMatch(self, value: str, match_value: str, ignore_case: bool = False) -> bool:
65-
""" check if the string does not match the match_value """
66-
if ignore_case and value.lower() != match_value.lower():
67-
return True
68-
elif value != match_value:
69-
return True
70-
71-
def isPasswordNotInList(self, value: str, list_values: list, ignore_case: bool = False) -> bool:
72-
""" check if the string is not in the list """
73-
if ignore_case and value.lower() not in [x.lower() for x in list_values]:
74-
return True
75-
elif value not in list_values:
76-
return True
77-
78-
def isPasswordNotInFile(self, value: str, file_path: str, ignore_case: bool = False) -> bool:
79-
""" check if the string is not in the file """
37+
def is_password_uppercase(self, value: str, min_length: int = 1) -> bool:
38+
"""Check if the string has at least `min_length` uppercase letters."""
39+
return len(re.findall(r'[A-Z]', value)) >= min_length
40+
41+
def is_password_lowercase(self, value: str, min_length: int = 1) -> bool:
42+
"""Check if the string has at least `min_length` lowercase letters."""
43+
return len(re.findall(r'[a-z]', value)) >= min_length
44+
45+
def is_password_number(self, value: str, min_length: int = 1) -> bool:
46+
"""Check if the string has at least `min_length` digits."""
47+
return len(re.findall(r'\d', value)) >= min_length
48+
49+
def is_password_length(self, value: str, min_length: int = 8) -> bool:
50+
"""Check if the string is at least `min_length` characters long."""
51+
return len(value) >= min_length
52+
53+
def is_password_special_char(self, value: str, min_length: int = 1) -> bool:
54+
"""Check if the string has at least `min_length` special characters."""
55+
# Common special characters set: !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
56+
return len(re.findall(r'[^a-zA-Z0-9]', value)) >= min_length
57+
58+
def is_password_match(self, value: str, match_value: str, ignore_case: bool = False) -> bool:
59+
"""Check if the password matches `match_value`."""
60+
if ignore_case:
61+
return value.lower() == match_value.lower()
62+
return value == match_value
63+
64+
def is_password_not_match(self, value: str, match_value: str, ignore_case: bool = False) -> bool:
65+
"""Check if the password does not match `match_value`."""
66+
if ignore_case:
67+
return value.lower() != match_value.lower()
68+
return value != match_value
69+
70+
def is_password_not_in_list(self, value: str, list_values: Optional[List[str]] = None,
71+
ignore_case: bool = False) -> bool:
72+
"""Check if the password is not in a list of disallowed passwords."""
73+
if list_values is None:
74+
list_values = []
75+
76+
if ignore_case:
77+
return value.lower() not in [x.lower() for x in list_values]
78+
return value not in list_values
79+
80+
def is_password_not_in_file(self, value: str, file_path: str, ignore_case: bool = False) -> bool:
81+
"""Check if the password is not in a file of disallowed passwords."""
82+
if not hasattr(self, "read_file"):
83+
raise NotImplementedError("read_file() method not implemented in BaseValidator or subclass.")
84+
8085
data = self.read_file(file_path, split_lines=True)
8186

82-
if ignore_case and value.lower() not in [x.lower() for x in data]:
83-
return True
84-
elif value not in data:
85-
return True
87+
if ignore_case:
88+
return value.lower() not in [x.lower() for x in data]
89+
return value not in data

0 commit comments

Comments
 (0)