Coverage for kwai/modules/identity/users/user_account.py: 98%
48 statements
« prev ^ index » next coverage.py v7.3.0, created at 2023-09-05 17:55 +0000
« prev ^ index » next coverage.py v7.3.0, created at 2023-09-05 17:55 +0000
1"""Module that implements a user account entity."""
3from kwai.core.domain.entity import Entity
4from kwai.core.domain.value_objects.identifier import IntIdentifier
5from kwai.core.domain.value_objects.local_timestamp import LocalTimestamp
6from kwai.core.domain.value_objects.password import Password
7from kwai.modules.identity.exceptions import NotAllowedException
8from kwai.modules.identity.users.user import UserEntity
10UserAccountIdentifier = IntIdentifier
13class UserAccountEntity(Entity[UserAccountIdentifier]):
14 """A user account entity."""
16 def __init__(
17 self,
18 *,
19 user: UserEntity,
20 password: Password,
21 id_: UserAccountIdentifier | None = None,
22 last_login: LocalTimestamp | None = None,
23 last_unsuccessful_login: LocalTimestamp | None = None,
24 revoked: bool = False,
25 admin: bool = False,
26 ):
27 super().__init__(id_ or UserAccountIdentifier())
28 self._user = user
29 self._password = password
30 self._last_login = last_login or LocalTimestamp()
31 self._last_unsuccessful_login = last_unsuccessful_login or LocalTimestamp()
32 self._revoked = revoked
33 self._admin = admin
35 @property
36 def admin(self) -> bool:
37 """Check if this user an administrator."""
38 return self._admin
40 @property
41 def last_login(self) -> LocalTimestamp:
42 """Return the timestamp of the last successful login."""
43 return self._last_login
45 @property
46 def last_unsuccessful_login(self) -> LocalTimestamp:
47 """Return the timestamp of the last unsuccessful login."""
48 return self._last_unsuccessful_login
50 def login(self, password: str) -> bool:
51 """Check if the given password is correct.
53 When login succeeds, last_login will be updated.
54 When login fails, last_unsuccessful_login will be updated.
56 Args:
57 password(str): The password.
58 """
59 if self._password.verify(password):
60 self._last_login = LocalTimestamp.create_now()
61 return True
63 self._last_unsuccessful_login = LocalTimestamp.create_now()
64 return False
66 @property
67 def password(self) -> Password:
68 """Return the password of the user."""
69 return self._password
71 def reset_password(self, password: Password):
72 """Reset the password of the user account.
74 Args:
75 password(Password): The new password.
76 """
77 if self._revoked:
78 raise NotAllowedException()
80 self._password = password
81 self._user.mark_for_update()
83 def revoke(self):
84 """Revoke a user account."""
85 self._revoked = True
86 self._user.mark_for_update()
88 @property
89 def revoked(self) -> bool:
90 """Check if this user is revoked."""
91 return self._revoked
93 @property
94 def user(self) -> UserEntity:
95 """Return the associated user entity."""
96 return self._user