feat: bootstrap backend MVP and architecture docs
This commit is contained in:
1
app/repositories/__init__.py
Normal file
1
app/repositories/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""Repository layer."""
|
||||
63
app/repositories/permissions_repo.py
Normal file
63
app/repositories/permissions_repo.py
Normal file
@@ -0,0 +1,63 @@
|
||||
from sqlalchemy import delete, select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models.permission import Permission
|
||||
|
||||
|
||||
class PermissionsRepository:
|
||||
def __init__(self, db: Session) -> None:
|
||||
self.db = db
|
||||
|
||||
def list_by_user_id(self, user_id: str) -> list[Permission]:
|
||||
stmt = select(Permission).where(Permission.user_id == user_id)
|
||||
return list(self.db.scalars(stmt).all())
|
||||
|
||||
def create_if_not_exists(
|
||||
self,
|
||||
user_id: str,
|
||||
scope_type: str,
|
||||
scope_id: str,
|
||||
module: str,
|
||||
action: str,
|
||||
) -> Permission:
|
||||
stmt = select(Permission).where(
|
||||
Permission.user_id == user_id,
|
||||
Permission.scope_type == scope_type,
|
||||
Permission.scope_id == scope_id,
|
||||
Permission.module == module,
|
||||
Permission.action == action,
|
||||
)
|
||||
existing = self.db.scalar(stmt)
|
||||
if existing:
|
||||
return existing
|
||||
|
||||
item = Permission(
|
||||
user_id=user_id,
|
||||
scope_type=scope_type,
|
||||
scope_id=scope_id,
|
||||
module=module,
|
||||
action=action,
|
||||
)
|
||||
self.db.add(item)
|
||||
self.db.commit()
|
||||
self.db.refresh(item)
|
||||
return item
|
||||
|
||||
def revoke(
|
||||
self,
|
||||
user_id: str,
|
||||
scope_type: str,
|
||||
scope_id: str,
|
||||
module: str,
|
||||
action: str,
|
||||
) -> int:
|
||||
stmt = delete(Permission).where(
|
||||
Permission.user_id == user_id,
|
||||
Permission.scope_type == scope_type,
|
||||
Permission.scope_id == scope_id,
|
||||
Permission.module == module,
|
||||
Permission.action == action,
|
||||
)
|
||||
result = self.db.execute(stmt)
|
||||
self.db.commit()
|
||||
return int(result.rowcount or 0)
|
||||
38
app/repositories/users_repo.py
Normal file
38
app/repositories/users_repo.py
Normal file
@@ -0,0 +1,38 @@
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models.user import User
|
||||
|
||||
|
||||
class UsersRepository:
|
||||
def __init__(self, db: Session) -> None:
|
||||
self.db = db
|
||||
|
||||
def get_by_sub(self, authentik_sub: str) -> User | None:
|
||||
stmt = select(User).where(User.authentik_sub == authentik_sub)
|
||||
return self.db.scalar(stmt)
|
||||
|
||||
def upsert_by_sub(
|
||||
self,
|
||||
authentik_sub: str,
|
||||
email: str | None,
|
||||
display_name: str | None,
|
||||
is_active: bool,
|
||||
) -> User:
|
||||
user = self.get_by_sub(authentik_sub)
|
||||
if user is None:
|
||||
user = User(
|
||||
authentik_sub=authentik_sub,
|
||||
email=email,
|
||||
display_name=display_name,
|
||||
is_active=is_active,
|
||||
)
|
||||
self.db.add(user)
|
||||
else:
|
||||
user.email = email
|
||||
user.display_name = display_name
|
||||
user.is_active = is_active
|
||||
|
||||
self.db.commit()
|
||||
self.db.refresh(user)
|
||||
return user
|
||||
Reference in New Issue
Block a user