Exemplo n.º 1
0
    def raise_if_blocked_or_unacknowledged(self, confirmation_token):
        if self.blocker is not None:
            raise ProblemException(
                400,
                "Landing is Blocked",
                "There are landing blockers present which prevent landing.",
                ext=self.to_dict(),
                type=
                "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400",
            )

        details = self.to_dict()
        if not tokens_are_equal(details["confirmation_token"],
                                confirmation_token):
            if confirmation_token is None:
                raise ProblemException(
                    400,
                    "Unacknowledged Warnings",
                    "There are landing warnings present which have not "
                    "been acknowledged.",
                    ext=details,
                    type=
                    "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400",
                )

            raise ProblemException(
                400,
                "Acknowledged Warnings Have Changed",
                "The warnings present when the request was constructed have "
                "changed. Please acknowledge the new warnings and try again.",
                ext=details,
                type=
                "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400",
            )
Exemplo n.º 2
0
def _create_problem(exc: Exception):
    """
    Transforms an exception into a ProblemException according to `exc`

    Parameters
    ----------
    exc : Exception
        If `exc` is an instance of `WazuhException` it will be casted into a ProblemException, otherwise it will be
        raised

    Raises
    ------
        ProblemException or `exc` exception type
    """
    if isinstance(exc, WazuhException):
        ext = remove_nones_to_dict({'remediation': exc.remediation,
                                    'code': exc.code,
                                    'dapi_errors': exc.dapi_errors
                                    })
    elif isinstance(exc, APIException):
        ext = remove_nones_to_dict({'code': exc.code})
    else:
        ext = None
    if isinstance(exc, WazuhError):
        raise ProblemException(status=400, title='Wazuh Error', detail=exc.message, ext=ext)
    elif isinstance(exc, (WazuhInternalError, WazuhException)):
        raise ProblemException(status=500, title='Wazuh Internal Error', detail=exc.message, ext=ext)
    elif isinstance(exc, APIError):
        raise ProblemException(status=400, title='Wazuh Error', detail=exc.details, ext=ext)
    elif isinstance(exc, APIException):
        raise ProblemException(status=500, title='Wazuh Internal Error', detail=exc.details, ext=ext)
    raise exc
Exemplo n.º 3
0
    def raise_if_blocked_or_unacknowledged(self, confirmation_token):
        details = self.to_dict()

        if details['blockers']:
            raise ProblemException(
                400,
                'Landing is Blocked',
                'There are landing blockers present which prevent landing.',
                ext=details,
                type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400' # noqa
            )  # yapf: disable

        if not tokens_are_equal(details['confirmation_token'],
                                confirmation_token):
            if confirmation_token is None:
                raise ProblemException(
                    400,
                    'Unacknowledged Warnings',
                    'There are landing warnings present which have not '
                    'been acknowledged.',
                    ext=details,
                    type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400' # noqa
                )  # yapf: disable

            raise ProblemException(
                400,
                'Acknowledged Warnings Have Changed',
                'The warnings present when the request was constructed have '
                'changed. Please acknowledge the new warnings and try again.',
                ext=details,
                type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400' # noqa
            )  # yapf: disable
Exemplo n.º 4
0
def _unmarshal_transplant_request(data):
    try:
        path = [
            (revision_id_to_int(item["revision_id"]), int(item["diff_id"]))
            for item in data["landing_path"]
        ]
    except (ValueError, TypeError):
        raise ProblemException(
            400,
            "Landing Path Malformed",
            "The provided landing_path was malformed.",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400",
        )

    if not path:
        raise ProblemException(
            400,
            "Landing Path Required",
            "A non empty landing_path is required.",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400",
        )

    # Confirmation token is optional. Convert usage of an empty
    # string to None as well to make using the API easier.
    confirmation_token = data.get("confirmation_token") or None

    return path, confirmation_token
def get_jwks():
    """Return the auth0 jwks."""
    jwks_url = "https://{oidc_domain}/.well-known/jwks.json".format(
        oidc_domain=current_app.config["OIDC_DOMAIN"])
    cache_key = jwks_cache_key(jwks_url)

    jwks = None
    with cache.suppress_failure():
        jwks = cache.get(cache_key)

    if jwks is not None:
        return jwks

    try:
        jwks_response = requests.get(jwks_url)
    except requests.exceptions.Timeout:
        raise ProblemException(
            500,
            "Auth0 Timeout",
            "Authentication server timed out, try again later",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500",
        )
    except requests.exceptions.ConnectionError:
        raise ProblemException(
            500,
            "Auth0 Connection Problem",
            "Can't connect to authentication server, try again later",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500",
        )
    except requests.exceptions.HTTPError:
        raise ProblemException(
            500,
            "Auth0 Response Error",
            "Authentication server response was invalid, try again later",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500",
        )
    except requests.exceptions.RequestException:
        raise ProblemException(
            500,
            "Auth0 Error",
            "Problem communicating with Auth0, try again later",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500",
        )

    try:
        jwks = jwks_response.json()
    except ValueError:
        logger.error("Auth0 jwks response was not valid json")
        raise ProblemException(
            500,
            "Auth0 Response Error",
            "Authentication server response was invalid, try again later",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500",
        )

    with cache.suppress_failure():
        cache.set(cache_key, jwks, timeout=60)

    return jwks
Exemplo n.º 6
0
def get_jwks():
    """Return the auth0 jwks."""
    jwks_url = current_app.config['OIDC_JWKS_URL']
    cache_key = jwks_cache_key(jwks_url)

    jwks = None
    with cache.suppress_failure():
        jwks = cache.get(cache_key)

    if jwks is not None:
        return jwks

    try:
        jwks_response = requests.get(jwks_url)
    except requests.exceptions.Timeout:
        raise ProblemException(
            500,
            'Auth0 Timeout',
            'Authentication server timed out, try again later',
            type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500'
        )  # yapf: disable
    except requests.exceptions.ConnectionError:
        raise ProblemException(
            500,
            'Auth0 Connection Problem',
            'Can\'t connect to authentication server, try again later',
            type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500'
        )  # yapf: disable
    except requests.exceptions.HTTPError:
        raise ProblemException(
            500,
            'Auth0 Response Error',
            'Authentication server response was invalid, try again '
            'later',
            type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500'
        )  # yapf: disable
    except requests.exceptions.RequestException:
        raise ProblemException(
            500,
            'Auth0 Error',
            'Problem communicating with Auth0, try again later',
            type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500'
        )  # yapf: disable

    try:
        jwks = jwks_response.json()
    except ValueError:
        logger.error('Auth0 jwks response was not valid json')
        raise ProblemException(
            500,
            'Auth0 Response Error',
            'Authentication server response was invalid, try again later',
            type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500'
        )  # yapf: disable

    with cache.suppress_failure():
        cache.set(cache_key, jwks, timeout=60)

    return jwks
Exemplo n.º 7
0
    def validate(self, product: dict, **kwargs) -> None:
        if not product or not product.get('name'):
            raise ProblemException(title='Invalid product',
                                   detail="Product 'name' must have a value!")

        if not product.get('product_group_uri'):
            raise ProblemException(
                title='Invalid product',
                detail="Product 'product_group_uri' must have a value!")
Exemplo n.º 8
0
def put(landing_job_id, data):
    """Update a landing job.

    Checks whether the logged in user is allowed to modify the landing job that is
    passed, does some basic validation on the data passed, and updates the landing job
    instance accordingly.

    Args:
        landing_job_id (int): The unique ID of the LandingJob object.
        data (dict): A dictionary containing the cleaned data payload from the request.

    Raises:
        ProblemException: If a LandingJob object corresponding to the landing_job_id
            is not found, if a user is not authorized to access said LandingJob object,
            if an invalid status is provided, or if a LandingJob object can not be
            updated (for example, when trying to cancel a job that is already in
            progress).
    """
    landing_job = LandingJob.query.with_for_update().get(landing_job_id)

    if not landing_job:
        raise ProblemException(
            404,
            "Landing job not found",
            f"A landing job with ID {landing_job_id} was not found.",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404",
        )

    ldap_username = g.auth0_user.email
    if landing_job.requester_email != ldap_username:
        raise ProblemException(
            403,
            "Unauthorized",
            f"User not authorized to update landing job {landing_job_id}",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403",
        )

    if data["status"] != LandingJobStatus.CANCELLED.value:
        raise ProblemException(
            400,
            "Invalid status provided",
            f"The provided status {data['status']} is not allowed.",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400",
        )

    if landing_job.status == LandingJobStatus.SUBMITTED:
        landing_job.transition_status(LandingJobAction.CANCEL)
        db.session.commit()
        return {"id": landing_job.id}, 200
    else:
        raise ProblemException(
            400,
            "Landing job could not be cancelled.",
            f"Landing job status ({landing_job.status}) does not allow cancelling.",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400",
        )
Exemplo n.º 9
0
    def validate(self, duration: dict, **kwargs) -> None:
        start = duration.get('start')
        end = duration.get('end', 0)

        if not duration or not start:
            raise ProblemException(title='Invalid query duration',
                                   detail="Query 'start' must have a value!")

        if start < end:
            raise ProblemException(
                title='Invalid query duration',
                detail="Query 'start' must be greater than 'end'")
Exemplo n.º 10
0
    def delete_object(self, obj: Product, **kwargs) -> None:
        if obj.indicators.count():
            raise ProblemException(
                status=403, title='Deleting product forbidden', detail='Some SLIs reference this product.')

        db.session.delete(obj)
        db.session.commit()
Exemplo n.º 11
0
def load_folder(ident, status=404, message=None):
    try:
        return watolib.Folder.by_id(ident)
    except MKUserError as exc:
        if message is None:
            message = str(exc)
        raise ProblemException(status, http_client.responses[status], message)
def post_update(product, name, body):
    kairosdb_url = os.getenv('KAIROSDB_URL')
    with dbconn() as conn:
        cur = conn.cursor()
        cur.execute(
            'SELECT ds_definition FROM zsm_data.data_source WHERE '
            'ds_product_id = (SELECT p_id FROM zsm_data.product WHERE p_slug = %s) AND ds_sli_name = %s',
            (product, name))
        row = cur.fetchone()
        if not row:
            return 'Not found', 404
        definition, = row

    start = body.get('start', MAX_QUERY_TIME_SLICE)
    end = body.get('end')

    if end and end >= start:
        raise ProblemException(
            title='Invalid "end" field value',
            detail='"end" field should be less than "start" field value')

    count = process_sli(product, name, definition, kairosdb_url, start, end,
                        'minutes', database_uri)

    return {'count': count}
Exemplo n.º 13
0
    def wrapper(*args, **kwargs):
        token_info = request.token_info
        if not token_info or token_info.get('realm') != '/employees':
            raise ProblemException(
                status=401, title='UnAuthorized', detail='Only employees are allowed to modify/create resources.')

        return f(*args, **kwargs)
Exemplo n.º 14
0
def update_timeperiod(params):
    """Update a time period"""

    body = params['body']
    name = params['name']
    time_period = load_timeperiod(name)
    if time_period is None:
        raise ProblemException(404, http.client.responses[404],
                               f"Time period {name} not found")

    if "exceptions" in body:
        time_period = dict(
            (key, time_period[key])
            for key in [*defines.weekday_ids(), "alias", "exclude"]
            if key in time_period)
        time_period["exceptions"] = _format_exceptions(body["exceptions"])

    if "alias" in body:
        time_period['alias'] = body['alias']

    if "active_time_ranges" in body:
        time_period.update(_daily_time_ranges(body['active_time_ranges']))

    if "exclude" in body:
        time_period["exclude"] = body["exclude"]

    save_timeperiod(name, time_period)
    return Response(status=204)
Exemplo n.º 15
0
    def check(cls, *, get_revision, get_diff, **kwargs):
        if get_revision() is None:
            raise ProblemException(
                404,
                'Revision not found',
                'The requested revision does not exist',
                type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404' # noqa
            )  # yapf: disable

        if get_diff() is None:
            raise ProblemException(
                404,
                'Diff not found',
                'The requested diff does not exist',
                type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404'  # noqa
            )  # yapf: disable
def _not_authorized_problem_exception():
    return ProblemException(
        403,
        "Not Authorized",
        "You're not authorized to proceed.",
        type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403",
    )
Exemplo n.º 17
0
def bulk_delete_downtimes(params):
    """Bulk delete downtimes"""
    live = sites.live()
    entries = params['entries']
    not_found = []

    downtimes: Dict[int, int] = Query(
        [Downtimes.id, Downtimes.is_service],
        And(*[Downtimes.id.equals(downtime_id) for downtime_id in entries]),
    ).to_dict(live)

    for downtime_id in entries:
        if downtime_id not in downtimes:
            not_found.append(downtime_id)

    if not_found:
        raise ProblemException(404, http.client.responses[400],
                               f"Downtimes {', '.join(not_found)} not found")

    for downtime_id, is_service in downtimes.items():
        if is_service:
            downtime_commands.del_service_downtime(live, downtime_id)
        else:
            downtime_commands.del_host_downtime(live, downtime_id)
    return Response(status=204)
Exemplo n.º 18
0
def with_problem():
    raise ProblemException(type='http://www.example.com/error',
                           title='Some Error',
                           detail='Something went wrong somewhere',
                           status=418,
                           instance='instance1',
                           headers={'x-Test-Header': 'In Test'})
Exemplo n.º 19
0
def require_etag(etag):
    # type: (ETags) -> None
    if request.if_match.as_set() != etag.as_set():
        raise ProblemException(
            412,
            "Precondition failed",
            "ETag didn't match. Probable cause: Object changed by another user.",
        )
Exemplo n.º 20
0
 def filter_active(cls, *criterion):
     try:
         return cls.query.filter(*criterion).filter_by(status='active')
     except SQLAlchemyError as e:
         db.session.rollback()
         raise ProblemException(
             500, 'Database error',
             f'Database error while fetching record. Details: {e}')
def get_auth_token():
    auth = request.headers.get("Authorization")
    if auth is None:
        raise ProblemException(
            401,
            "Authorization Header Required",
            "Authorization header is required and was not provided",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401",
        )

    if not auth:
        raise ProblemException(
            401,
            "Authorization Header Invalid",
            "Authorization header must not be empty",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401",
        )

    parts = auth.split()
    n_parts = len(parts)
    if parts[0].lower() != "bearer":
        raise ProblemException(
            401,
            "Authorization Header Invalid",
            "Authorization header must begin with Bearer",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401",
        )

    if n_parts == 1:
        raise ProblemException(
            401,
            "Authorization Header Invalid",
            "Token not found in Authorization header",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401",
        )

    if n_parts > 2:
        raise ProblemException(
            401,
            "Authorization Header Invalid",
            "Authorization header must be a Bearer token",
            type="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401",
        )

    assert n_parts == 2
    return parts[1]
Exemplo n.º 22
0
 def delete_object(self, obj: Indicator, **kwargs) -> None:
     if obj.targets.count():
         raise ProblemException(
             status=403,
             title='Deleting SLI forbidden',
             detail='Some SLO targets reference this SLI.')
     db.session.delete(obj)
     db.session.commit()
Exemplo n.º 23
0
 def get(cls, **kwargs):
     try:
         return cls.query.filter_by(**kwargs).one_or_none()
     except SQLAlchemyError as e:
         db.session.rollback()
         raise ProblemException(
             500, 'Database error',
             f'Database error while fetching record. Details: {e}')
Exemplo n.º 24
0
    def delete(self, obj: db.Model, **kwargs) -> None:
        user = request.user if hasattr(request, 'user') else None

        logger.debug('User {} deleting resource {}'.format(user, obj))

        if not user or user not in ADMINS:
            raise ProblemException(
                status=401, title='UnAuthorized', detail='Only Admins are allowed to delete this resource!')
Exemplo n.º 25
0
def search(image_id):
    img = Media.get(id=image_id)
    if not img:
        raise ProblemException(title='Does not exists',
                               detail='Image with given id does not exists')

    response = utils.create_presigned_post('flocake-cdn', img.file_name)
    return response
Exemplo n.º 26
0
def get_auth_token():
    auth = request.headers.get('Authorization')
    if auth is None:
        raise ProblemException(
            401,
            'Authorization Header Required',
            'Authorization header is required and was not provided',
            type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401' # noqa
        )  # yapf: disable

    if not auth:
        raise ProblemException(
            401,
            'Authorization Header Invalid',
            'Authorization header must not be empty',
            type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401' # noqa
        )  # yapf: disable

    parts = auth.split()
    n_parts = len(parts)
    if parts[0].lower() != 'bearer':
        raise ProblemException(
            401,
            'Authorization Header Invalid',
            'Authorization header must begin with Bearer',
            type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401' # noqa
        )  # yapf: disable

    if n_parts == 1:
        raise ProblemException(
            401,
            'Authorization Header Invalid',
            'Token not found in Authorization header',
            type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401' # noqa
        )  # yapf: disable

    if n_parts > 2:
        raise ProblemException(
            401,
            'Authorization Header Invalid',
            'Authorization header must be a Bearer token',
            type='https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401' # noqa
        )  # yapf: disable

    assert n_parts == 2
    return parts[1]
Exemplo n.º 27
0
 def exists(cls, ent_id):
     try:
         result = cls.query.get(ent_id)
     except SQLAlchemyError as e:
         db.session.rollback()
         raise ProblemException(
             500, 'Database error',
             f'Database error while doing head check. Details: {e}')
     return result is not None
Exemplo n.º 28
0
def _get_etag(folder):
    attributes = folder.attributes()
    if 'meta_data' in attributes:
        etags = [str(attributes['meta_data']['updated_at'])]
        return ETags(strong_etags=etags)
    else:
        raise ProblemException(
            500, "Folder %r has no meta_data." % (folder.name(), ),
            "Can't create ETag.")
Exemplo n.º 29
0
    def delete_object(self, obj: ProductGroup, **kwargs) -> None:
        if obj.products.count():
            raise ProblemException(
                status=403,
                title='Deleting Product group forbidden',
                detail='Some products still belong to this product group.')

        db.session.delete(obj)
        db.session.commit()
Exemplo n.º 30
0
 def delete_object(self, obj: Indicator, **kwargs) -> None:
     if obj.targets.count():
         raise ProblemException(
             status=403,
             title='Deleting SLI forbidden',
             detail='Some SLO targets reference this SLI.')
     obj.name = '{}-{}'.format(obj.name, datetime.utcnow())
     obj.is_deleted = True
     db.session.commit()