Пример #1
0
class Sightings(Resource):
    """
    Manipulations with Sightings.
    """
    @api.parameters(PaginationParameters())
    @api.response(schemas.BaseSightingSchema(many=True))
    def get(self, args):
        """
        List of Sighting.

        Returns a list of Sighting starting from ``offset`` limited by ``limit``
        parameter.
        """
        return Sighting.query.offset(args['offset']).limit(args['limit'])

    @api.login_required(oauth_scopes=['sightings:write'])
    @api.parameters(parameters.CreateSightingParameters())
    @api.response(schemas.DetailedSightingSchema())
    @api.response(code=HTTPStatus.CONFLICT)
    def post(self, args):
        """
        Create a new instance of Sighting.
        """
        context = api.commit_or_abort(
            db.session,
            default_error_message='Failed to create a new Sighting')
        with context:
            sighting = Sighting(**args)
            db.session.add(sighting)
        return sighting
Пример #2
0
class Users(Resource):
    """
    Manipulations with users.
    """
    @api.login_required(oauth_scopes=['users:read'])
    @api.permission_required(permissions.AdminRolePermission())
    @api.parameters(PaginationParameters())
    @api.response(schemas.BaseUserSchema(many=True))
    def get(self, args):
        """
        List of users.

        Returns a list of users starting from ``offset`` limited by ``limit``
        parameter.
        """
        #return User.query.offset(args['offset']).limit(args['limit'])
        return User.objects.skip(args['offset']).limit(args['limit'])

    @api.parameters(parameters.AddUserParameters())
    @api.response(schemas.DetailedUserSchema())
    @api.response(code=HTTPStatus.FORBIDDEN)
    @api.response(code=HTTPStatus.CONFLICT)
    @api.doc(id='create_user')
    def post(self, args):
        """
        Create a new user.
        """
        with api.commit_or_abort(
                default_error_message="Failed to create a new user."):
            new_user = User(**args)
            new_user.save()
            #db.session.add(new_user)
        return new_user
Пример #3
0
    def paginate(self, parameters=None, locations=None):
        """
        Endpoint parameters registration decorator special for pagination.
        If ``parameters`` is not provided default PaginationParameters will be
        used.

        Also, any custom Parameters can be used, but it needs to have ``limit`` and ``offset``
        fields.
        """
        if not parameters:
            # Use default parameters if None specified
            from app.extensions.api.parameters import PaginationParameters
            parameters = PaginationParameters()

        if not all(mandatory in parameters.declared_fields
                   for mandatory in ('limit', 'offset')):
            raise AttributeError(
                '`limit` and `offset` fields must be in Parameter passed to `paginate()`'
            )

        def decorator(func):
            @wraps(func)
            def wrapper(self_, parameters_args, *args, **kwargs):
                queryset = func(self_, parameters_args, *args, **kwargs)
                total_count = queryset.count()
                return (queryset.offset(parameters_args['offset']).limit(
                    parameters_args['limit']), HTTPStatus.OK, {
                        'X-Total-Count': total_count
                    })

            return self.parameters(parameters, locations)(wrapper)

        return decorator
Пример #4
0
class Organizations(Resource):
    """
    Manipulations with Organizations.
    """
    @api.parameters(PaginationParameters())
    @api.response(schemas.BaseOrganizationSchema(many=True))
    def get(self, args):
        """
        List of Organization.

        Returns a list of Organization starting from ``offset`` limited by ``limit``
        parameter.
        """
        return Organization.query.offset(args['offset']).limit(args['limit'])

    @api.login_required(oauth_scopes=['organizations:write'])
    @api.parameters(parameters.CreateOrganizationParameters())
    @api.response(schemas.DetailedOrganizationSchema())
    @api.response(code=HTTPStatus.CONFLICT)
    def post(self, args):
        """
        Create a new instance of Organization.
        """
        context = api.commit_or_abort(
            db.session,
            default_error_message='Failed to create a new Organization')
        with context:
            organization = Organization(**args)
            db.session.add(organization)
        return organization
Пример #5
0
class Users(Resource):
    """
    Manipulations with users.
    """
    @api.login_required(oauth_scopes=['users:read'])
    @api.permission_required(permissions.AdminRolePermission())
    @api.parameters(PaginationParameters())
    @api.response(schemas.BaseUserSchema(many=True))
    def get(self, args):
        """
        List of users.

        Returns a list of users starting from ``offset`` limited by ``limit``
        parameter.
        """
        return User.query.offset(args['offset']).limit(args['limit'])

    @api.parameters(parameters.AddUserParameters())
    @api.response(schemas.DetailedUserSchema())
    @api.response(code=http_exceptions.Forbidden.code)
    @api.response(code=http_exceptions.Conflict.code)
    def post(self, args):
        """
        Create a new user.
        """
        with api.commit_or_abort(
                db.session,
                default_error_message="Failed to create a new user."):
            new_user = User(**args)
            db.session.add(new_user)
        return new_user
Пример #6
0
class Assets(Resource):
    """
    Manipulations with Assets.
    """

    @api.login_required(oauth_scopes=['assets:read'])
    @api.permission_required(permissions.AdminRolePermission())
    @api.response(schemas.BaseAssetSchema(many=True))
    @api.parameters(PaginationParameters())
    def get(self, args):
        """
        List of Assets.

        Returns a list of Asset starting from ``offset`` limited by ``limit``
        parameter.
        """
        return Asset.query.offset(args['offset']).limit(args['limit'])

    @api.login_required(oauth_scopes=['assets:write'])
    @api.permission_required(permissions.AdminRolePermission())
    @api.response(schemas.DetailedAssetSchema())
    @api.response(code=HTTPStatus.CONFLICT)
    def post(self):
        """
        Create a new instance of Asset.
        """
        return process_file_upload()
class Teams(Resource):
    """
    Manipulations with teams.
    """
    @api_v1.login_required(scopes=['teams:read'])
    @api_v1.parameters(PaginationParameters())
    @api_v1.response(schemas.BaseTeamSchema(many=True))
    def get(self, args):
        """
        List of teams.

        Returns a list of teams starting from ``offset`` limited by ``limit``
        parameter.
        """
        return Team.query.all()[args['offset']:args['offset'] + args['limit']]

    @api_v1.login_required(scopes=['teams:write'])
    @api_v1.parameters(parameters.CreateTeamParameters())
    @api_v1.response(schemas.DetailedTeamSchema())
    @api_v1.response(code=http_exceptions.Conflict.code)
    def post(self, args):
        """
        Create a new team.
        """
        team = Team(**args)
        # pylint: disable=no-member
        db.session.add(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 create a new team.")
        return team
class Teams(Resource):
    """
    Manipulations with teams.
    """
    @api.parameters(PaginationParameters())
    @api.response(schemas.BaseTeamSchema(many=True))
    def get(self, args):
        """
        List of teams.

        Returns a list of teams starting from ``offset`` limited by ``limit``
        parameter.
        """
        return Team.query.offset(args['offset']).limit(args['limit'])

    @api.login_required(oauth_scopes=['teams:write'])
    @api.parameters(parameters.CreateTeamParameters())
    @api.response(schemas.DetailedTeamSchema())
    @api.response(code=HTTPStatus.CONFLICT)
    def post(self, args):
        """
        Create a new team.
        """
        with api.commit_or_abort(
                db.session,
                default_error_message="Failed to create a new team"):
            team = Team(**args)
            db.session.add(team)
            team_member = TeamMember(team=team,
                                     user=current_user,
                                     is_leader=True)
            db.session.add(team_member)
        return team
Пример #9
0
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
Пример #10
0
class Payments(Resource):
    """
    Manipulations with Payments.
    """
    @api.parameters(PaginationParameters())
    @api.response(schemas.BasePaymentSchema(many=True))
    def get(self, args):
        """
        List of Payment.

        Returns a list of Payment starting from ``offset`` limited by ``limit``
        parameter.
        """
        return Payment.query.offset(args['offset']).limit(args['limit'])

    @api.parameters(parameters.CreatePaymentParameters())
    @api.response(schemas.DetailedPaymentSchema())
    @api.response(code=HTTPStatus.CONFLICT)
    def post(self, args):
        """
        Create a new instance of Payment.
        """
        with api.commit_or_abort(
                db.session,
                default_error_message="Failed to create a new Payment"):
            payment = Payment(**args)
            db.session.add(payment)
        return payment
class AssetTransactions(Resource):
    """
    Transactions of a given asset
    """
    @api.parameters(PaginationParameters())
    @api.response(TransactionSchema(many=True))
    def get(self, args, asset_id):
        """
        Get transactions of an asset with the id 'asset_id'.
        """
        return blockchain.get_asset_transactions(asset_id=asset_id,
                                                 offset=args['offset'],
                                                 limit=args['limit'])
class Users(Resource):
    """
    Manipulations with users.
    """

    @api_v1.login_required(scopes=['users:read'])
    @api_v1.permission_required(permissions.AdminRolePermission())
    @api_v1.parameters(PaginationParameters())
    @api_v1.response(schemas.BaseUserSchema(many=True))
    def get(self, args):
        """
        List of users.

        Returns a list of users starting from ``offset`` limited by ``limit``
        parameter.
        """
        return User.query.all()[args['offset']: args['offset'] + args['limit']]

    @api_v1.parameters(parameters.AddUserParameters())
    @api_v1.response(schemas.DetailedUserSchema())
    @api_v1.response(code=http_exceptions.Forbidden.code)
    @api_v1.response(code=http_exceptions.Conflict.code)
    def post(self, args):
        """
        Create a new user.
        """
        # Check reCAPTCHA if necessary
        recaptcha_key = args.pop('recaptcha_key', None)
        captcha_is_valid = False
        if not recaptcha_key:
            no_captcha_permission = permissions.AdminRolePermission()
            if no_captcha_permission.check():
                captcha_is_valid = True
        elif recaptcha_key == 'secret_key':
            captcha_is_valid = True

        if not captcha_is_valid:
            abort(code=http_exceptions.Forbidden.code, message="CAPTCHA key is incorrect.")

        new_user = User(**args)

        # pylint: disable=no-member
        db.session.add(new_user)
        try:
            db.session.commit()
        except sqlalchemy.exc.IntegrityError:
            db.session.rollback()
            # TODO: handle errors better
            abort(code=http_exceptions.Conflict.code, message="Could not create a new user.")

        return new_user
Пример #13
0
class Projects(Resource):
    """
    Manipulations with Projects.
    """
    @api.permission_required(
        permissions.ModuleAccessPermission,
        kwargs_on_request=lambda kwargs: {
            'module': Project,
            'action': AccessOperation.READ,
        },
    )
    @api.parameters(PaginationParameters())
    @api.response(schemas.BaseProjectSchema(many=True))
    def get(self, args):
        """
        List of Project.

        Returns a list of Project starting from ``offset`` limited by ``limit``
        parameter.
        """
        return Project.query.offset(args['offset']).limit(args['limit'])

    @api.permission_required(
        permissions.ModuleAccessPermission,
        kwargs_on_request=lambda kwargs: {
            'module': Project,
            'action': AccessOperation.WRITE,
        },
    )
    @api.login_required(oauth_scopes=['projects:write'])
    @api.parameters(parameters.CreateProjectParameters())
    @api.response(schemas.DetailedProjectSchema())
    @api.response(code=HTTPStatus.CONFLICT)
    def post(self, args):
        """
        Create a new instance of Project.
        """
        context = api.commit_or_abort(
            db.session, default_error_message='Failed to create a new Project')
        args['owner_guid'] = current_user.guid
        project = Project(**args)
        # User who creates the project gets added to it
        project.add_user(current_user)
        with context:
            db.session.add(project)

        db.session.refresh(project)

        return project
Пример #14
0
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
Пример #15
0
class OAuth2Clients(Resource):
    """
    Manipulations with OAuth2 clients.
    """

    # @api.parameters(parameters.ListOAuth2ClientsParameters())
    @api.parameters(PaginationParameters())
    @api.response(schemas.DetailedOAuth2ClientSchema(many=True))
    def get(self, args):
        """
        List of OAuth2 Clients.

        Returns a list of OAuth2 Clients starting from ``offset`` limited by
        ``limit`` parameter.
        """
        oauth2_clients = OAuth2Client.query
        oauth2_clients = oauth2_clients.filter(
            OAuth2Client.user_guid == current_user.guid,
            OAuth2Client.level != OAuth2Client.ClientLevels.confidential,
        )

        if oauth2_clients.count() == 0 and current_user.is_admin:
            default_scopes = list(
                api_v1.authorizations['oauth2_password']['scopes'].keys())
            args_ = {
                'default_scopes': default_scopes,
            }
            _generate_new_client(args_)
            return self.get()

        return oauth2_clients.offset(args['offset']).limit(args['limit'])

    @api.login_required(oauth_scopes=['auth:write'])
    @api.parameters(parameters.CreateOAuth2ClientParameters())
    @api.response(schemas.DetailedOAuth2ClientSchema())
    @api.response(code=HTTPStatus.FORBIDDEN)
    @api.response(code=HTTPStatus.CONFLICT)
    @api.doc(id='create_oauth_client')
    def post(self, args):
        """
        Create a new OAuth2 Client.

        Essentially, OAuth2 Client is a ``guid`` and ``secret``
        pair associated with a user.
        """
        new_oauth2_client = _generate_new_client(args)
        return new_oauth2_client
class TeamMembers(Resource):
    """
    Manipulations with members of a specific team.
    """
    @api_v1.login_required(scopes=['teams:read'])
    @api_v1.permission_required(permissions.OwnerRolePermission(partial=True))
    @api_v1.parameters(PaginationParameters())
    @api_v1.response(schemas.BaseTeamMemberSchema(many=True))
    def get(self, args, team_id):
        """
        Get team members by team ID.
        """
        team = Team.query.get_or_404(team_id)
        with permissions.OwnerRolePermission(obj=team):
            return team.members[args['offset']:args['offset'] + args['limit']]

    @api_v1.login_required(scopes=['teams:write'])
    @api_v1.permission_required(permissions.OwnerRolePermission(partial=True))
    @api_v1.parameters(parameters.AddTeamMemberParameters())
    @api_v1.response(code=http_exceptions.Conflict.code)
    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
Пример #17
0
class Assets(Resource):
    """
    Manipulations with Assets.
    """
    @api.login_required(oauth_scopes=['assets:read'])
    @api.permission_required(permissions.AdminRolePermission())
    @api.response(schemas.BaseAssetSchema(many=True))
    @api.parameters(PaginationParameters())
    def get(self, args):
        """
        List of Assets.

        Returns a list of Asset starting from ``offset`` limited by ``limit``
        parameter.
        """
        return (Asset.query.order_by(Asset.guid).offset(args['offset']).limit(
            args['limit']))
Пример #18
0
class Teams(Resource):
    """
    Manipulations with teams.
    """

    @api.login_required(oauth_scopes=['teams:read'])
    @api.parameters(PaginationParameters())
    @api.response(schemas.BaseTeamSchema(many=True))
    def get(self, args):
        """
        List of teams.

        Returns a list of teams starting from ``offset`` limited by ``limit``
        parameter.
        """
        return Team.query.offset(args['offset']).limit(args['limit'])

    @api.login_required(oauth_scopes=['teams:write'])
    @api.parameters(parameters.CreateTeamParameters())
    @api.response(schemas.DetailedTeamSchema())
    @api.response(code=http_exceptions.Conflict.code)
    def post(self, args):
        """
        Create a new team.
        """
        try:
            try:
                team = Team(**args)
            except ValueError as exception:
                abort(code=http_exceptions.Conflict.code, message=str(exception))
            db.session.add(team)
            try:
                db.session.commit()
            except sqlalchemy.exc.IntegrityError:
                abort(code=http_exceptions.Conflict.code, message="Could not create a new team.")
        finally:
            db.session.rollback()
        return team
Пример #19
0
class Submissions(Resource):
    """
    Manipulations with Submissions.
    """
    @api.permission_required(
        permissions.ModuleAccessPermission,
        kwargs_on_request=lambda kwargs: {
            'module': Submission,
            'action': AccessOperation.READ,
        },
    )
    @api.parameters(PaginationParameters())
    @api.response(schemas.BaseSubmissionSchema(many=True))
    def get(self, args):
        """
        List of Submission.

        Returns a list of Submission starting from ``offset`` limited by ``limit``
        parameter.
        """
        return Submission.query.offset(args['offset']).limit(args['limit'])

    @api.permission_required(
        permissions.ModuleAccessPermission,
        kwargs_on_request=lambda kwargs: {
            'module': Submission,
            'action': AccessOperation.WRITE,
        },
    )
    @api.login_required(oauth_scopes=['submissions:write'])
    @api.parameters(parameters.CreateSubmissionParameters())
    @api.response(schemas.DetailedSubmissionSchema())
    @api.response(code=HTTPStatus.CONFLICT)
    def post(self, args):
        r"""
        Create a new instance of Submission.

        CommandLine:
            EMAIL='test@localhost'
            PASSWORD='******'
            TIMESTAMP=$(date '+%Y%m%d-%H%M%S%Z')
            curl \
                -X POST \
                -c cookie.jar \
                -F email=${EMAIL} \
                -F password=${PASSWORD} \
                https://houston.dyn.wildme.io/api/v1/auth/sessions | jq
            curl \
                -X GET \
                -b cookie.jar \
                https://houston.dyn.wildme.io/api/v1/users/me | jq
            curl \
                -X POST \
                -b cookie.jar \
                -F description="This is a test submission (via CURL), please ignore" \
                https://houston.dyn.wildme.io/api/v1/submissions/ | jq
        """
        context = api.commit_or_abort(
            db.session,
            default_error_message='Failed to create a new Submission')
        with context:
            args['owner_guid'] = current_user.guid
            submission = Submission(**args)
            db.session.add(submission)
        repo, project = submission.ensure_repository()
        return submission