feat: add auth service with local bcrypt password authentication

This commit is contained in:
Oliver Hofmann
2026-04-27 09:42:33 +02:00
parent e72e4ec466
commit f93793a1d8
3 changed files with 132 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
from datetime import datetime
from pydantic import BaseModel
class UserOut(BaseModel):
id: int
username: str
full_name: str
email: str | None
department: str | None
role: str | None
is_active: bool
is_admin: bool
last_login: datetime | None
created_at: datetime
model_config = {"from_attributes": True}
+45
View File
@@ -0,0 +1,45 @@
from datetime import datetime, timezone
from typing import Optional
from passlib.context import CryptContext
from sqlalchemy.orm import Session
from app.modules.auth.models import User
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def hash_password(plain: str) -> str:
return pwd_context.hash(plain)
def verify_password(plain: str, hashed: str) -> bool:
return pwd_context.verify(plain, hashed)
def get_user(db: Session, username: str) -> Optional[User]:
return db.query(User).filter(User.username == username).first()
def authenticate_user(
db: Session, username: str, password: str, ldap_enabled: bool
) -> Optional[User]:
user = get_user(db, username)
if user is None or not user.is_active:
return None
local_ok = user.pw_hash is not None and verify_password(password, user.pw_hash)
if local_ok:
_touch_last_login(db, user)
return user
if ldap_enabled:
# LDAP auth implemented in Part 2
pass
return None
def _touch_last_login(db: Session, user: User) -> None:
user.last_login = datetime.now(timezone.utc)
db.commit()