Ejemplo n.º 1
0
    def common_error_handler(exception):
        """
        Generally, each route handler should be decorated with @dss_handler, which manages exceptions. The two cases
        that fail are:

        1. handlers that are not decorated.
        2. handlers that return a code that is not in the swagger spec.

        In both cases, the exception would be punted here, and we return this very generic error that also happens to
        bypass all validation.
        """
        problem = {
            'status': requests.codes.server_error,
            'code': "unhandled_exception",
            'title': str(exception),
            'stacktrace': traceback.format_exc(),
        }
        if isinstance(exception, (OAuthProblem, OAuthResponseProblem,
                                  OAuthScopeProblem, Forbidden)):
            problem['status'] = exception.code
            problem['code'] = exception.__class__.__name__
            problem['title'] = exception.description
        return FlaskApi.get_response(
            ConnexionResponse(
                status_code=problem['status'],
                mimetype="application/problem+json",
                content_type="application/problem+json",
                body=problem,
            ))
Ejemplo n.º 2
0
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except werkzeug.exceptions.HTTPException as ex:
            status = ex.code
            code = ex.name
            title = str(ex)
            stacktrace = traceback.format_exc()
            headers = None
        except DRSException as ex:
            status = ex.status
            code = ex.code
            title = ex.message
            stacktrace = traceback.format_exc()
            headers = None
        except Exception as ex:
            status = requests.codes.server_error
            code = "unhandled_exception"
            title = str(ex)
            stacktrace = traceback.format_exc()
            headers = None
        logger.error(stacktrace)

        return ConnexionResponse(status_code=status,
                                 mimetype="application/problem+json",
                                 content_type="application/problem+json",
                                 headers=headers,
                                 body={
                                     'status': status,
                                     'code': code,
                                     'title': title,
                                     'stacktrace': stacktrace,
                                 })
Ejemplo n.º 3
0
def authorize():
    query_params = request.args.copy() if request.args else {}
    openid_provider = Config.get_openid_provider()
    query_params["openid_provider"] = openid_provider
    query_params['response_type'] = "code"
    client_id = query_params.get("client_id")
    client_id = client_id if client_id != 'None' else None
    if client_id:
        query_params['audience'] = Config.get_audience()
        auth_params = query_params
    else:
        state = base64.b64encode(json.dumps(query_params).encode()).decode()
        # TODO: set random state
        oauth2_config = Config.get_oauth2_config()
        auth_params = dict(
            client_id=oauth2_config[openid_provider]["client_id"],
            response_type="code",
            scope="openid email profile",
            redirect_uri=oauth2_config[openid_provider]["redirect_uri"],
            state=state,
            audience=Config.get_audience(),
            prompt=query_params.get('prompt')
            if query_params.get('prompt') == 'none' else 'login')

    dest = furl(get_openid_config(openid_provider)["authorization_endpoint"],
                query_params=auth_params)
    return ConnexionResponse(status_code=requests.codes.found,
                             headers=dict(Location=dest.url))
 def _framework_to_connexion_response(cls, response, mimetype):
     """ Cast framework response class to ConnexionResponse used for schema validation """
     return ConnexionResponse(status_code=response.status,
                              mimetype=mimetype,
                              content_type=response.content_type,
                              headers=response.headers,
                              body=response.body)
async def get_configuration_node(request,
                                 node_id,
                                 pretty=False,
                                 wait_for_complete=False,
                                 section=None,
                                 field=None,
                                 raw: bool = False):
    """Get a specified node's configuration (ossec.conf)

    Parameters
    ----------
    node_id : str
        Cluster node name
    pretty : bool
        Show results in human-readable format. It only works when `raw` is False (JSON format). Default `True`
    wait_for_complete : bool, optional
        Disable response timeout or not. Default `False`
    section : str
        Indicates the wazuh configuration section
    field : str
        Indicates a section child, e.g, fields for rule section are include, decoder_dir, etc.
    raw : bool, optional
        Whether to return the file content in raw or JSON format. Default `True`

    Returns
    -------
    web.json_response or ConnexionResponse
        Depending on the `raw` parameter, it will return an object or other:
            raw=True            -> ConnexionResponse (application/xml)
            raw=False (default) -> web.json_response (application/json)
        If any exception was raised, it will return a web.json_response with details.
    """
    f_kwargs = {
        'node_id': node_id,
        'section': section,
        'field': field,
        'raw': raw
    }

    nodes = raise_if_exc(await get_system_nodes())
    dapi = DistributedAPI(
        f=manager.read_ossec_conf,
        f_kwargs=remove_nones_to_dict(f_kwargs),
        request_type='distributed_master',
        is_async=False,
        wait_for_complete=wait_for_complete,
        logger=logger,
        rbac_permissions=request['token_info']['rbac_policies'],
        nodes=nodes)
    data = raise_if_exc(await dapi.distribute_function())

    if isinstance(data, AffectedItemsWazuhResult):
        response = web.json_response(data=data,
                                     status=200,
                                     dumps=prettify if pretty else dumps)
    else:
        response = ConnexionResponse(body=data["message"],
                                     mimetype='application/xml',
                                     content_type='application/xml')
    return response
Ejemplo n.º 6
0
async def get_download_file(request,
                            pretty: bool = False,
                            wait_for_complete: bool = False,
                            filename: str = None):
    """Download an specified decoder file.

    :param pretty: Show results in human-readable format
    :param wait_for_complete: Disable timeout response
    :param filename: Filename to download.
    :return: Raw XML file
    """
    f_kwargs = {'filename': filename}

    dapi = DistributedAPI(
        f=rule_framework.get_file,
        f_kwargs=remove_nones_to_dict(f_kwargs),
        request_type='local_any',
        is_async=False,
        wait_for_complete=wait_for_complete,
        logger=logger,
        rbac_permissions=request['token_info']['rbac_policies'])
    data = raise_if_exc(await dapi.distribute_function())
    response = ConnexionResponse(body=data["message"],
                                 mimetype='application/xml')

    return response
def image_id_image_get(id_):  # noqa: E501
    """Fetch the image file belonging to the image object identified by the ID in the path.

     # noqa: E501

    :param id_: ID number of the image to fetch.
    :type id_: int

    :rtype: bytearray
    """
    engine = QueryEngine()
    i = engine.query_image(id_)
    if not i:
        return Error('404', f'Image {id_} not found'), 404
    try:
        fname = os.path.join(IMG_DIR, i.file)
        with open(fname, 'rb') as f:
            data = f.read()
    except FileNotFoundError:
        return Error('404', f'Image file not found'), 404
    except PermissionError:
        return Error('404', f'Permission denied'), 403
    response = ConnexionResponse(status_code=200,
                                 mimetype=i.mime,
                                 content_type=f'{i.mime}; charset=binary',
                                 body=data,
                                 headers={})
    return response
Ejemplo n.º 8
0
async def get_group_file_xml(request,
                             group_id,
                             file_name,
                             pretty=False,
                             wait_for_complete=False):
    """Get the files placed under the group directory in xml format.

    :param pretty: Show results in human-readable format
    :param wait_for_complete: Disable timeout response
    :param group_id: Group ID.
    :param file_name: Filename
    :return: File data in XML
    """
    f_kwargs = {
        'group_list': [group_id],
        'filename': file_name,
        'type_conf': request.query.get('type', None),
        'return_format': 'xml'
    }

    dapi = DistributedAPI(
        f=agent.get_file_conf,
        f_kwargs=remove_nones_to_dict(f_kwargs),
        request_type='local_master',
        is_async=False,
        wait_for_complete=wait_for_complete,
        logger=logger,
        rbac_permissions=request['token_info']['rbac_policies'])
    data = raise_if_exc(await dapi.distribute_function())
    response = ConnexionResponse(body=data["data"], mimetype='application/xml')

    return response
def test_get_response_from_connexion_response(api):
    response = yield from api.get_response(ConnexionResponse(status_code=201, mimetype='text/plain', body='foo', headers={'X-header': 'value'}))
    assert isinstance(response, web.Response)
    assert response.status == 201
    assert response.body == b'foo'
    assert response.content_type == 'text/plain'
    assert dict(response.headers) == {'Content-Type': 'text/plain; charset=utf-8', 'X-header': 'value'}
Ejemplo n.º 10
0
def post(body):
    """Provide detailed information about a specific place."""
    result = collect_place_details(
        body['place_id'],
        body['name'],
        body['address'],
    )
    return ConnexionResponse(body=dataclasses.asdict(result))
Ejemplo n.º 11
0
async def aiohttp_users_post(user):
    if "name" not in user:
        return ConnexionResponse(body={"error": "name is undefined"},
                                 status_code=400,
                                 content_type='application/json')
    user['id'] = len(USERS) + 1
    USERS.append(user)
    return aiohttp.web.json_response(data=USERS[-1], status=201)
Ejemplo n.º 12
0
 def get_connexion_response(cls, response):
     return ConnexionResponse(
         status_code=response.status_code,
         mimetype=response.mimetype,
         content_type=response.content_type,
         headers=response.headers,
         body=response.get_data(),
     )
Ejemplo n.º 13
0
def rfc7807error_response(title, status, detail=None):
    body = {'title': title, 'status': status}
    if detail:
        body['detail'] = detail

    return ConnexionResponse(status_code=status,
                             mimetype=RFC7807_MIMETYPE,
                             content_type=RFC7807_MIMETYPE,
                             body=body)
Ejemplo n.º 14
0
def readiness():
    """Readiness probe that checks if connection to DB is established."""
    try:
        # TODO: Check if there is a better way to check database connection can be established.
        assert db.session.query(literal_column("1")).all()
        return "ready", 200, {"Content-Type": "text/plain"}
    except:
        # Bad gateway since database can't be reached.
        return ConnexionResponse(status_code=502)
Ejemplo n.º 15
0
    def problem(status,
                title,
                detail=None,
                type=None,
                instance=None,
                headers=None,
                ext=None):
        """
        Returns a `Problem Details <https://tools.ietf.org/html/draft-ietf-appsawg-http-problem-00>`_ error response.


        :param status: The HTTP status code generated by the origin server for this occurrence of the problem.
        :type status: int
        :param title: A short, human-readable summary of the problem type.  It SHOULD NOT change from occurrence to
                      occurrence of the problem, except for purposes of localisation.
        :type title: str
        :param detail: An human readable explanation specific to this occurrence of the problem.
        :type detail: str
        :param type: An absolute URI that identifies the problem type.  When dereferenced, it SHOULD provide human-readable
                     documentation for the problem type (e.g., using HTML).  When this member is not present its value is
                     assumed to be "about:blank".
        :type: type: str
        :param instance: An absolute URI that identifies the specific occurrence of the problem.  It may or may not yield
                         further information if dereferenced.
        :type instance: str
        :param headers: HTTP headers to include in the response
        :type headers: dict | None
        :param ext: Extension members to include in the body
        :type ext: dict | None
        :return: error response
        :rtype: ConnexionResponse
        """
        if not type:
            type = 'about:blank'

        problem_response = ApiStatus(code=status, msg=title, data=[])
        if detail:
            problem_response.data.append(
                ProtobufAny(type_url='detail', value=detail))

        if instance:
            problem_response.data.append(
                ProtobufAny(type_url='instance', value=instance))

        if ext:
            problem_response.data.append(ProtobufAny(type_url='ext',
                                                     value=ext))

        mimetype = content_type = 'application/problem+json'
        # return 200 http status code
        # http://wiki.envisioncn.com/pages/viewpage.action?pageId=13057195
        return ConnexionResponse(200,
                                 mimetype,
                                 content_type,
                                 body=problem_response,
                                 headers=headers)
Ejemplo n.º 16
0
def logout():
    oauth2_config = Config.get_oauth2_config()
    openid_provider = Config.get_openid_provider()
    query_params = getattr(Config.app.current_request, 'query_params')
    client_id = oauth2_config[openid_provider][
        "client_id"] if not query_params else query_params.get('client_id')
    url = furl(f"https://{openid_provider}/v2/logout",
               query_params=dict(client_id=client_id)).url
    return ConnexionResponse(status_code=requests.codes.ok,
                             headers=dict(Location=url))
Ejemplo n.º 17
0
 def _framework_to_connexion_response(cls, response, mimetype):
     """ Cast framework response class to ConnexionResponse used for schema validation """
     body = None
     if hasattr(response,
                "body"):  # StreamResponse and FileResponse don't have body
         body = response.body
     return ConnexionResponse(status_code=response.status,
                              mimetype=mimetype,
                              content_type=response.content_type,
                              headers=response.headers,
                              body=body)
Ejemplo n.º 18
0
    def get_connexion_response(cls, response, mimetype=None):
        response.body = cls._cast_body(response.body, mimetype)

        if isinstance(response, ConnexionResponse):
            return response

        return ConnexionResponse(status_code=response.status,
                                 mimetype=response.content_type,
                                 content_type=response.content_type,
                                 headers=response.headers,
                                 body=response.body)
Ejemplo n.º 19
0
def search(location):
    """Return a list of all places nearby our coordinates."""
    # Define data.
    places_api_key = os.environ['RYR_COLLECTOR_GOOGLE_PLACES_API_KEY']

    # Prepare client.
    gmap = GoogleCollector()
    gmap.authenticate(api_key=places_api_key)

    # Retrieve nearby places.
    places_nearby = gmap.search_places_nearby(location)
    return ConnexionResponse(body=places_nearby)
Ejemplo n.º 20
0
    def get_connexion_response(cls, response, mimetype=None):
        if isinstance(response, ConnexionResponse):
            return response

        if not isinstance(response, flask.current_app.response_class):
            response = cls.get_response(response, mimetype)

        return ConnexionResponse(
            status_code=response.status_code,
            mimetype=response.mimetype,
            content_type=response.content_type,
            headers=response.headers,
            body=response.get_data(),
        )
Ejemplo n.º 21
0
def health_check(*args, **kwargs):
    health_checks = dict()
    health_checks.update(**Config.get_directory().health_checks(),
                         **get_openip_health_status(),
                         **authorize.health_checks())
    if all([check == 'ok' for check in health_checks.values()]):
        body = dict(health_status='ok', services=health_checks)
        status = 200
        headers = {"Content-Type": "application/json"}
    else:
        body = dict(health_status='unhealthy', services=health_checks)
        status = 500
        headers = {"Content-Type": "application/json+problem"}
    return ConnexionResponse(status_code=status, headers=headers, body=body)
Ejemplo n.º 22
0
def serve_openid_config():
    """
    Part of OIDC
    """
    auth_host = request.headers['host']
    if auth_host != os.environ["API_DOMAIN_NAME"]:
        raise FusilladeHTTPException(
            status=400,
            title="Bad Request",
            detail=
            f"host: {auth_host}, is not supported. host must be {os.environ['API_DOMAIN_NAME']}."
        )
    openid_config = get_openid_config(Config.get_openid_provider()).copy()
    openid_config.update(**proxied_endpoints)
    return ConnexionResponse(body=openid_config, status_code=requests.codes.ok)
Ejemplo n.º 23
0
async def get_file(request,
                   pretty: bool = False,
                   wait_for_complete: bool = False,
                   filename: str = None,
                   raw: bool = False):
    """"Get content of one CDB list file, in raw or dict format.

    Parameters
    ----------
    pretty : bool
        Show results in human-readable format.
    wait_for_complete : bool
        Disable timeout response.
    filename : str
        Name of filename to get data from.
    raw : bool, optional
        Respond in raw format.

    Returns
    -------
    web.json_response, ConnexionResponse
        Depending on the `raw` parameter, it will return an object or other:
            raw=True            -> ConnexionResponse (text/plain)
            raw=False (default) -> web.json_response (application/json)
        If any exception was raised, it will return a web.json_response with details.
    """
    f_kwargs = {'filename': filename, 'raw': raw}

    dapi = DistributedAPI(
        f=cdb_list.get_list_file,
        f_kwargs=remove_nones_to_dict(f_kwargs),
        request_type='local_master',
        is_async=False,
        wait_for_complete=wait_for_complete,
        logger=logger,
        rbac_permissions=request['token_info']['rbac_policies'])
    data = raise_if_exc(await dapi.distribute_function())
    if isinstance(data, AffectedItemsWazuhResult):
        response = web.json_response(data=data,
                                     status=200,
                                     dumps=prettify if pretty else dumps)
    else:
        response = ConnexionResponse(body=data["message"],
                                     mimetype='text/plain',
                                     content_type='text/plain')

    return response
Ejemplo n.º 24
0
async def get_file(request,
                   pretty: bool = False,
                   wait_for_complete: bool = False,
                   filename: str = None,
                   raw: bool = False):
    """Get rule file content.

    Parameters
    ----------
    pretty : bool, optional
        Show results in human-readable format. It only works when `raw` is False (JSON format). Default `True`
    wait_for_complete : bool, optional
        Disable response timeout or not. Default `False`
    filename : str
        Filename to download.
    raw : bool, optional
        Whether to return the file content in raw or JSON format. Default `False`

    Returns
    -------
    web.json_response or ConnexionResponse
        Depending on the `raw` parameter, it will return an object or other:
            raw=True            -> ConnexionResponse (application/xml)
            raw=False (default) -> web.json_response (application/json)
        If any exception was raised, it will return a web.json_response with details.
    """
    f_kwargs = {'filename': filename, 'raw': raw}

    dapi = DistributedAPI(
        f=rule_framework.get_rule_file,
        f_kwargs=remove_nones_to_dict(f_kwargs),
        request_type='local_master',
        is_async=False,
        wait_for_complete=wait_for_complete,
        logger=logger,
        rbac_permissions=request['token_info']['rbac_policies'])
    data = raise_if_exc(await dapi.distribute_function())
    if isinstance(data, AffectedItemsWazuhResult):
        response = web.json_response(data=data,
                                     status=200,
                                     dumps=prettify if pretty else dumps)
    else:
        response = ConnexionResponse(body=data["message"],
                                     mimetype='application/xml',
                                     content_type='application/xml')

    return response
Ejemplo n.º 25
0
def dss_notification(body):
    bundle_uuid = body['match']['bundle_uuid']
    bundle_version = body['match']['bundle_version']
    subscription_id = body['subscription_id']
    event_type = body['event_type']

    payload = {
        'bundle_uuid': bundle_uuid,
        'bundle_version': bundle_version,
        'event_type': event_type,
    }
    queue_url = matrix_infra_config.notification_q_url
    sqs_handler.add_message_to_queue(queue_url, payload)

    return ConnexionResponse(
        status_code=requests.codes.ok,
        body=f"Received notification from subscription {subscription_id}: "
        f"{event_type} {bundle_uuid}.{bundle_version}")
Ejemplo n.º 26
0
    def wrapper(*args, **kwargs):
        method, path = request.method, request.path
        if os.environ.get('DSS_READ_ONLY_MODE') is None or "GET" == method or ("POST" == method and "search" in path):
            try:
                return func(*args, **kwargs)
            except werkzeug.exceptions.HTTPException as ex:
                status = ex.code
                code = ex.name
                title = str(ex)
                stacktrace = traceback.format_exc()
            except DSSException as ex:
                status = ex.status
                code = ex.code
                title = ex.message
                stacktrace = traceback.format_exc()
            except Exception as ex:
                status = requests.codes.server_error
                code = "unhandled_exception"
                title = str(ex)
                stacktrace = traceback.format_exc()
            headers = None
            logger.error(json.dumps(dict(status=status, code=code, title=title, stacktrace=stacktrace), indent=4))
        else:
            status = requests.codes.unavailable
            code = "read_only"
            title = "The DSS is currently read-only"
            stacktrace = ""
            headers = {'Retry-After': '600'}

        if include_retry_after_header(return_code=status, method=method, uri=path):
            headers = {'Retry-After': '10'}

        return ConnexionResponse(
            status_code=status,
            mimetype="application/problem+json",
            content_type="application/problem+json",
            headers=headers,
            body={
                'status': status,
                'code': code,
                'title': title,
                'stacktrace': stacktrace,
            })
Ejemplo n.º 27
0
def click_get(query, doc_id):  # noqa: E501
    """Click-through redirector for capturing implicit feedback

    :param query: Original query content
    :type query: str
    :param url: URL of selected result
    :type url: str

    :rtype: None
    """

    url = mainEngine.get_metadata_for_doc_id(doc_id).get("url")

    #FIXME: Validate that URL is something from the index metadata!
    response = ConnexionResponse(status_code=302,
                                 headers={'Location':
                                          url})  #,"X-Debug": r[0]["url"]})

    return response
Ejemplo n.º 28
0
        def wrapper(request):
            try:
                return origwrapper(request)
            except DSSBindingException as ex:
                status = ex.status
                code = ex.code
                title = ex.message
                stacktrace = traceback.format_exc()

                return FlaskApi.get_response(
                    ConnexionResponse(
                        status_code=status,
                        mimetype="application/problem+json",
                        content_type="application/problem+json",
                        body={
                            'status': status,
                            'code': code,
                            'title': title,
                            'stacktrace': stacktrace,
                        },
                    ))
Ejemplo n.º 29
0
async def get_date():
    return ConnexionResponse(body={'value': datetime.date(2000, 1, 2)})
Ejemplo n.º 30
0
async def get_uuid():
    return ConnexionResponse(
        body={'value': uuid.UUID(hex='e7ff66d0-3ec2-4c4e-bed0-6e4723c24c51')})