コード例 #1
0
ファイル: role_service.py プロジェクト: Rakkoc/ertis-auth
    async def create_role(self, data, utilizer, event_service):
        resource = generate_slug(data)
        resource['membership_id'] = utilizer['membership_id']

        role = await self._check_slug_conflict(resource)
        role['_id'] = ObjectId()
        role['membership_owner'] = resource.get('membership_owner', False)
        role['sys'] = {
            'created_at': datetime.datetime.utcnow(),
            'created_by': utilizer.get('username', utilizer.get('name'))
        }
        await self.db.roles.insert_one(role)

        role['_id'] = str(role['_id'])
        await event_service.on_event((Event(**{
            'document': role,
            'prior': {},
            'utilizer': utilizer,
            'type': 'RoleCreatedEvent',
            'membership_id': utilizer['membership_id'],
            'sys': {
                'created_at': datetime.datetime.utcnow(),
                'created_by': utilizer.get('username', utilizer.get('name'))
            }
        })))

        return role
コード例 #2
0
    async def create_application(self, resource, utilizer, event_service):
        resource['membership_id'] = utilizer['membership_id']
        resource['_id'] = ObjectId()
        resource['sys'] = {
            'created_at': datetime.datetime.utcnow(),
            'created_by': utilizer.get('username', utilizer.get('name'))
        }

        await self.role_service.get_role_by_slug(resource['role'],
                                                 utilizer['membership_id'])

        await self._ensure_name_is_unique_in_membership(resource)
        resource = generate_app_secrets(resource)
        await self.db.applications.insert_one(resource)
        await event_service.on_event((Event(
            **{
                'document': resource,
                'prior': {},
                'utilizer': utilizer,
                'type': 'ApplicationCreatedEvent',
                'membership_id': utilizer['membership_id'],
                'sys': {
                    'created_at': datetime.datetime.utcnow(),
                    'created_by': utilizer.get('username', utilizer.get(
                        'name'))
                }
            })))
        return resource
コード例 #3
0
ファイル: password_service.py プロジェクト: Rakkoc/ertis-auth
    async def set_password(self, payload, membership_id, event_service):
        email = payload['email'].lower()
        password = payload['password']
        reset_token = payload['reset_token']

        user = await self._find_user_by_query({
            'email': email,
            'reset_password.reset_token': reset_token,
            'membership_id': membership_id
        })

        await asyncio.gather(
            self._reset_user_password(user, password),
            event_service.on_event(
                Event(
                    **{
                        'document': user,
                        'prior': {},
                        'utilizer': user,
                        'type': 'PasswordResetEvent',
                        'membership_id': user['membership_id'],
                        'sys': {
                            'created_at': datetime.datetime.utcnow()
                        }
                    })))

        await self.user_service.revoke_and_delete_old_active_tokens(user)
コード例 #4
0
    async def verify_token(self, token, settings, event_service):
        await ensure_token_is_not_revoked(self.db, token)
        user = await self.validate_token(token,
                                         settings['application_secret'],
                                         verify=True)

        token_response = {
            'verified': True,
            'refreshable': user['decoded_token'].get('rf'),
            'token': token
        }

        await event_service.on_event(
            Event(
                **{
                    'document': token_response,
                    'prior': {},
                    'utilizer': user,
                    'type': 'TokenVerifiedEvent',
                    'membership_id': user['membership_id'],
                    'sys': {
                        'created_at': datetime.datetime.utcnow()
                    }
                }))

        return token_response
コード例 #5
0
ファイル: password_service.py プロジェクト: Rakkoc/ertis-auth
    async def reset_password(self, payload, membership_id, event_service):
        email = payload['email'].lower()

        user = await self._find_user_by_query({
            'email': email,
            'membership_id': membership_id
        })

        password_reset = generate_password_reset_fields()
        user = await self._set_reset_password_to_user(
            user['_id'], membership_id, {
                'reset_password': password_reset,
                'ip_info': user.get('ip_info', {})
            })

        await event_service.on_event(
            Event(
                **{
                    'document': password_reset,
                    'prior': {},
                    'utilizer': user,
                    'type': 'PasswordResetEvent',
                    'membership_id': user['membership_id'],
                    'sys': {
                        'created_at': datetime.datetime.utcnow()
                    }
                }))

        return user
コード例 #6
0
    async def update_user(self, resource_id, data, utilizer, user_type_service,
                          event_service):
        membership_id = utilizer['membership_id']
        resource = await self._find_user(resource_id, membership_id)

        provided_data = pop_non_updatable_fields(data)
        await validate_user_model_by_user_type(membership_id,
                                               resource,
                                               user_type_service,
                                               operation=OperationTypes.UPDATE)

        resource = prepare_user_fields(resource,
                                       utilizer['membership_id'],
                                       data.get('password'),
                                       opt='update')

        _resource = copy.deepcopy(resource)
        _resource.update(provided_data)
        if _resource == resource:
            raise ErtisError(err_code="errors.identicalDocument",
                             err_msg="Identical document error",
                             status_code=409)

        if _resource['username'] != resource['username']:
            await self.revoke_and_delete_old_active_tokens(_resource)

        resource['sys'].update({
            'modified_at':
            datetime.datetime.utcnow(),
            'modified_by':
            utilizer.get('username', utilizer.get('name'))
        })

        provided_data['sys'] = resource['sys']

        resource = await self.update_user_with_body(resource_id,
                                                    utilizer['membership_id'],
                                                    provided_data)
        resource.pop('password')

        resource['_id'] = str(resource['_id'])
        _resource['_id'] = str(_resource['_id'])
        await event_service.on_event((Event(
            **{
                'document': resource,
                'prior': _resource,
                'utilizer': utilizer,
                'type': 'UserUpdatedEvent',
                'membership_id': utilizer['membership_id'],
                'sys': {
                    'created_at': datetime.datetime.utcnow(),
                    'created_by': utilizer.get('username', utilizer.get(
                        'name'))
                }
            })))
        return resource
コード例 #7
0
    async def create_provider(self, resource, utilizer):
        resource['membership_id'] = utilizer['membership_id']
        resource['_id'] = ObjectId()
        resource['sys'] = {
            'created_at': datetime.datetime.utcnow(),
            'created_by': utilizer.get('username', utilizer.get('name'))
        }

        resource['slug'] = slugify(resource['name'])

        default_role = resource.get('default_role')
        exists_role = await self.db.roles.find_one({
            "slug":
            default_role,
            "membership_id":
            utilizer['membership_id']
        })

        if not exists_role:
            raise ErtisError(
                err_code="errors.roleNotFound",
                err_msg="Role not found by given slug: <{}>".format(
                    default_role),
                status_code=400)

        exist_provider = await self.db.providers.find_one({
            'slug':
            resource['slug'],
            'membership_id':
            utilizer['membership_id']
        })

        if exist_provider:
            raise ErtisError(
                err_msg=
                "Provider already exists in db with given generated slug: <{}>"
                .format(resource['slug']),
                err_code="errors.resourceAlreadyExists",
                status_code=409)

        await self.db.providers.insert_one(resource)
        await self.event_service.on_event((Event(
            **{
                'document': resource,
                'prior': {},
                'utilizer': utilizer,
                'type': 'ProviderCreatedEvent',
                'membership_id': utilizer['membership_id'],
                'sys': {
                    'created_at': datetime.datetime.utcnow(),
                    'created_by': utilizer.get('username', utilizer.get(
                        'name'))
                }
            })))
        return resource
コード例 #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
コード例 #9
0
ファイル: role_service.py プロジェクト: Rakkoc/ertis-auth
    async def delete_role(self, resource_id, utilizer, event_service):
        role = await self.get_role(resource_id, utilizer["membership_id"])
        await self._remove_role(resource_id, utilizer['membership_id'])

        role['_id'] = str(role['_id'])
        await event_service.on_event((Event(**{
            'document': {},
            'prior': role,
            'utilizer': utilizer,
            'type': 'RoleDeletedEvent',
            'membership_id': utilizer['membership_id'],
            'sys': {
                'created_at': datetime.datetime.utcnow(),
                'created_by': utilizer.get('username', utilizer.get('name'))
            }
        })))
コード例 #10
0
    async def update_user_type(self, user_type_id, data, utilizer,
                               event_service):
        membership_id = utilizer['membership_id']
        resource = await self.get_user_type(membership_id,
                                            user_type_id=user_type_id)

        _resource = copy.deepcopy(resource)
        _resource.update(data)

        if _resource == resource:
            raise ErtisError(err_code="errors.identicalDocumentError",
                             err_msg="Identical document error",
                             status_code=409)

        resource = disallow_update_fields(resource, _resource)
        resource = regenerate_slug_by_name(resource, _resource)
        validate(resource)

        resource['sys'].update({
            'modified_at':
            datetime.datetime.utcnow(),
            'modified_by':
            utilizer.get('username', utilizer.get('name'))
        })

        data['sys'] = resource['sys']

        resource = await update_user_type_with_body(self.db, user_type_id,
                                                    membership_id, data)

        resource['_id'] = str(resource['_id'])
        _resource['_id'] = str(_resource['_id'])
        await event_service.on_event((Event(
            **{
                'document': resource,
                'prior': _resource,
                'utilizer': utilizer,
                'type': 'UserTypeUpdatedEvent',
                'membership_id': utilizer['membership_id'],
                'sys': {
                    'created_at': datetime.datetime.utcnow(),
                    'created_by': utilizer.get('username', utilizer.get(
                        'name'))
                }
            })))

        return resource
コード例 #11
0
    async def create_user(self,
                          resource,
                          membership_id,
                          utilizer,
                          user_type_service,
                          event_service,
                          creator=None):
        await validate_user_model_by_user_type(membership_id,
                                               resource,
                                               user_type_service,
                                               operation=OperationTypes.CREATE,
                                               creator=creator)

        resource = prepare_user_fields(resource, membership_id,
                                       resource['password'])
        await self._ensure_email_and_username_available(resource)
        _ = await self.role_service.get_role_by_slug(resource["role"],
                                                     membership_id)

        resource['sys'] = {
            'created_at': datetime.datetime.utcnow(),
            'created_by': utilizer.get('username', utilizer.get('name'))
        }

        await self.db.users.insert_one(resource)
        resource.pop('password', None)

        resource['_id'] = str(resource['_id'])
        await event_service.on_event((Event(
            **{
                'document': resource,
                'prior': {},
                'utilizer': utilizer,
                'type': 'UserCreatedEvent',
                'membership_id': utilizer['membership_id'],
                'sys': {
                    'created_at': datetime.datetime.utcnow(),
                    'created_by': utilizer.get('username', utilizer.get(
                        'name'))
                }
            })))

        return resource
コード例 #12
0
    async def delete_provider(self, provider_id, utilizer, event_service):
        provider = await find_provider(self.db, utilizer['membership_id'],
                                       provider_id)
        await remove_provider(self.db, utilizer['membership_id'], provider_id)

        provider['_id'] = str(provider['_id'])
        await event_service.on_event((Event(
            **{
                'document': {},
                'prior': provider,
                'utilizer': utilizer,
                'type': 'ProviderDeletedEvent',
                'membership_id': utilizer['membership_id'],
                'sys': {
                    'created_at': datetime.datetime.utcnow(),
                    'created_by': utilizer.get('username', utilizer.get(
                        'name'))
                }
            })))
コード例 #13
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()
                        }
                    })))
コード例 #14
0
    async def update_provider(self, provider_id, data, utilizer,
                              event_service):
        resource = await find_provider(self.db, utilizer['membership_id'],
                                       provider_id)

        _resource = copy.deepcopy(resource)

        provided_body = pop_non_updatable_fields(data)
        resource.update(provided_body)
        if resource == _resource:
            raise ErtisError(err_msg="Identical document error",
                             err_code="errors.identicalDocument",
                             status_code=409)

        resource['sys'].update({
            'modified_at':
            datetime.datetime.utcnow(),
            'modified_by':
            utilizer.get('username', utilizer.get('name'))
        })

        provided_body['sys'] = resource['sys']
        updated_provider = await update_provider_with_body(
            self.db, provider_id, utilizer['membership_id'], provided_body)

        _resource['_id'] = str(_resource['_id'])
        updated_provider['_id'] = str(updated_provider['_id'])

        await event_service.on_event((Event(
            **{
                'document': updated_provider,
                'prior': _resource,
                'utilizer': utilizer,
                'type': 'ProviderUpdatedEvent',
                'membership_id': utilizer['membership_id'],
                'sys': {
                    'created_at': datetime.datetime.utcnow(),
                    'created_by': utilizer.get('username', utilizer.get(
                        'name'))
                }
            })))
        return updated_provider
コード例 #15
0
    async def delete_application(self, application_id, utilizer,
                                 event_service):
        application = await self._find_application(application_id,
                                                   utilizer['membership_id'])
        await self._remove_application(utilizer['membership_id'],
                                       application_id)

        application['_id'] = str(application['_id'])
        await event_service.on_event((Event(
            **{
                'document': {},
                'prior': application,
                'utilizer': utilizer,
                'type': 'ApplicationDeletedEvent',
                'membership_id': utilizer['membership_id'],
                'sys': {
                    'created_at': datetime.datetime.utcnow(),
                    'created_by': utilizer.get('username', utilizer.get(
                        'name'))
                }
            })))
コード例 #16
0
ファイル: password_service.py プロジェクト: Rakkoc/ertis-auth
    async def change_password(self, payload, user, event_service):
        user_id = payload.get('user_id')
        password = payload.get('password')
        password_confirm = payload.get('password_confirm')

        if not (user['role_definition']['membership_owner']
                or user_id == str(user['_id'])):
            raise ErtisError(err_msg="User cannot change other users password",
                             err_code="errors.userCannotChangeOthersPassword",
                             status_code=403)

        if password != password_confirm:
            raise ErtisError(
                err_code="errors.passwordAndPasswordConfirmDoesNotMatch",
                err_msg="Password and password confirm does not match",
                status_code=400)

        hashed_password = hash_user_password(password)
        await asyncio.gather(
            self.user_service.update_user_with_body(
                user_id, user['membership_id'], {
                    'password': hashed_password,
                    'ip_info': user.get('ip_info', {})
                }),
            event_service.on_event(
                Event(
                    **{
                        'document': user,
                        'prior': {},
                        'utilizer': user,
                        'type': 'PasswordChangedEvent',
                        'membership_id': user['membership_id'],
                        'sys': {
                            'created_at': datetime.datetime.utcnow()
                        }
                    })),
            self.user_service.revoke_and_delete_old_active_tokens(user),
        )
コード例 #17
0
    async def generate_token(self, settings, membership, payload,
                             event_service, **kwargs):
        membership_id = str(membership['_id'])
        skip_auth = False

        payload['username'] = payload['username'].lower()
        token_generation_parameters = {
            'body': payload,
            'application_secret': settings['application_secret'],
            'token_ttl': membership['token_ttl'],
            'refresh_token_ttl': membership['refresh_token_ttl'],
            'membership_id': membership_id,
            'skip_auth': skip_auth,
            **kwargs
        }

        user = await self._find_user(payload['username'], membership_id)

        self._check_user_status(user)

        token = await self._craft_token(user, **token_generation_parameters)

        await asyncio.gather(
            self._update_user_with_token(token, user),
            event_service.on_event((Event(
                **{
                    'document': token,
                    'prior': {},
                    'utilizer': user,
                    'type': 'TokenCreatedEvent',
                    'membership_id': membership_id,
                    'sys': {
                        'created_at': datetime.datetime.utcnow()
                    }
                }))), self._insert_active_tokens(user, token, membership))

        return token
コード例 #18
0
    async def create_user_type(self, resource, utilizer, event_service):
        membership_id = utilizer['membership_id']
        resource = slugify_name(resource)
        await ensure_user_type_not_exists(resource['slug'], membership_id,
                                          self.db)

        resource['_id'] = ObjectId()
        resource['sys'] = {
            'created_by': utilizer.get('username', utilizer.get('name')),
            'created_at': datetime.datetime.utcnow()
        }

        resource['membership_id'] = membership_id

        resource = set_additional_parameters_to_false(resource)
        resource = fill_min_max_fields_if_not_given(resource)
        validate(resource)

        await self.db.user_types.insert_one(resource)

        resource['_id'] = str(resource['_id'])
        await event_service.on_event((Event(
            **{
                'document': resource,
                'prior': {},
                'utilizer': utilizer,
                'type': 'UserTypeCreatedEvent',
                'membership_id': utilizer['membership_id'],
                'sys': {
                    'created_at': datetime.datetime.utcnow(),
                    'created_by': utilizer.get('username', utilizer.get(
                        'name'))
                }
            })))

        return resource
コード例 #19
0
    async def delete_user(self, resource_id, utilizer, event_service):
        if str(utilizer['_id']) == resource_id:
            raise ErtisError(err_code="errors.userCannotDeleteHerself",
                             err_msg="User can not delete herself",
                             status_code=400)

        user = await self._find_user(resource_id, utilizer["membership_id"])
        user['_id'] = str(user['_id'])

        await self._remove_user(resource_id, utilizer['membership_id'])

        await event_service.on_event((Event(
            **{
                'document': {},
                'prior': user,
                'utilizer': utilizer,
                'type': 'UserDeletedEvent',
                'membership_id': utilizer['membership_id'],
                'sys': {
                    'created_at': datetime.datetime.utcnow(),
                    'created_by': utilizer.get('username', utilizer.get(
                        'name'))
                }
            })))
コード例 #20
0
    async def update_application(self, application_id, data, utilizer,
                                 event_service):
        resource = await self._find_application(application_id,
                                                utilizer['membership_id'])

        provided_body = pop_non_updatable_fields(data)
        _resource = self._check_identicality(resource, provided_body)

        resource['sys'].update({
            'modified_at':
            datetime.datetime.utcnow(),
            'modified_by':
            utilizer.get('username', utilizer.get('name'))
        })

        provided_body['sys'] = resource['sys']
        updated_application = await self._update_application_with_body(
            application_id, utilizer['membership_id'], provided_body)

        _resource['_id'] = str(_resource['_id'])
        updated_application['_id'] = str(updated_application['_id'])

        await event_service.on_event((Event(
            **{
                'document': updated_application,
                'prior': _resource,
                'utilizer': utilizer,
                'type': 'ApplicationUpdatedEvent',
                'membership_id': utilizer['membership_id'],
                'sys': {
                    'created_at': datetime.datetime.utcnow(),
                    'created_by': utilizer.get('username', utilizer.get(
                        'name'))
                }
            })))
        return updated_application