Skip to content

Commit c7f65bd

Browse files
author
Qinkai Li
committed
fix: critical fix to allow callsign to be none and password_salt to be a string field of max 32 charcters
1 parent b2622b7 commit c7f65bd

File tree

3 files changed

+20
-25
lines changed

3 files changed

+20
-25
lines changed

gs/backend/api/v1/aro/endpoints/auth/oauth.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,15 @@
99
After initial authentication, the user will need to additionally verify with their callsign.
1010
"""
1111

12-
from datetime import datetime, timedelta
13-
from hashlib import pbkdf2_hmac
12+
from datetime import datetime
1413
from os import urandom
15-
from typing import Optional
1614
from uuid import UUID, uuid4
1715

1816
from authlib.integrations.starlette_client import OAuth, OAuthError
1917
from starlette.requests import Request
2018
from starlette.config import Config
2119
from fastapi.responses import RedirectResponse
22-
from fastapi import APIRouter, Depends, HTTPException, status
20+
from fastapi import APIRouter, HTTPException, status
2321
from pydantic import BaseModel, EmailStr
2422
from sqlmodel import select
2523

@@ -204,7 +202,7 @@ async def google_callback(request: Request) -> TokenResponse:
204202
user = get_user_by_google_id(google_id=google_id)
205203
if not user:
206204
# Does the user email already exist?
207-
existing_user = get_user_by_email(user)
205+
existing_user = get_user_by_email(email)
208206
if existing_user:
209207
# Link Google Account to existing email
210208
with get_db_session() as session:
@@ -247,9 +245,8 @@ async def register(request: RegisterRequest) -> TokenResponse:
247245
existing_user = get_user_by_email(request.email)
248246
if existing_user:
249247
raise HTTPException(
250-
251248
status_code=status.HTTP_409_CONFLICT,
252-
details="Email has already been taken.",
249+
detail="Email has already been taken.",
253250
)
254251

255252
# Create all user data
@@ -274,7 +271,7 @@ async def register(request: RegisterRequest) -> TokenResponse:
274271
login = AROUserLogin(
275272
email=user.email,
276273
password=hashed_password,
277-
password_salt=salt,
274+
password_salt=salt.hex(),
278275
hashing_algorithm_name=HASH_ALGORITHM,
279276
user_data_id=user.id,
280277
email_verification_token=verification_token,
@@ -286,7 +283,7 @@ async def register(request: RegisterRequest) -> TokenResponse:
286283
auth_token = create_auth_token(user.id, AROAuthToken.EMAIL_PASSWORD)
287284

288285
return TokenResponse(
289-
token=auth_token,
286+
token=auth_token.token,
290287
user_id=user.id,
291288
expires_at=auth_token.expiry,
292289
)
@@ -312,7 +309,7 @@ async def login(request: LoginRequest) -> TokenResponse:
312309
if not verify_password(request.password, login_record.password_salt, login_record.password):
313310
raise HTTPException(
314311
status_code=status.HTTP_401_UNAUTHORIZED,
315-
details="Incorrect email or password.",
312+
detail="Incorrect email or password.",
316313
)
317314

318315
# Get the user data
@@ -327,7 +324,7 @@ async def login(request: LoginRequest) -> TokenResponse:
327324
auth_token = create_auth_token(user.id, AROAuthToken.EMAIL_PASSWORD)
328325

329326
return TokenResponse(
330-
token=auth_token,
327+
token=auth_token.token,
331328
user_id=user.id,
332329
expires_at=auth_token.expiry,
333330
)
@@ -349,10 +346,10 @@ async def logout(token: str) -> dict:
349346
select(AROUserAuthToken).where(AROUserAuthToken.token == token)
350347
).first()
351348

352-
if not auth_token():
349+
if not auth_token:
353350
raise HTTPException(
354351
status_code=status.HTTP_404_NOT_FOUND,
355-
details="Couldn't find your login credentials. How did you even log in?",
352+
detail="Couldn't find your login credentials. How did you even log in?",
356353
)
357354

358355
session.delete(auth_token)
@@ -378,7 +375,7 @@ async def get_current_user(token: str) -> UserResponse:
378375
if not auth_token():
379376
raise HTTPException(
380377
status_code=status.HTTP_404_NOT_FOUND,
381-
details="Couldn't find your login credentials. How did you even log in?",
378+
detail="Couldn't find your login credentials. How did you even log in?",
382379
)
383380

384381
# Check for expiracy

gs/backend/api/v1/aro/endpoints/services.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
AROUsers,
1818
)
1919
from gs.backend.data.database.engine import get_db_session
20-
from gs.backend.data.enums.aro_auth_token import AROAuthToken
21-
from gs.backend.data.tables.aro_user_tables import AROAuthToken
2220

2321
TOKEN_EXPIRY_HOURS = 6.7
2422
HASH_ALGORITHM = "sha256"
@@ -29,8 +27,9 @@ def hash_password(password: str, salt: bytes) -> str:
2927
hashed = pbkdf2_hmac(HASH_ALGORITHM, password.encode(), salt, HASH_ITERATIONS)
3028
return hashed.hex()
3129

32-
def verify_password(password: str, salt: bytes, hashed: str) -> bool:
30+
def verify_password(password: str, salt_hex: bytes, hashed: str) -> bool:
3331
# Verify a hashed password against its hash
32+
salt = bytes.fromhex(salt_hex)
3433
return hash_password(password, salt) == hashed
3534

3635
def create_auth_token(user_id: UUID, auth_type: AROUserAuthToken) -> AROUserAuthToken:
@@ -55,14 +54,14 @@ def create_auth_token(user_id: UUID, auth_type: AROUserAuthToken) -> AROUserAuth
5554
def get_user_by_email(email: str) -> AROUsers | None:
5655
# Find a user by their email address.
5756
with get_db_session() as session:
58-
found_user = session.exec(select(AROUsers).where(AROUsers.email == email))
59-
return found_user
57+
found_user = session.exec(select(AROUsers).where(AROUsers.email == email)).first()
58+
return found_user
6059

6160
def get_user_by_google_id(google_id: str) -> AROUsers | None:
6261
# Find a user from their Google ID.
6362
with get_db_session() as session:
64-
found_user = session.exec(select(AROUsers).where(AROUsers.google_id == google_id))
65-
return found_user
63+
found_user = session.exec(select(AROUsers).where(AROUsers.google_id == google_id)).first()
64+
return found_user
6665

6766
def create_oauth_user(google_id: str, email: str, first_name: str, last_name: str | None) -> AROUsers:
6867
# Create a new user from Google OAuth data.

gs/backend/data/tables/aro_user_tables.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class AROUsers(BaseSQLModel, table=True):
4848

4949
id: UUID = Field(default_factory=uuid4, primary_key=True, index=True)
5050

51-
call_sign: str = Field(
51+
call_sign: str | None = Field(
5252
min_length=CALL_SIGN_MIN_LENGTH,
5353
max_length=CALL_SIGN_MAX_LENGTH,
5454
default=None,
@@ -100,8 +100,8 @@ class AROUserLogin(BaseSQLModel, table=True):
100100

101101
id: UUID = Field(default_factory=uuid4, primary_key=True, index=True) # unique id for logins
102102
email: EmailStr = Field(min_length=EMAIL_MIN_LENGTH, max_length=DEFAULT_MAX_LENGTH, unique=True)
103-
password: str = Field(max_length=20)
104-
password_salt: bytes = urandom(16)
103+
password: str = Field(max_length=128)
104+
password_salt: str = Field(max_length=32)
105105
created_on: datetime = Field(default_factory=datetime.now)
106106
hashing_algorithm_name: str = Field(min_length=1, max_length=20)
107107
user_data_id: UUID = Column(DB_UUID, ForeignKey(AROUsers.id)) # type: ignore
@@ -110,7 +110,6 @@ class AROUserLogin(BaseSQLModel, table=True):
110110
__tablename__ = ARO_USER_LOGIN
111111
__table_args__ = {"schema": ARO_USER_SCHEMA_NAME}
112112

113-
114113
class AROUserAuthToken(BaseSQLModel, table=True):
115114
"""
116115
Stores all information for User Auth Tokens

0 commit comments

Comments
 (0)