1
|
|
|
""" |
2
|
|
|
byceps.services.authorization.impex_service |
3
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
4
|
|
|
|
5
|
|
|
Import/export |
6
|
|
|
|
7
|
|
|
:Copyright: 2006-2020 Jochen Kupperschmidt |
8
|
|
|
:License: Modified BSD, see LICENSE for details. |
9
|
|
|
""" |
10
|
|
|
|
11
|
|
|
from pathlib import Path |
12
|
|
|
from typing import Dict, Iterator, List, Tuple, Union |
13
|
|
|
|
14
|
|
|
import rtoml |
15
|
|
|
|
16
|
|
|
from ...database import db |
17
|
|
|
|
18
|
|
|
from .models import Permission as DbPermission, Role as DbRole |
19
|
|
|
from . import service |
20
|
|
|
|
21
|
|
|
|
22
|
|
|
# -------------------------------------------------------------------- # |
23
|
|
|
# import |
24
|
|
|
|
25
|
|
|
|
26
|
|
|
def import_from_file(path: Path) -> Tuple[int, int]: |
27
|
|
|
"""Import permissions, roles, and their relations from TOML.""" |
28
|
|
|
data = rtoml.load(path) |
29
|
|
|
|
30
|
|
|
permissions = data['permissions'] |
31
|
|
|
roles = data['roles'] |
32
|
|
|
|
33
|
|
|
_create_permissions(permissions) |
34
|
|
|
_create_roles(roles) |
35
|
|
|
|
36
|
|
|
return len(permissions), len(roles) |
37
|
|
|
|
38
|
|
|
|
39
|
|
|
def _create_permissions(permissions: List[Dict[str, str]]) -> None: |
40
|
|
|
for permission in permissions: |
41
|
|
|
service.create_permission(permission['id'], permission['title']) |
42
|
|
|
|
43
|
|
|
|
44
|
|
|
def _create_roles(roles: List[Dict[str, Union[str, List[str]]]]) -> None: |
45
|
|
|
for role in roles: |
46
|
|
|
role_id = role['id'] |
47
|
|
|
|
48
|
|
|
service.create_role(role_id, role['title']) |
49
|
|
|
|
50
|
|
|
for permission_id in role['assigned_permissions']: |
51
|
|
|
service.assign_permission_to_role(permission_id, role_id) |
52
|
|
|
|
53
|
|
|
|
54
|
|
|
# -------------------------------------------------------------------- # |
55
|
|
|
# export |
56
|
|
|
|
57
|
|
|
|
58
|
|
|
def export() -> str: |
59
|
|
|
"""Export all permissions, roles, and their relations as TOML.""" |
60
|
|
|
permissions = list(_collect_permissions()) |
61
|
|
|
roles = list(_collect_roles()) |
62
|
|
|
|
63
|
|
|
data = { |
64
|
|
|
'permissions': permissions, |
65
|
|
|
'roles': roles, |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
return rtoml.dumps(data, pretty=True) |
69
|
|
|
|
70
|
|
|
|
71
|
|
|
def _collect_permissions() -> Iterator[Dict[str, str]]: |
72
|
|
|
"""Collect all permissions, even those not assigned to any role.""" |
73
|
|
|
permissions = DbPermission.query \ |
74
|
|
|
.options( |
75
|
|
|
db.undefer('title'), |
76
|
|
|
) \ |
77
|
|
|
.order_by(DbPermission.id) \ |
78
|
|
|
.all() |
79
|
|
|
|
80
|
|
|
for permission in permissions: |
81
|
|
|
yield { |
82
|
|
|
'id': permission.id, |
83
|
|
|
'title': permission.title, |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
|
87
|
|
|
def _collect_roles() -> Iterator[Dict[str, Union[str, List[str]]]]: |
88
|
|
|
"""Collect all roles and the permissions assigned to them.""" |
89
|
|
|
roles = DbRole.query \ |
90
|
|
|
.options( |
91
|
|
|
db.undefer('title'), |
92
|
|
|
db.joinedload('role_permissions'), |
93
|
|
|
) \ |
94
|
|
|
.order_by(DbRole.id) \ |
95
|
|
|
.all() |
96
|
|
|
|
97
|
|
|
for role in roles: |
98
|
|
|
permission_ids = [permission.id for permission in role.permissions] |
99
|
|
|
permission_ids.sort() |
100
|
|
|
|
101
|
|
|
yield { |
102
|
|
|
'id': role.id, |
103
|
|
|
'title': role.title, |
104
|
|
|
'assigned_permissions': permission_ids, |
105
|
|
|
} |
106
|
|
|
|