示例#1
0
def validate_manifest_uris(manifest: dict):
    """ Fetch & validate manifest's remote objects """

    request_type = manifest.get('request_type', '')

    entry_validators = {
        "groundtruth_uri":
        lambda k, v: validate_groundtruth_entry(k, v, request_type),
        "taskdata_uri":
        lambda _, v: validate_taskdata_entry(v)
    }

    for uri_key, validate_entry in entry_validators.items():
        uri = manifest.get(uri_key)

        if uri is None:
            continue

        try:
            response = requests.get(uri)
            response.raise_for_status()

            entries_count = traverse_json_entries(response.json(),
                                                  validate_entry)
        except (BaseError, RequestException) as e:
            raise ValidationError(f"{uri_key} validation failed: {e}") from e

        if entries_count == 0:
            raise ValidationError(f"fetched {uri_key} is empty")
 def keys_uuid_check(self, value):
     for key in self.keys_iterator(value):
         if key != key.lower():
             raise ValidationError("use lowercase")
         try:
             UUID(key)
         except:
             raise ValidationError("invalid uuid")
示例#3
0
    def validate_requester_question_example(self, data, value):
        # validation runs before other params, so need to handle missing case
        if not data.get('request_type'):
            raise ValidationError("request_type missing")

        # based on https://github.com/hCaptcha/hmt-basemodels/issues/27#issuecomment-590706643
        supports_lists = ['image_label_area_select', 'image_label_binary']

        if isinstance(value,
                      list) and not data['request_type'] in supports_lists:
            raise ValidationError(
                "Lists are not allowed in this challenge type")
        return value
示例#4
0
 def validate_taskdata_uri(self, data, value):
     if data.get('taskdata') and len(
             data.get('taskdata')) > 0 and data.get('taskdata_uri'):
         raise ValidationError(
             u'Specify only one of taskdata {} or taskdata_uri {}'.format(
                 data.get('taskdata'), data.get('taskdata_uri')))
     return value
    def validate_score(self, value):
        if value is None:
            return value

        if not isinstance(value, dict):
            raise ValidationError("value must be a dict")

        if len(value) != 1:
            raise ValidationError("invalid number of keys")

        score = value.get("score")
        if score is None:
            raise ValidationError("score missing")

        if not isinstance(score, (float, int)):
            raise ValidationError("invalid score value type")
        
        if score > 1 or score < 0:
            raise ValidationError("invalid score value")
示例#6
0
    def validate_requester_restricted_answer_set(self, data, value):
        """image_label_area_select should always have a single RAS set"""
        # validation runs before other params, so need to handle missing case
        if not data.get('request_type'):
            raise ValidationError("request_type missing")

        if data['request_type'] == 'image_label_area_select':
            if not value or len(value.keys()) == 0:
                value = {'label': {}}
                data['requester_restricted_answer_set'] = value
        return value
示例#7
0
def validate_request_type(self, data, value):
    """
    validate request types for all types of challenges
    multi_challenge should always have multi_challenge_manifests
    """
    # validation runs before other params, so need to handle missing case
    if not data.get('request_type'):
        raise ValidationError("request_type missing")

    if data.get('request_type') == 'multi_challenge':
        if not data.get('multi_challenge_manifests'):
            raise ValidationError(
                "multi_challenge requires multi_challenge_manifests.")
    elif data.get('request_type') in [
            'image_label_multiple_choice', 'image_label_area_select'
    ]:
        if data.get('multiple_choice_min_choices', 1) > data.get(
                'multiple_choice_max_choices', 1):
            raise ValidationError(
                "multiple_choice_min_choices cannot be greater than multiple_choice_max_choices"
            )

    return value
示例#8
0
def validate_taskdata_entry(value: dict):
    """ Validate taskdata entry """
    if not isinstance(value, dict):
        raise ValidationError("taskdata entry should be dict")

    TaskDataEntry(value).validate()
示例#9
0
 def validate_metadata(self, data, value):
     if len(str(value)) > 1024:
         raise ValidationError("metadata should be < 1024")
     return value
 def keys_choices_check(self, value, choices):
     for key in self.keys_iterator(value):
         if key not in choices:
             raise ValidationError(f"{key} not allowed. Use {choices}")
 def keys_lowercase_check(self, value):
     for key in self.keys_iterator(value):
         if key != key.lower():
             raise ValidationError("use lowercase")
 def keys_iterator(self, value):
     if isinstance(value, list):
         for restriction in value:
             if len(restriction) != 1:
                 raise ValidationError("exactly 1 element is required")
             yield next(iter(restriction))
示例#13
0
 def validate_groundtruth(self, data, value):
     if data.get('groundtruth_uri') and data.get('groundtruth'):
         raise ValidationError(
             "Specify only groundtruth_uri or groundtruth, not both.")
     return value