Skip to content

Commit 774531e

Browse files
committed
new password requirements
1 parent f35ac27 commit 774531e

File tree

5 files changed

+33
-0
lines changed

5 files changed

+33
-0
lines changed

app/api/public/users.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def map_error_code_to_http_status_code(error_code: ErrorCode) -> int:
2727

2828

2929
_error_code_to_http_status_code_map: dict[ErrorCode, int] = {
30+
ErrorCode.BAD_REQUEST: 400,
3031
ErrorCode.INCORRECT_CREDENTIALS: 401,
3132
ErrorCode.INSUFFICIENT_PRIVILEGES: 401,
3233
ErrorCode.PENDING_VERIFICATION: 401,

app/errors.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ class ErrorCode(StrEnum):
77
INCORRECT_CREDENTIALS = "INCORRECT_CREDENTIALS"
88
INSUFFICIENT_PRIVILEGES = "INSUFFICIENT_PRIVILEGES"
99
PENDING_VERIFICATION = "PENDING_VERIFICATION"
10+
BAD_REQUEST = "BAD_REQUEST"
1011
NOT_FOUND = "NOT_FOUND"
1112
CONFLICT = "CONFLICT"
1213

app/security.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,22 @@ def hash_secure_token(unhashed_secure_token: str) -> str:
4141
unhashed_secure_token.encode(),
4242
usedforsecurity=False,
4343
).hexdigest()
44+
45+
46+
def validate_password_meets_requirements(password: str, /) -> bool:
47+
"""
48+
Validates that the password meets the security requirements.
49+
- Must be at least 8 characters long
50+
- Must contain at least one digit
51+
- Must contain at least one uppercase letter
52+
- Must contain at least one lowercase letter
53+
"""
54+
if len(password) < 8:
55+
return False
56+
if not any(char.isdigit() for char in password):
57+
return False
58+
if not any(char.isupper() for char in password):
59+
return False
60+
if not any(char.islower() for char in password):
61+
return False
62+
return True

app/usecases/authentication.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,12 @@ async def verify_password_reset(
208208
user_feedback="User not found.",
209209
)
210210

211+
if not security.validate_password_meets_requirements(new_password):
212+
return Error(
213+
error_code=ErrorCode.BAD_REQUEST,
214+
user_feedback="Password does not meet security requirements.",
215+
)
216+
211217
new_hashed_password = security.hash_osu_password(new_password)
212218
await users.update_password(
213219
user_id=user.id,

app/usecases/users.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ async def update_password(
159159
user_feedback="User not found.",
160160
)
161161

162+
if not security.validate_password_meets_requirements(new_password):
163+
return Error(
164+
error_code=ErrorCode.BAD_REQUEST,
165+
user_feedback="Password does not meet security requirements.",
166+
)
167+
162168
if not security.check_osu_password(
163169
untrusted_password=current_password,
164170
hashed_password=user.hashed_password,

0 commit comments

Comments
 (0)