2024-03-30 22:39:09 +00:00
|
|
|
import typing
|
2023-04-15 11:00:02 +00:00
|
|
|
|
|
|
|
import canaille.core.models
|
|
|
|
import canaille.oidc.models
|
|
|
|
from canaille.app import models
|
2024-04-16 20:42:29 +00:00
|
|
|
from canaille.backends import Backend
|
2024-04-01 16:25:38 +00:00
|
|
|
from canaille.backends.models import BackendModel
|
2023-04-15 11:00:02 +00:00
|
|
|
|
|
|
|
|
2024-04-01 16:25:38 +00:00
|
|
|
class MemoryModel(BackendModel):
|
|
|
|
def __init__(self, *args, **kwargs):
|
2024-03-31 10:11:44 +00:00
|
|
|
self._state = {}
|
|
|
|
self._cache = {}
|
2023-04-15 11:00:02 +00:00
|
|
|
for attribute, value in kwargs.items():
|
|
|
|
setattr(self, attribute, value)
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return f"<{self.__class__.__name__} id={self.id}>"
|
|
|
|
|
2024-03-31 00:05:48 +00:00
|
|
|
@classmethod
|
|
|
|
def serialize(cls, value):
|
2024-03-31 10:06:13 +00:00
|
|
|
if isinstance(value, list):
|
|
|
|
values = [cls.serialize(item) for item in value]
|
|
|
|
return [item for item in values if item]
|
|
|
|
|
2024-03-31 00:05:48 +00:00
|
|
|
return value.id if isinstance(value, MemoryModel) else value
|
|
|
|
|
2024-03-31 00:20:39 +00:00
|
|
|
@classmethod
|
2024-03-31 10:06:13 +00:00
|
|
|
def deserialize(cls, attribute_name, value):
|
|
|
|
if isinstance(value, list):
|
|
|
|
values = [cls.deserialize(attribute_name, item) for item in value]
|
|
|
|
return [item for item in values if item]
|
|
|
|
|
|
|
|
if not value:
|
|
|
|
multiple_attribute = (
|
|
|
|
typing.get_origin(cls.attributes[attribute_name]) is list
|
|
|
|
)
|
|
|
|
return [] if multiple_attribute else None
|
|
|
|
|
2024-04-21 09:47:23 +00:00
|
|
|
model, _ = cls.get_model_annotations(attribute_name)
|
|
|
|
if model and not isinstance(value, model):
|
|
|
|
backend_model = getattr(models, model.__name__)
|
2024-04-16 20:42:29 +00:00
|
|
|
return Backend.instance.get(backend_model, id=value)
|
2024-03-31 10:06:13 +00:00
|
|
|
|
|
|
|
return value
|
2024-03-31 00:20:39 +00:00
|
|
|
|
2023-04-15 11:00:02 +00:00
|
|
|
def __eq__(self, other):
|
|
|
|
if other is None:
|
|
|
|
return False
|
|
|
|
|
2023-08-17 13:55:41 +00:00
|
|
|
if not isinstance(other, MemoryModel):
|
2024-04-16 20:42:29 +00:00
|
|
|
return self == Backend.instance.get(self.__class__, id=other)
|
2023-04-15 11:00:02 +00:00
|
|
|
|
2024-03-31 10:11:44 +00:00
|
|
|
return self._state == other._state
|
2023-04-15 11:00:02 +00:00
|
|
|
|
|
|
|
def __hash__(self):
|
|
|
|
return hash(self.id)
|
|
|
|
|
2024-04-01 12:31:31 +00:00
|
|
|
def __getattribute__(self, name):
|
|
|
|
if name != "attributes" and name in self.attributes:
|
2024-03-31 10:11:44 +00:00
|
|
|
return self.deserialize(name, self._cache.get(name, self._state.get(name)))
|
2023-04-15 11:00:02 +00:00
|
|
|
|
2024-04-01 12:31:31 +00:00
|
|
|
return super().__getattribute__(name)
|
2023-04-15 11:00:02 +00:00
|
|
|
|
|
|
|
def __setattr__(self, name, value):
|
|
|
|
if name in self.attributes:
|
2024-03-31 10:11:44 +00:00
|
|
|
self._cache[name] = value
|
|
|
|
self._state[name] = self.serialize(value)
|
2023-04-15 11:00:02 +00:00
|
|
|
else:
|
|
|
|
super().__setattr__(name, value)
|
|
|
|
|
2024-04-06 17:22:47 +00:00
|
|
|
|
|
|
|
class User(canaille.core.models.User, MemoryModel):
|
2024-04-22 18:04:24 +00:00
|
|
|
pass
|
2024-04-06 17:22:47 +00:00
|
|
|
|
2023-04-15 11:00:02 +00:00
|
|
|
|
2023-08-17 13:55:41 +00:00
|
|
|
class Group(canaille.core.models.Group, MemoryModel):
|
2024-04-22 18:04:24 +00:00
|
|
|
pass
|
2023-04-15 11:00:02 +00:00
|
|
|
|
|
|
|
|
2023-08-17 13:55:41 +00:00
|
|
|
class Client(canaille.oidc.models.Client, MemoryModel):
|
2024-04-22 18:04:24 +00:00
|
|
|
pass
|
2023-04-15 11:00:02 +00:00
|
|
|
|
|
|
|
|
2023-08-17 13:55:41 +00:00
|
|
|
class AuthorizationCode(canaille.oidc.models.AuthorizationCode, MemoryModel):
|
2024-04-22 18:04:24 +00:00
|
|
|
pass
|
2023-04-15 11:00:02 +00:00
|
|
|
|
|
|
|
|
2023-08-17 13:55:41 +00:00
|
|
|
class Token(canaille.oidc.models.Token, MemoryModel):
|
2024-04-22 18:04:24 +00:00
|
|
|
pass
|
2023-04-15 11:00:02 +00:00
|
|
|
|
|
|
|
|
2023-08-17 13:55:41 +00:00
|
|
|
class Consent(canaille.oidc.models.Consent, MemoryModel):
|
2024-04-22 18:04:24 +00:00
|
|
|
pass
|