コード例 #1
0
ファイル: common.py プロジェクト: janreyho/eve-demo
def marshal_write_response(document, resource):
    """ Limit response document to minimize bandwidth when client supports it.

    :param document: the response document.
    :param resource: the resource being consumed by the request.

    .. versionchanged: 0.5
       Avoid exposing 'auth_field' if it is not intended to be public.

    .. versionadded:: 0.4
    """

    resource_def = app.config['DOMAIN'][resource]
    if app.config['BANDWIDTH_SAVER'] is True:
        # only return the automatic fields and special extra fields
        fields = auto_fields(resource) + resource_def['extra_response_fields']
        document = dict((k, v) for (k, v) in document.items() if k in fields)
    else:
        # avoid exposing the auth_field if it is not included in the
        # resource schema.
        auth_field = resource_def.get('auth_field')
        if auth_field and auth_field not in resource_def['schema']:
            try:
                del(document[auth_field])
            except:
                # 'auth_field' value has not been set by the auth class.
                pass
    return document
コード例 #2
0
ファイル: common.py プロジェクト: mehakraza/charity-backend
def marshal_write_response(document, resource):
    """ Limit response document to minimize bandwidth when client supports it.

    :param document: the response document.
    :param resource: the resource being consumed by the request.

    .. versionchanged: 0.5
       Avoid exposing 'auth_field' if it is not intended to be public.

    .. versionadded:: 0.4
    """

    resource_def = app.config['DOMAIN'][resource]
    if app.config['BANDWIDTH_SAVER'] is True:
        # only return the automatic fields and special extra fields
        fields = auto_fields(resource) + resource_def['extra_response_fields']
        document = dict((k, v) for (k, v) in document.items() if k in fields)
    else:
        # avoid exposing the auth_field if it is not included in the
        # resource schema.
        auth_field = resource_def.get('auth_field')
        if auth_field and auth_field not in resource_def['schema']:
            try:
                del (document[auth_field])
            except:
                # 'auth_field' value has not been set by the auth class.
                pass
    return document
コード例 #3
0
ファイル: utils.py プロジェクト: stt/eve-ntifier
 def insert(self, resource, doc_or_docs):
     #if isinstance(doc_or_docs, list): TODO
     # if upsert..
     ids = []
     for doc in doc_or_docs:
         keys = self.repo[resource].keys()
         id = 1 if len(keys) == 0 else int(max(keys))+1
         for f in auto_fields(resource):
             if f in doc: del doc[f]
         doc[config.ID_FIELD] = id
         self.repo[resource][id] = doc
         ids.append(id)
     self._write()
     return ids
コード例 #4
0
ファイル: common.py プロジェクト: Acapla/eve
def marshal_write_response(document, resource):
    """ Limit response document to minimize bandwidth when client supports it.

    :param document: the response document.
    :param resource: the resource being consumed by the request.

    .. versionadded:: 0.4
    """

    if app.config['BANDWIDTH_SAVER'] is True:
        # only return the automatic fields and special extra fields
        fields = auto_fields(resource) + \
            app.config['DOMAIN'][resource]['extra_response_fields']
        document = dict((k, v) for (k, v) in document.items() if k in fields)

    return document
コード例 #5
0
ファイル: common.py プロジェクト: xxoxx/eve
def marshal_write_response(document, resource):
    """ Limit response document to minimize bandwidth when client supports it.

    :param document: the response document.
    :param resource: the resource being consumed by the request.

    .. versionadded:: 0.4
    """

    if app.config['BANDWIDTH_SAVER'] is True:
        # only return the automatic fields and special extra fields
        fields = auto_fields(resource) + \
            app.config['DOMAIN'][resource]['extra_response_fields']
        document = dict((k, v) for (k, v) in document.items() if k in fields)

    return document
コード例 #6
0
    def _datasource_ex(self,
                       resource,
                       query=None,
                       client_projection=None,
                       client_sort=None,
                       check_auth_value=True,
                       force_auth_field_projection=False):
        """ Returns both db collection and exact query (base filter included)
        to which an API resource refers to.

        .. versionchanged:: 0.5.2
           Make User Restricted Resource Access work with HMAC Auth too.

        .. versionchanged:: 0.5
           Let client projection work when 'allow_unknown' is active (#497).

        .. versionchanged:: 0.4
           Always return required/auto fields (issue 282.)

        .. versionchanged:: 0.3
           Field exclusion support in client projections.
           Honor auth_field even when client query is missing.
           Only inject auth_field in queries when we are not creating new
           documents.
           'auth_field' and 'request_auth_value' fetching is now delegated to
           auth.auth_field_and value().

        .. versionchanged:: 0.2
           Difference between resource and item endpoints is now determined
           by the presence of a '|' in request.endpoint.
           Support for 'default_sort'.

        .. versionchanged:: 0.1.1
           auth.request_auth_value is now used to store the auth_field value.

        .. versionchanged:: 0.1.0
           Calls `combine_queries` to merge query and filter_
           Updated logic performing `auth_field` check

        .. versionchanged:: 0.0.9
           Storing self.app.auth.userid in auth_field when 'user-restricted
           resource access' is enabled.
           Support for Python 3.3.

        .. versionchanged:: 0.0.6
           'auth_username_field' is injected even in empty queries.
           Projection queries ('?projection={"name": 1}')

        .. versionchanged:: 0.0.5
           Support for 'user-restricted resource access'.

        .. versionadded:: 0.0.4
        """

        datasource, filter_, projection_, sort_ = self.datasource(resource)
        if client_sort:
            sort = client_sort
        else:
            # default sort is activated only if 'sorting' is enabled for the
            # resource.
            # TODO Consider raising a validation error on startup instead?
            sort = sort_ if sort_ and config.DOMAIN[resource]['sorting'] else \
                None

        if filter_:
            if query:
                # Can't just dump one set of query operators into another
                # e.g. if the dataset contains a custom datasource pattern
                #   'filter': {'username': {'$exists': True}}
                # and we try to filter on the field `username`,
                # which is correct?

                # Solution: call the db driver `combine_queries` operation
                # which will apply db-specific syntax to produce the
                # intersection of the two queries
                query = self.combine_queries(query, filter_)
            else:
                query = filter_

        fields = projection_
        if client_projection:
            if projection_:
                # only allow fields which are included with the standard
                # projection for the resource (avoid sniffing of private
                # fields)
                keep_fields = auto_fields(resource)
                if 1 in client_projection.values():
                    # inclusive projection - all values are 0 unless spec. or
                    # auto
                    fields = dict([(field, field in keep_fields)
                                   for field in fields.keys()])
                for field, value in client_projection.items():
                    field_base = field.split('.')[0]
                    if field_base not in keep_fields and field_base in fields:
                        fields[field] = value
            else:
                # there's no standard projection so we assume we are in a
                # allow_unknown = True
                fields = client_projection
        # always drop exclusion projection, thus avoid mixed projection not
        # supported by db driver
        fields = dict([(field, 1) for field, value in fields.items() if value])

        # If the current HTTP method is in `public_methods` or
        # `public_item_methods`, skip the `auth_field` check

        # Only inject the auth_field in the query when not creating new
        # documents.
        if request and request.method != 'POST' and (
                check_auth_value or force_auth_field_projection):
            auth_field, request_auth_value = auth_field_and_value(resource)
            if auth_field:
                if request_auth_value and check_auth_value:
                    if query:
                        # If the auth_field *replaces* a field in the query,
                        # and the values are /different/, deny the request
                        # This prevents the auth_field condition from
                        # overwriting the query (issue #77)
                        auth_field_in_query = \
                            self.app.data.query_contains_field(query,
                                                               auth_field)
                        if auth_field_in_query and \
                            self.app.data.get_value_from_query(
                                query, auth_field) != request_auth_value:
                            desc = 'Incompatible User-Restricted Resource ' \
                                   'request.'
                            abort(401, description=desc)
                        else:
                            query = self.app.data.combine_queries(
                                query, {auth_field: request_auth_value})
                    else:
                        query = {auth_field: request_auth_value}
                if force_auth_field_projection:
                    fields[auth_field] = 1
        return datasource, query, fields, sort
コード例 #7
0
ファイル: base.py プロジェクト: omixen/eve
    def _datasource_ex(self, resource, query=None, client_projection=None,
                       client_sort=None):
        """ Returns both db collection and exact query (base filter included)
        to which an API resource refers to.

        .. versionchanged:: 0.4
           Always return required/auto fields (issue 282.)

        .. versionchanged:: 0.3
           Field exclusion support in client projections.
           Honor auth_field even when client query is missing.
           Only inject auth_field in queries when we are not creating new
           documents.
           'auth_field' and 'request_auth_value' fetching is now delegated to
           auth.auth_field_and value().

        .. versionchanged:: 0.2
           Difference between resource and item endpoints is now determined
           by the presence of a '|' in request.endpoint.
           Support for 'default_sort'.

        .. versionchanged:: 0.1.1
           auth.request_auth_value is now used to store the auth_field value.

        .. versionchanged:: 0.1.0
           Calls `combine_queries` to merge query and filter_
           Updated logic performing `auth_field` check

        .. versionchanged:: 0.0.9
           Storing self.app.auth.userid in auth_field when 'user-restricted
           resource access' is enabled.
           Support for Python 3.3.

        .. versionchanged:: 0.0.6
           'auth_username_field' is injected even in empty queries.
           Projection queries ('?projection={"name": 1}')

        .. versionchanged:: 0.0.5
           Support for 'user-restricted resource access'.

        .. versionadded:: 0.0.4
        """

        datasource, filter_, projection_, sort_ = self._datasource(resource)

        if client_sort:
            sort = client_sort
        else:
            # default sort is activated only if 'sorting' is enabled for the
            # resource.
            # TODO Consider raising a validation error on startup instead?
            sort = sort_ if sort_ and config.DOMAIN[resource]['sorting'] else \
                None

        if filter_:
            if query:
                # Can't just dump one set of query operators into another
                # e.g. if the dataset contains a custom datasource pattern
                #   'filter': {'username': {'$exists': True}}
                # and we try to filter on the field `username`,
                # which is correct?

                # Solution: call the db driver `combine_queries` operation
                # which will apply db-specific syntax to produce the
                # intersection of the two queries
                query = self.combine_queries(query, filter_)
            else:
                query = filter_

        fields = projection_
        if client_projection:
            # only allow fields which are included with the standard projection
            # for the resource (avoid sniffing of private fields)
            keep_fields = auto_fields(resource)
            if 0 not in client_projection.values():
                # inclusive projection - all values are 0 unless spec. or auto
                fields = dict([(field, field in keep_fields) for field in
                               fields.keys()])
            for field, value in client_projection.items():
                field_base = field.split('.')[0]
                if field_base not in keep_fields and field_base in fields:
                    fields[field] = value
            fields = dict([(field, 1) for field, value in fields.items() if
                           value])

        # If the current HTTP method is in `public_methods` or
        # `public_item_methods`, skip the `auth_field` check

        # Only inject the auth_field in the query when not creating new
        # documents.
        if request and request.method not in ('POST', 'PUT'):
            auth_field, request_auth_value = auth_field_and_value(resource)
            if auth_field and request.authorization and request_auth_value:
                if query:
                    # If the auth_field *replaces* a field in the query,
                    # and the values are /different/, deny the request
                    # This prevents the auth_field condition from
                    # overwriting the query (issue #77)
                    auth_field_in_query = \
                        self.app.data.query_contains_field(query, auth_field)
                    if auth_field_in_query and \
                            self.app.data.get_value_from_query(
                                query, auth_field) != request_auth_value:
                        abort(401, description=debug_error_message(
                            'Incompatible User-Restricted Resource request. '
                            'Request was for "%s"="%s" but `auth_field` '
                            'requires "%s"="%s".' % (
                                auth_field,
                                self.app.data.get_value_from_query(
                                    query, auth_field),
                                auth_field,
                                request_auth_value)
                        ))
                    else:
                        query = self.app.data.combine_queries(
                            query, {auth_field: request_auth_value}
                        )
                else:
                    query = {auth_field: request_auth_value}
        return datasource, query, fields, sort
コード例 #8
0
ファイル: __init__.py プロジェクト: stt/eve-peewee
    def _find(self, resource, req, **lookup):
        sort = []
        spec = {}

        model = self._get_model_cls(resource)

        if req:
            if req.where:
                # could map mongo-style and_, or_ to peewee ops for eve/sqla compatibility
                try:
                    spec = json.loads(req.where)
                except ValueError as exc:
                    self.app.logger.exception(exc)
                    abort(400, description='Unable to parse `where` clause')

            if config.VALIDATE_FILTERS:
                bad_filter = validate_filters(spec, resource)
                if bad_filter:
                    abort(400, bad_filter)

            if config.DOMAIN[resource]['soft_delete'] and not req.show_deleted:
                # Soft delete filtering applied after validate_filters call as
                # querying against the DELETED field must always be allowed when
                # soft_delete is enabled
                #spec[config.DELETED+'__ne'] = True
                if not self.query_contains_field(spec, config.DELETED):
                    spec = self.combine_queries(spec, {config.DELETED+'__ne': True})

            if req.sort:
                for sort_arg in [s.strip() for s in req.sort.split(",")]:
                    sn = sort_arg[1:] if sort_arg[0] == "-" else sort_arg
                    try:
                        if sort_arg[0] == "-":
                            sort.append(getattr(model, sn).desc())
                        else:
                            sort.append(getattr(model, sn))
                    except AttributeError:
                        abort(400, description='Unknown field name: %s' % sn)

        if 'lookup' in lookup and lookup['lookup']:
            spec = self.combine_queries(
                spec, lookup['lookup'])
            spec = lookup['lookup']

        client_projection = self._client_projection(req)

        datasource, spec, projection, sort = self._datasource_ex(
            resource,
            spec,
            client_projection,
            sort)

        # TODO? http://eve-sqlalchemy.readthedocs.org/en/latest/tutorial.html#embedded-resources
        if len(projection):
            fields = [getattr(model, config.ID_FIELD)]
            exclude_only = all(not v for v in projection.values())
            include_only = all(projection.values())
            keep_fields = auto_fields(resource)
            for f in self.models[resource]._meta.fields.keys():
                if f == config.ID_FIELD: continue
                check_list = [include_only and f in projection,
                              exclude_only and f not in projection,
                              f in projection and projection[f]]
                # if not an auto_field and not projected out
                if f not in keep_fields and not any(check_list): continue
                fields.append(getattr(model, f))
            op = model.select(*fields)
        else:
            op = model.select()

        op = self._parse_where(op, spec)

        if sort:
            def fix_sort(sort_arg):
                # default sort takes [('fname',1)]
                if not isinstance(sort_arg, tuple):
                    return sort_arg
                sn,asc = sort_arg
                sortf = getattr(model, sn)
                if not asc: sortf = sortf.desc()
                return sortf

            sort = map(fix_sort, sort)
            op = op.order_by(*sort)

        return op
コード例 #9
0
    def _datasource_ex(self, resource, query=None, client_projection=None,
                       client_sort=None):
        """ Returns both db collection and exact query (base filter included)
        to which an API resource refers to.

        .. versionchanged:: 0.4
           Always return required/auto fields (issue 282.)

        .. versionchanged:: 0.3
           Field exclusion support in client projections.
           Honor auth_field even when client query is missing.
           Only inject auth_field in queries when we are not creating new
           documents.
           'auth_field' and 'request_auth_value' fetching is now delegated to
           auth.auth_field_and value().

        .. versionchanged:: 0.2
           Difference between resource and item endpoints is now determined
           by the presence of a '|' in request.endpoint.
           Support for 'default_sort'.

        .. versionchanged:: 0.1.1
           auth.request_auth_value is now used to store the auth_field value.

        .. versionchanged:: 0.1.0
           Calls `combine_queries` to merge query and filter_
           Updated logic performing `auth_field` check

        .. versionchanged:: 0.0.9
           Storing self.app.auth.userid in auth_field when 'user-restricted
           resource access' is enabled.
           Support for Python 3.3.

        .. versionchanged:: 0.0.6
           'auth_username_field' is injected even in empty queries.
           Projection queries ('?projection={"name": 1}')

        .. versionchanged:: 0.0.5
           Support for 'user-restricted resource access'.

        .. versionadded:: 0.0.4
        """

        datasource, filter_, projection_, sort_ = self._datasource(resource)

        if client_sort:
            sort = client_sort
        else:
            # default sort is activated only if 'sorting' is enabled for the
            # resource.
            # TODO Consider raising a validation error on startup instead?
            sort = sort_ if sort_ and config.DOMAIN[resource]['sorting'] else \
                None

        if filter_:
            if query:
                # Can't just dump one set of query operators into another
                # e.g. if the dataset contains a custom datasource pattern
                #   'filter': {'username': {'$exists': True}}
                # and we try to filter on the field `username`,
                # which is correct?

                # Solution: call the db driver `combine_queries` operation
                # which will apply db-specific syntax to produce the
                # intersection of the two queries
                query = self.combine_queries(query, filter_)
            else:
                query = filter_

        fields = projection_
        keep_fields = auto_fields(resource)
        if client_projection:
            # only allow fields which are included with the standard projection
            # for the resource (avoid sniffing of private fields)
            if 0 in client_projection.values():
                # exclusive projection - all values are 1 unless specified
                for field, value in client_projection.items():
                    if value == 0 and value not in keep_fields and \
                            field in fields:
                        del fields[field]
            else:
                # inclusive projection - all values are 0 unless spec. or auto
                for field in list(fields.keys()):
                    if field not in client_projection and \
                            field not in keep_fields:
                        del fields[field]

        # If the current HTTP method is in `public_methods` or
        # `public_item_methods`, skip the `auth_field` check

        # Only inject the auth_field in the query when not creating new
        # documents.
        if request and request.method not in ('POST', 'PUT'):
            auth_field, request_auth_value = auth_field_and_value(resource)
            if auth_field and request.authorization and request_auth_value:
                if query:
                    # If the auth_field *replaces* a field in the query,
                    # and the values are /different/, deny the request
                    # This prevents the auth_field condition from
                    # overwriting the query (issue #77)
                    auth_field_in_query = \
                        self.app.data.query_contains_field(query, auth_field)
                    if auth_field_in_query and \
                            self.app.data.get_value_from_query(
                                query, auth_field) != request_auth_value:
                        abort(401, description=debug_error_message(
                            'Incompatible User-Restricted Resource request. '
                            'Request was for "%s"="%s" but `auth_field` '
                            'requires "%s"="%s".' % (
                                auth_field,
                                self.app.data.get_value_from_query(
                                    query, auth_field),
                                auth_field,
                                request_auth_value)
                        ))
                    else:
                        query = self.app.data.combine_queries(
                            query, {auth_field: request_auth_value}
                        )
                else:
                    query = {auth_field: request_auth_value}
        return datasource, query, fields, sort