Пример #1
0
def delete_perm(perm_id):
    perm = Permission.find_by_id(perm_id)

    if not perm:
        raise ApiError('not found', 404)

    admin_audit_trail.send(current_app._get_current_object(),
                           event='permission-deleted',
                           message='',
                           user=g.user,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=perm.id,
                           type='permission',
                           request=request)

    if perm.delete():
        return jsonify(status='ok')
    else:
        raise ApiError('failed to delete permission', 500)
Пример #2
0
def delete_group(group_id):
    group = Group.find_by_id(group_id)

    if not group:
        raise ApiError('not found', 404)

    admin_audit_trail.send(current_app._get_current_object(),
                           event='group-deleted',
                           message='',
                           user=g.login,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=group.id,
                           type='group',
                           request=request)

    if group.delete():
        return jsonify(status='ok')
    else:
        raise ApiError('failed to delete user group', 500)
Пример #3
0
def delete_key(key):
    key = ApiKey.find_by_id(key)

    if not key:
        raise ApiError('not found', 404)

    admin_audit_trail.send(current_app._get_current_object(),
                           event='apikey-deleted',
                           message='',
                           user=g.user,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=key.id,
                           type='apikey',
                           request=request)

    if key.delete():
        return jsonify(status='ok')
    else:
        raise ApiError('failed to delete API key', 500)
Пример #4
0
def delete_user(user_id):
    user = User.find_by_id(user_id)

    if not user:
        raise ApiError('not found', 404)

    admin_audit_trail.send(current_app._get_current_object(),
                           event='user-deleted',
                           message='',
                           user=g.user,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=user.id,
                           type='user',
                           request=request)

    if user.delete():
        return jsonify(status='ok')
    else:
        raise ApiError('failed to delete user', 500)
Пример #5
0
    def __init__(self,
                 page: int = 1,
                 page_size: int = None,
                 items: int = 0) -> None:

        self.page = page
        self.page_size = page_size or current_app.config['DEFAULT_PAGE_SIZE']
        self.items = items

        if items and self.page > self.pages or self.page < 1:
            raise ApiError('page out of range: 1-%s' % self.pages, 416)
Пример #6
0
def update_perm(perm_id):
    if not request.json:
        raise ApiError('nothing to change', 400)

    for s in request.json.get('scopes', []):
        if s not in list(Scope):
            raise ApiError("'{}' is not a valid Scope".format(s), 400)

    perm = Permission.find_by_id(perm_id)

    if not perm:
        raise ApiError('not found', 404)

    admin_audit_trail.send(current_app._get_current_object(), event='permission-updated', message='', user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=perm.id, type='permission', request=request)

    if perm.update(**request.json):
        return jsonify(status='ok')
    else:
        raise ApiError('failed to update permission', 500)
Пример #7
0
def create_heartbeat():
    try:
        heartbeat = Heartbeat.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if g.get('customer', None):
        heartbeat.customer = g.get('customer')

    try:
        heartbeat = heartbeat.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    if heartbeat:
        return jsonify(status="ok",
                       id=heartbeat.id,
                       heartbeat=heartbeat.serialize), 201
    else:
        raise ApiError("insert or update of received heartbeat failed", 500)
Пример #8
0
def create_heartbeat():
    try:
        heartbeat = Heartbeat.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    heartbeat.customer = assign_customer(wanted=heartbeat.customer,
                                         permission='admin:heartbeats')

    try:
        heartbeat = heartbeat.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    if heartbeat:
        return jsonify(status="ok",
                       id=heartbeat.id,
                       heartbeat=heartbeat.serialize), 201
    else:
        raise ApiError("insert or update of received heartbeat failed", 500)
Пример #9
0
def keycloak():

    if not current_app.config['KEYCLOAK_URL']:
        return jsonify(
            status="error",
            message="Must define KEYCLOAK_URL setting in server configuration."
        ), 503

    access_token_url = "{0}/auth/realms/{1}/protocol/openid-connect/token".format(
        current_app.config['KEYCLOAK_URL'],
        current_app.config['KEYCLOAK_REALM'])

    payload = {
        'client_id': request.json['clientId'],
        'client_secret': current_app.config['OAUTH2_CLIENT_SECRET'],
        'redirect_uri': request.json['redirectUri'],
        'grant_type': 'authorization_code',
        'code': request.json['code'],
    }

    try:
        r = requests.post(access_token_url, data=payload)
    except Exception:
        return jsonify(status="error",
                       message="Failed to call Keycloak API over HTTPS")
    access_token = r.json()

    headers = {
        "Authorization":
        "{0} {1}".format(access_token['token_type'],
                         access_token['access_token'])
    }
    r = requests.get(
        "{0}/auth/realms/{1}/protocol/openid-connect/userinfo".format(
            current_app.config['KEYCLOAK_URL'],
            current_app.config['KEYCLOAK_REALM']),
        headers=headers)
    profile = r.json()

    roles = profile['roles']
    login = profile['preferred_username']

    if is_authorized('ALLOWED_KEYCLOAK_ROLES', roles):
        raise ApiError("User %s is not authorized" % login, 403)

    customers = get_customers(login, groups=roles)

    token = create_token(profile['sub'],
                         profile['name'],
                         login,
                         provider='keycloak',
                         customers=customers,
                         roles=roles)
    return jsonify(token=token.tokenize)
Пример #10
0
def delete_blackout(blackout_id):
    customer = g.get('customer', None)
    blackout = Blackout.find_by_id(blackout_id, customer)

    if not blackout:
        raise ApiError('not found', 404)

    write_audit_trail.send(current_app._get_current_object(),
                           event='blackout-deleted',
                           message='',
                           user=g.user,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=blackout.id,
                           type='blackout',
                           request=request)

    if blackout.delete():
        return jsonify(status='ok')
    else:
        raise ApiError('failed to delete blackout', 500)
Пример #11
0
def get_group_users(group_id):
    if not Group.find_by_id(group_id):
        raise ApiError('not found', 404)

    group_users = GroupUsers.find_by_id(group_id)

    if group_users:
        return jsonify(status='ok',
                       users=[user.serialize for user in group_users],
                       total=len(group_users))
    else:
        return jsonify(status='ok', users=[], total=0)
Пример #12
0
def delete_heartbeat(heartbeat_id):
    customer = g.get('customer', None)
    heartbeat = Heartbeat.find_by_id(heartbeat_id, customer)

    if not heartbeat:
        raise ApiError('not found', 404)

    write_audit_trail.send(current_app._get_current_object(),
                           event='heartbeat-deleted',
                           message='',
                           user=g.login,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=heartbeat.id,
                           type='heartbeat',
                           request=request)

    if heartbeat.delete():
        return jsonify(status='ok')
    else:
        raise ApiError('failed to delete heartbeat', 500)
Пример #13
0
    def incoming(self, query_string, payload):
        # logging.info("get alert: %s", payload['alerts'])
        # transform this alert group to related each other
        related_alert = []
        for alert in payload['alerts']:
            related_alert.append(alert['labels']['event'])

        #logging.info(related_alert)
        if payload and 'alerts' in payload:
            external_url = payload.get('externalURL')
            try:
                return [
                    parse_alertmanager(alert, external_url, related_alert)
                    for alert in payload['alerts']
                ]
            except Exception as e:
                logging.error(e)
                raise ApiError('Error : ' + e, 400)
        else:
            raise ApiError('no alerts in Alertmanager notification payload',
                           400)
Пример #14
0
def gitlab():

    access_token_url = current_app.config['GITLAB_URL'] + '/oauth/token'
    tokeninfo_url = current_app.config['GITLAB_URL'] + '/oauth/token/info'
    userinfo_url = current_app.config['GITLAB_URL'] + '/oauth/userinfo'
    gitlab_api_url = current_app.config['GITLAB_URL'] + '/api/v4'

    payload = {
        'client_id': request.json['clientId'],
        'client_secret': current_app.config['OAUTH2_CLIENT_SECRET'],
        'redirect_uri': request.json['redirectUri'],
        'grant_type': 'authorization_code',
        'code': request.json['code'],
    }

    try:
        r = requests.post(access_token_url, data=payload)
    except Exception:
        return jsonify(status="error", message="Failed to call Gitlab API over HTTPS")
    token = r.json()

    headers = {'Authorization': 'Bearer ' + token['access_token']}
    r = requests.get(tokeninfo_url, headers=headers)
    scopes = r.json().get('scopes', [])
    current_app.logger.info('GitLab scopes: {}'.format(scopes))

    if 'openid' in scopes:
        r = requests.post(userinfo_url, headers=headers)
        profile = r.json()

        user_id = profile['sub']
        login = profile['nickname']
        groups = profile.get('groups', [])
        email_verified = profile.get('email_verified', False)
    else:
        r = requests.get(gitlab_api_url + '/user', headers=headers)
        profile = r.json()

        user_id = profile['id']
        login = profile['username']

        r = requests.get(gitlab_api_url + '/groups', headers=headers)
        groups = [g['path'] for g in r.json()]
        email_verified = True if profile.get('email', None) else False

    if not_authorized('ALLOWED_GITLAB_GROUPS', groups):
        raise ApiError("User %s is not authorized" % login, 403)

    customers = get_customers(login, groups)

    token = create_token(user_id, profile.get('name', '@'+login), login, provider='gitlab', customers=customers,
                         groups=groups, email=profile.get('email', None), email_verified=email_verified)
    return jsonify(token=token.tokenize)
Пример #15
0
def add_note(alert_id):
    note_text = request.json.get('text') or request.json.get('note')

    if not note_text:
        raise ApiError("must supply 'note' text")

    customers = g.get('customers', None)
    alert = Alert.find_by_id(alert_id, customers)

    if not alert:
        raise ApiError('not found', 404)

    note = alert.add_note(note_text)

    write_audit_trail.send(current_app._get_current_object(), event='alert-note-added', message='', user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=note.id, type='note', request=request)

    if note:
        return jsonify(status='ok', id=note.id, note=note.serialize), 201, {'Location': absolute_url('/alert/{}/note/{}'.format(alert.id, note.id))}
    else:
        raise ApiError('failed to add note for alert', 500)
Пример #16
0
def pingdom():

    try:
        incomingAlert = parse_pingdom(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    incomingAlert.customer = assign_customer(wanted=incomingAlert.customer)
    add_remote_ip(request, incomingAlert)

    try:
        alert = process_alert(incomingAlert)
    except RejectException as e:
        raise ApiError(str(e), 403)
    except Exception as e:
        raise ApiError(str(e), 500)

    if alert:
        return jsonify(status='ok', id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError('insert or update of pingdom check failed', 500)
Пример #17
0
def delete_alert(alert_id):
    customers = g.get('customers', None)
    alert = Alert.find_by_id(alert_id, customers)

    if not alert:
        raise ApiError('not found', 404)

    write_audit_trail.send(current_app._get_current_object(),
                           event='alert-deleted',
                           message='',
                           user=g.login,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=alert.id,
                           type='alert',
                           request=request)

    if alert.delete():
        return jsonify(status='ok')
    else:
        raise ApiError('failed to delete alert', 500)
Пример #18
0
def newrelic():

    try:
        incomingAlert = parse_newrelic(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    incomingAlert.customer = assign_customer(wanted=incomingAlert.customer)
    add_remote_ip(request, incomingAlert)

    try:
        alert = process_alert(incomingAlert)
    except RejectException as e:
        raise ApiError(str(e), 403)
    except Exception as e:
        raise ApiError(str(e), 500)

    if alert:
        return jsonify(status="ok", id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError("insert or update of New Relic alert failed", 500)
Пример #19
0
def cloudwatch():

    try:
        incomingAlert = parse_notification(request.get_json(force=True))
    except ValueError as e:
        raise ApiError(str(e), 400)

    incomingAlert.customer = assign_customer(wanted=incomingAlert.customer)
    add_remote_ip(request, incomingAlert)

    try:
        alert = process_alert(incomingAlert)
    except RejectException as e:
        raise ApiError(str(e), 403)
    except Exception as e:
        raise ApiError(str(e), 500)

    if alert:
        return jsonify(status='ok', id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError('insert or update of cloudwatch alarm failed', 500)
Пример #20
0
def create_perm():
    try:
        perm = Permission.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    for want_scope in perm.scopes:
        if not Permission.is_in_scope(want_scope, g.scopes):
            raise ApiError(
                "Requested scope '{}' not in existing scopes: {}".format(
                    want_scope, ','.join(g.scopes)), 403)

    try:
        perm = perm.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    if perm:
        return jsonify(status='ok', id=perm.id, permission=perm.serialize), 201
    else:
        raise ApiError('create API key failed', 500)
Пример #21
0
def action_alert(alert_id):
    action = request.json.get('action', None)
    text = request.json.get('text', '%s operator action' % action)
    timeout = request.json.get('timeout', None)

    if not action:
        raise ApiError("must supply 'action' as json data", 400)

    customers = g.get('customers', None)
    alert = Alert.find_by_id(alert_id, customers)

    if not alert:
        raise ApiError('not found', 404)

    try:
        alert, action, text, timeout = process_action(alert, action, text, timeout)
        alert = alert.from_action(action, text, timeout)
    except RejectException as e:
        write_audit_trail.send(current_app._get_current_object(), event='alert-action-rejected', message=alert.text,
                               user=g.login, customers=g.customers, scopes=g.scopes, resource_id=alert.id, type='alert',
                               request=request)
        raise ApiError(str(e), 400)
    except InvalidAction as e:
        raise ApiError(str(e), 409)
    except Exception as e:
        raise ApiError(str(e), 500)

    write_audit_trail.send(current_app._get_current_object(), event='alert-actioned', message=text, user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=alert.id, type='alert', request=request)

    if alert:
        return jsonify(status='ok')
    else:
        raise ApiError('failed to action alert', 500)
Пример #22
0
def add_note(alert_id):
    note_text = request.json.get('text') or request.json.get('note')

    if not note_text:
        raise ApiError("must supply 'note' text", 400)

    customers = g.get('customers', None)
    alert = Alert.find_by_id(alert_id, customers)

    if not alert:
        raise ApiError('not found', 404)

    try:
        alert, note_text = process_note(alert, note_text)
        note = alert.add_note(note_text)
    except RejectException as e:
        write_audit_trail.send(current_app._get_current_object(), event='alert-note-rejected', message='',
                               user=g.login, customers=g.customers, scopes=g.scopes, resource_id=note.id, type='note',
                               request=request)
        raise ApiError(str(e), 400)
    except ForwardingLoop as e:
        return jsonify(status='ok', message=str(e)), 202
    except AlertaException as e:
        raise ApiError(e.message, code=e.code, errors=e.errors)
    except Exception as e:
        raise ApiError(str(e), 500)

    write_audit_trail.send(current_app._get_current_object(), event='alert-note-added', message='', user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=note.id, type='note', request=request)

    if note:
        return jsonify(status='ok', id=note.id, note=note.serialize), 201, {'Location': absolute_url('/alert/{}/note/{}'.format(alert.id, note.id))}
    else:
        raise ApiError('failed to add note for alert', 500)
Пример #23
0
def pagerduty():

    data = request.json

    updated = False
    if data and 'messages' in data:
        for message in data['messages']:
            try:
                incident_key, status, text = parse_pagerduty(message)
            except ValueError as e:
                raise ApiError(str(e), 400)

            customer = g.get('customer', None)
            try:
                alert = Alert.get(id=incident_key, customer=customer)
            except Exception as e:
                raise ApiError(str(e), 500)

            if not alert:
                raise ApiError("not found", 404)

            try:
                updated = alert.set_status(status, text)
            except Exception as e:
                raise ApiError(str(e), 500)
    else:
        raise ApiError("no messages in PagerDuty data payload", 400)

    if updated:
        return jsonify(status="ok"), 200
    else:
        raise ApiError("update PagerDuty incident status failed", 500)
Пример #24
0
def set_status(alert_id):
    status = request.json.get('status', None)
    text = request.json.get('text', '')
    timeout = request.json.get('timeout', None)

    if not status:
        raise ApiError("must supply 'status' as json data", 400)

    customers = g.get('customers', None)
    alert = Alert.find_by_id(alert_id, customers)

    if not alert:
        raise ApiError('not found', 404)

    try:
        alert, status, text = process_status(alert, status, text)
        alert = alert.from_status(status, text, timeout)
    except RejectException as e:
        write_audit_trail.send(current_app._get_current_object(), event='alert-status-rejected', message=alert.text,
                               user=g.login, customers=g.customers, scopes=g.scopes, resource_id=alert.id, type='alert',
                               request=request)
        raise ApiError(str(e), 400)
    except AlertaException as e:
        raise ApiError(e.message, code=e.code, errors=e.errors)
    except Exception as e:
        raise ApiError(str(e), 500)

    write_audit_trail.send(current_app._get_current_object(), event='alert-status-changed', message=text, user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=alert.id, type='alert', request=request)
    if alert:
        return jsonify(status='ok')
    else:
        raise ApiError('failed to set status', 500)
Пример #25
0
def receive():
    try:
        alert = Alert.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    alert.customer = assign_customer(wanted=alert.customer)

    def audit_trail_alert(event: str):
        write_audit_trail.send(current_app._get_current_object(), event=event, message=alert.text, user=g.login,
                               customers=g.customers, scopes=g.scopes, resource_id=alert.id, type='alert', request=request)

    try:
        alert = process_alert(alert)
    except RejectException as e:
        audit_trail_alert(event='alert-rejected')
        raise ApiError(str(e), 403)
    except RateLimit as e:
        audit_trail_alert(event='alert-rate-limited')
        return jsonify(status='error', message=str(e), id=alert.id), 429
    except HeartbeatReceived as heartbeat:
        audit_trail_alert(event='alert-heartbeat')
        return jsonify(status='ok', message=str(heartbeat), id=heartbeat.id), 202
    except BlackoutPeriod as e:
        audit_trail_alert(event='alert-blackout')
        return jsonify(status='ok', message=str(e), id=alert.id), 202
    except ForwardingLoop as e:
        return jsonify(status='ok', message=str(e)), 202
    except AlertaException as e:
        raise ApiError(e.message, code=e.code, errors=e.errors)
    except Exception as e:
        raise ApiError(str(e), 500)

    write_audit_trail.send(current_app._get_current_object(), event='alert-received', message=alert.text, user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=alert.id, type='alert', request=request)

    if alert:
        return jsonify(status='ok', id=alert.id, alert=alert.serialize), 201
    else:
        raise ApiError('insert or update of received alert failed', 500)
Пример #26
0
def update_me():
    if not request.json:
        raise ApiError('nothing to change', 400)

    if 'roles' in request.json:
        raise ApiError('not allowed to update roles', 400)
    if 'email_verified' in request.json:
        raise ApiError('not allowed to set email verified', 400)

    user = User.find_by_id(g.user_id)

    if not user:
        raise ApiError('not found', 404)

    if 'email' in request.json:
        user_by_email = User.find_by_email(email=request.json['email'])
        if user_by_email and user_by_email.id != user.id:
            raise ApiError('user with that email already exists', 409)

    updated = user.update(**request.json)

    write_audit_trail.send(current_app._get_current_object(), event='user-me-updated', message='', user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=user.id, type='user', request=request)

    if updated:
        return jsonify(status='ok', user=updated.serialize)
    else:
        raise ApiError('failed to update user', 500)
Пример #27
0
def only_json():
    # SAML2 Assertion Consumer Service expects POST request with 'Content-Type': 'application/x-www-form-urlencoded' from IdP
    if request.method == 'POST' and request.path == '/auth/saml' and request.headers[
            'Content-Type'] == 'application/x-www-form-urlencoded':
        return

    if request.path == '/auth/logout':
        return

    if request.method in ['POST', 'PUT'] and not request.is_json:
        raise ApiError(
            "POST and PUT requests must set 'Content-Type' to 'application/json'",
            415)
Пример #28
0
def verify_email(hash):

    user = User.verify_hash(hash, salt='confirm')
    if user:
        if user.email_verified:
            raise ApiError('email already verified', 400)
        user.set_email_verified()

        auth_audit_trail.send(current_app._get_current_object(),
                              event='basic-auth-verify-email',
                              message='user confirm email address',
                              user=user.email,
                              customers=[],
                              scopes=[],
                              resource_id=user.id,
                              type='user',
                              request=request)

        return jsonify(status='ok',
                       message='email address {} confirmed'.format(user.email))
    else:
        raise ApiError('invalid confirmation hash', 400)
Пример #29
0
def create_blackout():
    try:
        blackout = Blackout.parse(request.json)
    except Exception as e:
        raise ApiError(str(e), 400)

    if g.get('customer', None):
        blackout.customer = g.get('customer')

    try:
        blackout = blackout.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    if blackout:
        return jsonify(status="ok",
                       id=blackout.id,
                       blackout=blackout.serialize), 201, {
                           'Location': absolute_url('/blackout/' + blackout.id)
                       }
    else:
        raise ApiError("insert blackout failed", 500)
Пример #30
0
def bulk_action_alert():
    from alerta.tasks import action_alerts

    action = request.json.get('action', None)
    text = request.json.get('text', 'bulk status update')
    timeout = request.json.get('timeout', None)

    if not action:
        raise ApiError("must supply 'action' as json data", 400)

    query = qb.from_params(request.args)
    alerts = [alert.id for alert in Alert.find_all(query)]

    if not alerts:
        raise ApiError('not found', 404)

    task = action_alerts.delay(alerts, action, text, timeout)

    return jsonify(status='ok',
                   message=f'{len(alerts)} alerts queued for action'), 202, {
                       'Location': absolute_url('/_bulk/task/' + task.id)
                   }