import pytest from dataclasses import replace from ahriman.models.user import User from ahriman.models.user_access import UserAccess def test_algo() -> None: """ must correctly define algorithm used """ assert User(username="user", password=None, access=UserAccess.Read).algo is None assert User(username="user", password="", access=UserAccess.Read).algo is None assert User(username="user", password="$$$", access=UserAccess.Read).algo is None assert User( username="user", password="$6$rounds=656000$mWBiecMPrHAL1VgX$oU4Y5HH8HzlvMaxwkNEJjK13ozElyU1wAHBoO/WW5dAaE4YEfnB0X3FxbynKMl4FBdC3Ovap0jINz4LPkNADg0", access=UserAccess.Read, ).algo == "$6$" assert User( username="user", password="$2b$12$VCWKazvYxH7B0eAalDGAbu/3y1dSWs79sv/2ujjX1TMaFdVUy80hy", access=UserAccess.Read, ).algo == "$2b$" def test_check_credentials_hash_password(user: User) -> None: """ must generate and validate user password """ current_password = user.password user = user.hash_password("salt") assert user.check_credentials(current_password, "salt") assert not user.check_credentials(current_password, "salt1") assert not user.check_credentials(user.password, "salt") def test_check_credentials_empty_hash(user: User) -> None: """ must reject any authorization if the hash is invalid """ current_password = user.password user = replace(user, password="") assert not user.check_credentials(current_password, "salt") def test_check_credentials_sha512() -> None: """ must raise DeprecationWarning for sha512 hashed passwords """ user = User( username="user", password="$6$rounds=656000$mWBiecMPrHAL1VgX$oU4Y5HH8HzlvMaxwkNEJjK13ozElyU1wAHBoO/WW5dAaE4YEfnB0X3FxbynKMl4FBdC3Ovap0jINz4LPkNADg0", access=UserAccess.Read, ) with pytest.raises(ValueError): assert user.check_credentials("password", "salt") def test_hash_password_empty_hash(user: User) -> None: """ must return empty string after hash in case if password not set """ user = replace(user, password="") assert user.hash_password("salt") == user user = replace(user, password=None) assert user.hash_password("salt") == user def test_generate_password() -> None: """ must generate password with specified length """ password = User.generate_password(16) assert password assert len(password) == 16 password = User.generate_password(42) assert password assert len(password) == 42 def test_verify_access_read(user: User) -> None: """ user with read access must be able to only request read """ user = replace(user, access=UserAccess.Read) assert user.verify_access(UserAccess.Read) assert not user.verify_access(UserAccess.Full) def test_verify_access_write(user: User) -> None: """ user with write access must be able to do anything """ user = replace(user, access=UserAccess.Full) assert user.verify_access(UserAccess.Read) assert user.verify_access(UserAccess.Full) def test_repr(user: User) -> None: """ must print user without password """ assert "pa55w0rd" not in str(user)