def test_WriteAccessPermission_authenticated_user(authenticated_user_instance): authenticated_user_instance.is_active = True with permissions.WriteAccessPermission(): pass authenticated_user_instance.is_active = False with pytest.raises(HTTPException): with permissions.WriteAccessPermission(): pass
class TeamByID(Resource): """ Manipulations with a specific team. """ @api.permission_required( permissions.OwnerRolePermission, kwargs_on_request=lambda kwargs: {'obj': kwargs['team']} ) @api.response(schemas.DetailedTeamSchema()) def get(self, team): """ Get team details by ID. """ return team @api.login_required(oauth_scopes=['teams:write']) @api.permission_required( permissions.OwnerRolePermission, kwargs_on_request=lambda kwargs: {'obj': kwargs['team']} ) @api.permission_required(permissions.WriteAccessPermission()) @api.parameters(parameters.PatchTeamDetailsParameters()) @api.response(schemas.DetailedTeamSchema()) @api.response(code=HTTPStatus.CONFLICT) def patch(self, args, team): """ Patch team details by ID. """ with api.commit_or_abort( db.session, default_error_message="Failed to update team details." ): parameters.PatchTeamDetailsParameters.perform_patch(args, obj=team) db.session.merge(team) return team @api.login_required(oauth_scopes=['teams:write']) @api.permission_required( permissions.OwnerRolePermission, kwargs_on_request=lambda kwargs: {'obj': kwargs['team']} ) @api.permission_required(permissions.WriteAccessPermission()) @api.response(code=HTTPStatus.CONFLICT) @api.response(code=HTTPStatus.NO_CONTENT) def delete(self, team): """ Delete a team by ID. """ with api.commit_or_abort( db.session, default_error_message="Failed to delete the team." ): db.session.delete(team) return None
class TeamMemberByID(Resource): """ Manipulations with a specific team member. """ @api.login_required(oauth_scopes=['teams:write']) @api.resolve_object_by_model(Team, 'team') @api.permission_required( permissions.OwnerRolePermission, kwargs_on_request=lambda kwargs: {'obj': kwargs['team']} ) @api.permission_required(permissions.WriteAccessPermission()) @api.response(code=http_exceptions.Conflict.code) def delete(self, team, user_id): """ Remove a member from a team. """ team_member = TeamMember.query.filter_by(team=team, user_id=user_id).first_or_404() db.session.delete(team_member) try: db.session.commit() except sqlalchemy.exc.IntegrityError: db.session.rollback() # TODO: handle errors better abort( code=http_exceptions.Conflict.code, message="Could not update team details." ) return None
class TeamMembers(Resource): """ Manipulations with members of a specific team. """ @api.login_required(oauth_scopes=['teams:read']) @api.resolve_object_by_model(Team, 'team') @api.permission_required( permissions.OwnerRolePermission, kwargs_on_request=lambda kwargs: {'obj': kwargs['team']} ) @api.permission_required(permissions.OwnerRolePermission(partial=True)) @api.parameters(PaginationParameters()) @api.response(schemas.BaseTeamMemberSchema(many=True)) def get(self, args, team): """ Get team members by team ID. """ return team.members[args['offset']: args['offset'] + args['limit']] @api.login_required(oauth_scopes=['teams:write']) @api.resolve_object_by_model(Team, 'team') @api.permission_required( permissions.OwnerRolePermission, kwargs_on_request=lambda kwargs: {'obj': kwargs['team']} ) @api.permission_required(permissions.WriteAccessPermission()) @api.parameters(parameters.AddTeamMemberParameters()) @api.response(schemas.BaseTeamMemberSchema()) @api.response(code=http_exceptions.Conflict.code) def post(self, args, team): """ Add a new member to a team. """ try: user_id = args.pop('user_id') user = User.query.get(user_id) if user is None: abort( code=http_exceptions.NotFound.code, message="User with id %d does not exist" % user_id ) try: team_member = TeamMember(team=team, user=user, **args) except ValueError as exception: abort(code=http_exceptions.Conflict.code, message=str(exception)) db.session.add(team_member) try: db.session.commit() except sqlalchemy.exc.IntegrityError: abort( code=http_exceptions.Conflict.code, message="Could not update team details." ) finally: db.session.rollback() return team_member
class NotificationByID(Resource): """ Manipulations with a specific Notification. """ @api.response(schemas.DetailedNotificationSchema()) def get(self, notification): """ Get Notification details by ID. """ return notification @api.login_required(oauth_scopes=['notifications:write']) @api.permission_required(permissions.WriteAccessPermission()) @api.response(code=HTTPStatus.CONFLICT) @api.response(code=HTTPStatus.NO_CONTENT) def delete(self, notification): """ Delete a Notification by ID. """ context = api.commit_or_abort( db.session, default_error_message='Failed to delete the Notification.') with context: db.session.delete(notification) return None
def patch(self, args, team_id): """ Patch team details by ID. """ team = Team.query.get_or_404(team_id) # pylint: disable=no-member with permissions.OwnerRolePermission(obj=team): with permissions.WriteAccessPermission(): for operation in args['body']: if not self._process_patch_operation(operation, team=team): log.info( "Team patching has ignored unknown operation %s", operation) db.session.merge(team) try: db.session.commit() except sqlalchemy.exc.IntegrityError: db.session.rollback() # TODO: handle errors better abort(code=http_exceptions.Conflict.code, message="Could not update team details.") return team
class TeamMemberByID(Resource): """ Manipulations with a specific team member. """ @api.login_required(oauth_scopes=['teams:write']) @api.permission_required( permissions.OwnerRolePermission, kwargs_on_request=lambda kwargs: {'obj': kwargs['team']} ) @api.permission_required(permissions.WriteAccessPermission()) @api.response(code=HTTPStatus.CONFLICT) def delete(self, team, user_id): """ Remove a member from a team. """ with api.commit_or_abort( default_error_message="Failed to update team details." ): team_member = TeamMember.objects(team=team, user_id=user_id).first_or_404() #team_member = TeamMember.query.filter_by(team=team, user_id=user_id).first_or_404() team_member.save() #db.session.delete(team_member) return None
def delete(self, args, team_id): """ Remove a member from a team. """ team = Team.query.get_or_404(team_id) # pylint: disable=no-member with permissions.OwnerRolePermission(obj=team): with permissions.WriteAccessPermission(): user_id = args['user_id'] team_member = TeamMember.query.filter_by( team=team, user_id=user_id).one() if team_member is None: abort(code=http_exceptions.NotFound.code, message="User with id %d does not exist" % user_id) db.session.delete(team_member) try: db.session.commit() except sqlalchemy.exc.IntegrityError: db.session.rollback() # TODO: handle errors better abort(code=http_exceptions.Conflict.code, message="Could not update team details.") return team
def post(self, args, team_id): """ Add a new member to a team. """ team = Team.query.get_or_404(team_id) # pylint: disable=no-member with permissions.OwnerRolePermission(obj=team): with permissions.WriteAccessPermission(): user_id = args.pop('user_id') user = User.query.get(user_id) if user is None: abort(code=http_exceptions.NotFound.code, message="User with id %d does not exist" % user_id) team_member = TeamMember(team=team, user=user, **args) db.session.add(team_member) try: db.session.commit() except sqlalchemy.exc.IntegrityError: db.session.rollback() # TODO: handle errors better abort(code=http_exceptions.Conflict.code, message="Could not update team details.") return None
class CollaborationByID(Resource): """ Manipulations with a specific Collaboration. """ @api.response(schemas.DetailedCollaborationSchema()) def get(self, collaboration): """ Get Collaboration details by ID. """ return collaboration @api.login_required(oauth_scopes=['collaborations:write']) @api.permission_required(permissions.WriteAccessPermission()) @api.parameters(parameters.PatchCollaborationDetailsParameters()) @api.response(schemas.DetailedCollaborationSchema()) @api.response(code=HTTPStatus.CONFLICT) def patch(self, args, collaboration): """ Patch Collaboration details by ID. """ context = api.commit_or_abort( db.session, default_error_message='Failed to update Collaboration details.' ) with context: parameters.PatchCollaborationDetailsParameters.perform_patch( args, obj=collaboration ) db.session.merge(collaboration) return collaboration @api.login_required(oauth_scopes=['collaborations:write']) @api.permission_required(permissions.WriteAccessPermission()) @api.response(code=HTTPStatus.CONFLICT) @api.response(code=HTTPStatus.NO_CONTENT) def delete(self, collaboration): """ Delete a Collaboration by ID. """ context = api.commit_or_abort( db.session, default_error_message='Failed to delete the Collaboration.' ) with context: db.session.delete(collaboration) return None
class EncounterByID(Resource): """ Manipulations with a specific Encounter. """ @api.response(schemas.DetailedEncounterSchema()) def get(self, encounter): """ Get Encounter details by ID. """ return encounter @api.login_required(oauth_scopes=['encounters:write']) @api.permission_required(permissions.WriteAccessPermission()) @api.parameters(parameters.PatchEncounterDetailsParameters()) @api.response(schemas.DetailedEncounterSchema()) @api.response(code=HTTPStatus.CONFLICT) def patch(self, args, encounter): """ Patch Encounter details by ID. """ context = api.commit_or_abort( db.session, default_error_message='Failed to update Encounter details.' ) with context: parameters.PatchEncounterDetailsParameters.perform_patch(args, obj=encounter) db.session.merge(encounter) return encounter @api.login_required(oauth_scopes=['encounters:write']) @api.permission_required(permissions.WriteAccessPermission()) @api.response(code=HTTPStatus.CONFLICT) @api.response(code=HTTPStatus.NO_CONTENT) def delete(self, encounter): """ Delete a Encounter by ID. """ context = api.commit_or_abort( db.session, default_error_message='Failed to delete the Encounter.' ) with context: db.session.delete(encounter) return None
class SightingByID(Resource): """ Manipulations with a specific Sighting. """ @api.response(schemas.DetailedSightingSchema()) def get(self, sighting): """ Get Sighting details by ID. """ return sighting @api.login_required(oauth_scopes=['sightings:write']) @api.permission_required(permissions.WriteAccessPermission()) @api.parameters(parameters.PatchSightingDetailsParameters()) @api.response(schemas.DetailedSightingSchema()) @api.response(code=HTTPStatus.CONFLICT) def patch(self, args, sighting): """ Patch Sighting details by ID. """ context = api.commit_or_abort( db.session, default_error_message='Failed to update Sighting details.') with context: parameters.PatchSightingDetailsParameters.perform_patch( args, obj=sighting) db.session.merge(sighting) return sighting @api.login_required(oauth_scopes=['sightings:write']) @api.permission_required(permissions.WriteAccessPermission()) @api.response(code=HTTPStatus.CONFLICT) @api.response(code=HTTPStatus.NO_CONTENT) def delete(self, sighting): """ Delete a Sighting by ID. """ context = api.commit_or_abort( db.session, default_error_message='Failed to delete the Sighting.') with context: db.session.delete(sighting) return None
class TeamMembers(Resource): """ Manipulations with members of a specific team. """ @api.permission_required( permissions.OwnerRolePermission, kwargs_on_request=lambda kwargs: {'obj': kwargs['team']} ) @api.permission_required(permissions.OwnerRolePermission(partial=True)) @api.parameters(PaginationParameters()) @api.response(schemas.BaseTeamMemberSchema(many=True)) def get(self, args, team): """ Get team members by team ID. """ return team.members.skip(args['offset']).limit(args['limit']) @api.login_required(oauth_scopes=['teams:write']) @api.permission_required( permissions.OwnerRolePermission, kwargs_on_request=lambda kwargs: {'obj': kwargs['team']} ) @api.permission_required(permissions.WriteAccessPermission()) @api.parameters(parameters.AddTeamMemberParameters()) @api.response(schemas.BaseTeamMemberSchema()) @api.response(code=HTTPStatus.CONFLICT) def post(self, args, team): """ Add a new member to a team. """ with api.commit_or_abort( default_error_message="Failed to update team details." ): user_id = args.pop('user_id') #user = User.query.get(user_id) user = User.objects(user_id=user_id).first() if user is None: abort( code=HTTPStatus.NOT_FOUND, message="User with id %d does not exist" % user_id ) team_member = TeamMember(team=team, user=user, **args) team_member.save() #db.session.add(team_member) return team_member
class HoustonConfigs(Resource): """ Manipulations with configs. """ @api.login_required(oauth_scopes=['config.houston:write']) @api.permission_required(permissions.StaffRolePermission()) @api.permission_required(permissions.WriteAccessPermission()) @api.parameters(parameters.PatchHoustonConfigParameters()) @api.response(code=HTTPStatus.CONFLICT) def patch(self, args): """ Patch config details by ID. """ response = parameters.PatchHoustonConfigParameters.perform_patch( args, obj=None) return response
def delete(self, team_id): """ Delete a team by ID. """ team = Team.query.get_or_404(team_id) # pylint: disable=no-member with permissions.OwnerRolePermission(obj=team): with permissions.WriteAccessPermission(): db.session.delete(team) try: db.session.commit() except sqlalchemy.exc.IntegrityError: db.session.rollback() # TODO: handle errors better abort(code=http_exceptions.Conflict.code, message="Could not delete the team.") return None
class TeamByID(Resource): """ Manipulations with a specific team. """ @api.login_required(oauth_scopes=['teams:read']) @api.resolve_object_by_model(Team, 'team') @api.permission_required( permissions.OwnerRolePermission, kwargs_on_request=lambda kwargs: {'obj': kwargs['team']} ) @api.response(schemas.DetailedTeamSchema()) def get(self, team): """ Get team details by ID. """ return team @api.login_required(oauth_scopes=['teams:write']) @api.resolve_object_by_model(Team, 'team') @api.permission_required( permissions.OwnerRolePermission, kwargs_on_request=lambda kwargs: {'obj': kwargs['team']} ) @api.permission_required(permissions.WriteAccessPermission()) @api.parameters(parameters.PatchTeamDetailsParameters()) @api.response(schemas.DetailedTeamSchema()) @api.response(code=http_exceptions.Conflict.code) def patch(self, args, team): """ Patch team details by ID. """ try: for operation in args: try: if not self._process_patch_operation(operation, team=team): log.info("Team patching has ignored unknown operation %s", operation) except ValueError as exception: abort(code=http_exceptions.Conflict.code, message=str(exception)) db.session.merge(team) try: db.session.commit() except sqlalchemy.exc.IntegrityError: abort( code=http_exceptions.Conflict.code, message="Could not update team details." ) finally: db.session.rollback() return team @api.login_required(oauth_scopes=['teams:write']) @api.resolve_object_by_model(Team, 'team') @api.permission_required( permissions.OwnerRolePermission, kwargs_on_request=lambda kwargs: {'obj': kwargs['team']} ) @api.permission_required(permissions.WriteAccessPermission()) @api.response(code=http_exceptions.Conflict.code) def delete(self, team): """ Delete a team by ID. """ db.session.delete(team) try: db.session.commit() except sqlalchemy.exc.IntegrityError: db.session.rollback() # TODO: handle errors better abort( code=http_exceptions.Conflict.code, message="Could not delete the team." ) return None def _process_patch_operation(self, operation, team): """ Args: operation (dict) - one patch operation in RFC 6902 format. team (Team) - team instance which is needed to be patched. state (dict) - inter-operations state storage. Returns: processing_status (bool) - True if operation was handled, otherwise False. """ if 'value' not in operation: # TODO: handle errors better abort(code=http_exceptions.UnprocessableEntity.code, message="value is required") assert operation['path'][0] == '/', "Path must always begin with /" field_name = operation['path'][1:] field_value = operation['value'] if operation['op'] == parameters.PatchTeamDetailsParameters.OP_REPLACE: setattr(team, field_name, field_value) return True return False