예제 #1
0
    def validate_input(self, json_data):
        if 'response' not in json_data:
            raise RequiredInputError('response', 'request.body.response')

        if json_data['response'] not in self.VALID_RESPONSES:
            raise InvalidInputError('response', 'request.body.response')

        if json_data['response'] == 'reject':
            if 'inputs' not in json_data:
                raise RequiredInputError('inputs', 'request.body.inputs')

            if any([
                    type(json_data['inputs']) is not list,
                    len(json_data['inputs']) == 0,
            ]):
                raise RequiredListError('inputs', 'request.body.inputs')

            for index, field in enumerate(json_data['inputs']):
                errors = []
                try:
                    self.validate_field(field, index)
                except InputError as e:
                    errors.append(e.to_json())

                if errors:
                    raise BadRequest(errors)

            if 'comment' not in json_data:
                raise RequiredInputError('comment', 'request.body.comment')

            if type(json_data['comment']) is not str:
                raise BadRequest([{
                    'detail': '\'comment\' must be a str',
                    'code': 'validation.invalid',
                    'where': 'request.body.comment',
                }])

        return [
            Form.state_json(self.id, [
                {
                    'name': 'response',
                    'value': json_data['response'],
                    'value_caption': json_data['response'],
                },
                {
                    'name': 'comment',
                    'value': json_data['comment'],
                    'value_caption': json_data['comment'],
                },
                {
                    'name': 'inputs',
                    'value': json_data.get('inputs'),
                    'value_caption': json.dumps(json_data.get('inputs')),
                },
            ])
        ]
예제 #2
0
파일: inputs.py 프로젝트: tracsa/cacahuate
    def validate(self, value, form_index):
        super().validate(value, form_index)

        value = value or self.get_default()

        if not value:
            if self.required:
                raise RequiredInputError(
                    self.name, 'request.body.form_array.{}.{}'.format(
                        form_index, self.name))

            return None

        try:
            datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%fZ")
        except TypeError:
            raise InvalidDateError(
                self.name,
                'request.body.form_array.{}.{}'.format(form_index, self.name))
        except ValueError:
            raise InvalidDateError(
                self.name,
                'request.body.form_array.{}.{}'.format(form_index, self.name))

        return value
예제 #3
0
파일: inputs.py 프로젝트: tracsa/cacahuate
    def validate(self, value, form_index):
        super().validate(value, form_index)

        if not value:
            value = None

        if value is not None and type(value) is not dict:
            raise InvalidInputError(
                self.name,
                'request.body.form_array.{}.{}'.format(form_index, self.name))

        provider = self.provider

        if not value and self.required:
            raise RequiredInputError(
                self.name,
                'request.body.form_array.{}.{}'.format(form_index, self.name))

        if provider == 'doqer':
            if value is not None:
                valid = reduce(
                    and_,
                    map(lambda attr: attr in value and value[attr] is not None,
                        ['id', 'mime', 'name', 'type']))

                if not valid:
                    raise InvalidInputError(
                        self.name, 'request.body.form_array.{}.{}'.format(
                            form_index, self.name))
        else:
            raise MisconfiguredProvider(
                'File provider `{}` not implemented'.format(provider))

        return value
예제 #4
0
파일: inputs.py 프로젝트: tracsa/cacahuate
    def validate(self, value, form_index):
        # allowed types are None, String, and Numbers
        curated = None

        if value is None or value == '':
            curated = None
        elif isinstance(value, numbers.Number) or type(value) == str:
            try:
                curated = float(value)
            except ValueError:
                raise RequiredFloatError(
                    self.name, 'request.body.form_array.{}.{}'.format(
                        form_index, self.name))
        else:
            raise RequiredFloatError(
                self.name,
                'request.body.form_array.{}.{}'.format(form_index, self.name))

        if curated is None and self.required:
            raise RequiredInputError(
                self.name,
                'request.body.form_array.{}.{}'.format(form_index, self.name))

        if curated is None:
            curated = self.get_default()

        return curated
예제 #5
0
파일: inputs.py 프로젝트: tracsa/cacahuate
    def validate(self, value, form_index):
        value = value or self.get_default()

        if self.required and (value == '' or value is None):
            raise RequiredInputError(
                self.name,
                'request.body.form_array.{}.{}'.format(form_index, self.name))

        return value
예제 #6
0
def validate_json(json_data: dict, req: list):
    errors = []

    for item in req:
        if item not in json_data:
            errors.append(
                RequiredInputError(item,
                                   'request.body.{}'.format(item)).to_json())

    if errors:
        raise BadRequest(errors)
예제 #7
0
파일: node.py 프로젝트: cnpoe/cacahuate
    def validate_input(self, json_data):
        if 'response' not in json_data:
            raise RequiredInputError('response', 'request.body.response')

        if json_data['response'] not in self.VALID_RESPONSES:
            raise InvalidInputError('response', 'request.body.response')

        if json_data['response'] == 'reject':
            if 'inputs' not in json_data:
                raise RequiredInputError('inputs', 'request.body.inputs')

            if type(json_data['inputs']) is not list:
                raise RequiredListError('inputs', 'request.body.inputs')

            for index, field in enumerate(json_data['inputs']):
                errors = []
                try:
                    self.validate_field(field, index)
                except InputError as e:
                    errors.append(e.to_json())

                if errors:
                    raise BadRequest(errors)

        return [
            Form.state_json(self.id, [
                {
                    'name': 'response',
                    'value': json_data['response'],
                },
                {
                    'name': 'comment',
                    'value': json_data['comment'],
                },
                {
                    'name': 'inputs',
                    'value': json_data.get('inputs'),
                },
            ])
        ]
예제 #8
0
    def validate(self, value, form_index):
        super().validate(value, form_index)

        curated = None

        if not value:
            curated = None
        elif isinstance(value, dict):
            if 'label' not in value or 'href' not in value:
                raise InvalidInputError(
                    self.name,
                    'request.body.form_array.{}.{}'.format(
                        form_index,
                        self.name
                    )
                )

            label = value['label']
            href = value['href']

            link_valid = re.match('^(https?://)[a-z0-9.]+/?$', href)

            if not link_valid:
                raise InvalidInputError(
                    self.name,
                    'request.body.form_array.{}.{}'.format(
                        form_index,
                        self.name
                    )
                )

            curated = {
                'label': label,
                'href': href,
            }
        else:
            raise InvalidInputError(
                self.name,
                'request.body.form_array.{}.{}'.format(
                    form_index,
                    self.name
                )
            )

        if not curated and self.required:
            raise RequiredInputError(
                self.name,
                'request.body.form_array.{}.{}'.format(form_index, self.name)
            )

        return curated
예제 #9
0
파일: inputs.py 프로젝트: tracsa/cacahuate
    def validate(self, value, form_index):
        if self.required and type(value) != int and not value:
            raise RequiredInputError(
                self.name,
                'request.body.form_array.{}.{}'.format(form_index, self.name))

        if type(value) != int and not value:
            value = self.get_default()

        try:
            value = int(value)
        except ValueError:
            raise RequiredIntError(
                self.name,
                'request.body.form_array.{}.{}'.format(form_index, self.name))

        return value
예제 #10
0
파일: node.py 프로젝트: cnpoe/cacahuate
    def validate_field(self, field, index):
        if type(field) != dict:
            raise RequiredDictError('inputs.{}'.format(index),
                                    'request.body.inputs.{}'.format(index))

        if 'ref' not in field:
            raise RequiredInputError(
                'inputs.{}.ref'.format(index),
                'request.body.inputs.{}.ref'.format(index))

        try:
            node, actor, ref, input = field['ref'].split('.')
            index, ref = ref.split(':')
        except ValueError:
            raise InvalidInputError('inputs.{}.ref'.format(index),
                                    'request.body.inputs.{}.ref'.format(index))

        if not self.in_dependencies(field['ref']):
            raise InvalidInputError('inputs.{}.ref'.format(index),
                                    'request.body.inputs.{}.ref'.format(index))
예제 #11
0
def execution_patch(id):
    execution = Execution.get_or_exception(id)
    collection = mongo.db[app.config['EXECUTION_COLLECTION']]
    execution_state = next(collection.find({'id': id}))

    validate_json(request.json, ['comment', 'inputs'])

    xml = Xml.load(app.config, execution.process_name, direct=True)
    dom = xml.get_dom()

    if type(request.json['inputs']) != list:
        raise RequiredListError('inputs', 'request.body.inputs')

    processed_inputs = []

    for i, field in enumerate(request.json['inputs']):
        if type(field) != dict:
            raise RequiredDictError(str(i), 'request.body.inputs.{}'.format(i))

        if 'ref' not in field:
            raise RequiredInputError('id',
                                     'request.body.inputs.{}.ref'.format(i))

        if type(field['ref']) != str:
            raise RequiredStrError('ref',
                                   'request.body.inputs.{}.ref'.format(i))

        # check down the state tree for existence of the requested ref
        processed_ref = []
        pieces = field['ref'].split('.')

        try:
            node_id = pieces.pop(0)
            node_state = execution_state['state']['items'][node_id]
        except IndexError:
            raise InputError('Missing segment in ref for node_id',
                             'request.body.inputs.{}.ref'.format(i),
                             'validation.invalid')
        except KeyError:
            raise InputError('node {} not found'.format(node_id),
                             'request.body.inputs.{}.ref'.format(i),
                             'validation.invalid')

        if node_state['type'] != 'action':
            raise InputError('only action nodes may be patched',
                             'request.body.inputs.{}.ref'.format(i),
                             'validation.invalid')

        processed_ref.append(node_id)

        # node xml element
        node = get_element_by(dom, 'action', 'id', node_id)

        if len(node_state['actors']['items']) == 1:
            only_key = list(node_state['actors']['items'].keys())[0]
            actor_state = node_state['actors']['items'][only_key]
        else:
            try:
                actor_username = pieces.pop(0)
                actor_state = node_state['actors']['items'][actor_username]
            except IndexError:
                raise InputError('Missing segment in ref for actor username',
                                 'request.body.inputs.{}.ref'.format(i),
                                 'validation.invalid')
            except KeyError:
                raise InputError('actor {} not found'.format(actor_username),
                                 'request.body.inputs.{}.ref'.format(i),
                                 'validation.invalid')

        processed_ref.append(actor_state['user']['identifier'])

        try:
            form_ref = pieces.pop(0)
        except IndexError:
            raise InputError('Missing segment in ref for form ref',
                             'request.body.inputs.{}.ref'.format(i),
                             'validation.invalid')

        if re.match(r'\d+', form_ref):
            try:
                form_index = int(form_ref)
                form_state = actor_state['forms'][form_index]
            except KeyError:
                raise InputError('form index {} not found'.format(form_ref),
                                 'request.body.inputs.{}.ref'.format(i),
                                 'validation.invalid')
        else:
            matching_forms = list(
                map(lambda f: f['ref'] == form_ref, actor_state['forms']))
            form_count = len(list(filter(lambda x: x, matching_forms)))

            if form_count == 1:
                form_index = matching_forms.index(True)
                form_state = actor_state['forms'][form_index]
            elif form_count == 0:
                raise InputError(
                    'No forms with ref {} in node'.format(form_ref),
                    'request.body.inputs.{}.ref'.format(i),
                    'validation.invalid')
            else:
                raise InputError(
                    'More than one form with ref {}'.format(form_ref),
                    'request.body.inputs.{}.ref'.format(i),
                    'validation.invalid')

        processed_ref.append(str(form_index) + ':' + form_state['ref'])

        # form xml element
        form = get_element_by(node, 'form', 'id', form_state['ref'])

        try:
            input_name = pieces.pop(0)
            form_state['inputs']['items'][input_name]
        except IndexError:
            raise InputError('Missing segment in ref for input name',
                             'request.body.inputs.{}.ref'.format(i),
                             'validation.invalid')
        except KeyError:
            raise InputError('input {} not found'.format(input_name),
                             'request.body.inputs.{}.ref'.format(i),
                             'validation.invalid')

        processed_ref.append(input_name)

        processed_inputs.append({
            'ref': '.'.join(processed_ref),
        })

        # input xml element
        input_el = get_element_by(form, 'input', 'name', input_name)

        if 'value' in field:
            try:
                input_obj = make_input(input_el)
                value = input_obj.validate(field['value'], 0)
                caption = input_obj.make_caption(value)

                processed_inputs[-1]['value'] = value
                processed_inputs[-1]['value_caption'] = caption
            except InputError as e:
                raise InputError('value invalid: {}'.format(str(e)),
                                 'request.body.inputs.{}.value'.format(i),
                                 'validation.invalid')

    channel = get_channel()
    channel.basic_publish(
        exchange='',
        routing_key=app.config['RABBIT_QUEUE'],
        body=json.dumps({
            'command': 'patch',
            'execution_id': execution.id,
            'comment': request.json['comment'],
            'inputs': processed_inputs,
        }),
        properties=pika.BasicProperties(delivery_mode=2, ),
    )

    return jsonify({
        'data': 'accepted',
    }), 202