Passed
Push — master ( c55bf2...b94d48 )
by
unknown
02:35
created

tracim.lib.utils.auth   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 12
eloc 68
dl 0
loc 116
rs 10
c 0
b 0
f 0

3 Functions

Rating   Name   Duplication   Size   Complexity  
A get_workspace() 0 18 4
A get_user() 0 15 2
B check_credentials() 0 37 6
1
# -*- coding: utf-8 -*-
0 ignored issues
show
Coding Style introduced by
This module should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
2
import typing
3
4
from json.decoder import JSONDecodeError
0 ignored issues
show
Bug introduced by
The name JSONDecodeError does not seem to exist in module json.decoder.
Loading history...
5
from sqlalchemy.orm.exc import NoResultFound
6
7
from pyramid.request import Request
8
from pyramid.security import ALL_PERMISSIONS
0 ignored issues
show
Unused Code introduced by
Unused ALL_PERMISSIONS imported from pyramid.security
Loading history...
9
from pyramid.security import Allow
0 ignored issues
show
Unused Code introduced by
Unused Allow imported from pyramid.security
Loading history...
10
from pyramid.security import unauthenticated_userid
11
12
from tracim.models.auth import Group
0 ignored issues
show
Unused Code introduced by
Unused Group imported from tracim.models.auth
Loading history...
13
from tracim.models.auth import User
14
from tracim.models.data import Workspace
15
from tracim.models.data import UserRoleInWorkspace
0 ignored issues
show
Unused Code introduced by
Unused UserRoleInWorkspace imported from tracim.models.data
Loading history...
16
from tracim.lib.core.user import UserApi
17
from tracim.lib.core.workspace import WorkspaceApi
18
from tracim.lib.core.userworkspace import RoleApi
19
20
# INFO - G.M - 06-04-2018 - Auth for pyramid
21
# based on this tutorial : https://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/auth/basic.html  # nopep8
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (119/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
22
BASIC_AUTH_WEBUI_REALM = "tracim"
23
24
# Global Permissions
25
ADMIN_PERM = 'admin'
26
MANAGE_GLOBAL_PERM = 'manage_global'
27
USER_PERM = 'user'
28
# Workspace-specific permission
29
READ_PERM = 'read'
30
CONTRIBUTE_PERM = 'contribute'
31
MANAGE_CONTENT_PERM = 'manage_content'
32
MANAGE_WORKSPACE_PERM = 'manage_workspace'
33
34
35
def get_user(request: Request) -> typing.Optional[User]:
36
    """
37
    Get current pyramid user from request
38
    :param request: pyramid request
39
    :return:
40
    """
41
    app_config = request.registry.settings['CFG']
42
    uapi = UserApi(None, session=request.dbsession, config=app_config)
43
    user = None
44
    try:
45
        login = unauthenticated_userid(request)
46
        user = uapi.get_one_by_email(login)
47
    except NoResultFound:
48
        pass
49
    return user
50
51
52
def get_workspace(request: Request) -> typing.Optional[Workspace]:
53
    """
54
    Get current workspace from request
55
    :param request: pyramid request
56
    :return:
57
    """
58
    workspace = None
59
    try:
60
        if 'workspace_id' not in request.json_body:
61
            return None
62
        workspace_id = request.json_body['workspace_id']
63
        wapi = WorkspaceApi(current_user=None, session=request.dbsession)
64
        workspace = wapi.get_one(workspace_id)
65
    except JSONDecodeError:
66
        pass
67
    except NoResultFound:
68
        pass
69
    return workspace
70
71
72
def check_credentials(
73
        login: str,
74
        cleartext_password: str,
75
        request: Request
76
) -> typing.Optional[list]:
77
    """
78
    Check credential for pyramid basic_auth, checks also for
79
    global and Workspace related permissions.
80
    :param login: login of user
81
    :param cleartext_password: user password in cleartext
82
    :param request: Pyramid request
83
    :return: None if auth failed, list of permissions if auth succeed
84
    """
85
    user = get_user(request)
86
87
    # Do not accept invalid user
88
    if not user \
89
            or user.email != login \
90
            or not user.validate_password(cleartext_password):
91
        return None
92
    permissions = []
93
94
    # Global groups
95
    for group in user.groups:
96
        permissions.append(group.group_id)
97
98
    # Current workspace related group
99
    workspace = get_workspace(request)
100
    if workspace:
101
        roleapi = RoleApi(current_user=user, session=request.dbsession)
102
        role = roleapi.get_one(
103
            user_id=user.user_id,
104
            workspace_id=workspace.workspace_id,
105
        )
106
        permissions.append(role)
107
108
    return permissions
109
110
111
class Root(object):
112
    """
113
    Root of all Pyramid requests, used to store global acl
114
    """
115
    __acl__ = ()
116