Completed
Push — main ( d1ed65...998805 )
by Jochen
03:28
created

export()   A

Complexity

Conditions 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 7
nop 0
dl 0
loc 11
ccs 0
cts 5
cp 0
crap 2
rs 10
c 0
b 0
f 0
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