forked from Github-Mirrors/canaille
refactor: Model identifier_attributes are fixed.
This commit is contained in:
parent
ee9b49402d
commit
256566df94
8 changed files with 34 additions and 60 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
Changed
|
||||||
|
^^^^^^^
|
||||||
|
- Model `identifier_attributes` are fixed.
|
||||||
|
|
||||||
[0.0.53] - 2024-04-22
|
[0.0.53] - 2024-04-22
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import ldap.dn
|
||||||
import ldap.filter
|
import ldap.filter
|
||||||
from ldap.controls.readentry import PostReadControl
|
from ldap.controls.readentry import PostReadControl
|
||||||
|
|
||||||
from canaille.app import classproperty
|
|
||||||
from canaille.backends.models import BackendModel
|
from canaille.backends.models import BackendModel
|
||||||
|
|
||||||
from .backend import Backend
|
from .backend import Backend
|
||||||
|
@ -136,10 +135,6 @@ class LDAPObject(BackendModel, metaclass=LDAPObjectMetaclass):
|
||||||
else "<LDAPOBject>"
|
else "<LDAPOBject>"
|
||||||
)
|
)
|
||||||
|
|
||||||
@classproperty
|
|
||||||
def identifier_attribute(cls):
|
|
||||||
return cls.rdn_attribute
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
ldap_attributes = self.may() + self.must()
|
ldap_attributes = self.may() + self.must()
|
||||||
|
|
||||||
|
|
|
@ -43,10 +43,6 @@ class User(canaille.core.models.User, LDAPObject):
|
||||||
|
|
||||||
return super().match_filter(filter)
|
return super().match_filter(filter)
|
||||||
|
|
||||||
@property
|
|
||||||
def identifier(self):
|
|
||||||
return self.rdn_value
|
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
group_attr = self.python_attribute_to_ldap("groups")
|
group_attr = self.python_attribute_to_ldap("groups")
|
||||||
if group_attr not in self.changes:
|
if group_attr not in self.changes:
|
||||||
|
@ -92,10 +88,6 @@ class Group(canaille.core.models.Group, LDAPObject):
|
||||||
"description": "description",
|
"description": "description",
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
|
||||||
def identifier(self):
|
|
||||||
return self.rdn_value
|
|
||||||
|
|
||||||
|
|
||||||
class Client(canaille.oidc.models.Client, LDAPObject):
|
class Client(canaille.oidc.models.Client, LDAPObject):
|
||||||
ldap_object_class = ["oauthClient"]
|
ldap_object_class = ["oauthClient"]
|
||||||
|
@ -139,10 +131,6 @@ class Client(canaille.oidc.models.Client, LDAPObject):
|
||||||
**client_metadata_attributes,
|
**client_metadata_attributes,
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
|
||||||
def identifier(self):
|
|
||||||
return self.rdn_value
|
|
||||||
|
|
||||||
|
|
||||||
class AuthorizationCode(canaille.oidc.models.AuthorizationCode, LDAPObject):
|
class AuthorizationCode(canaille.oidc.models.AuthorizationCode, LDAPObject):
|
||||||
ldap_object_class = ["oauthAuthorizationCode"]
|
ldap_object_class = ["oauthAuthorizationCode"]
|
||||||
|
@ -167,10 +155,6 @@ class AuthorizationCode(canaille.oidc.models.AuthorizationCode, LDAPObject):
|
||||||
"revokation_date": "oauthRevokationDate",
|
"revokation_date": "oauthRevokationDate",
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
|
||||||
def identifier(self):
|
|
||||||
return self.rdn_value
|
|
||||||
|
|
||||||
|
|
||||||
class Token(canaille.oidc.models.Token, LDAPObject):
|
class Token(canaille.oidc.models.Token, LDAPObject):
|
||||||
ldap_object_class = ["oauthToken"]
|
ldap_object_class = ["oauthToken"]
|
||||||
|
@ -193,10 +177,6 @@ class Token(canaille.oidc.models.Token, LDAPObject):
|
||||||
"audience": "oauthAudience",
|
"audience": "oauthAudience",
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
|
||||||
def identifier(self):
|
|
||||||
return self.rdn_value
|
|
||||||
|
|
||||||
|
|
||||||
class Consent(canaille.oidc.models.Consent, LDAPObject):
|
class Consent(canaille.oidc.models.Consent, LDAPObject):
|
||||||
ldap_object_class = ["oauthConsent"]
|
ldap_object_class = ["oauthConsent"]
|
||||||
|
@ -213,7 +193,3 @@ class Consent(canaille.oidc.models.Consent, LDAPObject):
|
||||||
"issue_date": "oauthIssueDate",
|
"issue_date": "oauthIssueDate",
|
||||||
"revokation_date": "oauthRevokationDate",
|
"revokation_date": "oauthRevokationDate",
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
|
||||||
def identifier(self):
|
|
||||||
return self.rdn_value
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import copy
|
||||||
import datetime
|
import datetime
|
||||||
import typing
|
import typing
|
||||||
import uuid
|
import uuid
|
||||||
from typing import ClassVar
|
|
||||||
|
|
||||||
import canaille.core.models
|
import canaille.core.models
|
||||||
import canaille.oidc.models
|
import canaille.oidc.models
|
||||||
|
@ -235,30 +234,26 @@ class MemoryModel(BackendModel):
|
||||||
else:
|
else:
|
||||||
super().__setattr__(name, value)
|
super().__setattr__(name, value)
|
||||||
|
|
||||||
@property
|
|
||||||
def identifier(self):
|
|
||||||
return getattr(self, self.identifier_attribute)
|
|
||||||
|
|
||||||
|
|
||||||
class User(canaille.core.models.User, MemoryModel):
|
class User(canaille.core.models.User, MemoryModel):
|
||||||
identifier_attribute: ClassVar[str] = "user_name"
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Group(canaille.core.models.Group, MemoryModel):
|
class Group(canaille.core.models.Group, MemoryModel):
|
||||||
identifier_attribute: ClassVar[str] = "display_name"
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Client(canaille.oidc.models.Client, MemoryModel):
|
class Client(canaille.oidc.models.Client, MemoryModel):
|
||||||
identifier_attribute: ClassVar[str] = "client_id"
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AuthorizationCode(canaille.oidc.models.AuthorizationCode, MemoryModel):
|
class AuthorizationCode(canaille.oidc.models.AuthorizationCode, MemoryModel):
|
||||||
identifier_attribute: ClassVar[str] = "authorization_code_id"
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Token(canaille.oidc.models.Token, MemoryModel):
|
class Token(canaille.oidc.models.Token, MemoryModel):
|
||||||
identifier_attribute: ClassVar[str] = "token_id"
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Consent(canaille.oidc.models.Consent, MemoryModel):
|
class Consent(canaille.oidc.models.Consent, MemoryModel):
|
||||||
identifier_attribute: ClassVar[str] = "consent_id"
|
pass
|
||||||
|
|
|
@ -69,6 +69,16 @@ class Model:
|
||||||
}
|
}
|
||||||
return cls._attributes
|
return cls._attributes
|
||||||
|
|
||||||
|
@property
|
||||||
|
def identifier(self):
|
||||||
|
"""Returns a unique value that will be used to identify the model
|
||||||
|
instance.
|
||||||
|
|
||||||
|
This value will be used in URLs in canaille, so it should be
|
||||||
|
unique and short.
|
||||||
|
"""
|
||||||
|
return getattr(self, self.identifier_attribute)
|
||||||
|
|
||||||
|
|
||||||
class BackendModel:
|
class BackendModel:
|
||||||
"""The backend model abstract class.
|
"""The backend model abstract class.
|
||||||
|
@ -109,16 +119,6 @@ class BackendModel:
|
||||||
return only one element or :py:data:`None` if no item is matching."""
|
return only one element or :py:data:`None` if no item is matching."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
@property
|
|
||||||
def identifier(self):
|
|
||||||
"""Returns a unique value that will be used to identify the model
|
|
||||||
instance.
|
|
||||||
|
|
||||||
This value will be used in URLs in canaille, so it should be
|
|
||||||
unique and short.
|
|
||||||
"""
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
"""Validates the current modifications in the database."""
|
"""Validates the current modifications in the database."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
|
@ -95,10 +95,6 @@ class SqlAlchemyModel(BackendModel):
|
||||||
.scalar_one_or_none()
|
.scalar_one_or_none()
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
|
||||||
def identifier(self):
|
|
||||||
return getattr(self, self.identifier_attribute)
|
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
self.last_modified = datetime.datetime.now(datetime.timezone.utc).replace(
|
self.last_modified = datetime.datetime.now(datetime.timezone.utc).replace(
|
||||||
microsecond=0
|
microsecond=0
|
||||||
|
@ -127,7 +123,6 @@ membership_association_table = Table(
|
||||||
|
|
||||||
class User(canaille.core.models.User, Base, SqlAlchemyModel):
|
class User(canaille.core.models.User, Base, SqlAlchemyModel):
|
||||||
__tablename__ = "user"
|
__tablename__ = "user"
|
||||||
identifier_attribute = "user_name"
|
|
||||||
|
|
||||||
id: Mapped[str] = mapped_column(
|
id: Mapped[str] = mapped_column(
|
||||||
String, primary_key=True, default=lambda: str(uuid.uuid4())
|
String, primary_key=True, default=lambda: str(uuid.uuid4())
|
||||||
|
@ -171,7 +166,6 @@ class User(canaille.core.models.User, Base, SqlAlchemyModel):
|
||||||
|
|
||||||
class Group(canaille.core.models.Group, Base, SqlAlchemyModel):
|
class Group(canaille.core.models.Group, Base, SqlAlchemyModel):
|
||||||
__tablename__ = "group"
|
__tablename__ = "group"
|
||||||
identifier_attribute = "display_name"
|
|
||||||
|
|
||||||
id: Mapped[str] = mapped_column(
|
id: Mapped[str] = mapped_column(
|
||||||
String, primary_key=True, default=lambda: str(uuid.uuid4())
|
String, primary_key=True, default=lambda: str(uuid.uuid4())
|
||||||
|
@ -200,7 +194,6 @@ client_audience_association_table = Table(
|
||||||
|
|
||||||
class Client(canaille.oidc.models.Client, Base, SqlAlchemyModel):
|
class Client(canaille.oidc.models.Client, Base, SqlAlchemyModel):
|
||||||
__tablename__ = "client"
|
__tablename__ = "client"
|
||||||
identifier_attribute = "client_id"
|
|
||||||
|
|
||||||
id: Mapped[str] = mapped_column(
|
id: Mapped[str] = mapped_column(
|
||||||
String, primary_key=True, default=lambda: str(uuid.uuid4())
|
String, primary_key=True, default=lambda: str(uuid.uuid4())
|
||||||
|
@ -250,7 +243,6 @@ class Client(canaille.oidc.models.Client, Base, SqlAlchemyModel):
|
||||||
|
|
||||||
class AuthorizationCode(canaille.oidc.models.AuthorizationCode, Base, SqlAlchemyModel):
|
class AuthorizationCode(canaille.oidc.models.AuthorizationCode, Base, SqlAlchemyModel):
|
||||||
__tablename__ = "authorization_code"
|
__tablename__ = "authorization_code"
|
||||||
identifier_attribute = "authorization_code_id"
|
|
||||||
|
|
||||||
id: Mapped[str] = mapped_column(
|
id: Mapped[str] = mapped_column(
|
||||||
String, primary_key=True, default=lambda: str(uuid.uuid4())
|
String, primary_key=True, default=lambda: str(uuid.uuid4())
|
||||||
|
@ -293,7 +285,6 @@ token_audience_association_table = Table(
|
||||||
|
|
||||||
class Token(canaille.oidc.models.Token, Base, SqlAlchemyModel):
|
class Token(canaille.oidc.models.Token, Base, SqlAlchemyModel):
|
||||||
__tablename__ = "token"
|
__tablename__ = "token"
|
||||||
identifier_attribute = "token_id"
|
|
||||||
|
|
||||||
id: Mapped[str] = mapped_column(
|
id: Mapped[str] = mapped_column(
|
||||||
String, primary_key=True, default=lambda: str(uuid.uuid4())
|
String, primary_key=True, default=lambda: str(uuid.uuid4())
|
||||||
|
@ -331,7 +322,6 @@ class Token(canaille.oidc.models.Token, Base, SqlAlchemyModel):
|
||||||
|
|
||||||
class Consent(canaille.oidc.models.Consent, Base, SqlAlchemyModel):
|
class Consent(canaille.oidc.models.Consent, Base, SqlAlchemyModel):
|
||||||
__tablename__ = "consent"
|
__tablename__ = "consent"
|
||||||
identifier_attribute = "consent_id"
|
|
||||||
|
|
||||||
id: Mapped[str] = mapped_column(
|
id: Mapped[str] = mapped_column(
|
||||||
String, primary_key=True, default=lambda: str(uuid.uuid4())
|
String, primary_key=True, default=lambda: str(uuid.uuid4())
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import datetime
|
import datetime
|
||||||
from typing import Annotated
|
from typing import Annotated
|
||||||
|
from typing import ClassVar
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
@ -23,6 +24,8 @@ class User(Model):
|
||||||
implementation in Canaille.
|
implementation in Canaille.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
identifier_attribute: ClassVar[str] = "user_name"
|
||||||
|
|
||||||
user_name: str
|
user_name: str
|
||||||
"""A service provider's unique identifier for the user, typically used by
|
"""A service provider's unique identifier for the user, typically used by
|
||||||
the user to directly authenticate to the service provider.
|
the user to directly authenticate to the service provider.
|
||||||
|
@ -325,6 +328,8 @@ class Group(Model):
|
||||||
<https://datatracker.ietf.org/doc/html/rfc7643#section-4.2>`_.
|
<https://datatracker.ietf.org/doc/html/rfc7643#section-4.2>`_.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
identifier_attribute: ClassVar[str] = "display_name"
|
||||||
|
|
||||||
display_name: str
|
display_name: str
|
||||||
"""A human-readable name for the Group.
|
"""A human-readable name for the Group.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
from typing import ClassVar
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
@ -16,6 +17,8 @@ class Client(Model):
|
||||||
specifications.
|
specifications.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
identifier_attribute: ClassVar[str] = "client_id"
|
||||||
|
|
||||||
description: Optional[str] = None
|
description: Optional[str] = None
|
||||||
preconsent: Optional[bool] = False
|
preconsent: Optional[bool] = False
|
||||||
audience: List["Client"] = []
|
audience: List["Client"] = []
|
||||||
|
@ -288,6 +291,8 @@ class Client(Model):
|
||||||
class AuthorizationCode(Model):
|
class AuthorizationCode(Model):
|
||||||
"""OpenID Connect temporary authorization code definition."""
|
"""OpenID Connect temporary authorization code definition."""
|
||||||
|
|
||||||
|
identifier_attribute: ClassVar[str] = "authorization_code_id"
|
||||||
|
|
||||||
authorization_code_id: str
|
authorization_code_id: str
|
||||||
code: str
|
code: str
|
||||||
client: "Client"
|
client: "Client"
|
||||||
|
@ -306,6 +311,8 @@ class AuthorizationCode(Model):
|
||||||
class Token(Model):
|
class Token(Model):
|
||||||
"""OpenID Connect token definition."""
|
"""OpenID Connect token definition."""
|
||||||
|
|
||||||
|
identifier_attribute: ClassVar[str] = "token_id"
|
||||||
|
|
||||||
token_id: str
|
token_id: str
|
||||||
access_token: str
|
access_token: str
|
||||||
client: "Client"
|
client: "Client"
|
||||||
|
@ -322,6 +329,8 @@ class Token(Model):
|
||||||
class Consent(Model):
|
class Consent(Model):
|
||||||
"""Long-term user consent to an application."""
|
"""Long-term user consent to an application."""
|
||||||
|
|
||||||
|
identifier_attribute: ClassVar[str] = "consent_id"
|
||||||
|
|
||||||
consent_id: str
|
consent_id: str
|
||||||
subject: User
|
subject: User
|
||||||
client: "Client"
|
client: "Client"
|
||||||
|
|
Loading…
Reference in a new issue