mirror of
https://github.com/enpaul/keyosk.git
synced 2024-11-24 23:47:49 +00:00
WIP add initial serializers
This commit is contained in:
parent
733ffa6cd8
commit
199cad3f43
@ -1,7 +1,9 @@
|
|||||||
"""Custom fields for handing de/serializing custom data types"""
|
"""Custom fields for handing de/serializing custom data types"""
|
||||||
|
from datetime import datetime
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
from typing import Sequence
|
||||||
from typing import Type
|
from typing import Type
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
@ -80,3 +82,50 @@ class PathString(msh.fields.String):
|
|||||||
|
|
||||||
def _deserialize(self, value: str, attr, data, **kwargs) -> Path:
|
def _deserialize(self, value: str, attr, data, **kwargs) -> Path:
|
||||||
return Path(super()._deserialize(value, attr, data, **kwargs))
|
return Path(super()._deserialize(value, attr, data, **kwargs))
|
||||||
|
|
||||||
|
|
||||||
|
class Epoch(msh.fields.Field):
|
||||||
|
"""Translate between datetime objects and an integer reperesenting epoch time"""
|
||||||
|
|
||||||
|
def _serialize(self, value: Union[datetime, int], attr, obj, **kwargs) -> int:
|
||||||
|
"""Serialize a datetime object to an integer"""
|
||||||
|
|
||||||
|
if isinstance(value, datetime):
|
||||||
|
return int(value.timestamp())
|
||||||
|
return value
|
||||||
|
|
||||||
|
def _deserialize(self, value: int, attr, data, **kwargs) -> datetime:
|
||||||
|
"""Deserialize an integer to a datetime object"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
if value < 0:
|
||||||
|
raise msh.ValidationError(f"Invalid epoch time '{value}'")
|
||||||
|
except TypeError:
|
||||||
|
raise msh.ValidationError(
|
||||||
|
f"Invalid epoch value '{value}' of type '{type(value)}'"
|
||||||
|
)
|
||||||
|
return datetime.fromtimestamp(int(value))
|
||||||
|
|
||||||
|
|
||||||
|
class RawMultiType(msh.fields.Raw):
|
||||||
|
"""Like raw, but limits the types the value can be to a specified list
|
||||||
|
|
||||||
|
.. note:: Like the Marshmallow :class:`Raw` field, no additional validation is done on the value
|
||||||
|
beyond checking its type.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, types: Sequence[type], *args, **kwargs):
|
||||||
|
"""Initialize the field
|
||||||
|
|
||||||
|
:param types: Sequence of types that the value to de/serialize can be
|
||||||
|
"""
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self._types = tuple(types)
|
||||||
|
|
||||||
|
def _deserialize(self, value: Any, attr, data, **kwargs) -> Any:
|
||||||
|
"""Deserialize the value, raising a validation error if it is not of an allowed type"""
|
||||||
|
if not isinstance(value, self._types):
|
||||||
|
raise msh.ValidationError(
|
||||||
|
f"Invalid value '{value}' of type {type(value)}: expected one of {self._types}"
|
||||||
|
)
|
||||||
|
return value
|
||||||
|
0
keyosk/serializers/__init__.py
Normal file
0
keyosk/serializers/__init__.py
Normal file
25
keyosk/serializers/account.py
Normal file
25
keyosk/serializers/account.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
from typing import List
|
||||||
|
|
||||||
|
import marshmallow as msh
|
||||||
|
|
||||||
|
from keyosk import fields as custom_fields
|
||||||
|
from keyosk.serializers.account_acl import AccountACLSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class AccountSerializer(msh.Schema):
|
||||||
|
|
||||||
|
uuid = msh.fields.UUID(required=True)
|
||||||
|
created = custom_fields.Epoch(required=True)
|
||||||
|
updated = custom_fields.Epoch(required=True)
|
||||||
|
username = msh.fields.String(required=True)
|
||||||
|
enabled = msh.fields.Boolean(required=True)
|
||||||
|
extras = msh.fields.Dict(
|
||||||
|
keys=msh.fields.String(),
|
||||||
|
values=custom_fields.RawMultiType([int, float, bool, str, None]),
|
||||||
|
required=True,
|
||||||
|
)
|
||||||
|
acls = msh.fields.List(msh.fields.Nested(AccountACLSerializer), required=True)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def creation_fields() -> List[str]:
|
||||||
|
return ["uuid", "created", "updated"]
|
13
keyosk/serializers/account_acl.py
Normal file
13
keyosk/serializers/account_acl.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import marshmallow as msh
|
||||||
|
|
||||||
|
|
||||||
|
class AccountACLSerializer(msh.Schema):
|
||||||
|
|
||||||
|
access_list = msh.fields.String(required=True, data_key="access-list")
|
||||||
|
permission = msh.fields.String(required=True)
|
||||||
|
with_server_secret = msh.fields.Boolean(
|
||||||
|
required=True, data_key="with-server-secret"
|
||||||
|
)
|
||||||
|
with_client_secret = msh.fields.Boolean(
|
||||||
|
required=True, data_key="with-client-secret"
|
||||||
|
)
|
38
keyosk/serializers/domain.py
Normal file
38
keyosk/serializers/domain.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import marshmallow as msh
|
||||||
|
|
||||||
|
|
||||||
|
class DomainSerializer(msh.Schema):
|
||||||
|
|
||||||
|
uuid = msh.fields.UUID(required=True)
|
||||||
|
created = msh.fields.DateTime(required=True)
|
||||||
|
updated = msh.fields.DateTime(required=True)
|
||||||
|
name = msh.fields.String(required=True)
|
||||||
|
audience = msh.fields.String(required=True)
|
||||||
|
title = msh.fields.String(required=True, allow_none=True)
|
||||||
|
description = msh.fields.String(required=True, allow_none=True)
|
||||||
|
contact = msh.fields.String(required=True, allow_none=True)
|
||||||
|
enabled = msh.fields.Boolean(required=True)
|
||||||
|
enable_client_set_auth = msh.fields.Boolean(
|
||||||
|
required=True, data_key="enable-client-set-auth"
|
||||||
|
)
|
||||||
|
enable_server_set_auth = msh.fields.Boolean(
|
||||||
|
required=True, data_key="enable-server-set-auth"
|
||||||
|
)
|
||||||
|
enable_refresh = msh.fields.Boolean(required=True, data_key="enable-refresh")
|
||||||
|
lifespan_access = msh.fields.Boolean(required=True, data_key="lifespan-access")
|
||||||
|
lifespan_refresh = msh.fields.Boolean(required=True, data_key="lifespan-refresh")
|
||||||
|
access_lists = msh.fields.List()
|
||||||
|
|
||||||
|
# created = peewee.DateTimeField(null=False, default=datetime.datetime.utcnow)
|
||||||
|
# updated = peewee.DateTimeField(null=False, default=datetime.datetime.utcnow)
|
||||||
|
# name = peewee.CharField(null=False, unique=True)
|
||||||
|
# audience = peewee.CharField(null=False, unique=True)
|
||||||
|
# title = peewee.CharField(null=True)
|
||||||
|
# description = peewee.CharField(null=True)
|
||||||
|
# contact = peewee.CharField(null=True)
|
||||||
|
# enabled = peewee.BooleanField(null=False)
|
||||||
|
# enable_client_set_auth = peewee.BooleanField(null=False)
|
||||||
|
# enable_server_set_auth = peewee.BooleanField(null=False)
|
||||||
|
# enable_refresh = peewee.BooleanField(null=False)
|
||||||
|
# lifespan_access = peewee.IntegerField(null=False)
|
||||||
|
# lifespan_refresh = peewee.IntegerField(null=False)
|
Loading…
Reference in New Issue
Block a user