Refactor backend views

This commit is contained in:
2025-06-08 17:40:50 +02:00
parent aa6b55a911
commit 7ad41f43d8
25 changed files with 1382 additions and 452 deletions

View File

@ -1,21 +1,58 @@
"""Common helpers."""
import re
from typing import Self
import uuid
import bcrypt
from dataclasses import dataclass, field
from enum import Enum
import bcrypt
from pydantic import BaseModel
from sqlalchemy import Select
from sqlalchemy.orm import selectinload
from sqlalchemy.future import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select
from sqlalchemy.orm import selectinload
from sshecret_backend.models import Client, ClientAccessPolicy
RE_UUID = re.compile(
"^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$"
)
RelaxedId = uuid.UUID | str
class IdType(Enum):
"""Id type."""
ID = "id"
NAME = "name"
class FlexID(BaseModel):
"""Flexible identifier."""
type: IdType
value: RelaxedId
@classmethod
def id(cls, id: RelaxedId) -> Self:
"""Construct from ID."""
return cls(type=IdType.ID, value=id)
@classmethod
def name(cls, name: str) -> Self:
"""Construct from name."""
return cls(type=IdType.NAME, value=name)
@classmethod
def from_string(cls, value: str) -> Self:
"""Convert from path string."""
if value.startswith("id:"):
return cls.id(value[3:])
elif value.startswith("name:"):
return cls.name(value[5:])
return cls.name(value)
@dataclass
class NewClientVersion:
@ -60,7 +97,10 @@ def client_with_relationships() -> Select[tuple[Client]]:
async def resolve_client_id(
session: AsyncSession, name: str, version: int | None = None, include_deleted: bool = False,
session: AsyncSession,
name: str,
version: int | None = None,
include_deleted: bool = False,
) -> uuid.UUID | None:
"""Get the ID of a client name."""
if include_deleted:
@ -123,7 +163,8 @@ async def get_client_by_name(session: AsyncSession, name: str) -> Client | None:
async def refresh_client(session: AsyncSession, client: Client) -> None:
"""Refresh the client and load in all relationships."""
await session.refresh(
client, attribute_names=["secrets", "policies", "previous_version", "updated_at"]
client,
attribute_names=["secrets", "policies", "previous_version", "updated_at"],
)