Ejemplo n.º 1
0
    async def _set_reset_password_to_user(self, user_id, membership_id,
                                          reset_password_model):
        try:
            await self.db.users.update_one(
                {
                    '_id': maybe_object_id(user_id),
                    'membership_id': membership_id
                }, {'$set': reset_password_model})
        except Exception as e:
            raise ErtisError(
                err_code="errors.errorOccurredWhileUpdatingUser",
                err_msg=
                "An error occurred while updating user with provided body",
                status_code=500,
                context={'provided_body': reset_password_model},
                reason=str(e))

        user = await self.db.users.find_one({
            '_id': maybe_object_id(user_id),
            'membership_id': membership_id
        })

        if not user:
            raise ErtisError(
                err_msg="User not found in db by given _id: <{}>".format(
                    user_id),
                err_code="errors.userNotFound",
                status_code=404)

        return user
Ejemplo n.º 2
0
def normalize_ids(where):
    if not where:
        return {}

    if '_id' in where:
        if type(where['_id']) == dict and "$in" in where['_id']:
            _ids = [maybe_object_id(_id) for _id in where['_id']['$in']]
            where['_id']['$in'] = _ids
            return where
        elif type(where['_id']) == str:
            where['_id'] = maybe_object_id(where['_id'])
            return where
    return where
Ejemplo n.º 3
0
    async def validate_token(self, token, secret, verify):
        try:
            decoded = jwt.decode(token,
                                 key=secret,
                                 algorithms='HS256',
                                 verify=verify)

        except ExpiredSignatureError as e:
            raise ErtisError(status_code=401,
                             err_msg="Provided token has expired",
                             err_code="errors.tokenExpiredError",
                             context={'message': str(e)})
        except Exception as e:
            raise ErtisError(status_code=401,
                             err_msg="Provided token is invalid",
                             err_code="errors.tokenIsInvalid",
                             context={'e': str(e)})

        where = {'_id': maybe_object_id(decoded['prn'])}

        user = await self.db.users.find_one(where)
        if not user:
            raise ErtisError(err_msg="User could not be found with this token",
                             err_code="errors.userNotFound",
                             status_code=404)
        user['decoded_token'] = decoded

        return user
Ejemplo n.º 4
0
    async def revoke_and_delete_old_active_tokens(self, user):
        membership = await self.db.memberships.find_one(
            {'_id': maybe_object_id(user['membership_id'])})

        where = {
            'membership_id': user['membership_id'],
            'user_id': str(user['_id'])
        }

        active_tokens_document = self.db.active_tokens.find(where)
        active_tokens_document = await active_tokens_document.to_list(
            length=None)

        for active_token in active_tokens_document:
            now = datetime.datetime.utcnow()
            await self.db.revoked_tokens.insert_one({
                'token':
                active_token['token'],
                'refreshable':
                True if active_token['type'] == 'refresh' else False,
                'revoked_at':
                now,
                'token_owner':
                user,
                'expire_date':
                now +
                datetime.timedelta(0, membership['refresh_token_ttl'] * 60)
            })

        await self.db.active_tokens.delete_many(where)
Ejemplo n.º 5
0
 async def _update_user_with_token(self, token, user):
     user_token = copy.deepcopy(token)
     user_token['created_at'] = datetime.datetime.utcnow()
     user_token['access_token_status'] = 'active'
     user_token['refresh_token_status'] = 'active'
     await self.db.users.update_one({'_id': maybe_object_id(user['_id'])}, {
         '$set': {
             'token': user_token,
             'ip_info': user.get('ip_info', {})
         }
     })
Ejemplo n.º 6
0
async def remove_provider(db, membership_id, provider_id):
    try:
        await db.providers.delete_one({
            '_id': maybe_object_id(provider_id),
            'membership_id': membership_id
        })
    except Exception as e:
        raise ErtisError(err_msg="An error occurred while deleting provider",
                         err_code="errors.errorOccurredWhileDeletingProvider",
                         status_code=500,
                         context={'_id': provider_id},
                         reason=str(e))
Ejemplo n.º 7
0
 async def _remove_user(self, user_id, membership_id):
     try:
         await self.db.users.delete_one({
             '_id': maybe_object_id(user_id),
             'membership_id': membership_id
         })
     except Exception as e:
         raise ErtisError(err_msg="An error occurred while deleting user",
                          err_code="errors.errorOccurredWhileDeletingUser",
                          status_code=500,
                          context={'user_id': user_id},
                          reason=str(e))
Ejemplo n.º 8
0
    async def refresh_token(self, do_revoke, refreshable_token, settings,
                            event_service):
        revoke_flag = True if do_revoke == 'true' else False

        user = await self._load_user(refreshable_token,
                                     settings['application_secret'],
                                     settings['verify_token'])

        if user['decoded_token']['rf'] is False:
            raise ErtisError(err_msg="Provided token is not refreshable",
                             err_code="errors.refreshableTokenError",
                             status_code=400)

        membership = await self.db.memberships.find_one(
            {'_id': maybe_object_id(user['membership_id'])})

        await ensure_token_is_not_revoked(self.db, refreshable_token)

        refreshed_token = await self._refresh_token(
            refreshable_token, user, settings['application_secret'],
            membership['token_ttl'], membership['refresh_token_ttl'])

        tasks = [
            self._update_user_with_token(refreshed_token, user),
            event_service.on_event((Event(
                **{
                    'document': refreshed_token,
                    'prior': {},
                    'utilizer': user,
                    'type': 'TokenRefreshedEvent',
                    'membership_id': user['membership_id'],
                    'sys': {
                        'created_at': datetime.datetime.utcnow()
                    }
                })))
        ]

        if revoke_flag:
            tasks.append(
                self.revoke_token(refreshable_token,
                                  settings,
                                  event_service,
                                  user=user))

        tasks.append(
            self._remove_from_active_tokens(user, refreshable_token,
                                            user['decoded_token']['rf']))
        tasks.append(
            self._insert_active_tokens(user, refreshed_token, membership))

        await asyncio.gather(*tasks)

        return refreshed_token
Ejemplo n.º 9
0
    async def get_application(self, application_id):
        application = await self.db.applications.find_one({
            '_id': maybe_object_id(application_id)
        })

        if not application:
            raise ErtisError(
                err_code="errors.applicationNotFound",
                err_msg="Application was not found in db by given id: <{}>".format(str(application_id)),
                status_code=404
            )

        return application
Ejemplo n.º 10
0
    async def _find_role(self, role_id, membership_id):
        role = await self.db.roles.find_one({
            '_id': maybe_object_id(role_id),
            'membership_id': membership_id
        })

        if not role:
            raise ErtisError(
                err_msg="Role not found by given id: <{}> in membership".format(role_id),
                err_code="errors.roleNotFoundError",
                status_code=404
            )

        return role
Ejemplo n.º 11
0
async def find_provider(db, membership_id, provider_id):
    provider = await db.providers.find_one({
        '_id': maybe_object_id(provider_id),
        'membership_id': membership_id
    })

    if not provider:
        raise ErtisError(
            err_code="errors.providerNotFound",
            err_msg="Provider was not found by given id: <{}>".format(
                provider_id),
            status_code=404)

    return provider
Ejemplo n.º 12
0
    async def _find_user(self, user_id, membership_id):
        user = await self.db.users.find_one({
            '_id': maybe_object_id(user_id),
            'membership_id': membership_id
        })

        if not user:
            raise ErtisError(
                err_msg="User not found in db by given _id: <{}>".format(
                    user_id),
                err_code="errors.userNotFound",
                status_code=404)

        return user
Ejemplo n.º 13
0
async def find_event(db, membership_id, event_id):
    event_doc = await db.events.find_one({
        '_id': maybe_object_id(event_id),
        'membership_id': membership_id
    })

    if not event_doc:
        raise ErtisError(
            err_code="errors.notFound",
            err_msg="Event not found by given id: <{}> in membership: <{}>".
            format(str(event_id), str(membership_id)),
            status_code=404)

    return event_doc
Ejemplo n.º 14
0
async def update_user_type_with_body(db, user_type_id, membership_id, data):
    try:
        await db.user_types.update_one(
            {
                '_id': maybe_object_id(user_type_id),
                'membership_id': membership_id
            }, {'$set': data})
    except Exception as e:
        raise ErtisError(
            err_code="errors.errorOccurredWhileUpdatingUserType",
            err_msg=
            "An error occurred while updating user type with provided body",
            status_code=500,
            context={'provided_body': data},
            reason=str(e))

    user_type = await find_user_type(membership_id, db, user_type_id)
    return user_type
Ejemplo n.º 15
0
    async def update_user_with_body(self, user_id, membership_id, body):
        try:
            await self.db.users.update_one(
                {
                    '_id': maybe_object_id(user_id),
                    'membership_id': membership_id
                }, {'$set': body})
        except Exception as e:
            raise ErtisError(
                err_code="errors.errorOccurredWhileUpdatingUser",
                err_msg=
                "An error occurred while updating user with provided body",
                status_code=500,
                context={'provided_body': body},
                reason=str(e))

        user = await self._find_user(user_id, membership_id)
        return user
Ejemplo n.º 16
0
    async def _update_user_token_status(self, user, revoked_token, status):
        token = user.get('token', {})

        for key, val in token.items():
            if val != revoked_token:
                continue

            field_name = key + '_status'
            token[field_name] = status
            await self.db.users.update_one(
                {
                    '_id': maybe_object_id(user['_id']),
                    'membership_id': user['membership_id']
                },
                {'$set': {
                    'token': token,
                    'ip_info': user.get('ip_info', {})
                }})
Ejemplo n.º 17
0
    async def me(self, application):
        app_role = await self.db.roles.find_one({
            'slug': application['role'],
            'membership_id': application['membership_id']
        })

        role_permissions = app_role.get('permissions', []) if app_role else []
        application['role_permissions'] = role_permissions
        application['membership_owner'] = app_role.get('membership_owner')

        membership = await self.db.memberships.find_one({
            '_id': maybe_object_id(application['membership_id'])
        })

        application['membership'] = membership
        application.pop('membership_id', None)
        application.pop('role_definition', None)
        return application
Ejemplo n.º 18
0
async def find_user_type(membership_id,
                         db,
                         user_type_id=None,
                         raise_exec=True):
    where = {'membership_id': membership_id}

    if user_type_id:
        where['_id'] = maybe_object_id(user_type_id)

    user_type = await db.user_types.find_one(where)

    if not user_type and raise_exec:
        raise ErtisError(
            err_msg="User type not found in membership: <{}>".format(
                membership_id),
            err_code="errors.userTypeNotFound",
            status_code=404)

    return user_type
Ejemplo n.º 19
0
    async def revoke_token(self, token, settings, event_service, user=None):
        if not user:
            user = await self.validate_token(token,
                                             settings['application_secret'],
                                             verify=True)

        membership = await self.db.memberships.find_one(
            {'_id': maybe_object_id(user['membership_id'])})

        await ensure_token_is_not_revoked(self.db, token)
        now = datetime.datetime.utcnow()
        await self.db.revoked_tokens.insert_one({
            'token':
            token,
            'refreshable':
            user['decoded_token']['rf'],
            'revoked_at':
            now,
            'token_owner':
            user,
            'expire_date':
            now + datetime.timedelta(0, membership['refresh_token_ttl'] * 60)
        })

        await self._remove_from_active_tokens(user, token,
                                              user['decoded_token']['rf'])

        await asyncio.gather(
            self._update_user_token_status(user, token, 'revoked'),
            event_service.on_event(
                Event(
                    **{
                        'document': {
                            'token': token
                        },
                        'prior': {},
                        'utilizer': user,
                        'type': 'TokenRevokedEvent',
                        'membership_id': user['membership_id'],
                        'sys': {
                            'created_at': datetime.datetime.utcnow()
                        }
                    })))
Ejemplo n.º 20
0
async def ensure_membership_is_exists(db, membership_id, user=None):
    membership = await db.memberships.find_one(
        {'_id': maybe_object_id(membership_id)})

    if not membership:
        raise ErtisError(
            err_msg="Membership not found in db by given membership_id: <{}>".
            format(membership_id),
            err_code="errors.MembershipNotFound",
            status_code=404)

    if user and str(user['membership_id']) != membership_id:
        raise ErtisError(
            err_code="errors.userNotPermittedForMembership",
            err_msg="User is not permitted for membership: <{}>".format(
                membership_id),
            status_code=401)

    return membership
Ejemplo n.º 21
0
    async def _reset_user_password(self, user, password):
        is_expired = check_expire_date_for_reset_token(
            user['reset_password']['expire_date'])

        if is_expired:
            raise ErtisError(
                err_msg="Provided password reset token has expired",
                err_code="errors.passwordResetTokenHasExpired",
                status_code=400)

        new_password = hash_user_password(password)

        await self.db.users.update_one({'_id': maybe_object_id(user['_id'])}, {
            '$set': {
                'password': new_password
            },
            '$unset': {
                'reset_password': 1
            }
        })
Ejemplo n.º 22
0
    async def on_event(self, event):
        data = {
            "_id": getattr(event, '_id', ObjectId()),
            "type": event.type,
            "document": getattr(event, 'document'),
            "prior": getattr(event, 'prior'),
            "utilizer": getattr(event, 'utilizer'),
            "membership_id": getattr(event, 'membership_id', None),
            "custom": getattr(event, 'custom', None),
            "sys": {
                "created_at": datetime.datetime.utcnow(),
                "created_by": getattr(event, 'utilizer').get('username', getattr(event, 'utilizer').get('name'))
            }
        }

        dumped = json.loads(json.dumps(data, default=bson_to_json), object_hook=object_hook)

        dumped['_id'] = maybe_object_id(dumped['_id'])

        await self.db.events.insert_one(dumped)

        logger.info("Persisted event <{}>.".format(event.type))
Ejemplo n.º 23
0
    async def me(self, user):

        user_role = await self.db.roles.find_one({
            'slug':
            user['role'],
            'membership_id':
            user['membership_id']
        })

        user_permissions = user_role.get('permissions',
                                         []) if user_role else []
        user['role_permissions'] = user_permissions

        user['membership_owner'] = user_role.get('membership_owner')

        membership = await self.db.memberships.find_one(
            {'_id': maybe_object_id(user['membership_id'])})

        user['membership'] = membership
        user.pop('membership_id', None)
        user.pop('password', None)
        user.pop('decoded_token', None)
        user.pop('role_definition', None)
        return user
Ejemplo n.º 24
0
    async def _update_role_with_body(self, role_id, membership_id, body):
        try:
            await self.db.roles.update_one(
                {
                    '_id': maybe_object_id(role_id),
                    'membership_id': membership_id
                },
                {
                    '$set': body
                }
            )
        except Exception as e:
            raise ErtisError(
                err_code="errors.errorOccurredWhileUpdatingRole",
                err_msg="An error occurred while updating role with provided body",
                status_code=500,
                context={
                    'provided_body': body
                },
                reason=str(e)
            )

        role = await self._find_role(role_id, membership_id)
        return role
Ejemplo n.º 25
0
    async def update_user(self, exists_user, exists_provider, token,
                          provided_user):
        providers = exists_user.get('providers', [])

        is_provider_found = False
        for provider in providers:
            if provider['slug'] != exists_provider['slug']:
                continue
            is_provider_found = True
            break

        if is_provider_found:
            provider.update({
                'provider_slug': exists_provider['slug'],
                'provider_type': exists_provider['type'],
                'token': token,
                'user_id': provided_user['user_id']
            })
        else:
            providers.append({
                'provider': exists_provider['name'],
                'token': token,
                'user_id': provided_user['user_id'],
                'slug': exists_provider['slug']
            })

        await self.db.users.update_one(
            {
                '_id': maybe_object_id(exists_user['_id']),
                'membership_id': exists_user['membership_id']
            }, {'$set': {
                'providers': providers
            }})

        exists_user['providers'] = providers
        return exists_user
Ejemplo n.º 26
0
def remove_mock_data(membership, user, role):
    db.memberships.delete_one({'_id': maybe_object_id(membership['_id'])})

    db.users.delete_one({'_id': maybe_object_id(user['_id'])})

    db.roles.delete_one({'_id': maybe_object_id(role['_id'])})
Ejemplo n.º 27
0
def remove_user_type(user_type_id):
    db.user_types.delete_one({'_id': maybe_object_id(user_type_id)})