auth für user
This commit is contained in:
36
app/auth/account.py
Normal file
36
app/auth/account.py
Normal file
@@ -0,0 +1,36 @@
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.auth.admin import password_matches
|
||||
from app.db.models import SyncUser
|
||||
from app.db.repositories import UserRepository
|
||||
from app.security.credentials import CredentialCipher
|
||||
|
||||
|
||||
def authenticate_self_service(
|
||||
session: Session, cipher: CredentialCipher, email: str, password: str
|
||||
) -> SyncUser | None:
|
||||
"""Matches submitted email/password against any user's stored MyWhoosh OR
|
||||
Garmin credentials -- decrypted and compared locally rather than
|
||||
verified against the live MyWhoosh/Garmin APIs, so logging into this app
|
||||
never opens a redundant upstream session (which, for MyWhoosh, would
|
||||
itself trigger the "already logged in from another device" conflict)."""
|
||||
submitted_email = email.strip()
|
||||
if not submitted_email or not password:
|
||||
return None
|
||||
for user in UserRepository(session).list_all():
|
||||
if _credential_matches(cipher, user.mywhoosh_email_enc, user.mywhoosh_password_enc, submitted_email, password):
|
||||
return user
|
||||
if _credential_matches(cipher, user.garmin_email_enc, user.garmin_password_enc, submitted_email, password):
|
||||
return user
|
||||
return None
|
||||
|
||||
|
||||
def _credential_matches(
|
||||
cipher: CredentialCipher, email_enc: str, password_enc: str, submitted_email: str, submitted_password: str
|
||||
) -> bool:
|
||||
try:
|
||||
stored_email = cipher.decrypt(email_enc)
|
||||
stored_password = cipher.decrypt(password_enc)
|
||||
except ValueError:
|
||||
return False
|
||||
return stored_email == submitted_email and password_matches(submitted_password, stored_password)
|
||||
@@ -10,3 +10,10 @@ def password_matches(submitted: str, configured: str) -> bool:
|
||||
def require_admin(request: Request) -> None:
|
||||
if request.session.get("admin_authenticated") is not True:
|
||||
raise HTTPException(status_code=status.HTTP_303_SEE_OTHER, headers={"Location": "/login"})
|
||||
|
||||
|
||||
def require_self_service(request: Request) -> int:
|
||||
user_id = request.session.get("self_service_user_id")
|
||||
if not isinstance(user_id, int):
|
||||
raise HTTPException(status_code=status.HTTP_303_SEE_OTHER, headers={"Location": "/account-login"})
|
||||
return user_id
|
||||
|
||||
Reference in New Issue
Block a user