Exemple #1
0
def update_group(public_id: int, data: dict):
    """
    HTTP `PUT`/`PATCH` route for update a single group resource.

    Args:
        public_id (int): Public ID of the updatable group.
        data (UserGroupModel.SCHEMA): New group data to update.

    Raises:
        ManagerGetError: When the group with the `public_id` was not found.
        ManagerUpdateError: When something went wrong during the update.

    Returns:
        UpdateSingleResponse: With update result of the new updated group.
    """
    group_manager: GroupManager = GroupManager(database_manager=current_app.database_manager,
                                               right_manager=RightManager(rights))
    try:
        group = UserGroupModel.from_data(data=data, rights=RightManager(rights).rights)
        group_dict = UserGroupModel.to_dict(group)
        group_dict['rights'] = [right.get('name') for right in group_dict.get('rights', [])]
        group_manager.update(public_id=PublicID(public_id), group=group_dict)
        api_response = UpdateSingleResponse(result=group_dict, url=request.url,
                                            model=UserGroupModel.MODEL)
    except ManagerGetError as err:
        return abort(404, err.message)
    except ManagerUpdateError as err:
        return abort(400, err.message)
    return api_response.make_response()
def get_rights(params: CollectionParameters):
    """
    HTTP `GET`/`HEAD` route for getting a iterable collection of resources.

    Args:
        params (CollectionParameters): Passed parameters over the http query string

    Returns:
        GetMultiResponse: Which includes a IterationResult of the BaseRight.

    Notes:
        Calling the route over HTTP HEAD method will result in an empty body.

    Raises:
        ManagerIterationError: If the collection could not be iterated.
        ManagerGetError: If the collection/resources could not be found.
    """
    right_manager = RightManager(right_tree)
    body = request.method == 'HEAD'

    try:
        if params.optional['view'] == 'tree':
            api_response = GetMultiResponse(
                right_manager.tree_to_json(right_tree),
                total=len(right_tree),
                params=params,
                url=request.url,
                model='Right-Tree',
                body=body)
            return api_response.make_response(pagination=False)
        else:
            iteration_result: IterationResult[
                BaseRight] = right_manager.iterate(filter=params.filter,
                                                   limit=params.limit,
                                                   skip=params.skip,
                                                   sort=params.sort,
                                                   order=params.order)
            rights = [
                BaseRight.to_dict(type) for type in iteration_result.results
            ]
            api_response = GetMultiResponse(rights,
                                            total=iteration_result.total,
                                            params=params,
                                            url=request.url,
                                            model=Model('Right'),
                                            body=request.method == 'HEAD')
            return api_response.make_response()
    except ManagerIterationError as err:
        return abort(400, err.message)
    except ManagerGetError as err:
        return abort(404, err.message)
Exemple #3
0
def get_group(public_id: int):
    """
    HTTP `GET`/`HEAD` route for a single group resource.

    Args:
        public_id (int): Public ID of the group.

    Raises:
        ManagerGetError: When the selected group does not exists.

    Notes:
        Calling the route over HTTP HEAD method will result in an empty body.

    Returns:
        GetSingleResponse: Which includes the json data of a UserGroupModel.
    """
    group_manager: GroupManager = GroupManager(database_manager=current_app.database_manager,
                                               right_manager=RightManager(rights))
    try:
        group = group_manager.get(public_id)
    except ManagerGetError as err:
        return abort(404, err.message)
    api_response = GetSingleResponse(UserGroupModel.to_dict(group), url=request.url,
                                     model=UserGroupModel.MODEL, body=request.method == 'HEAD')
    return api_response.make_response()
Exemple #4
0
def get_groups(params: CollectionParameters):
    """
    HTTP `GET`/`HEAD` route for getting a iterable collection of resources.

    Args:
        params (CollectionParameters): Passed parameters over the http query string

    Returns:
        GetMultiResponse: Which includes a IterationResult of the UserGroupModel.

    Notes:
        Calling the route over HTTP HEAD method will result in an empty body.

    Raises:
        ManagerIterationError: If the collection could not be iterated.
        ManagerGetError: If the collection/resources could not be found.
    """
    group_manager: GroupManager = GroupManager(database_manager=current_app.database_manager,
                                               right_manager=RightManager(rights))
    try:
        iteration_result: IterationResult[UserGroupModel] = group_manager.iterate(
            filter=params.filter, limit=params.limit, skip=params.skip, sort=params.sort, order=params.order)
        groups = [UserGroupModel.to_dict(group) for group in iteration_result.results]
        api_response = GetMultiResponse(groups, total=iteration_result.total, params=params,
                                        url=request.url, model=UserGroupModel.MODEL, body=request.method == 'HEAD')
    except FrameworkIterationError as err:
        return abort(400, err.message)
    except ManagerGetError as err:
        return abort(404, err.message)
    return api_response.make_response()
Exemple #5
0
def insert_group(data: dict):
    """
    HTTP `POST` route for insert a single group resource.

    Args:
        data (UserGroupModel.SCHEMA): Insert data of a new group.

    Raises:
        ManagerGetError: If the inserted group could not be found after inserting.
        ManagerInsertError: If something went wrong during insertion.

    Returns:
        InsertSingleResponse: Insert response with the new group and its public_id.
    """
    group_manager: GroupManager = GroupManager(database_manager=current_app.database_manager,
                                               right_manager=RightManager(rights))
    try:
        result_id: PublicID = group_manager.insert(data)
        group = group_manager.get(public_id=result_id)
    except ManagerGetError as err:
        return abort(404, err.message)
    except ManagerInsertError as err:
        return abort(400, err.message)
    api_response = InsertSingleResponse(result_id=result_id, raw=UserGroupModel.to_dict(group), url=request.url,
                                        model=UserGroupModel.MODEL)
    return api_response.make_response(prefix='groups')
Exemple #6
0
def get_right(name: str):
    """
    HTTP `GET`/`HEAD` route for a single right resource.

    Args:
        name (str): Name of the right.

    Raises:
        ManagerGetError: When the selected right does not exists.

    Notes:
        Calling the route over HTTP HEAD method will result in an empty body.

    Returns:
        GetSingleResponse: Which includes the json data of a BaseRight.
    """
    right_manager: RightManager = RightManager(right_tree)

    try:
        right = right_manager.get(name)
    except ManagerGetError as err:
        return abort(404, err.message)
    api_response = GetSingleResponse(BaseRight.to_dict(right), url=request.url, model=Model('Right'),
                                     body=request.method == 'HEAD')
    return api_response.make_response()
Exemple #7
0
def right_required(required_right: str, excepted: dict = None):
    """wraps function for routes which requires a special user right
    requires: insert_request_user
    """

    with current_app.app_context():
        group_manager = GroupManager(current_app.database_manager,
                                     RightManager(rights))

    def _page_right(func):
        @functools.wraps(func)
        def _decorate(*args, **kwargs):
            try:
                current_user: UserModel = kwargs['request_user']
            except KeyError:
                return abort(400, 'No request user was provided')
            try:
                group: UserGroupModel = group_manager.get(
                    current_user.group_id)
                has_right = group.has_right(required_right)
            except ManagerGetError:
                return abort(404, 'Group or right not exists')
            if not has_right and not group.has_extended_right(required_right):
                return abort(
                    403,
                    'Request user does not have the right for this action')
            return func(*args, **kwargs)

        return _decorate

    return _page_right
Exemple #8
0
def delete_group(public_id: int, params: GroupDeletionParameters):
    """
    HTTP `DELETE` route for delete a single group resource.

    Args:
        public_id (int): Public ID of the user.
        params (GroupDeletionParameters): Optional action parameters for handling users when the group \
                                          is going to be deleted.

    Notes:
        Based on the params attribute. Users can be moved or deleted.

    Raises:
        ManagerGetError: When the group with the `public_id` was not found.
        ManagerDeleteError: When something went wrong during the deletion.

    Returns:
        DeleteSingleResponse: Delete result with the deleted group as data.
    """
    group_manager: GroupManager = GroupManager(database_manager=current_app.database_manager,
                                               right_manager=RightManager(rights))
    user_manager: UserManager = UserManager(database_manager=current_app.database_manager)

    # Check of action is set
    if params.action:
        users_in_group: List[UserModel] = user_manager.get_many(Query({'group_id': public_id}))
        if len(users_in_group) > 0:
            if params.action == GroupDeleteMode.MOVE.value:
                if params.group_id:
                    for user in users_in_group:
                        user.group_id = int(params.group_id)
                        try:
                            user_manager.update(user.public_id, user)
                        except ManagerUpdateError as err:
                            return abort(400,
                                         f'Could not move user: {user.public_id} to group: {params.group_id} | '
                                         f'Error: {err.message}')

            if params.action == GroupDeleteMode.DELETE.value:
                for user in users_in_group:
                    try:
                        user_manager.delete(user.public_id)
                    except ManagerDeleteError as err:
                        return abort(400, f'Could not delete user: {user.public_id} | Error: {err.message}')

    try:
        deleted_group = group_manager.delete(public_id=PublicID(public_id))
        api_response = DeleteSingleResponse(raw=UserGroupModel.to_dict(deleted_group), model=UserGroupModel.MODEL)
    except ManagerGetError as err:
        return abort(404, err.message)
    except ManagerDeleteError as err:
        return abort(404, err.message)
    return api_response.make_response()
Exemple #9
0
def user_has_right(required_right: str) -> bool:
    """Check if a user has a specific right"""
    from flask import request, current_app
    with current_app.app_context():
        user_manager = UserManager(current_app.database_manager)
        group_manager = GroupManager(current_app.database_manager, RightManager(rights))

    token = parse_authorization_header(request.headers['Authorization'])
    try:
        decrypted_token = TokenValidator(database_manager=current_app.database_manager).decode_token(token)
    except ValidationError as err:
        return abort(401)
    try:
        user_id = decrypted_token['DATAGERRY']['value']['user']['public_id']
        user = user_manager.get(user_id)
        group = group_manager.get(user.group_id)
        right_status = group.has_right(right_name=required_right)
        if not right_status:
            right_status = group.has_extended_right(right_name=required_right)
        return right_status
    except ManagerGetError:
        return False
Exemple #10
0
In addition, the rights management, group administration and access rights are defined here.
"""
from typing import List

from cmdb.user_management.models.settings import UserSettingModel
from cmdb.user_management.models.user import UserModel
from cmdb.user_management.models.right import BaseRight

from cmdb.user_management.models.group import UserGroupModel
from cmdb.user_management.user_manager import UserManager
from cmdb.user_management.managers.right_manager import RightManager
from cmdb.user_management.rights import __all__ as rights

# TODO: Refactor to use with dependency injection

right_manager = RightManager(rights)

__COLLECTIONS__: List = [
    UserModel,
    UserSettingModel,
    UserGroupModel
]

__ADMIN_GROUP_RIGHTS__: List[BaseRight] = [
    right_manager.get('base.*')
]

__USER_GROUP_RIGHTS__: List[BaseRight] = [
    right_manager.get('base.framework.object.*'),
    right_manager.get('base.framework.type.view'),
    right_manager.get('base.framework.category.view'),
Exemple #11
0
def parse_authorization_header(header):
    """
    Parses the HTTP Auth Header to a JWT Token
    Args:
        header: Authorization header of the HTTP Request
    Examples:
        request.headers['Authorization'] or something same
    Returns:
        Valid JWT token
    """
    if not header:
        return None
    value = wsgi_to_bytes(header)
    try:
        auth_type, auth_info = value.split(None, 1)
        auth_type = auth_type.lower()
    except ValueError:
        # Fallback for old versions
        auth_type = b"bearer"
        auth_info = value

    if auth_type == b"basic":
        try:
            username, password = base64.b64decode(auth_info).split(b":", 1)

            with current_app.app_context():
                username = to_unicode(username, "utf-8")
                password = to_unicode(password, "utf-8")

                user_manager: UserManager = UserManager(current_app.database_manager)
                group_manager: GroupManager = GroupManager(current_app.database_manager,
                                                           right_manager=RightManager(rights))
                security_manager: SecurityManager = SecurityManager(current_app.database_manager)
                auth_settings = SystemSettingsReader(current_app.database_manager).get_all_values_from_section(
                    'auth', default=AuthModule.__DEFAULT_SETTINGS__)
                auth_module = AuthModule(auth_settings, user_manager=user_manager,
                                         group_manager=group_manager, security_manager=security_manager)

                try:
                    user_instance = auth_module.login(username, password)
                except Exception as e:
                    return None
                if user_instance:
                    tg = TokenGenerator(current_app.database_manager)
                    return tg.generate_token(payload={'user': {
                        'public_id': user_instance.get_public_id()
                    }})
                else:
                    return None
        except Exception:
            return None

    if auth_type == b"bearer":
        try:
            with current_app.app_context():
                tv = TokenValidator(current_app.database_manager)
                decoded_token = tv.decode_token(auth_info)
                tv.validate_token(decoded_token)
            return auth_info
        except Exception:
            return None
    return None