Skip to content

Commit 7547ee3

Browse files
committed
refactor: tidyup user and auth before REFS #51
1 parent 2dc0152 commit 7547ee3

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

Diff for: src/labs/models/user.py

+43-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
"""An application user
1+
""" An application user
2+
3+
The aim is to provide a set of fields that are common to most
4+
applications with a good know set of practices around authentication
5+
both via password and one time passwords.
6+
27
"""
38

49
from typing import Optional
@@ -62,18 +67,38 @@ class User(
6267
def check_password(self, plain_text_pass):
6368
return verify_password(plain_text_pass, self.password)
6469

65-
def get_otp(self, digits: int, timeout: int):
66-
"""
70+
def get_otp(
71+
self,
72+
digits: int = 6,
73+
timeout: int = 30
74+
):
75+
""" Get the current OTP for the user
76+
77+
This is sent to the user via email or SMS and is used to
78+
authenticate the user. This should be different based
79+
on the timeout and the digits.
6780
"""
6881
otp = TOTP(self.secret, digits=digits, interval=timeout)
6982
return otp.now()
7083

71-
def verify_otp(self, timeout: int, window: int, token: str):
84+
def verify_otp(
85+
self,
86+
token: str,
87+
timeout: int = 30,
88+
window: int = 30
89+
):
90+
"""
91+
"""
7292
otp = TOTP(self.secret, interval=timeout)
7393
return otp.verify(token, valid_window=window)
7494

7595
@classmethod
7696
async def get_by_email(cls, session, email):
97+
""" A custom getter where the user is found via email
98+
99+
The aim is to assist with finding the user by email
100+
which is handy when authenticating via passwords
101+
"""
77102
query = cls._base_get_query().where(cls.email == email)
78103
try:
79104
results = await session.execute(query)
@@ -113,6 +138,19 @@ def receive_init(target, args, kwargs):
113138
target.otp_secret = random_base32()
114139

115140
def encrypt_password(target, value, oldvalue, initiator):
141+
""" Encrypt the password when it is set
142+
143+
This enables the application logic to simply set the plain
144+
text password and the model encrypts it on the way in.
145+
146+
The idea is to abstract this from the duties of the application.
147+
"""
116148
return hash_password(value)
117149

118-
event.listen(User.password, 'set', encrypt_password, retval=True)
150+
# Support for the above method to run when the password is set
151+
event.listen(
152+
User.password,
153+
'set',
154+
encrypt_password,
155+
retval=True
156+
)

Diff for: src/labs/utils/auth.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ def verify_password(
2424
hashed_password
2525
) -> bool:
2626
""" Use the crypt context to verify the password
27+
28+
the str.encode is used to convert the string to bytes
2729
"""
2830
return bcrypt.checkpw(
2931
str.encode(plain_password),
@@ -36,7 +38,7 @@ def hash_password(password) -> str:
3638
This is used by the setter in the User model to hash
3739
the password when the handlers set the property.
3840
39-
the input string has to be
41+
the input string has to be an byte string
4042
"""
4143
encoded_password = bcrypt.hashpw(
4244
str.encode(password),

0 commit comments

Comments
 (0)