diff options
author | 2024-08-25 00:16:18 +0100 | |
---|---|---|
committer | 2024-08-25 00:16:18 +0100 | |
commit | 9ffe5f25bdaa5f251ddd6d253af75c1c588af526 (patch) | |
tree | ff18b525106815f39b5c604cfadff5412d8d4262 | |
parent | Add an admin endpoint for syncing templates & variants from printful (diff) |
Add a new route to fetch templates and variants
-rw-r--r-- | thallium-backend/src/auth.py | 5 | ||||
-rw-r--r-- | thallium-backend/src/dto/__init__.py | 13 | ||||
-rw-r--r-- | thallium-backend/src/dto/templates.py | 32 | ||||
-rw-r--r-- | thallium-backend/src/dto/users.py | 4 | ||||
-rw-r--r-- | thallium-backend/src/routes/templates.py | 29 |
5 files changed, 72 insertions, 11 deletions
diff --git a/thallium-backend/src/auth.py b/thallium-backend/src/auth.py index 7b9a0fa..56987a8 100644 --- a/thallium-backend/src/auth.py +++ b/thallium-backend/src/auth.py @@ -138,10 +138,13 @@ class HasPermission: Raises MissingPermissions if not. """ - def __init__(self, required_permissions: UserPermission) -> None: + def __init__(self, required_permissions: UserPermission, *, allow_vouchers: bool = False) -> None: self.required_permissions = required_permissions + self.allow_vouchers = allow_vouchers async def __call__(self, request: Request) -> None: """Check the requesting user has all specified permissions.""" + if hasattr(request.state, "voucher") and self.allow_vouchers: + return if not request.state.user.permissions & self.required_permissions == self.required_permissions: raise MissingPermissionsError diff --git a/thallium-backend/src/dto/__init__.py b/thallium-backend/src/dto/__init__.py index 2a53355..1392017 100644 --- a/thallium-backend/src/dto/__init__.py +++ b/thallium-backend/src/dto/__init__.py @@ -1,5 +1,16 @@ from .login import VoucherClaim, VoucherLogin +from .templates import Template, TemplateWithVariant, Variant from .users import User, UserPermission from .vouchers import Voucher -__all__ = ("LoginData", "User", "UserPermission", "Voucher", "VoucherClaim", "VoucherLogin") +__all__ = ( + "LoginData", + "User", + "UserPermission", + "Voucher", + "VoucherClaim", + "VoucherLogin", + "Template", + "TemplateWithVariant", + "Variant", +) diff --git a/thallium-backend/src/dto/templates.py b/thallium-backend/src/dto/templates.py new file mode 100644 index 0000000..48ab685 --- /dev/null +++ b/thallium-backend/src/dto/templates.py @@ -0,0 +1,32 @@ +from datetime import datetime +from decimal import Decimal + +from pydantic import BaseModel + + +class Template(BaseModel): + """Base model for a template.""" + + template_id: int + title: str + product_id: int + mockup_file_url: str + last_synced: datetime + + +class Variant(BaseModel): + """Base model for a template.""" + + variant_id: int + name: str + size: str + colour: str + colour_code: str + price: Decimal + last_synced: datetime + + +class TemplateWithVariant(Template): + """A voucher as stored in the database.""" + + variants: list[Variant] diff --git a/thallium-backend/src/dto/users.py b/thallium-backend/src/dto/users.py index 35eadec..8faf4e7 100644 --- a/thallium-backend/src/dto/users.py +++ b/thallium-backend/src/dto/users.py @@ -10,8 +10,8 @@ class UserPermission(IntFlag): VIEW_VOUCHERS = 2**0 ISSUE_VOUCHERS = 2**1 REVOKE_VOUCHERS = 2**1 - VIEW_PRODUCTS = 2**2 - MANAGE_USERS = 2**3 + MANAGE_USERS = 2**2 + VIEW_TEMPLATES = 2**3 UPDATE_TEMPLATES = 2**4 diff --git a/thallium-backend/src/routes/templates.py b/thallium-backend/src/routes/templates.py index 7dad7f7..e928745 100644 --- a/thallium-backend/src/routes/templates.py +++ b/thallium-backend/src/routes/templates.py @@ -1,16 +1,31 @@ import logging from fastapi import APIRouter, Depends +from sqlalchemy import select +from sqlalchemy.orm import joinedload -from src.auth import TokenAuth -from src.settings import PrintfulClient +from src.auth import HasPermission, TokenAuth, UserPermission +from src.dto import Template, TemplateWithVariant +from src.orm import Template as DBTemplate +from src.settings import DBSession -router = APIRouter(tags=["Printful"], prefix="/printful", dependencies=[Depends(TokenAuth(allow_regular_users=True))]) +router = APIRouter( + tags=["Templates"], + prefix="/templates", + dependencies=[Depends(TokenAuth(allow_regular_users=True, allow_vouchers=True))], +) log = logging.getLogger(__name__) [email protected]("/templates") -async def get_templates(client: PrintfulClient) -> dict: [email protected]("/", dependencies=[Depends(HasPermission(UserPermission.VIEW_TEMPLATES, allow_vouchers=True))]) +async def get_templates(db: DBSession, *, with_variants: bool = False) -> list[Template] | list[TemplateWithVariant]: """Return all templates in printful.""" - resp = await client.get("/product-templates") - return resp.json() + stmt = select(DBTemplate) + if with_variants: + stmt = stmt.options(joinedload(DBTemplate.variants)) + res = await db.scalars(stmt) + + if with_variants: + return res.unique().all() + + return res.all() |