mirror of
https://github.com/enpaul/keyosk.git
synced 2024-11-24 23:47:49 +00:00
Add domain and domain administration models
This commit is contained in:
parent
2b5eafa71a
commit
425d39cd48
123
keyosk/database/domain.py
Normal file
123
keyosk/database/domain.py
Normal file
@ -0,0 +1,123 @@
|
||||
"""Authentication domain model definition"""
|
||||
import datetime
|
||||
from typing import List
|
||||
|
||||
import peewee
|
||||
|
||||
from keyosk.database._shared import KeyoskBaseModel
|
||||
from keyosk.database.domain_admin import DomainAdmin
|
||||
|
||||
|
||||
class Domain(KeyoskBaseModel):
|
||||
"""Authentication domain storage model
|
||||
|
||||
:attribute created: Datetime indicating when the domain was first created
|
||||
:attribute updated: Datetime indicating when the domain was last modified
|
||||
:attribute name: Simple URL-friendly name for the domain
|
||||
:attribute audience: Value to populate the ``audience`` claim of issued JWTs with
|
||||
when authenticating against this domain
|
||||
:attribute title: Human-friendly display name for the domain
|
||||
:attribute description: Human-friendly longer description of the domain's usage or
|
||||
purpose
|
||||
:attribute contact: Contact link for the domain
|
||||
:attribute enabled: Whether the domain is enabled for authentication
|
||||
:attribute enable_password: Whether to allow accounts to authenticate using the
|
||||
client-set authentication secret
|
||||
:attribute enable_autopassword: Whether to allow accounts to authenticate using the
|
||||
server-set authentication secret
|
||||
:attribute lifespan_access: Number of seconds that an issued JWT access token should
|
||||
be valid for
|
||||
:attribute lifespan_refresh: Number of seconds an an issued JWT refresh token should
|
||||
be valid for
|
||||
:attribute administration: Container of additional settings related to the
|
||||
administration of the domain itself
|
||||
:property access_list_names: List of Access Control Lists under the domain that accounts
|
||||
can have permission entries on
|
||||
:property permission_names: List of permissions that can be assigned to an account's ACL
|
||||
entry
|
||||
"""
|
||||
|
||||
class Meta: # pylint: disable=too-few-public-methods,missing-docstring
|
||||
table_name = "domain"
|
||||
|
||||
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_password = peewee.BooleanField(null=False)
|
||||
enable_autopassword = peewee.BooleanField(null=False)
|
||||
enable_refresh = peewee.BooleanField(null=False)
|
||||
lifespan_access = peewee.IntegerField(null=False)
|
||||
lifespan_refresh = peewee.IntegerField(null=False)
|
||||
administration = peewee.ForeignKeyField(DomainAdmin, null=False, unique=True)
|
||||
|
||||
@property
|
||||
def access_list_names(self) -> List[str]:
|
||||
"""Return the list of ACL items from the backref"""
|
||||
return [item.name for item in self._access_lists]
|
||||
|
||||
@property
|
||||
def permission_names(self) -> List[str]:
|
||||
"""Return the list of permission names from the backref"""
|
||||
return [item.name for item in self._permissions]
|
||||
|
||||
@staticmethod
|
||||
def dict_keys() -> List[str]:
|
||||
return [
|
||||
"uuid",
|
||||
"created",
|
||||
"updated",
|
||||
"name",
|
||||
"audience",
|
||||
"title",
|
||||
"description",
|
||||
"contact",
|
||||
"enabled",
|
||||
"enable_password",
|
||||
"enable_autopassword",
|
||||
"enable_refresh",
|
||||
"lifespan_access",
|
||||
"lifespan_refresh",
|
||||
"access_list_names",
|
||||
"permission_names",
|
||||
"administration",
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def foreign_ref() -> List[str]:
|
||||
return ["administration"]
|
||||
|
||||
|
||||
class DomainAccessList(KeyoskBaseModel):
|
||||
"""Access list name model definition
|
||||
|
||||
:attribute name: Name of the access control list
|
||||
:attribute domain: Authentication domain the ACL applies to
|
||||
"""
|
||||
|
||||
class Meta: # pylint: disable=missing-docstring,too-few-public-methods
|
||||
table_name = "domain_acl"
|
||||
|
||||
name = peewee.CharField(null=False)
|
||||
domain = peewee.ForeignKeyField(Domain, backref="access_lists")
|
||||
|
||||
|
||||
class DomainPermission(KeyoskBaseModel):
|
||||
"""Permission name model definition
|
||||
|
||||
:attribute name: Name of the permission
|
||||
:attribute bitindex: Index in the generated bitmask that indicates this permission;
|
||||
zero-indexed
|
||||
:attribute domain: Authentication domain the permission should apply to the ACLs of
|
||||
"""
|
||||
|
||||
class Meta: # pylint: disable=missing-docstring,too-few-public-methods
|
||||
table_name = "domain_permission"
|
||||
|
||||
name = peewee.CharField(null=False)
|
||||
bitindex = peewee.IntegerField(null=False)
|
||||
domain = peewee.ForeignKeyField(Domain, backref="permissions")
|
70
keyosk/database/domain_admin.py
Normal file
70
keyosk/database/domain_admin.py
Normal file
@ -0,0 +1,70 @@
|
||||
"""Authentication domain meta admin settings model definition
|
||||
|
||||
The domain administration settings allow access to be granted to accounts assigned to
|
||||
the domain to manage the domain itself. This allows accounts to manage the parts of
|
||||
Keyosk that they need to without granting permissions to every domain Keyosk knows
|
||||
about.
|
||||
|
||||
However, to avoid circular foreign key references, the admin settings need their own
|
||||
relation tabel. If these settings were part of the main :class:`Domain` model then there
|
||||
would be circular references between it and the :class:`DomainAccessList` and
|
||||
:class:`DomainPermission` models.
|
||||
"""
|
||||
from typing import Generator
|
||||
from typing import Tuple
|
||||
|
||||
import peewee
|
||||
|
||||
from keyosk.database._shared import KeyoskBaseModel
|
||||
from keyosk.database.mappings import DomainAccessList
|
||||
from keyosk.database.mappings import DomainPermission
|
||||
|
||||
|
||||
class DomainAdmin(KeyoskBaseModel):
|
||||
"""Authentication domain meta administration storage model
|
||||
|
||||
:attribute access_list: The ACL that an account must have permissions for to manage
|
||||
the domain settings
|
||||
:attribute domain_read: Permission granted by the ACL entry that gives the assigned
|
||||
account read access to the domain settings
|
||||
:attribute domain_update: Permission granted by the ACL entry that gives the
|
||||
assigned account update access to the domain settings
|
||||
:attribute account_create: Permission granted by the ACL entry that gives the
|
||||
assigned account access to create new accounts assigned
|
||||
to the domain
|
||||
:attribute account_read: Permission granted by the ACL entry that gives the
|
||||
assigned account read access to the accounts assigned to
|
||||
the domain
|
||||
:attribute account_delete: Permission granted by the ACL entry that gives the
|
||||
assigned account access to unassign an account from the
|
||||
domain
|
||||
|
||||
There are two permissions not available via this model that may make sense to
|
||||
implement in the future: ``account_update`` and ``domain_delete``. The first is not
|
||||
implemented due to the potential conflicts it causes: an account can be assigned to
|
||||
multiple domains, so granting permissions on one domain to modify an account may
|
||||
implicitly grant that same permission on one or more accounts assigned to another
|
||||
domain; this seemed ill advised. The second is not implemented for no real good
|
||||
reason, other than it seemed out of the inteneded usage of "domain management".
|
||||
|
||||
.. note:: Both the permissions denoted above, as well as other permissions not
|
||||
enumerated here, are available through the primary Keyosk authentication
|
||||
domain.
|
||||
"""
|
||||
|
||||
class Meta: # pylint: disable=missing-docstring,too-few-public-methods
|
||||
table_name = "domain_admin"
|
||||
|
||||
access_list = peewee.ForeignKeyField(DomainAccessList, null=True)
|
||||
domain_read = peewee.ForeignKeyField(DomainPermission, null=True)
|
||||
domain_update = peewee.ForeignKeyField(DomainPermission, null=True)
|
||||
account_create = peewee.ForeignKeyField(DomainPermission, null=True)
|
||||
account_read = peewee.ForeignKeyField(DomainPermission, null=True)
|
||||
account_delete = peewee.ForeignKeyField(DomainPermission, null=True)
|
||||
|
||||
def __iter__(self) -> Generator[Tuple[str, str], None, None]:
|
||||
yield "access_list", self.access_list.name
|
||||
yield "domain_read", self.domain_read.name
|
||||
yield "account_create", self.account_create.name
|
||||
yield "account_read", self.account_read.name
|
||||
yield "account_delete", self.account_delete.name
|
Loading…
Reference in New Issue
Block a user