~homeworkprod/byceps

ref: 4237b3ec9496efe95dcce82bea3207ab9de4d520 byceps/byceps/services/authorization/models.py -rw-r--r-- 3.5 KiB
4237b3ec — Jochen Kupperschmidt Move ticketing blueprint into `site` subpackage 1 year, 11 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
"""
byceps.services.authorization.models
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:Copyright: 2006-2020 Jochen Kupperschmidt
:License: Modified BSD, see LICENSE for details.
"""

from sqlalchemy.ext.associationproxy import association_proxy

from ...database import db
from ...typing import UserID
from ...util.instances import ReprBuilder

from ..user.models.user import User

from .transfer.models import PermissionID, RoleID


class Permission(db.Model):
    """A permission for a specific task.

    Can be assigned to one or more roles.
    """

    __tablename__ = 'authz_permissions'

    id = db.Column(db.UnicodeText, primary_key=True)
    title = db.deferred(db.Column(db.UnicodeText, unique=True, nullable=False))

    roles = association_proxy('role_permissions', 'role')

    def __init__(self, permission_id: PermissionID, title: str) -> None:
        self.id = permission_id
        self.title = title

    def __repr__(self) -> str:
        return ReprBuilder(self) \
            .add_with_lookup('id') \
            .build()


class Role(db.Model):
    """A role.

    Combines one or more permissions.

    Can be assigned to a user.
    """

    __tablename__ = 'authz_roles'

    id = db.Column(db.UnicodeText, primary_key=True)
    title = db.deferred(db.Column(db.UnicodeText, unique=True, nullable=False))

    permissions = association_proxy('role_permissions', 'permission')
    users = association_proxy('user_roles', 'user')

    def __init__(self, role_id: RoleID, title: str) -> None:
        self.id = role_id
        self.title = title

    def __repr__(self) -> str:
        return ReprBuilder(self) \
            .add_with_lookup('id') \
            .build()


class RolePermission(db.Model):
    """The assignment of a permission to a role."""

    __tablename__ = 'authz_role_permissions'

    role_id = db.Column(db.UnicodeText, db.ForeignKey('authz_roles.id'), primary_key=True)
    role = db.relationship(Role,
                           backref=db.backref('role_permissions', collection_class=set, lazy='joined'),
                           collection_class=set)
    permission_id = db.Column(db.UnicodeText, db.ForeignKey('authz_permissions.id'), primary_key=True)
    permission = db.relationship(Permission, backref='role_permissions', collection_class=set, lazy='joined')

    def __init__(self, role_id: RoleID, permission_id: PermissionID) -> None:
        self.role_id = role_id
        self.permission_id = permission_id

    def __repr__(self) -> str:
        return ReprBuilder(self) \
            .add_with_lookup('role') \
            .add_with_lookup('permission') \
            .build()


class UserRole(db.Model):
    """The assignment of a role to a user."""

    __tablename__ = 'authz_user_roles'

    user_id = db.Column(db.Uuid, db.ForeignKey('users.id'), primary_key=True)
    user = db.relationship(User,
                           backref=db.backref('user_roles', collection_class=set),
                           collection_class=set)
    role_id = db.Column(db.UnicodeText, db.ForeignKey('authz_roles.id'), primary_key=True)
    role = db.relationship(Role,
                           backref=db.backref('user_roles', collection_class=set),
                           collection_class=set,
                           lazy='joined')

    def __init__(self, user_id: UserID, role_id: RoleID) -> None:
        self.user_id = user_id
        self.role_id = role_id

    def __repr__(self) -> str:
        return ReprBuilder(self) \
            .add_with_lookup('user') \
            .add_with_lookup('role') \
            .build()