def _resolve_json_reference(self, schema_path, schema_ref):
        """
        Processes schema referenced if request method should be POST and request should contain body
        :type: param section of api definition

        Example:
            {
            "in": "body",
            "name": "body",
            "description": "Pet object that needs to be added to the store",
            "required": False,
            "schema": {
                    "$ref": "#/definitions/Pet"
                }
            }
        Doc: https://swagger.io/docs/specification/using-ref/
        Local Reference
            - $ref: '#/definitions/myElement' # means go to the root of the current document and then find elements
            definitions and myElement one after one.

        Remote Reference
             - $ref: 'document.json' Uses the whole document located on the same server and in the same location.
            - The element of the document located on the same server – $ref: 'document.json#/myElement'
            - The element of the document located in the parent folder – $ref: '../document.json#/myElement'
            - The element of the document located in another folder – $ref: '../another-folder/document.json#/myElement'

        URL Reference
            - $ref: 'http://path/to/your/resource' Uses the whole document located on the different server.
            - The specific element of the document stored on the different server:
             – $ref: 'http://path/to/your/resource.json#myElement'
            - The document on the different server, which uses the same protocol (for example, HTTP or HTTPS):
             – $ref: '//anotherserver.com/files/example.json'

        This is a bit messy now, but once https://github.com/jacksmith15/json-ref-dict/issues/14
        resolved this can be added:
        from jsonref import JsonRef
        ref = RefDict(file)
        resolved = materialize(ref)
        Alternative: OpenApiParser
        Open issue: https://gitlab.com/Hares-Lab/openapi-parser/-/issues/1
        """
        resource_reference, item_location = schema_ref.split('#', 1)

        # Local reference:
        # Example: $ref: '#/definitions/myElement'
        if schema_ref.startswith('#'):
            self.logger.debug(
                f'Looking for reference in local file: {schema_path}')
        # URL Reference
        # Example: $ref: 'http://path/to/your/resource.json#myElement''
        elif schema_ref.startswith('http'):
            self.logger.info(
                'Downloading resource from: {} and using {}'.format(
                    resource_reference, item_location))
            self.additional_api_definition.update(
                get_api_definition_from_url(resource_reference,
                                            logger=self.logger.debug))
        elif schema_ref.startswith('//'):
            self.logger.warning(
                'Not implemented import: {}'.format(schema_ref))
            # The document on the different server, which uses the same protocol (for example, HTTP or HTTPS)
            # – $ref: '//anotherserver.com/files/example.json'
        # Remote (file) reference
        # Example: $ref: 'document.json#/myElement'
        elif len(schema_ref):
            self.logger.debug(f'Received reference: {schema_ref}')
            self.logger.debug(
                'It seems the schema is stored in local file {}, schema location: {}'
                .format(resource_reference, item_location))
            try:
                filepath = os.path.join(self.api_definition_base_path,
                                        resource_reference)
                self.additional_api_definition.update(
                    get_api_definition_from_file(filepath,
                                                 logger=self.logger.debug))
            except FailedToParseFileException:
                # This part is necessary only because some of the API definitions doesn't follow the standard
                if len(self.api_definition_url):
                    self.logger.debug(
                        'Local file is not available, but API definition was defined as URL ({}).'
                        'Trying to fetch {} from the same location'.format(
                            self.api_definition_url, resource_reference))
                    api_definition_url = "/".join([
                        get_base_url_form_api_src(self.api_definition_url),
                        resource_reference
                    ])
                    self.logger.debug(
                        'Trying to fetch api definition from: {}'.format(
                            api_definition_url))
                    self.additional_api_definition.update(
                        get_api_definition_from_url(api_definition_url,
                                                    logger=self.logger.debug))
                else:
                    msg = 'Local file reference was found in API definition, but file is not available'
                    self.logger.error(msg)
                    raise FailedToResolveReference(msg)

        else:
            self.logger.debug(
                f'Nothing to extract: {schema_path} - {schema_ref}')
        schema_definition_filtered = self._find_by_jsonpath(
            self.additional_api_definition, item_location)
        self.logger.debug(
            f'Parameter definition: {pretty_print(schema_definition_filtered, 50)} discovered from {schema_ref}'
        )
        return schema_definition_filtered
Exemple #2
0
    def get_schema(self, param):
        """
        Processes schema referenced if request method should be POST and request should contain body
        :type: param section of api definition

        Example:
            {
            "in": "body",
            "name": "body",
            "description": "Pet object that needs to be added to the store",
            "required": False,
            "schema": {
                    "$ref": "#/definitions/Pet"
                }
            }
        Doc: https://swagger.io/docs/specification/using-ref/
        Local Reference
            - $ref: '#/definitions/myElement' # means go to the root of the current document and then find elements
            definitions and myElement one after one.

        Remote Reference
             - $ref: 'document.json' Uses the whole document located on the same server and in the same location.
            - The element of the document located on the same server – $ref: 'document.json#/myElement'
            - The element of the document located in the parent folder – $ref: '../document.json#/myElement'
            - The element of the document located in another folder – $ref: '../another-folder/document.json#/myElement'

        URL Reference
            - $ref: 'http://path/to/your/resource' Uses the whole document located on the different server.
            - The specific element of the document stored on the different server:
             – $ref: 'http://path/to/your/resource.json#myElement'
            - The document on the different server, which uses the same protocol (for example, HTTP or HTTPS):
             – $ref: '//anotherserver.com/files/example.json'
        """
        schema_properties = None
        self.logger.info('Received schema definition: {}'.format(
            pretty_print(param, limit=500)))
        schema_ref = param.get('schema', {}).get('$ref')
        if not schema_ref:
            raise FailedToProcessSchemaException(
                'Faild to find shema ref in {}'.format(param))
        self.logger.debug(
            'Processing param id {}, reference for schema: {}'.format(
                param.get('id'), schema_ref))
        # Local reference:
        # Example: $ref: '#/definitions/myElement'
        if schema_ref.startswith('#'):
            self.logger.debug(
                'Looking for reference in local file: {}'.format(schema_ref))
            schema_path = schema_ref.split('/')
            # dropping first element of the list as it defines it is local reference (#)
            schema_path.pop(0)
            schema_definition = get_item(self.api_resources, schema_path)
            schema_properties = self.get_properties_from_schema_definition(
                schema_definition)
        # URL Reference
        # Example: $ref: 'http://path/to/your/resource.json#myElement''
        elif schema_ref.startswith('http'):
            self.logger.debug(
                'Looking for remote reference: {}'.format(schema_ref))
            resource_reference, item_location = schema_ref.split('#', 1)
            self.logger.info(
                'Downloading resource from: {} and using {}'.format(
                    resource_reference, item_location))
            schema_definition = get_api_definition_from_url(resource_reference)
            schema_properties = self.get_properties_from_schema_definition(
                schema_definition, item_location)
        elif schema_ref.startswith('//'):
            self.logger.warning(
                'Not implemented import: {}'.format(schema_ref))
            # The document on the different server, which uses the same protocol (for example, HTTP or HTTPS)
            # – $ref: '//anotherserver.com/files/example.json'
        # Remote (file) reference
        # Example: $ref: 'document.json#/myElement'
        else:
            file_reference, item_location = schema_ref.split('#', 1)
            self.logger.debug(
                'It seems the schema is stored in local file {}, schema location: {}'
                .format(file_reference, item_location))
            try:
                schema_definition = get_api_definition_from_file(
                    file_reference)
            except FailedToParseFileException:
                # This part is necessary only because some of the API definitions doesn't follow the standard
                if len(self.api_definition_url):
                    self.logger.debug(
                        'Local file is not available, but API definition was defined as URL ({}).'
                        'Trying to fetch {} from the same location'.format(
                            self.api_definition_url, file_reference))
                    api_definition_url = "/".join([
                        get_base_url_form_api_src(self.api_definition_url),
                        file_reference
                    ])
                    self.logger.debug(
                        'Trying to fetch api definition from: {}'.format(
                            api_definition_url))
                    schema_definition = get_api_definition_from_url(
                        api_definition_url)
                else:
                    self.logger.warning(
                        'Local file reference was found in API definition, but file is not available'
                    )
                    schema_definition = dict()
            schema_properties = self.get_properties_from_schema_definition(
                schema_definition, item_location)
        self.logger.info('Parameter definition: {} discovered from {}'.format(
            schema_properties, param))
        return schema_properties
 def _get_api_definition(self, path, url):
     if path is not None:
         return get_api_definition_from_file(path, logger=self.logger.debug)
     elif url is not None:
         return get_api_definition_from_url(url, logger=self.logger.debug)
Exemple #4
0
                     type=str2bool,
                     required=False,
                     help='Use basic output for logging (useful if running in jenkins). Example --basic_output=True',
                     dest='basic_output',
                     default=False)
 parser.add_argument('--headers',
                     type=json_data,
                     required=False,
                     help='Http request headers added to all request. Example: \'[{"Authorization": "SuperSecret"}, '
                          '{"Auth2": "asd"}]\'',
                     dest='headers',
                     default=None)
 args = parser.parse_args()
 api_definition_json = dict()
 if args.src_file:
     api_definition_json = get_api_definition_from_file(args.src_file)
 elif args.src_url:
     api_definition_json = get_api_definition_from_url(args.src_url)
 else:
     argparse.ArgumentTypeError('No API definition source provided -s, --src_file or --src_url should be defined')
     exit()
 prog = Fuzzer(api_resources=api_definition_json,
               report_dir=args.report_dir,
               test_level=args.level,
               alternate_url=args.alternate_url,
               test_result_dst=args.test_result_dst,
               log_level=args.log_level,
               basic_output=args.basic_output,
               auth_headers=args.headers,
               api_definition_url=args.src_url,
               junit_report_path=args.test_result_dst