Example #1
0
def validate_actions(actions, dereferencer, app_name):
    from walkoff.appgateway import get_app_action
    from walkoff.appgateway import get_all_actions_for_app
    defined_actions = get_all_actions_for_app(app_name)
    seen = set()
    for action_name, action in actions.items():
        if action['run'] not in defined_actions:
            raise InvalidApi('Action {0} has "run" property {1} '
                             'which is not defined in App {2}'.format(
                                 action_name, action['run'], app_name))
        action = dereferencer(action)
        action_params = dereferencer(action.get('parameters', []))
        event = action.get('event', '')
        if action_params:
            validate_action_params(action_params,
                                   dereferencer,
                                   app_name,
                                   action_name,
                                   get_app_action(app_name, action['run']),
                                   event=event)
        if 'default_return' in action:
            if action['default_return'] not in action.get('returns', []):
                raise InvalidApi(
                    'Default return {} not in defined return codes {}'.format(
                        action['default_return'],
                        action.get('returns', []).keys()))

        validate_app_action_return_codes(action.get('returns', []), app_name,
                                         action_name)
        seen.add(action['run'])
    if seen != set(defined_actions):
        logger.warning(
            'App {0} has defined the following actions which do not have a corresponding API: '
            '{1}'.format(app_name, (set(defined_actions) - seen)))
Example #2
0
def validate_data_in_param(params, data_in_param_name, message_prefix):
    data_in_param = next(
        (param for param in params if param['name'] == data_in_param_name),
        None)
    if data_in_param is None:
        raise InvalidApi('{0} has a data_in param {1} '
                         'for which it does not have a '
                         'corresponding parameter'.format(
                             message_prefix, data_in_param_name))
    elif not data_in_param.get('required', False):
        raise InvalidApi(
            '{0} has a data_in param {1} which is not marked as required in the api. '
            'Add "required: true" to parameter specification for {1}'.format(
                message_prefix, data_in_param_name))
Example #3
0
def validate_condition_transform_params(spec, app_name, action_type,
                                        defined_actions, dereferencer):
    from walkoff.appgateway import get_transform
    from walkoff.appgateway import get_condition
    seen = set()
    for action_name, action in spec.items():
        action = dereferencer(action)
        action_params = dereferencer(action.get('parameters', []))
        if action['run'] not in defined_actions:
            raise InvalidApi('{0} action {1} has a "run" param {2} '
                             'which is not defined'.format(
                                 action_type, action_name, action['run']))

        data_in_param_name = action['data_in']
        validate_data_in_param(
            action_params, data_in_param_name,
            '{0} action {1}'.format(action_type, action_name))
        if action_type == 'Condition':
            function_ = get_condition(app_name, action['run'])
        else:
            function_ = get_transform(app_name, action['run'])
        validate_action_params(action_params, dereferencer, action_type,
                               action_name, function_)
        seen.add(action['run'])

    if seen != set(defined_actions):
        logger.warning(
            'Global {0}s have defined the following actions which do not have a corresponding API: '
            '{1}'.format(action_type.lower(), (set(defined_actions) - seen)))
Example #4
0
def validate_action_params(parameters,
                           dereferencer,
                           app_name,
                           action_name,
                           action_func,
                           event=''):
    seen = set()
    for parameter in parameters:
        parameter = deref(parameter, dereferencer)
        name = parameter['name']
        if name in seen:
            raise InvalidApi('Duplicate parameter {0} in api for {1} '
                             'for action {2}'.format(name, app_name,
                                                     action_name))
        seen.add(name)

    if hasattr(action_func, '__arg_names'):
        method_params = list(action_func.__arg_names)
    else:
        method_params = get_function_arg_names(action_func)

    if method_params and method_params[0] == 'self':
        method_params.pop(0)

    if event:
        method_params.pop(0)

        if action_func.__event_name != event:
            logger.warning(
                'In app {0} action {1}, event documented {2} does not match '
                'event specified {3}'.format(app_name, action_name, event,
                                             action_func.__event_name))

    if not seen == set(method_params):
        only_in_api = seen - set(method_params)
        only_in_definition = set(method_params) - seen
        message = (
            'Discrepancy between defined parameters in API and in method definition '
            'for app {0} action {1}.'.format(app_name, action_name))
        if only_in_api:
            message += ' Only in API: {0}.'.format(only_in_api)
        if only_in_definition:
            message += ' Only in definition: {0}'.format(only_in_definition)
        raise InvalidApi(message)
Example #5
0
def validate_app_action_return_codes(return_codes, app, action):
    reserved = [
        return_code for return_code in return_codes
        if return_code in reserved_return_codes
    ]
    if reserved:
        message = 'App {0} action {1} has return codes {2} which are reserved'.format(
            app, action, reserved)
        logger.error(message)
        raise InvalidApi(message)
Example #6
0
def convert_json(spec, param_in, message_prefix):
    if 'type' in spec:
        parameter_type = spec['type']
        if parameter_type in TYPE_MAP:
            try:
                return convert_primitive_type(param_in, parameter_type)
            except ValueError:
                message = (
                    '{0} has invalid input. '
                    'Input {1} could not be converted to type {2}'.format(
                        message_prefix, param_in, parameter_type))
                logger.error(message)
                raise InvalidArgument(message)
        elif parameter_type == 'array':
            return convert_array(spec, param_in, message_prefix)
        elif parameter_type == 'object':
            return __convert_json(spec, param_in, message_prefix)
        else:
            raise InvalidApi('{0} has invalid api'.format(message_prefix))
    elif 'schema' in spec:
        return convert_json(spec['schema'], param_in, message_prefix)
    else:
        raise InvalidApi('{0} has invalid api'.format(message_prefix))
Example #7
0
def validate_definition(definition, dereferencer, definition_name=None):
    definition = dereferencer(definition)

    if 'allOf' in definition:
        for inner_definition in definition['allOf']:
            validate_definition(inner_definition, dereferencer)
    else:
        required = definition.get('required', [])
        properties = definition.get('properties', {}).keys()
        extra_properties = list(set(required) - set(properties))
        if extra_properties:
            raise InvalidApi("Required list of properties for definition "
                             "{0} not defined: {1}".format(
                                 definition_name, extra_properties))