170 lines
4.3 KiB
Python
170 lines
4.3 KiB
Python
"""Models for API views."""
|
|
|
|
import uuid
|
|
from datetime import datetime
|
|
from typing import Annotated, Self, override
|
|
|
|
from sqlmodel import Field, SQLModel
|
|
from pydantic import AfterValidator, IPvAnyAddress, IPvAnyNetwork
|
|
|
|
from sshecret.crypto import public_key_validator
|
|
|
|
from . import models
|
|
|
|
|
|
class ClientView(SQLModel):
|
|
"""View for a single client."""
|
|
|
|
id: uuid.UUID
|
|
name: str
|
|
description: str | None = None
|
|
public_key: str
|
|
policies: list[str] = ["0.0.0.0/0", "::/0"]
|
|
secrets: list[str] = Field(default_factory=list)
|
|
created_at: datetime | None
|
|
updated_at: datetime | None = None
|
|
|
|
@classmethod
|
|
def from_client_list(cls, clients: list[models.Client]) -> list[Self]:
|
|
"""Generate a list of responses from a list of clients."""
|
|
responses: list[Self] = [cls.from_client(client) for client in clients]
|
|
return responses
|
|
|
|
@classmethod
|
|
def from_client(cls, client: models.Client) -> Self:
|
|
"""Instantiate from a client."""
|
|
view = cls(
|
|
id=client.id,
|
|
name=client.name,
|
|
description=client.description,
|
|
public_key=client.public_key,
|
|
created_at=client.created_at,
|
|
updated_at=client.updated_at or None,
|
|
)
|
|
if client.secrets:
|
|
view.secrets = [secret.name for secret in client.secrets]
|
|
|
|
if client.policies:
|
|
view.policies = [policy.source for policy in client.policies]
|
|
|
|
return view
|
|
|
|
|
|
class ClientQueryResult(SQLModel):
|
|
"""Result class for queries towards the client list."""
|
|
|
|
clients: list[ClientView] = Field(default_factory=list)
|
|
total_results: int
|
|
remaining_results: int
|
|
|
|
|
|
class ClientCreate(SQLModel):
|
|
"""Model to create a client."""
|
|
|
|
name: str
|
|
description: str | None = None
|
|
public_key: Annotated[str, AfterValidator(public_key_validator)]
|
|
|
|
def to_client(self) -> models.Client:
|
|
"""Instantiate a client."""
|
|
return models.Client(
|
|
name=self.name,
|
|
public_key=self.public_key,
|
|
description=self.description,
|
|
)
|
|
|
|
|
|
class ClientUpdate(SQLModel):
|
|
"""Model to update the client public key."""
|
|
|
|
public_key: Annotated[str, AfterValidator(public_key_validator)]
|
|
|
|
|
|
class BodyValue(SQLModel):
|
|
"""A generic model with just a value parameter."""
|
|
|
|
value: str
|
|
|
|
|
|
class ClientSecretPublic(SQLModel):
|
|
"""Public model to manage client secrets."""
|
|
|
|
name: str
|
|
secret: str
|
|
description: str | None = None
|
|
|
|
@classmethod
|
|
def from_client_secret(cls, client_secret: models.ClientSecret) -> Self:
|
|
"""Instantiate from ClientSecret."""
|
|
return cls(
|
|
name=client_secret.name,
|
|
secret=client_secret.secret,
|
|
description=client_secret.description,
|
|
)
|
|
|
|
|
|
class ClientSecretResponse(ClientSecretPublic):
|
|
"""A secret view."""
|
|
|
|
created_at: datetime | None
|
|
updated_at: datetime | None = None
|
|
|
|
@override
|
|
@classmethod
|
|
def from_client_secret(cls, client_secret: models.ClientSecret) -> Self:
|
|
"""Instantiate from ClientSecret."""
|
|
|
|
return cls(
|
|
name=client_secret.name,
|
|
secret=client_secret.secret,
|
|
created_at=client_secret.created_at,
|
|
updated_at=client_secret.updated_at,
|
|
)
|
|
|
|
|
|
class ClientPolicyView(SQLModel):
|
|
"""Update object for client policy."""
|
|
|
|
sources: list[str] = ["0.0.0.0/0", "::/0"]
|
|
|
|
@classmethod
|
|
def from_client(cls, client: models.Client) -> Self:
|
|
"""Create from client."""
|
|
if not client.policies:
|
|
return cls()
|
|
return cls(sources=[policy.source for policy in client.policies])
|
|
|
|
|
|
class ClientPolicyUpdate(SQLModel):
|
|
"""Model for updating policies."""
|
|
|
|
sources: list[IPvAnyAddress | IPvAnyNetwork]
|
|
|
|
|
|
class ClientSecretList(SQLModel):
|
|
"""Model for aggregating identically named secrets."""
|
|
|
|
name: str
|
|
clients: list[str]
|
|
|
|
|
|
class ClientReference(SQLModel):
|
|
"""Reference to a client."""
|
|
|
|
id: str
|
|
name: str
|
|
|
|
|
|
class ClientSecretDetailList(SQLModel):
|
|
"""A more detailed version of the ClientSecretList."""
|
|
|
|
name: str
|
|
ids: list[str] = Field(default_factory=list)
|
|
clients: list[ClientReference] = Field(default_factory=list)
|
|
|
|
|
|
class AuditInfo(SQLModel):
|
|
"""Information about audit information."""
|
|
|
|
entries: int
|