feat(usermodel): implement User parameter validation methods
This commit is contained in:
parent
16fb570cfd
commit
876dc2ef5c
@ -11,6 +11,7 @@ services:
|
||||
- ./lumi2/__init__.py:/app/lumi2/__init__.py:ro
|
||||
- ./lumi2/exceptions.py:/app/lumi2/exceptions.py:ro
|
||||
- ./lumi2/ldap.py:/app/lumi2/ldap.py:ro
|
||||
- ./lumi2/usermodel.py:/app/lumi2/usermodel.py:ro
|
||||
- ./lumi2/usermanager.py:/app/lumi2/usermanager.py:ro
|
||||
- ./lumi2/static/:/app/lumi2/static/:ro
|
||||
- ./lumi2/templates/:/app/lumi2/templates/:ro
|
||||
|
@ -596,7 +596,7 @@ def get_user(connection: Connection, uid: str) -> User:
|
||||
'sn',
|
||||
'displayName',
|
||||
'uid',
|
||||
'password',
|
||||
'userPassword',
|
||||
'jpegPhoto',
|
||||
'mail',
|
||||
]
|
||||
|
@ -4,6 +4,10 @@ Also provides methods to convert LDAP user/group entries into user/group objects
|
||||
and vice versa.
|
||||
"""
|
||||
|
||||
from string import ascii_lowercase, ascii_uppercase, digits, whitespace
|
||||
from base64 import b64decode
|
||||
from binascii import Error as Base64DecodeError
|
||||
|
||||
from PIL import Image
|
||||
|
||||
class User:
|
||||
@ -12,23 +16,17 @@ class User:
|
||||
Attributes
|
||||
----------
|
||||
username : str
|
||||
The user's username. Can contain only uppercase/lowercase latin characters,
|
||||
numbers, hyphens, underscores and periods. Must start with a latin character.
|
||||
Minimum length is 1, maximum length is 64 characters.
|
||||
The user's username.
|
||||
password_hash : str
|
||||
Base64-encoded SHA512 hash of the user's password.
|
||||
email : str
|
||||
The user's email address.
|
||||
Must contain an '@'-character, may not contain any whitespace.
|
||||
first_name : str
|
||||
The user's first name.
|
||||
May not contain any whitespace.
|
||||
last_name : str
|
||||
The user's last name.
|
||||
May not contain any whitespace.
|
||||
display_name : str
|
||||
The user's display name (as required by some LDAP-enabled applications).
|
||||
May not contain any whitespace.
|
||||
picture : PIL.Image
|
||||
The user's profile picture as a PIL Image object.
|
||||
"""
|
||||
@ -62,17 +60,28 @@ class User:
|
||||
if not isinstance(input_str, str):
|
||||
raise TypeError(f"Expected a string but got: '{type(input_str)}'.")
|
||||
|
||||
# TODO implement
|
||||
return False
|
||||
if not len(input_str):
|
||||
return False
|
||||
if len(input_str) > 64:
|
||||
return False
|
||||
|
||||
if input_str[0] not in ascii_lowercase + ascii_uppercase:
|
||||
return False
|
||||
|
||||
valid_chars = ascii_lowercase + ascii_uppercase + digits + "-_."
|
||||
for char in input_str:
|
||||
if char not in valid_chars:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@staticmethod
|
||||
def is_valid_password_hash(input_str: str) -> bool:
|
||||
"""Checks whether the input string is a valid password hash.
|
||||
|
||||
Password hashes are base64-encoded bytes, and the hashing algorithm used
|
||||
to create the hash is hard to determine, but we can verify that the
|
||||
provided hash is a non-empty string containing base64-decodeable text.
|
||||
A valid password hash is a non-empty string containing base64-decodeable
|
||||
text.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -93,15 +102,24 @@ class User:
|
||||
if not isinstance(input_str, str):
|
||||
raise TypeError(f"Expected a string but got: '{type(input_str)}'.")
|
||||
|
||||
# TODO implement
|
||||
return False
|
||||
if not len(input_str):
|
||||
return False
|
||||
|
||||
try:
|
||||
b64decode(input_str, validate=True)
|
||||
return True
|
||||
except Base64DecodeError:
|
||||
return False
|
||||
|
||||
|
||||
@staticmethod
|
||||
def is_valid_email(input_str: str) -> bool:
|
||||
"""Checks whether the input string is a valid email address.
|
||||
|
||||
A valid email address contains no whitespace and at least one '@'-char.
|
||||
WARNING: this validation is very rudimentary. Proper validation requires
|
||||
a validation email to be sent and confirmed by the user.
|
||||
A valid email address contains no whitespace, at least one '@' character,
|
||||
and a '.' character somewhere after the '@'.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -122,8 +140,18 @@ class User:
|
||||
if not isinstance(input_str, str):
|
||||
raise TypeError(f"Expected a string but got: '{type(input_str)}'.")
|
||||
|
||||
# TODO implement
|
||||
return False
|
||||
if '@' not in input_str:
|
||||
return False
|
||||
if '.' not in input_str:
|
||||
return False
|
||||
if '.' not in input_str.split('@')[1]:
|
||||
return False
|
||||
|
||||
for char in input_str:
|
||||
if char in whitespace:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@staticmethod
|
||||
@ -152,8 +180,14 @@ class User:
|
||||
if not isinstance(input_str, str):
|
||||
raise TypeError(f"Expected a string but got: '{type(input_str)}'.")
|
||||
|
||||
# TODO implement
|
||||
return False
|
||||
if not len(input_str):
|
||||
return False
|
||||
|
||||
for char in input_str:
|
||||
if char in whitespace:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@staticmethod
|
||||
@ -181,6 +215,10 @@ class User:
|
||||
if not isinstance(input_image, Image):
|
||||
raise TypeError(f"Expected a PIL Image but got: '{type(input_image)}'.")
|
||||
|
||||
# TODO implement
|
||||
return True
|
||||
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
username: str, password_hash: str, email: str,
|
||||
|
@ -41,8 +41,7 @@ def test_is_valid_password_hash():
|
||||
|
||||
valid_hashes = [
|
||||
# can contain [A-Za-z0-9+/] and up to two '=' at the end
|
||||
"foobar", "EzM3",
|
||||
"abcABC123+/=", "a",
|
||||
"EzM3", "abcABC123+/=",
|
||||
]
|
||||
for valid_hash in valid_hashes:
|
||||
assert User.is_valid_password_hash(valid_hash)
|
||||
@ -55,7 +54,7 @@ def test_is_valid_email():
|
||||
|
||||
invalid_emails = [
|
||||
"", " ", "\t", "\n",
|
||||
" alice@example.com", "alice", "@", "@.",
|
||||
" alice@example.com", "alice", "@", "alice@com"
|
||||
"alice@example.com ", "alice@ex ample.com"
|
||||
]
|
||||
for invalid_email in invalid_emails:
|
||||
|
Loading…
Reference in New Issue
Block a user