Passed
Push — main ( cf3570...95bc96 )
by Jochen
04:50
created

byceps.util.authorization   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 48
dl 0
loc 92
rs 10
c 0
b 0
f 0
ccs 37
cts 37
cp 1
wmc 11

5 Functions

Rating   Name   Duplication   Size   Complexity  
A register_permissions() 0 7 2
A load_permissions() 0 8 2
A get_permissions_for_user() 0 14 1
A has_current_user_permission() 0 3 1
A has_current_user_any_permission() 0 3 1

4 Methods

Rating   Name   Duplication   Size   Complexity  
A PermissionRegistry.__init__() 0 2 1
A PermissionRegistry.get_registered_permission_ids() 0 3 1
A PermissionRegistry.get_registered_permissions() 0 5 1
A PermissionRegistry.register_permission() 0 5 1
1
"""
2
byceps.util.authorization
3
~~~~~~~~~~~~~~~~~~~~~~~~~
4
5
:Copyright: 2006-2021 Jochen Kupperschmidt
6
:License: Revised BSD (see `LICENSE` file for details)
7
"""
8
9 1
from __future__ import annotations
10 1
from importlib import import_module
11 1
import pkgutil
12
13 1
from flask import g
14 1
from flask_babel import LazyString
15
16 1
from ..services.authorization import service as authorization_service
17 1
from ..services.authorization.transfer.models import Permission, PermissionID
18 1
from ..typing import UserID
19
20
21 1
def load_permissions() -> None:
22
    """Load permissions from modules in the permissions package."""
23 1
    pkg_name = f'byceps.permissions'
24 1
    pkg_module = import_module(pkg_name)
25 1
    mod_infos = pkgutil.iter_modules(pkg_module.__path__)
26 1
    mod_names = {mod_info.name for mod_info in mod_infos}
27 1
    for mod_name in mod_names:
28 1
        import_module(f'{pkg_name}.{mod_name}')
29
30
31 1
def register_permissions(
32
    group: str, names_and_labels: list[tuple[str, LazyString]]
33
) -> None:
34
    """Register a permission."""
35 1
    for name, label in names_and_labels:
36 1
        permission_id = PermissionID(f'{group}.{name}')
37 1
        permission_registry.register_permission(permission_id, label)
38
39
40 1
def get_permissions_for_user(user_id: UserID) -> frozenset[str]:
41
    """Return the permissions this user has been granted."""
42 1
    registered_permission_ids = (
43
        permission_registry.get_registered_permission_ids()
44
    )
45 1
    user_permission_ids = authorization_service.get_permission_ids_for_user(
46
        user_id
47
    )
48
49
    # Ignore unregistered permission IDs.
50 1
    return frozenset(
51
        str(permission_id)
52
        for permission_id in registered_permission_ids
53
        if permission_id in user_permission_ids
54
    )
55
56
57 1
class PermissionRegistry:
58
    """A collection of valid permissions."""
59
60 1
    def __init__(self) -> None:
61 1
        self._permissions: dict[PermissionID, LazyString] = {}
62
63 1
    def register_permission(
64
        self, permission_id: PermissionID, label: LazyString
65
    ) -> None:
66
        """Add permission to the registry."""
67 1
        self._permissions[permission_id] = label
68
69 1
    def get_registered_permission_ids(self) -> frozenset[PermissionID]:
70
        """Return all registered permission IDs."""
71 1
        return frozenset(self._permissions.keys())
72
73 1
    def get_registered_permissions(self) -> frozenset[Permission]:
74
        """Return all registered permissions."""
75 1
        return frozenset(
76
            Permission(id=permission_id, title=label)
77
            for permission_id, label in self._permissions.items()
78
        )
79
80
81 1
permission_registry = PermissionRegistry()
82
83
84 1
def has_current_user_permission(permission: str) -> bool:
85
    """Return `True` if the current user has this permission."""
86 1
    return permission in g.user.permissions
87
88
89 1
def has_current_user_any_permission(*permissions: str) -> bool:
90
    """Return `True` if the current user has any of these permissions."""
91
    return any(map(has_current_user_permission, permissions))
92