Exemplo n.º 1
0
    def validate_schema(self, resource, schema):
        """ Validates a resource schema.

        :param resource: resource name.
        :param schema: schema definition for the resource.

        .. versionchanged:: 0.0.5
           Validation of the 'data_relation' field rule.
           Now collecting offending items in a list and inserting results into
           the exception message.
        """
        # TODO are there other mandatory settings? Validate them here
        offenders = []
        if eve.DATE_CREATED in schema:
            offenders.append(eve.DATE_CREATED)
        if eve.LAST_UPDATED in schema:
            offenders.append(eve.LAST_UPDATED)
        if eve.ID_FIELD in schema:
            offenders.append(eve.ID_FIELD)
        if offenders:
            raise SchemaException('field(s) "%s" not allowed in "%s" schema '
                                  '(they will be handled automatically).'
                                  % (resource, ', '.join(offenders)))

        for field, ruleset in schema.items():
            if 'data_relation' in ruleset:
                if 'collection' not in ruleset['data_relation']:
                    raise SchemaException("'collection' key is mandatory for "
                                          "the 'data_relation' rule in "
                                          "'%s: %s'" % (resource, field))
Exemplo n.º 2
0
    def validate_schema(self, resource, schema):
        """ Validates a resource schema.

        :param resource: resource name.
        :param schema: schema definition for the resource.

        .. versionchanged:: 0.2
           Allow ID_FIELD in resource schema if not of 'objectid' type.

        .. versionchanged:: 0.1.1
           'collection' setting renamed to 'resource' (data_relation).
           Fix order of string arguments in exception message.

        .. versionchanged:: 0.1.0
           Validation for 'embeddable' fields.

        .. versionchanged:: 0.0.5
           Validation of the 'data_relation' field rule.
           Now collecting offending items in a list and inserting results into
           the exception message.
        """
        # TODO are there other mandatory settings? Validate them here
        offenders = []
        if eve.DATE_CREATED in schema:
            offenders.append(eve.DATE_CREATED)
        if eve.LAST_UPDATED in schema:
            offenders.append(eve.LAST_UPDATED)
        if eve.ID_FIELD in schema and \
           schema[eve.ID_FIELD]['type'] == 'objectid':
            offenders.append(eve.ID_FIELD)
        if offenders:
            raise SchemaException('field(s) "%s" not allowed in "%s" schema '
                                  '(they will be handled automatically).' %
                                  (', '.join(offenders), resource))

        for field, ruleset in schema.items():
            if 'data_relation' in ruleset:
                if 'resource' not in ruleset['data_relation']:
                    raise SchemaException("'resource' key is mandatory for "
                                          "the 'data_relation' rule in "
                                          "'%s: %s'" % (resource, field))
                # If the field is listed as `embeddable`
                # it must be type == 'objectid'
                # TODO: allow serializing a list( type == 'objectid')
                if ruleset['data_relation'].get('embeddable', False):
                    if ruleset['type'] != 'objectid':
                        raise SchemaException(
                            "In order for the 'data_relation' rule to be "
                            "embeddable it must be of type 'objectid'")
Exemplo n.º 3
0
    def create_schema(cls, model_cls, lowercase=True):
        """
        :param model_cls: Mongoengine model class, subclass of
                        :class:`mongoengine.Document`.
        :param lowercase: True if names of resource for model class has to be
                        treated as lowercase string of classname.
        """
        schema = {}
        for field in model_cls._fields.values():
            if field.primary_key:
                # defined custom primary key -> fail, cos eve doesnt support it
                raise SchemaException("Custom primery key not allowed - eve "
                                      "does not support different id fields "
                                      "for resources.")
            fname = field.db_field
            if getattr(field, 'eve_field', False):
                # Do not convert auto-added fields 'updated' and 'created'.
                # This attribute is injected into model in EveMongoengine's
                # fix_model_class() method.
                continue
            if fname in ('_id', 'id'):
                # default id field, do not insert it into schema
                continue

            schema[fname] = cls.process_field(field, lowercase)
        return schema
Exemplo n.º 4
0
 def validate_field_name(field):
     forbidden = ["$", "."]
     if any(x in field for x in forbidden):
         raise SchemaException(
             "Field '%s' cannot contain any of the following: '%s'."
             % (field, ", ".join(forbidden))
         )
Exemplo n.º 5
0
    def create_schema(cls, model_cls, lowercase=True):
        """
        :param model_cls: Mongoengine model class, subclass of
                        :class:`mongoengine.Document`.
        :param lowercase: True if names of resource for model class has to be
                        treated as lowercase string of classname.
        """
        schema = {}

        # A DynamicDocument in MongoEngine is an expandable / uncontrolled
        # schema type. Any data set against the DynamicDocument that is not a
        # pre-defined field is automatically converted to a DynamicField.
        if issubclass(model_cls, DynamicDocument):
            schema['allow_unknown'] = True

        for field in model_cls._fields.values():
            if field.primary_key:
                # defined custom primary key -> fail, cos eve doesnt support it
                raise SchemaException("Custom primery key not allowed - eve "
                                      "does not support different id fields "
                                      "for resources.")
            fname = field.db_field
            if getattr(field, 'eve_field', False):
                # Do not convert auto-added fields 'updated' and 'created'.
                # This attribute is injected into model in EveMongoengine's
                # fix_model_class() method.
                continue
            if fname in ('_id', 'id'):
                # default id field, do not insert it into schema
                continue

            schema[fname] = cls.process_field(field, lowercase)
        return schema
Exemplo n.º 6
0
    def validate_schema(self, resource, schema):
        """ Validates a resource schema.

        :param resource: resource name.
        :param schema: schema definition for the resource.

        .. versionchanged:: 0.6.2
           Do not allow '$' and '.' in root and dict field names. #780.

        .. versionchanged:: 0.6
           ID_FIELD in the schema is not an offender anymore.

        .. versionchanged:: 0.5
           Add ETAG to automatic fields check.

        .. versionchanged:: 0.4
           Checks against offending document versioning fields.
           Supports embedded data_relation with version.

        .. versionchanged:: 0.2
           Allow ID_FIELD in resource schema if not of 'objectid' type.

        .. versionchanged:: 0.1.1
           'collection' setting renamed to 'resource' (data_relation).
           Fix order of string arguments in exception message.

        .. versionchanged:: 0.1.0
           Validation for 'embeddable' fields.

        .. versionchanged:: 0.0.5
           Validation of the 'data_relation' field rule.
           Now collecting offending items in a list and inserting results into
           the exception message.
        """

        def validate_field_name(field):
            forbidden = ["$", "."]
            if any(x in field for x in forbidden):
                raise SchemaException(
                    "Field '%s' cannot contain any of the following: '%s'."
                    % (field, ", ".join(forbidden))
                )

        resource_settings = self.config["DOMAIN"][resource]

        # ensure automatically handled fields aren't defined
        fields = [eve.DATE_CREATED, eve.LAST_UPDATED, eve.ETAG]

        if resource_settings["versioning"] is True:
            fields += [
                self.config["VERSION"],
                self.config["LATEST_VERSION"],
                resource_settings["id_field"] + self.config["VERSION_ID_SUFFIX"],
            ]
        if resource_settings["soft_delete"] is True:
            fields += [self.config["DELETED"]]

        offenders = []
        for field in fields:
            if field in schema:
                offenders.append(field)
        if offenders:
            raise SchemaException(
                'field(s) "%s" not allowed in "%s" schema '
                "(they will be handled automatically)."
                % (", ".join(offenders), resource)
            )

        if not isinstance(schema, dict):
            return

        for field, ruleset in schema.items():
            validate_field_name(field)
            if isinstance(ruleset, dict) and "dict" in ruleset.get("type", ""):
                for field in ruleset.get("schema", {}).keys():
                    validate_field_name(field)

            # check data_relation rules
            if "data_relation" in ruleset:
                if "resource" not in ruleset["data_relation"]:
                    raise SchemaException(
                        "'resource' key is mandatory for "
                        "the 'data_relation' rule in "
                        "'%s: %s'" % (resource, field)
                    )
                if ruleset["data_relation"].get("embeddable", False):

                    # special care for data_relations with a version
                    value_field = ruleset["data_relation"]["field"]
                    if ruleset["data_relation"].get("version", False):
                        if (
                            "schema" not in ruleset
                            or value_field not in ruleset["schema"]
                            or "type" not in ruleset["schema"][value_field]
                        ):
                            raise SchemaException(
                                "Must defined type for '%s' in schema when "
                                "declaring an embedded data_relation with"
                                " version." % value_field
                            )
Exemplo n.º 7
0
    def validate_schema(self, resource, schema):
        """ Validates a resource schema.

        :param resource: resource name.
        :param schema: schema definition for the resource.

        .. versionchanged:: 0.5
           Add ETAG to automatic fields check.

        .. versionchanged:: 0.4
           Checks against offending document versioning fields.
           Supports embedded data_relation with version.

        .. versionchanged:: 0.2
           Allow ID_FIELD in resource schema if not of 'objectid' type.

        .. versionchanged:: 0.1.1
           'collection' setting renamed to 'resource' (data_relation).
           Fix order of string arguments in exception message.

        .. versionchanged:: 0.1.0
           Validation for 'embeddable' fields.

        .. versionchanged:: 0.0.5
           Validation of the 'data_relation' field rule.
           Now collecting offending items in a list and inserting results into
           the exception message.
        """
        # ensure automatically handled fields aren't defined
        fields = [eve.DATE_CREATED, eve.LAST_UPDATED, eve.ETAG]
        # TODO: only add the following checks if settings['versioning'] == True
        fields += [
            self.config['VERSION'],
            self.config['LATEST_VERSION'],
            self.config['ID_FIELD'] + self.config['VERSION_ID_SUFFIX']]
        offenders = []
        for field in fields:
            if field in schema:
                offenders.append(field)
        if eve.ID_FIELD in schema and \
                schema[eve.ID_FIELD]['type'] == 'objectid':
            offenders.append(eve.ID_FIELD)
        if offenders:
            raise SchemaException('field(s) "%s" not allowed in "%s" schema '
                                  '(they will be handled automatically).'
                                  % (', '.join(offenders), resource))

        # check data_relation rules
        for field, ruleset in schema.items():
            if 'data_relation' in ruleset:
                if 'resource' not in ruleset['data_relation']:
                    raise SchemaException("'resource' key is mandatory for "
                                          "the 'data_relation' rule in "
                                          "'%s: %s'" % (resource, field))
                if ruleset['data_relation'].get('embeddable', False):

                    # special care for data_relations with a version
                    value_field = ruleset['data_relation']['field']
                    if ruleset['data_relation'].get('version', False):
                        if 'schema' not in ruleset or \
                                value_field not in ruleset['schema'] or \
                                'type' not in ruleset['schema'][value_field]:
                            raise SchemaException(
                                "Must defined type for '%s' in schema when "
                                "declaring an embedded data_relation with"
                                " version." % value_field
                            )
Exemplo n.º 8
0
    def validate_schema(self, resource, schema):
        """ Validates a resource schema.

        :param resource: resource name.
        :param schema: schema definition for the resource.

        .. versionchanged:: 0.6.2
           Do not allow '$' and '.' in root and dict field names. #780.

        .. versionchanged:: 0.6
           ID_FIELD in the schema is not an offender anymore.

        .. versionchanged:: 0.5
           Add ETAG to automatic fields check.

        .. versionchanged:: 0.4
           Checks against offending document versioning fields.
           Supports embedded data_relation with version.

        .. versionchanged:: 0.2
           Allow ID_FIELD in resource schema if not of 'objectid' type.

        .. versionchanged:: 0.1.1
           'collection' setting renamed to 'resource' (data_relation).
           Fix order of string arguments in exception message.

        .. versionchanged:: 0.1.0
           Validation for 'embeddable' fields.

        .. versionchanged:: 0.0.5
           Validation of the 'data_relation' field rule.
           Now collecting offending items in a list and inserting results into
           the exception message.
        """
        def validate_field_name(field):
            forbidden = ['$', '.']
            if any(x in field for x in forbidden):
                raise SchemaException(
                    "Field '%s' cannot contain any of the following: '%s'." %
                    (field, ', '.join(forbidden)))

        resource_settings = self.config['DOMAIN'][resource]

        # ensure automatically handled fields aren't defined
        fields = [eve.DATE_CREATED, eve.LAST_UPDATED, eve.ETAG]

        if resource_settings['versioning'] is True:
            fields += [
                self.config['VERSION'],
                self.config['LATEST_VERSION'],
                resource_settings['id_field'] +
                self.config['VERSION_ID_SUFFIX']]
        if resource_settings['soft_delete'] is True:
            fields += [self.config['DELETED']]

        offenders = []
        for field in fields:
            if field in schema:
                offenders.append(field)
        if offenders:
            raise SchemaException('field(s) "%s" not allowed in "%s" schema '
                                  '(they will be handled automatically).'
                                  % (', '.join(offenders), resource))

        for field, ruleset in schema.items():
            validate_field_name(field)
            if 'dict' in ruleset.get('type', ''):
                for field in ruleset.get('schema', {}).keys():
                    validate_field_name(field)

            # check data_relation rules
            if 'data_relation' in ruleset:
                if 'resource' not in ruleset['data_relation']:
                    raise SchemaException("'resource' key is mandatory for "
                                          "the 'data_relation' rule in "
                                          "'%s: %s'" % (resource, field))
                if ruleset['data_relation'].get('embeddable', False):

                    # special care for data_relations with a version
                    value_field = ruleset['data_relation']['field']
                    if ruleset['data_relation'].get('version', False):
                        if 'schema' not in ruleset or \
                                value_field not in ruleset['schema'] or \
                                'type' not in ruleset['schema'][value_field]:
                            raise SchemaException(
                                "Must defined type for '%s' in schema when "
                                "declaring an embedded data_relation with"
                                " version." % value_field
                            )