Beispiel #1
0
 def test_nested_multilevel(self):
     schema = {
         "subscription": {
             'type': 'dict',
             'schema': {
                 'type': {
                     'type': 'string'
                 },
                 'when': {
                     'type': 'dict',
                     'schema': {
                         'timestamp': {
                             'type': 'int',
                             'default': 0
                         },
                         'repr': {
                             'type': 'string',
                             'default': '0'
                         }
                     }
                 }
             }
         }
     }
     res = build_defaults(schema)
     self.assertEqual(
         {'subscription': {
             'when': {
                 'timestamp': 0,
                 'repr': '0'
             }
         }}, res)
 def test_simple(self):
     schema = {
         "name": {'type': 'string'},
         "email": {'type': 'string', 'default': "*****@*****.**"}
     }
     res = build_defaults(schema)
     self.assertEqual({'email': '*****@*****.**'}, res)
Beispiel #3
0
    def _set_resource_projection(self, ds, schema, settings):
        """ Set datasource projection for a resource

        .. versionchanged:: 0.6.3
           Fix: If datasource source is specified no fields are included by
           default. Closes #842.

        .. versionadded:: 0.6.2
        """

        projection = ds.get('projection', {})

        # check if any exclusion projection is defined
        exclusion = any(((k, v) for k, v in projection.items() if v == 0)) \
            if projection else None

        # If no exclusion projection is defined, enhance the projection
        # with automatic fields. Using both inclusion and exclusion will
        # be rejected by Mongo
        if not exclusion and len(schema) and \
           settings['allow_unknown'] is False:
            if not projection:
                projection.update(dict((field, 1) for (field) in schema))

            # enable retrieval of actual schema fields only. Eventual db
            # fields not included in the schema won't be returned.
            # despite projection, automatic fields are always included.
            projection[settings['id_field']] = 1
            projection[self.config['LAST_UPDATED']] = 1
            projection[self.config['DATE_CREATED']] = 1
            projection[self.config['ETAG']] = 1
            if settings['versioning'] is True:
                projection[self.config['VERSION']] = 1
                projection[settings['id_field'] +
                           self.config['VERSION_ID_SUFFIX']] = 1
        else:
            # all fields are returned.
            projection = None
        ds.setdefault('projection', projection)

        if settings['soft_delete'] is True and not exclusion and \
                ds['projection'] is not None:
            ds['projection'][self.config['DELETED']] = 1

        # 'defaults' helper set contains the names of fields with default
        # values in their schema definition.

        # TODO support default values for embedded documents.
        settings['defaults'] = build_defaults(schema)

        # list of all media fields for the resource
        settings['_media'] = [
            field for field, definition in schema.items()
            if definition.get('type') == 'media'
        ]

        if settings['_media'] and not self.media:
            raise ConfigException('A media storage class of type '
                                  ' eve.io.media.MediaStorage but be defined '
                                  'for "media" fields to be properly stored.')
 def test_schemaless_dict(self):
     schema = {
         "address": {
             'type': 'dict'
         }
     }
     self.assertEqual({}, build_defaults(schema))
 def test_default_in_list_schema(self):
     schema = {
         "one": {
             'type': 'list',
             'schema': {
                 'type': 'dict',
                 'schema': {
                     'title': {
                         'type': 'string',
                         'default': 'M.'
                     }
                 }
             }
         },
         "two": {
             'type': 'list',
             'schema': {
                 'type': 'dict',
                 'schema': {
                     'name': {'type': 'string'}
                 }
             }
         }
     }
     res = build_defaults(schema)
     self.assertEqual({"one": [{'title': 'M.'}]}, res)
Beispiel #6
0
 def test_default_in_list_schema(self):
     schema = {
         "one": {
             'type': 'list',
             'schema': {
                 'type': 'dict',
                 'schema': {
                     'title': {
                         'type': 'string',
                         'default': 'M.'
                     }
                 }
             }
         },
         "two": {
             'type': 'list',
             'schema': {
                 'type': 'dict',
                 'schema': {
                     'name': {
                         'type': 'string'
                     }
                 }
             }
         }
     }
     res = build_defaults(schema)
     self.assertEqual({"one": [{'title': 'M.'}]}, res)
Beispiel #7
0
    def _set_resource_projection(self, ds, schema, settings):
        """ Set datasource projection for a resource

        .. versionchanged:: 0.6.3
           Fix: If datasource source is specified no fields are included by
           default. Closes #842.

        .. versionadded:: 0.6.2
        """

        projection = ds.get('projection', {})

        # check if any exclusion projection is defined
        exclusion = any(((k, v) for k, v in projection.items() if v == 0)) \
            if projection else None

        # If no exclusion projection is defined, enhance the projection
        # with automatic fields. Using both inclusion and exclusion will
        # be rejected by Mongo
        if not exclusion and len(schema) and \
           settings['allow_unknown'] is False:
            if not projection:
                projection.update(dict((field, 1) for (field) in schema))

            # enable retrieval of actual schema fields only. Eventual db
            # fields not included in the schema won't be returned.
            # despite projection, automatic fields are always included.
            projection[settings['id_field']] = 1
            projection[self.config['LAST_UPDATED']] = 1
            projection[self.config['DATE_CREATED']] = 1
            projection[self.config['ETAG']] = 1
            if settings['versioning'] is True:
                projection[self.config['VERSION']] = 1
                projection[
                    settings['id_field'] +
                    self.config['VERSION_ID_SUFFIX']] = 1
        else:
            # all fields are returned.
            projection = None
        ds.setdefault('projection', projection)

        if settings['soft_delete'] is True and not exclusion and \
                ds['projection'] is not None:
            ds['projection'][self.config['DELETED']] = 1

        # 'defaults' helper set contains the names of fields with default
        # values in their schema definition.

        # TODO support default values for embedded documents.
        settings['defaults'] = build_defaults(schema)

        # list of all media fields for the resource
        settings['_media'] = [field for field, definition in schema.items() if
                              definition.get('type') == 'media']

        if settings['_media'] and not self.media:
            raise ConfigException('A media storage class of type '
                                  ' eve.io.media.MediaStorage but be defined '
                                  'for "media" fields to be properly stored.')
 def test_default_in_list_without_schema(self):
     schema = {
         "one": {
             'type': 'list',
             'schema': {
                 'type': 'string',
                 'default': 'item'
             }
         }
     }
     res = build_defaults(schema)
     self.assertEqual({"one": ['item']}, res)
Beispiel #9
0
 def test_simple(self):
     schema = {
         "name": {
             'type': 'string'
         },
         "email": {
             'type': 'string',
             'default': "*****@*****.**"
         }
     }
     res = build_defaults(schema)
     self.assertEqual({'email': '*****@*****.**'}, res)
 def test_nested_one_level(self):
     schema = {
         "address": {
             'type': 'dict',
             'schema': {
                 'street': {'type': 'string'},
                 'country': {'type': 'string', 'default': 'wonderland'}
             }
         }
     }
     res = build_defaults(schema)
     self.assertEqual({'address': {'country': 'wonderland'}}, res)
Beispiel #11
0
 def test_default_in_list_without_schema(self):
     schema = {
         "one": {
             'type': 'list',
             'schema': {
                 'type': 'string',
                 'default': 'item'
             }
         }
     }
     res = build_defaults(schema)
     self.assertEqual({"one": ['item']}, res)
Beispiel #12
0
 def test_lists_of_lists_with_default(self):
     schema = {
         'twisting': {
             'type': 'list',  # list of groups
             'required': True,
             'schema': {
                 'type': 'list',  # list of signals (in one group)
                 'schema': {
                     'type': 'string',
                     'default': 'listoflist',
                 }
             }
         }
     }
     res = build_defaults(schema)
     self.assertEqual({'twisting': [['listoflist']]}, res)
Beispiel #13
0
 def test_lists_of_lists_without_default(self):
     schema = {
         'twisting': {
             'type': 'list',  # list of groups
             'required': True,
             'schema': {
                 'type': 'list',  # list of signals (in one group)
                 'schema': {
                     'type': 'ObjectId',
                     'required': True
                 }
             }
         }
     }
     res = build_defaults(schema)
     self.assertEqual({}, res)
 def test_lists_of_lists_without_default(self):
     schema = {
         'twisting': {
             'type': 'list',  # list of groups
             'required': True,
             'schema': {
                 'type': 'list',  # list of signals (in one group)
                 'schema': {
                     'type': 'ObjectId',
                     'required': True
                 }
             }
         }
     }
     res = build_defaults(schema)
     self.assertEqual({}, res)
 def test_lists_of_lists_with_default(self):
     schema = {
         'twisting': {
             'type': 'list',  # list of groups
             'required': True,
             'schema': {
                 'type': 'list',  # list of signals (in one group)
                 'schema': {
                     'type': 'string',
                     'default': 'listoflist',
                 }
             }
         }
     }
     res = build_defaults(schema)
     self.assertEqual({'twisting': [['listoflist']]}, res)
Beispiel #16
0
 def test_nested_one_level(self):
     schema = {
         "address": {
             'type': 'dict',
             'schema': {
                 'street': {
                     'type': 'string'
                 },
                 'country': {
                     'type': 'string',
                     'default': 'wonderland'
                 }
             }
         }
     }
     res = build_defaults(schema)
     self.assertEqual({'address': {'country': 'wonderland'}}, res)
 def test_empty_defaults_multiple_level(self):
     schema = {
         'subscription': {
             'type': 'dict',
             'schema': {
                 'type': {'type': 'string'},
                 'when': {
                     'type': 'dict',
                     'schema': {
                         'timestamp': {'type': 'int'},
                         'repr': {'type': 'string'}
                     }
                 }
             }
         }
     }
     res = build_defaults(schema)
     self.assertEqual({}, res)
 def test_nested_multilevel(self):
     schema = {
         "subscription": {
             'type': 'dict',
             'schema': {
                 'type': {'type': 'string'},
                 'when': {
                     'type': 'dict',
                     'schema': {
                         'timestamp': {'type': 'int', 'default': 0},
                         'repr': {'type': 'string', 'default': '0'}
                     }
                 }
             }
         }
     }
     res = build_defaults(schema)
     self.assertEqual(
         {'subscription': {'when': {'timestamp': 0, 'repr': '0'}}},
         res)
Beispiel #19
0
 def test_empty_defaults_multiple_level(self):
     schema = {
         'subscription': {
             'type': 'dict',
             'schema': {
                 'type': {
                     'type': 'string'
                 },
                 'when': {
                     'type': 'dict',
                     'schema': {
                         'timestamp': {
                             'type': 'int'
                         },
                         'repr': {
                             'type': 'string'
                         }
                     }
                 }
             }
         }
     }
     res = build_defaults(schema)
     self.assertEqual({}, res)
Beispiel #20
0
    def _set_resource_defaults(self, resource, settings):
        """ Low-level method which sets default values for one resource.

        .. versionchanged:: 0.5
           Don't set default projection if 'allow_unknown' is active (#497).
           'internal_resource'

        .. versionchanged:: 0.3
           Set projection to None when schema is not provided for the resource.
           Support for '_media' helper.

        .. versionchanged:: 0.2
           'resource_title',
           'default_sort',
           'embedded_fields'.
           Support for endpoint-level authenticatoin classes.
        """
        settings.setdefault('url', resource)
        settings.setdefault('resource_methods',
                            self.config['RESOURCE_METHODS'])
        settings.setdefault('public_methods',
                            self.config['PUBLIC_METHODS'])
        settings.setdefault('allowed_roles', self.config['ALLOWED_ROLES'])
        settings.setdefault('allowed_read_roles',
                            self.config['ALLOWED_READ_ROLES'])
        settings.setdefault('allowed_write_roles',
                            self.config['ALLOWED_WRITE_ROLES'])
        settings.setdefault('cache_control', self.config['CACHE_CONTROL'])
        settings.setdefault('cache_expires', self.config['CACHE_EXPIRES'])

        settings.setdefault('item_lookup_field',
                            self.config['ITEM_LOOKUP_FIELD'])
        settings.setdefault('item_url', self.config['ITEM_URL'])
        settings.setdefault('resource_title', settings['url'])
        settings.setdefault('item_title',
                            resource.rstrip('s').capitalize())
        settings.setdefault('item_lookup', self.config['ITEM_LOOKUP'])
        settings.setdefault('public_item_methods',
                            self.config['PUBLIC_ITEM_METHODS'])
        settings.setdefault('allowed_item_roles',
                            self.config['ALLOWED_ITEM_ROLES'])
        settings.setdefault('allowed_item_read_roles',
                            self.config['ALLOWED_ITEM_READ_ROLES'])
        settings.setdefault('allowed_item_write_roles',
                            self.config['ALLOWED_ITEM_WRITE_ROLES'])
        settings.setdefault('allowed_filters',
                            self.config['ALLOWED_FILTERS'])
        settings.setdefault('sorting', self.config['SORTING'])
        settings.setdefault('embedding', self.config['EMBEDDING'])
        settings.setdefault('embedded_fields', [])
        settings.setdefault('pagination', self.config['PAGINATION'])
        settings.setdefault('projection', self.config['PROJECTION'])
        settings.setdefault('versioning', self.config['VERSIONING'])
        settings.setdefault('internal_resource',
                            self.config['INTERNAL_RESOURCE'])
        # TODO make sure that this we really need the test below
        if settings['item_lookup']:
            item_methods = self.config['ITEM_METHODS']
        else:
            item_methods = eve.ITEM_METHODS
        settings.setdefault('item_methods', item_methods)
        settings.setdefault('auth_field',
                            self.config['AUTH_FIELD'])
        settings.setdefault('allow_unknown', self.config['ALLOW_UNKNOWN'])
        settings.setdefault('extra_response_fields',
                            self.config['EXTRA_RESPONSE_FIELDS'])
        settings.setdefault('mongo_write_concern',
                            self.config['MONGO_WRITE_CONCERN'])
        settings.setdefault('hateoas',
                            self.config['HATEOAS'])
        settings.setdefault('authentication', self.auth if self.auth else None)
        # empty schemas are allowed for read-only access to resources
        schema = settings.setdefault('schema', {})
        self.set_schema_defaults(schema)

        datasource = {}
        settings.setdefault('datasource', datasource)
        settings['datasource'].setdefault('source', resource)
        settings['datasource'].setdefault('filter', None)
        settings['datasource'].setdefault('default_sort', None)

        if len(schema) and settings['allow_unknown'] is False:
            # enable retrieval of actual schema fields only. Eventual db
            # fields not included in the schema won't be returned.
            projection = {}
            # despite projection, automatic fields are always included.
            projection[self.config['ID_FIELD']] = 1
            projection[self.config['LAST_UPDATED']] = 1
            projection[self.config['DATE_CREATED']] = 1
            projection[self.config['ETAG']] = 1
            if settings['versioning'] is True:
                projection[self.config['VERSION']] = 1
                projection[
                    self.config['ID_FIELD'] +
                    self.config['VERSION_ID_SUFFIX']] = 1
            projection.update(dict((field, 1) for (field) in schema))
        else:
            # all fields are returned.
            projection = None
        settings['datasource'].setdefault('projection', projection)

        # 'defaults' helper set contains the names of fields with default
        # values in their schema definition.

        # TODO support default values for embedded documents.
        settings['defaults'] = build_defaults(schema)

        # list of all media fields for the resource
        settings['_media'] = [field for field, definition in schema.items() if
                              definition.get('type') == 'media']

        if settings['_media'] and not self.media:
            raise ConfigException('A media storage class of type '
                                  ' eve.io.media.MediaStorage but be defined '
                                  'for "media" fields to be properly stored.')
Beispiel #21
0
    def _set_resource_defaults(self, resource, settings):
        """ Low-level method which sets default values for one resource.

        .. versionchanged:: 0.6.2
           Fix: startup crash when both SOFT_DELETE and ALLOW_UNKNOWN are True.

           (#722).
        .. versionchanged:: 0.6.1
           Fix: inclusive projection defined for a datasource is ignored
           (#722).

        .. versionchanged:: 0.6
           Support for 'mongo_indexes'.

        .. versionchanged:: 0.5
           Don't set default projection if 'allow_unknown' is active (#497).
           'internal_resource'

        .. versionchanged:: 0.3
           Set projection to None when schema is not provided for the resource.
           Support for '_media' helper.

        .. versionchanged:: 0.2
           'resource_title',
           'default_sort',
           'embedded_fields'.
           Support for endpoint-level authenticatoin classes.
        """
        settings.setdefault('url', resource)
        settings.setdefault('resource_methods',
                            self.config['RESOURCE_METHODS'])
        settings.setdefault('public_methods',
                            self.config['PUBLIC_METHODS'])
        settings.setdefault('allowed_roles', self.config['ALLOWED_ROLES'])
        settings.setdefault('allowed_read_roles',
                            self.config['ALLOWED_READ_ROLES'])
        settings.setdefault('allowed_write_roles',
                            self.config['ALLOWED_WRITE_ROLES'])
        settings.setdefault('cache_control', self.config['CACHE_CONTROL'])
        settings.setdefault('cache_expires', self.config['CACHE_EXPIRES'])

        settings.setdefault('id_field', self.config['ID_FIELD'])
        settings.setdefault('item_lookup_field',
                            self.config['ITEM_LOOKUP_FIELD'])
        settings.setdefault('item_url', self.config['ITEM_URL'])
        settings.setdefault('resource_title', settings['url'])
        settings.setdefault('item_title',
                            resource.rstrip('s').capitalize())
        settings.setdefault('item_lookup', self.config['ITEM_LOOKUP'])
        settings.setdefault('public_item_methods',
                            self.config['PUBLIC_ITEM_METHODS'])
        settings.setdefault('allowed_item_roles',
                            self.config['ALLOWED_ITEM_ROLES'])
        settings.setdefault('allowed_item_read_roles',
                            self.config['ALLOWED_ITEM_READ_ROLES'])
        settings.setdefault('allowed_item_write_roles',
                            self.config['ALLOWED_ITEM_WRITE_ROLES'])
        settings.setdefault('allowed_filters',
                            self.config['ALLOWED_FILTERS'])
        settings.setdefault('sorting', self.config['SORTING'])
        settings.setdefault('embedding', self.config['EMBEDDING'])
        settings.setdefault('embedded_fields', [])
        settings.setdefault('pagination', self.config['PAGINATION'])
        settings.setdefault('projection', self.config['PROJECTION'])
        settings.setdefault('versioning', self.config['VERSIONING'])
        settings.setdefault('soft_delete', self.config['SOFT_DELETE'])
        settings.setdefault('bulk_enabled', self.config['BULK_ENABLED'])
        settings.setdefault('internal_resource',
                            self.config['INTERNAL_RESOURCE'])
        settings.setdefault('etag_ignore_fields', None)
        # TODO make sure that this we really need the test below
        if settings['item_lookup']:
            item_methods = self.config['ITEM_METHODS']
        else:
            item_methods = eve.ITEM_METHODS
        settings.setdefault('item_methods', item_methods)
        settings.setdefault('auth_field',
                            self.config['AUTH_FIELD'])
        settings.setdefault('allow_unknown', self.config['ALLOW_UNKNOWN'])
        settings.setdefault('transparent_schema_rules',
                            self.config['TRANSPARENT_SCHEMA_RULES'])
        settings.setdefault('extra_response_fields',
                            self.config['EXTRA_RESPONSE_FIELDS'])
        settings.setdefault('mongo_write_concern',
                            self.config['MONGO_WRITE_CONCERN'])
        settings.setdefault('mongo_indexes', {})
        settings.setdefault('hateoas',
                            self.config['HATEOAS'])
        settings.setdefault('authentication', self.auth if self.auth else None)
        # empty schemas are allowed for read-only access to resources
        schema = settings.setdefault('schema', {})
        self.set_schema_defaults(schema, settings['id_field'])

        # 'defaults' helper set contains the names of fields with default
        # values in their schema definition.

        # TODO support default values for embedded documents.
        settings['defaults'] = build_defaults(schema)

        # list of all media fields for the resource
        settings['_media'] = [field for field, definition in schema.items() if
                              definition.get('type') == 'media']

        if settings['_media'] and not self.media:
            raise ConfigException('A media storage class of type '
                                  ' eve.io.media.MediaStorage but be defined '
                                  'for "media" fields to be properly stored.')

        self._set_resource_datasource(resource, schema, settings)
Beispiel #22
0
    def _set_resource_defaults(self, resource, settings):
        """ Low-level method which sets default values for one resource.

        .. versionchanged:: 0.6.2
           Fix: startup crash when both SOFT_DELETE and ALLOW_UNKNOWN are True.

           (#722).
        .. versionchanged:: 0.6.1
           Fix: inclusive projection defined for a datasource is ignored
           (#722).

        .. versionchanged:: 0.6
           Support for 'mongo_indexes'.

        .. versionchanged:: 0.5
           Don't set default projection if 'allow_unknown' is active (#497).
           'internal_resource'

        .. versionchanged:: 0.3
           Set projection to None when schema is not provided for the resource.
           Support for '_media' helper.

        .. versionchanged:: 0.2
           'resource_title',
           'default_sort',
           'embedded_fields'.
           Support for endpoint-level authenticatoin classes.
        """
        settings.setdefault('url', resource)
        settings.setdefault('resource_methods',
                            self.config['RESOURCE_METHODS'])
        settings.setdefault('public_methods',
                            self.config['PUBLIC_METHODS'])
        settings.setdefault('allowed_roles', self.config['ALLOWED_ROLES'])
        settings.setdefault('allowed_read_roles',
                            self.config['ALLOWED_READ_ROLES'])
        settings.setdefault('allowed_write_roles',
                            self.config['ALLOWED_WRITE_ROLES'])
        settings.setdefault('cache_control', self.config['CACHE_CONTROL'])
        settings.setdefault('cache_expires', self.config['CACHE_EXPIRES'])

        settings.setdefault('id_field', self.config['ID_FIELD'])
        settings.setdefault('item_lookup_field',
                            self.config['ITEM_LOOKUP_FIELD'])
        settings.setdefault('item_url', self.config['ITEM_URL'])
        settings.setdefault('resource_title', settings['url'])
        settings.setdefault('item_title',
                            resource.rstrip('s').capitalize())
        settings.setdefault('item_lookup', self.config['ITEM_LOOKUP'])
        settings.setdefault('public_item_methods',
                            self.config['PUBLIC_ITEM_METHODS'])
        settings.setdefault('allowed_item_roles',
                            self.config['ALLOWED_ITEM_ROLES'])
        settings.setdefault('allowed_item_read_roles',
                            self.config['ALLOWED_ITEM_READ_ROLES'])
        settings.setdefault('allowed_item_write_roles',
                            self.config['ALLOWED_ITEM_WRITE_ROLES'])
        settings.setdefault('allowed_filters',
                            self.config['ALLOWED_FILTERS'])
        settings.setdefault('sorting', self.config['SORTING'])
        settings.setdefault('embedding', self.config['EMBEDDING'])
        settings.setdefault('embedded_fields', [])
        settings.setdefault('pagination', self.config['PAGINATION'])
        settings.setdefault('projection', self.config['PROJECTION'])
        settings.setdefault('versioning', self.config['VERSIONING'])
        settings.setdefault('soft_delete', self.config['SOFT_DELETE'])
        settings.setdefault('bulk_enabled', self.config['BULK_ENABLED'])
        settings.setdefault('internal_resource',
                            self.config['INTERNAL_RESOURCE'])
        settings.setdefault('etag_ignore_fields', None)
        # TODO make sure that this we really need the test below
        if settings['item_lookup']:
            item_methods = self.config['ITEM_METHODS']
        else:
            item_methods = eve.ITEM_METHODS
        settings.setdefault('item_methods', item_methods)
        settings.setdefault('auth_field',
                            self.config['AUTH_FIELD'])
        settings.setdefault('allow_unknown', self.config['ALLOW_UNKNOWN'])
        settings.setdefault('transparent_schema_rules',
                            self.config['TRANSPARENT_SCHEMA_RULES'])
        settings.setdefault('extra_response_fields',
                            self.config['EXTRA_RESPONSE_FIELDS'])
        settings.setdefault('mongo_write_concern',
                            self.config['MONGO_WRITE_CONCERN'])
        settings.setdefault('mongo_indexes', {})
        settings.setdefault('hateoas',
                            self.config['HATEOAS'])
        settings.setdefault('authentication', self.auth if self.auth else None)
        # empty schemas are allowed for read-only access to resources
        schema = settings.setdefault('schema', {})
        self.set_schema_defaults(schema, settings['id_field'])

        # 'defaults' helper set contains the names of fields with default
        # values in their schema definition.

        # TODO support default values for embedded documents.
        settings['defaults'] = build_defaults(schema)

        # list of all media fields for the resource
        settings['_media'] = [field for field, definition in schema.items() if
                              definition.get('type') == 'media']

        if settings['_media'] and not self.media:
            raise ConfigException('A media storage class of type '
                                  ' eve.io.media.MediaStorage but be defined '
                                  'for "media" fields to be properly stored.')

        self._set_resource_datasource(resource, schema, settings)
Beispiel #23
0
 def test_schemaless_dict(self):
     schema = {"address": {'type': 'dict'}}
     self.assertEqual({}, build_defaults(schema))
Beispiel #24
0
    def _set_resource_defaults(self, resource, settings):
        """ Low-level method which sets default values for one resource.

        .. versionchanged:: 0.6.2
           Fix: startup crash when both SOFT_DELETE and ALLOW_UNKNOWN are True.

           (#722).
        .. versionchanged:: 0.6.1
           Fix: inclusive projection defined for a datasource is ignored
           (#722).

        .. versionchanged:: 0.6
           Support for 'mongo_indexes'.

        .. versionchanged:: 0.5
           Don't set default projection if 'allow_unknown' is active (#497).
           'internal_resource'

        .. versionchanged:: 0.3
           Set projection to None when schema is not provided for the resource.
           Support for '_media' helper.

        .. versionchanged:: 0.2
           'resource_title',
           'default_sort',
           'embedded_fields'.
           Support for endpoint-level authenticatoin classes.
        """
        settings.setdefault('url', resource)
        settings.setdefault('resource_methods',
                            self.config['RESOURCE_METHODS'])
        settings.setdefault('public_methods',
                            self.config['PUBLIC_METHODS'])
        settings.setdefault('allowed_roles', self.config['ALLOWED_ROLES'])
        settings.setdefault('allowed_read_roles',
                            self.config['ALLOWED_READ_ROLES'])
        settings.setdefault('allowed_write_roles',
                            self.config['ALLOWED_WRITE_ROLES'])
        settings.setdefault('cache_control', self.config['CACHE_CONTROL'])
        settings.setdefault('cache_expires', self.config['CACHE_EXPIRES'])

        settings.setdefault('id_field', self.config['ID_FIELD'])
        settings.setdefault('item_lookup_field',
                            self.config['ITEM_LOOKUP_FIELD'])
        settings.setdefault('item_url', self.config['ITEM_URL'])
        settings.setdefault('resource_title', settings['url'])
        settings.setdefault('item_title',
                            resource.rstrip('s').capitalize())
        settings.setdefault('item_lookup', self.config['ITEM_LOOKUP'])
        settings.setdefault('public_item_methods',
                            self.config['PUBLIC_ITEM_METHODS'])
        settings.setdefault('allowed_item_roles',
                            self.config['ALLOWED_ITEM_ROLES'])
        settings.setdefault('allowed_item_read_roles',
                            self.config['ALLOWED_ITEM_READ_ROLES'])
        settings.setdefault('allowed_item_write_roles',
                            self.config['ALLOWED_ITEM_WRITE_ROLES'])
        settings.setdefault('allowed_filters',
                            self.config['ALLOWED_FILTERS'])
        settings.setdefault('sorting', self.config['SORTING'])
        settings.setdefault('embedding', self.config['EMBEDDING'])
        settings.setdefault('embedded_fields', [])
        settings.setdefault('pagination', self.config['PAGINATION'])
        settings.setdefault('projection', self.config['PROJECTION'])
        settings.setdefault('versioning', self.config['VERSIONING'])
        settings.setdefault('soft_delete', self.config['SOFT_DELETE'])
        settings.setdefault('bulk_enabled', self.config['BULK_ENABLED'])
        settings.setdefault('internal_resource',
                            self.config['INTERNAL_RESOURCE'])
        settings.setdefault('etag_ignore_fields', None)
        # TODO make sure that this we really need the test below
        if settings['item_lookup']:
            item_methods = self.config['ITEM_METHODS']
        else:
            item_methods = eve.ITEM_METHODS
        settings.setdefault('item_methods', item_methods)
        settings.setdefault('auth_field',
                            self.config['AUTH_FIELD'])
        settings.setdefault('allow_unknown', self.config['ALLOW_UNKNOWN'])
        settings.setdefault('transparent_schema_rules',
                            self.config['TRANSPARENT_SCHEMA_RULES'])
        settings.setdefault('extra_response_fields',
                            self.config['EXTRA_RESPONSE_FIELDS'])
        settings.setdefault('mongo_write_concern',
                            self.config['MONGO_WRITE_CONCERN'])
        settings.setdefault('mongo_indexes', {})
        settings.setdefault('hateoas',
                            self.config['HATEOAS'])
        settings.setdefault('authentication', self.auth if self.auth else None)
        # empty schemas are allowed for read-only access to resources
        schema = settings.setdefault('schema', {})
        self.set_schema_defaults(schema, settings['id_field'])

        datasource = {}
        settings.setdefault('datasource', datasource)

        ds = settings['datasource']
        ds.setdefault('source', resource)
        ds.setdefault('filter', None)
        ds.setdefault('default_sort', None)

        projection = ds.get('projection', {})

        # check if any exclusion projection is defined
        exclusion = any(((k, v) for k, v in projection.items() if v == 0))

        # If no exclusion projection is defined, enhance the projection
        # with automatic fields. Using both inclusion and exclusion will
        # be rejected by Mongo
        if not exclusion and len(schema) and \
           settings['allow_unknown'] is False:
            if not projection:
                projection.update(dict((field, 1) for (field) in schema))

            # enable retrieval of actual schema fields only. Eventual db
            # fields not included in the schema won't be returned.
            # despite projection, automatic fields are always included.
            projection[settings['id_field']] = 1
            projection[self.config['LAST_UPDATED']] = 1
            projection[self.config['DATE_CREATED']] = 1
            projection[self.config['ETAG']] = 1
            if settings['versioning'] is True:
                projection[self.config['VERSION']] = 1
                projection[
                    settings['id_field'] +
                    self.config['VERSION_ID_SUFFIX']] = 1
        else:
            # all fields are returned.
            projection = None
        ds.setdefault('projection', projection)

        if settings['soft_delete'] is True and not exclusion and \
                ds['projection'] is not None:
            ds['projection'][self.config['DELETED']] = 1

        # 'defaults' helper set contains the names of fields with default
        # values in their schema definition.

        # TODO support default values for embedded documents.
        settings['defaults'] = build_defaults(schema)

        # list of all media fields for the resource
        settings['_media'] = [field for field, definition in schema.items() if
                              definition.get('type') == 'media']

        if settings['_media'] and not self.media:
            raise ConfigException('A media storage class of type '
                                  ' eve.io.media.MediaStorage but be defined '
                                  'for "media" fields to be properly stored.')