コード例 #1
0
ファイル: test_blackouts.py プロジェクト: 3IWOH/alerta
    def setUp(self):

        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.alert = {
            'event': 'node_marginal',
            'resource': 'node404',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'warning',
            'correlate': ['node_down', 'node_marginal', 'node_up']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.admin_api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='demo-key'
            )
            self.customer_api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='demo-key',
                customer='Foo'
            )
            self.admin_api_key.create()
            self.customer_api_key.create()
コード例 #2
0
ファイル: test_users.py プロジェクト: raddessi/alerta
    def setUp(self):

        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'ADMIN_USERS': ['*****@*****.**'],
            'ALLOWED_EMAIL_DOMAINS': ['alerta.io', 'doe.com']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.alert = {
            'event': 'Foo',
            'resource': 'Bar',
            'environment': 'Production',
            'service': ['Quux']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.api_key = ApiKey(
                user='******',
                scopes=[Scope.admin, Scope.read, Scope.write],
                text='demo-key'
            )
            self.api_key.create()

        self.headers = {
            'Authorization': f'Key {self.api_key.key}',
            'Content-type': 'application/json'
        }
コード例 #3
0
ファイル: keys.py プロジェクト: guardian/alerta
def update_key(key):
    if not request.json:
        raise ApiError('nothing to change', 400)

    if not current_app.config['AUTH_REQUIRED']:
        key = ApiKey.find_by_id(key)
    elif Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        key = ApiKey.find_by_id(key)
    else:
        key = ApiKey.find_by_id(key, user=g.login)

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

    update = request.json
    update['customer'] = assign_customer(wanted=update.get('customer'), permission=Scope.admin_keys)

    for want_scope in update.get('scopes', []):
        if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
            raise ApiError("Requested scope '{}' not in existing scopes: {}".format(
                want_scope, ','.join(g.scopes)), 403)

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

    if key.update(**request.json):
        return jsonify(status='ok')
    else:
        raise ApiError('failed to update API key', 500)
コード例 #4
0
ファイル: keys.py プロジェクト: xtavras/alerta
def list_keys():
    query = qb.from_params(request.args, customers=g.customers)
    total = ApiKey.count(query)
    paging = Page.from_params(request.args, total)
    if not current_app.config['AUTH_REQUIRED']:
        keys = ApiKey.find_all(query,
                               page=paging.page,
                               page_size=paging.page_size)
    elif Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        keys = ApiKey.find_all(query,
                               page=paging.page,
                               page_size=paging.page_size)
    elif not g.get('login', None):
        raise ApiError("Must define 'user' to list user keys", 400)
    else:
        keys = ApiKey.find_by_user(user=g.login)

    if keys:
        return jsonify(status='ok',
                       page=paging.page,
                       pageSize=paging.page_size,
                       pages=paging.pages,
                       more=paging.has_more,
                       keys=[key.serialize for key in keys],
                       total=total)
    else:
        return jsonify(status='ok',
                       page=paging.page,
                       pageSize=paging.page_size,
                       pages=paging.pages,
                       more=paging.has_more,
                       message='not found',
                       keys=[],
                       total=0)
コード例 #5
0
    def setUp(self):
        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'PLUGINS': ['reject']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.alert = {
            'resource': 'node404',
            'event': 'node_marginal',
            'environment': 'Production',
            'severity': 'warning',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'service': ['Core', 'Web', 'Network'],
            'group': 'Network',
            'tags': ['level=20', 'switch:off']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.admin_api_key = ApiKey(user='******',
                                        scopes=['admin', 'read', 'write'],
                                        text='demo-key')
            self.customer_api_key = ApiKey(user='******',
                                           scopes=['admin', 'read', 'write'],
                                           text='demo-key',
                                           customer='Foo')
            self.admin_api_key.create()
            self.customer_api_key.create()
コード例 #6
0
ファイル: test_shelving.py プロジェクト: jjh74/alerta
    def setUp(self):
        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'PLUGINS': ['timeout'],
            'ALERT_TIMEOUT': 24680,
            'ACK_TIMEOUT': 98765,
            'SHELVE_TIMEOUT': 12345
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.alert = {
            'event': 'node_marginal',
            'resource': 'node404',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'warning',
            'correlate': ['node_down', 'node_marginal', 'node_up']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.admin_api_key = ApiKey(user='******',
                                        scopes=['admin', 'read', 'write'],
                                        text='demo-key')
            self.customer_api_key = ApiKey(user='******',
                                           scopes=['admin', 'read', 'write'],
                                           text='demo-key',
                                           customer='Foo')
            self.admin_api_key.create()
            self.customer_api_key.create()
コード例 #7
0
    def setUp(self):

        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'ADMIN_USERS': ['*****@*****.**'],
            'ALLOWED_EMAIL_DOMAINS': ['bonaparte.fr', 'debeauharnais.fr']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.alert = {
            'event': 'Foo',
            'resource': 'Bar',
            'environment': 'Production',
            'service': ['Quux']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.api_key = ApiKey(user='******',
                                  scopes=['admin', 'read', 'write'],
                                  text='demo-key')
            self.api_key.create()

        self.headers = {
            'Authorization': 'Key %s' % self.api_key.key,
            'Content-type': 'application/json'
        }
コード例 #8
0
ファイル: commands.py プロジェクト: kjetilmjos/alerta
def key(username, want_key, scopes, duration, text, customer, all, force):
    """
    Create an admin API key.
    """
    if username and username not in current_app.config['ADMIN_USERS']:
        raise click.UsageError('User {} not an admin'.format(username))

    if all and want_key:
        raise click.UsageError('Can only set API key with "--username".')

    scopes = [Scope(s) for s in scopes] or [Scope.admin, Scope.write, Scope.read]
    expires = datetime.utcnow() + timedelta(seconds=duration) if duration else None
    text = text or 'Created by alertad script'

    def create_key(admin, key=None):
        key = ApiKey(
            user=admin,
            key=key,
            scopes=scopes,
            expire_time=expires,
            text=text,
            customer=customer
        )
        try:
            key = key.create()
        except Exception as e:
            click.echo('ERROR: {}'.format(e))
        else:
            return key

    if all:
        for admin in current_app.config['ADMIN_USERS']:
            keys = [k for k in ApiKey.find_by_user(admin) if k.scopes == scopes]
            if keys and not force:
                key = keys[0]
            else:
                key = create_key(admin)
            click.echo('{:40} {}'.format(key.key, key.user))

    elif username:
        keys = [k for k in ApiKey.find_by_user(username) if k.scopes == scopes]
        if want_key:
            found_key = [k for k in keys if k.key == want_key]
            if found_key:
                key = found_key[0]
            else:
                key = create_key(username, key=want_key)
        else:
            if keys and not force:
                key = keys[0]
            else:
                key = create_key(username)
        if key:
            click.echo(key.key)
        else:
            sys.exit(1)

    else:
        raise click.UsageError("Must set '--username' or use '--all'")
コード例 #9
0
ファイル: test_scopes.py プロジェクト: ngohoa211/alerta
 def make_key(user, scopes=None, type=None, text=''):
     api_key = ApiKey(
         user=user,
         scopes=scopes,
         type=type,
         text=text
     )
     return api_key.create().key
コード例 #10
0
ファイル: test_scopes.py プロジェクト: 3IWOH/alerta
 def make_key(user, scopes=None, type=None, text=''):
     api_key = ApiKey(
         user=user,
         scopes=scopes,
         type=type,
         text=text
     )
     return api_key.create().key
コード例 #11
0
ファイル: keys.py プロジェクト: guardian/alerta
def get_key(key):
    if not current_app.config['AUTH_REQUIRED']:
        key = ApiKey.find_by_id(key)
    elif Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        key = ApiKey.find_by_id(key)
    else:
        user = g.get('login', None)
        key = ApiKey.find_by_id(key, user)

    if key:
        return jsonify(status='ok', total=1, key=key.serialize)
    else:
        raise ApiError('not found', 404)
コード例 #12
0
ファイル: commands.py プロジェクト: y-mori0110/alerta
 def create_key(admin, key):
     key = ApiKey(user=admin,
                  key=key,
                  scopes=['admin', 'write', 'read'],
                  text='Admin key created by alertad script',
                  expire_time=None)
     try:
         db.get_db()  # init db on global app context
         key = key.create()
     except Exception as e:
         click.echo('ERROR: {}'.format(e))
     else:
         click.echo('{} {}'.format(key.key, key.user))
コード例 #13
0
 def create_key(admin, key=None):
     key = ApiKey(user=admin,
                  key=key,
                  scopes=scopes,
                  expire_time=expires,
                  text=text,
                  customer=customer)
     try:
         key = key.create()
     except Exception as e:
         click.echo('ERROR: {}'.format(e))
     else:
         return key
コード例 #14
0
ファイル: keys.py プロジェクト: xtavras/alerta
def get_key(key):
    if not current_app.config['AUTH_REQUIRED']:
        key = ApiKey.find_by_id(key)
    elif Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        key = ApiKey.find_by_id(key)
    else:
        user = g.get('login', None)
        key = ApiKey.find_by_id(key, user)

    if key:
        return jsonify(status='ok', total=1, key=key.serialize)
    else:
        raise ApiError('not found', 404)
コード例 #15
0
ファイル: commands.py プロジェクト: 3IWOH/alerta
 def create_key(admin):
     key = ApiKey(
         user=admin,
         scopes=['admin', 'write', 'read'],
         text='Admin key created by alertad script',
         expire_time=None
     )
     try:
         db.get_db()  # init db on global app context
         key = key.create()
     except Exception as e:
         click.echo('ERROR: {}'.format(e))
     else:
         click.echo('{} {}'.format(key.key, key.user))
コード例 #16
0
ファイル: test_auth.py プロジェクト: guardian/alerta
    def setUp(self):

        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'ADMIN_USERS': ['*****@*****.**'],
            'ALLOWED_EMAIL_DOMAINS': ['bonaparte.fr', 'debeauharnais.fr', 'manorfarm.ru']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.alert = {
            'event': 'Foo',
            'resource': 'Bar',
            'environment': 'Production',
            'service': ['Quux']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.api_key = ApiKey(
                user='******',
                scopes=[Scope.admin, Scope.read, Scope.write],
                text='demo-key'
            )
            self.api_key.create()

        self.headers = {
            'Authorization': 'Key %s' % self.api_key.key,
            'Content-type': 'application/json'
        }
コード例 #17
0
ファイル: keys.py プロジェクト: kattunga/alerta
def create_key():
    try:
        key = ApiKey.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if 'admin' in g.scopes or 'admin:keys' in g.scopes:
        key.user = key.user or g.user
        key.customer = key.customer or g.get('customer', None)
    else:
        key.user = g.user
        key.customer = g.get('customer', None)

    if not key.user:
        raise ApiError("Must set 'user' to create API key", 400)

    for want_scope in key.scopes:
        if not Permission.is_in_scope(want_scope, g.scopes):
            raise ApiError("Requested scope '%s' not in existing scopes: %s" % (want_scope, ','.join(g.scopes)), 403)

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

    if key:
        return jsonify(status="ok", key=key.key, data=key.serialize), 201
    else:
        raise ApiError("create API key failed", 500)
コード例 #18
0
def create_key():
    try:
        key = ApiKey.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if 'admin' in g.scopes or 'admin:keys' in g.scopes:
        key.user = key.user or g.user
        key.customer = key.customer or g.get('customer', None)
    else:
        key.user = g.user
        key.customer = g.get('customer', None)

    if not key.user:
        raise ApiError(
            "An API key must be associated with a 'user'. Retry with user credentials.",
            400)

    for want_scope in key.scopes:
        if not Permission.is_in_scope(want_scope, g.scopes):
            raise ApiError(
                "Requested scope '%s' not in existing scopes: %s" %
                (want_scope, ','.join(g.scopes)), 403)

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

    if key:
        return jsonify(status="ok", key=key.key, data=key.serialize), 201
    else:
        raise ApiError("create API key failed", 500)
コード例 #19
0
def list_keys():
    if not current_app.config['AUTH_REQUIRED']:
        keys = ApiKey.find_all()
    elif 'admin' in g.scopes or 'admin:keys' in g.scopes:
        keys = ApiKey.find_all()
    elif not g.get('user', None):
        raise ApiError("Must define 'user' to list user keys", 400)
    else:
        keys = ApiKey.find_by_user(g.user)

    if keys:
        return jsonify(status="ok",
                       keys=[key.serialize for key in keys],
                       total=len(keys))
    else:
        return jsonify(status="ok", message="not found", keys=[], total=0)
コード例 #20
0
ファイル: keys.py プロジェクト: ngohoa211/alerta
def list_keys():
    if not current_app.config['AUTH_REQUIRED']:
        keys = ApiKey.find_all()
    elif Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        keys = ApiKey.find_all()
    elif not g.get('login', None):
        raise ApiError("Must define 'user' to list user keys", 400)
    else:
        keys = ApiKey.find_by_user(user=g.login)

    if keys:
        return jsonify(status='ok',
                       keys=[key.serialize for key in keys],
                       total=len(keys))
    else:
        return jsonify(status='ok', message='not found', keys=[], total=0)
コード例 #21
0
ファイル: keys.py プロジェクト: guardian/alerta
def create_key():
    try:
        key = ApiKey.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        key.user = key.user or g.login
    else:
        key.user = g.login

    key.customer = assign_customer(wanted=key.customer, permission=Scope.admin_keys)

    if not key.user:
        raise ApiError("An API key must be associated with a 'user'. Retry with user credentials.", 400)

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

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

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

    if key:
        return jsonify(status='ok', key=key.key, data=key.serialize), 201
    else:
        raise ApiError('create API key failed', 500)
コード例 #22
0
    def setUp(self):

        self.access_key = 'cc3b7f30-360e-47bc-8abb-c0a27625e134'
        self.secret_key = 'MjM0ODU4NGI1YWQxZWMyYzcxNjAxZDA4MzczNGQ1M2IK'

        test_config = {
            'DEBUG':
            True,
            'TESTING':
            True,
            'AUTH_REQUIRED':
            True,
            'CUSTOMER_VIEWS':
            True,
            'ADMIN_USERS': ['*****@*****.**'],
            'DELETE_SCOPES': ['delete:alerts'],
            'ALLOWED_EMAIL_DOMAINS':
            ['bonaparte.fr', 'debeauharnais.fr', 'manorfarm.ru'],
            'HMAC_AUTH_CREDENTIALS': [{
                'key': self.access_key,
                'secret': self.secret_key,
                'algorithm': 'sha256'
            }]
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.alert = {
            'event': 'Foo',
            'resource': 'Bar',
            'environment': 'Production',
            'service': ['Quux']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.api_key = ApiKey(
                user='******',
                scopes=[Scope.admin, Scope.read, Scope.write],
                text='demo-key')
            self.api_key.create()

        self.headers = {
            'Authorization': 'Key %s' % self.api_key.key,
            'Content-type': 'application/json'
        }
コード例 #23
0
ファイル: keys.py プロジェクト: justenb/alerta
def delete_key(key):
    key = ApiKey.find_by_id(key)

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

    if key.delete():
        return jsonify(status='ok')
    else:
        raise ApiError('failed to delete API key', 500)
コード例 #24
0
def delete_key(key):
    key = ApiKey.find_by_id(key)

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

    if key.delete():
        return jsonify(status="ok")
    else:
        raise ApiError("failed to delete API key", 500)
コード例 #25
0
ファイル: keys.py プロジェクト: kattunga/alerta
def delete_key(key):
    key = ApiKey.find_by_id(key)

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

    if key.delete():
        return jsonify(status="ok")
    else:
        raise ApiError("failed to delete API key", 500)
コード例 #26
0
ファイル: commands.py プロジェクト: y-mori0110/alerta
def keys():
    """List admin API keys."""
    for admin in current_app.config['ADMIN_USERS']:
        try:
            db.get_db()  # init db on global app context
            keys = ApiKey.find_by_user(admin)
        except Exception as e:
            click.echo('ERROR: {}'.format(e))
        else:
            for key in keys:
                click.echo('{:40} {}'.format(key.key, key.user))
コード例 #27
0
ファイル: commands.py プロジェクト: guardian/alerta
def keys():
    """List admin API keys."""
    for admin in current_app.config['ADMIN_USERS']:
        try:
            db.get_db()  # init db on global app context
            keys = ApiKey.find_by_user(admin)
        except Exception as e:
            click.echo('ERROR: {}'.format(e))
        else:
            for key in keys:
                click.echo('{:40} {}'.format(key.key, key.user))
コード例 #28
0
ファイル: commands.py プロジェクト: kjetilmjos/alerta
def keys():
    """
    List admin API keys.
    """
    for admin in current_app.config['ADMIN_USERS']:
        try:
            keys = [k for k in ApiKey.find_by_user(admin) if Scope.admin in k.scopes]
        except Exception as e:
            click.echo('ERROR: {}'.format(e))
        else:
            for key in keys:
                click.echo('{:40} {}'.format(key.key, key.user))
コード例 #29
0
        def wrapped(*args, **kwargs):

            auth_header = request.headers.get('Authorization', '')
            m = re.match(r'Key (\S+)', auth_header)
            param = m.group(1) if m else request.args.get('api-key', None)

            if param:
                key = ApiKey.verify_key(param)
                if not key:
                    raise ApiError("API key parameter '%s' is invalid" % param, 401)
                g.user = key.user
                g.customer = key.customer
                g.scopes = key.scopes

                if not Permission.is_in_scope(scope, g.scopes):
                    raise ApiError('Missing required scope: %s' % scope, 403)
                else:
                    return f(*args, **kwargs)

            auth_header = request.headers.get('Authorization', '')
            m = re.match(r'Bearer (\S+)', auth_header)
            token = m.group(1) if m else None

            if token:
                try:
                    jwt = Jwt.parse(token)
                except DecodeError:
                    raise ApiError('Token is invalid', 401)
                except ExpiredSignature:
                    raise ApiError('Token has expired', 401)
                except InvalidAudience:
                    raise ApiError('Invalid audience', 401)
                g.user = jwt.preferred_username
                g.customer = jwt.customer
                g.scopes = jwt.scopes

                if not Permission.is_in_scope(scope, g.scopes):
                    raise ApiError("Missing required scope: %s" % scope, 403)
                else:
                    return f(*args, **kwargs)

            if not current_app.config['AUTH_REQUIRED']:
                g.user = None
                g.customer = None
                g.scopes = []
                return f(*args, **kwargs)

            # Google App Engine Cron Service
            if request.headers.get('X-Appengine-Cron', False) and request.headers.get('X-Forwarded-For', '') == '0.1.0.1':
                return f(*args, **kwargs)

            raise ApiError('Missing authorization API Key or Bearer Token', 401)
コード例 #30
0
ファイル: keys.py プロジェクト: guardian/alerta
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.login,
                           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)
コード例 #31
0
ファイル: test_customers.py プロジェクト: y-mori0110/alerta
    def setUp(self):

        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'ADMIN_USERS': ['*****@*****.**'],
            'ALLOWED_EMAIL_DOMAINS': ['alerta.io', 'foo.com', 'bar.com']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.foo_alert = {
            'event': 'foo1',
            'resource': 'foo1',
            'environment': 'Production',
            'service': ['Web']
        }

        self.bar_alert = {
            'event': 'bar1',
            'resource': 'bar1',
            'environment': 'Production',
            'service': ['Web']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='admin-key'
            )
            self.api_key.create()

        self.admin_headers = {
            'Authorization': 'Key %s' % self.api_key.key,
            'Content-type': 'application/json'
        }
コード例 #32
0
ファイル: keys.py プロジェクト: xtavras/alerta
def update_key(key):
    if not request.json:
        raise ApiError('nothing to change', 400)

    if not current_app.config['AUTH_REQUIRED']:
        key = ApiKey.find_by_id(key)
    elif Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        key = ApiKey.find_by_id(key)
    else:
        key = ApiKey.find_by_id(key, user=g.login)

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

    update = request.json
    update['customer'] = assign_customer(wanted=update.get('customer'),
                                         permission=Scope.admin_keys)

    for want_scope in update.get('scopes', []):
        if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
            raise ApiError(
                "Requested scope '{}' not in existing scopes: {}".format(
                    want_scope, ','.join(g.scopes)), 403)

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

    updated = key.update(**request.json)
    if updated:
        return jsonify(status='ok', key=updated.serialize)
    else:
        raise ApiError('failed to update API key', 500)
コード例 #33
0
ファイル: keys.py プロジェクト: kattunga/alerta
def list_keys():
    if not current_app.config['AUTH_REQUIRED']:
        keys = ApiKey.find_all()
    elif 'admin' in g.scopes or 'admin:keys' in g.scopes:
        keys = ApiKey.find_all()
    elif not g.get('user', None):
            raise ApiError("Must define 'user' to list user keys", 400)
    else:
        keys = ApiKey.find_by_user(g.user)

    if keys:
        return jsonify(
            status="ok",
            keys=[key.serialize for key in keys],
            total=len(keys)
        )
    else:
        return jsonify(
            status="ok",
            message="not found",
            keys=[],
            total=0
        )
コード例 #34
0
ファイル: keys.py プロジェクト: guardian/alerta
def list_keys():
    if not current_app.config['AUTH_REQUIRED']:
        keys = ApiKey.find_all()
    elif Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        keys = ApiKey.find_all()
    elif not g.get('login', None):
        raise ApiError("Must define 'user' to list user keys", 400)
    else:
        keys = ApiKey.find_by_user(user=g.login)

    if keys:
        return jsonify(
            status='ok',
            keys=[key.serialize for key in keys],
            total=len(keys)
        )
    else:
        return jsonify(
            status='ok',
            message='not found',
            keys=[],
            total=0
        )
コード例 #35
0
ファイル: test_auth_ldap.py プロジェクト: frasy/alerta
    def setUp(self):

        test_config = {
            'TESTING': True,
            'DEBUG': True,
            'AUTH_REQUIRED': True,
            'AUTH_PROVIDER': 'ldap',
            'CUSTOMER_VIEWS': True,
            'ADMIN_USERS': ['*****@*****.**'],
            'LDAP_URL': 'ldap://myldap.server',
            'LDAP_BIND_USERNAME': '******',
            'LDAP_BIND_PASSWORD': '******',
            'LDAP_DOMAINS_SEARCH_QUERY': {
                'debeauharnais.fr': 'sAMAccountName={username}'
            },
            'LDAP_DOMAINS_USER_BASEDN': {
                'debeauharnais.fr': ''
            },
            'LDAP_DOMAINS': {
                'debeauharnais.fr': 'DN=%s'
            }
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.api_key = ApiKey(
                user='******',
                scopes=[Scope.admin, Scope.read, Scope.write],
                text='demo-key')
            self.api_key.create()

        self.headers = {
            'Authorization': 'Key %s' % self.api_key.key,
            'Content-type': 'application/json'
        }
コード例 #36
0
ファイル: keys.py プロジェクト: xtavras/alerta
def create_key():
    try:
        key = ApiKey.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        key.user = key.user or g.login
    else:
        key.user = g.login

    key.customer = assign_customer(wanted=key.customer,
                                   permission=Scope.admin_keys)

    if not key.user:
        raise ApiError(
            "An API key must be associated with a 'user'. Retry with user credentials.",
            400)

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

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

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

    if key:
        return jsonify(status='ok', key=key.key, data=key.serialize), 201
    else:
        raise ApiError('create API key failed', 500)
コード例 #37
0
ファイル: keys.py プロジェクト: xtavras/alerta
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.login,
                           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)
コード例 #38
0
ファイル: test_customers.py プロジェクト: guardian/alerta
    def setUp(self):

        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'ADMIN_USERS': ['*****@*****.**'],
            'ALLOWED_EMAIL_DOMAINS': ['alerta.io', 'foo.com', 'bar.com']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.foo_alert = {
            'event': 'foo1',
            'resource': 'foo1',
            'environment': 'Production',
            'service': ['Web']
        }

        self.bar_alert = {
            'event': 'bar1',
            'resource': 'bar1',
            'environment': 'Production',
            'service': ['Web']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.api_key = ApiKey(
                user='******',
                scopes=[Scope.admin, Scope.read, Scope.write],
                text='admin-key'
            )
            self.api_key.create()

        self.admin_headers = {
            'Authorization': 'Key %s' % self.api_key.key,
            'Content-type': 'application/json'
        }
コード例 #39
0
ファイル: keys.py プロジェクト: 40a/alerta
def update_key(key):
    if not request.json:
        raise ApiError('nothing to change', 400)

    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-updated',
                           message='',
                           user=g.user,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=key.id,
                           type='apikey',
                           request=request)

    if key.update(**request.json):
        return jsonify(status='ok')
    else:
        raise ApiError('failed to update API key', 500)
コード例 #40
0
ファイル: test_routing.py プロジェクト: guardian/alerta
    def setUp(self):

        # create dummy routing rules
        self.dist = pkg_resources.Distribution(__file__, project_name='alerta-routing', version='0.1')
        s = 'rules = tests.test_routing:rules'
        self.entry_point = pkg_resources.EntryPoint.parse(s, dist=self.dist)
        self.dist._ep_map = {'alerta.routing': {'rules': self.entry_point}}
        pkg_resources.working_set.add(self.dist)

        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'ADMIN_USERS': ['*****@*****.**'],
            'ALLOWED_EMAIL_DOMAINS': ['alerta.io', 'foo.com', 'bar.com'],
            'PD_API_KEYS': {
                'Tyrell Corporation': 'tc-key',
                'Cyberdyne Systems': 'cs-key',
                'Weyland-Yutani': 'wy-key',
                'Zorin Enterprises': 'ze-key'
            },
            'SLACK_API_KEYS': {
                'Soylent Corporation': 'sc-key',
                'Omni Consumer Products': 'ocp-key',
                # 'Dolmansaxlil Shoe Corporation': 'dsc-key'  # use default key
            },
            'API_KEY': 'default-key'
        }

        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.tier1_tc_alert = {
            'event': 'foo1',
            'resource': 'foo1',
            'environment': 'Production',
            'service': ['Web'],
            'customer': 'Tyrell Corporation'  # tier 1
        }

        self.tier1_wy_alert = {
            'event': 'foo1',
            'resource': 'foo1',
            'environment': 'Production',
            'service': ['Web'],
            'customer': 'Weyland-Yutani'  # tier 1
        }

        self.tier2_sc_alert = {
            'event': 'bar1',
            'resource': 'bar1',
            'environment': 'Production',
            'service': ['Web'],
            'customer': 'Soylent Corporation'  # tier 2
        }

        self.tier2_ocp_alert = {
            'event': 'bar1',
            'resource': 'bar1',
            'environment': 'Production',
            'service': ['Web'],
            'customer': 'Omni Consumer Products'  # tier 2
        }

        self.tier2_dsc_alert = {
            'event': 'bar1',
            'resource': 'bar1',
            'environment': 'Production',
            'service': ['Web'],
            'customer': 'Dolmansaxlil Shoe Corporation'  # tier 2
        }

        self.tier3_it_alert = {
            'event': 'bar1',
            'resource': 'bar1',
            'environment': 'Production',
            'service': ['Web'],
            'customer': 'Initech'  # tier 3
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.api_key = ApiKey(
                user='******',
                scopes=[Scope.admin, Scope.read, Scope.write],
                text='admin-key'
            )
            self.api_key.create()

        self.headers = {
            'Authorization': 'Key %s' % self.api_key.key,
            'Content-type': 'application/json'
        }

        # create dummy plugins
        plugins.plugins['pagerduty'] = DummyPagerDutyPlugin()
        plugins.plugins['slack'] = DummySlackPlugin()
        plugins.plugins['config'] = DummyConfigPlugin()
コード例 #41
0
class BlackoutsTestCase(unittest.TestCase):

    def setUp(self):
        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'PLUGINS': []
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.prod_alert = {
            'resource': 'node404',
            'event': 'node_down',
            'environment': 'Production',
            'severity': 'major',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'service': ['Core', 'Web', 'Network'],
            'group': 'Network',
            'tags': ['level=20', 'switch:off'],
            'origin': 'foo/bar'
        }

        self.dev_alert = {
            'resource': 'node404',
            'event': 'node_marginal',
            'environment': 'Development',
            'severity': 'warning',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'service': ['Core', 'Web', 'Network'],
            'group': 'Network',
            'tags': ['level=20', 'switch:off'],
            'origin': 'foo/bar'
        }

        self.fatal_alert = {
            'event': 'node_down',
            'resource': 'net01',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'critical',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'tags': ['foo'],
            'attributes': {'foo': 'abc def', 'bar': 1234, 'baz': False},
            'origin': 'foo/bar'
        }
        self.critical_alert = {
            'event': 'node_marginal',
            'resource': 'net02',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'critical',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'origin': 'foo/bar',
            'timeout': 30
        }
        self.major_alert = {
            'event': 'node_marginal',
            'resource': 'net03',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'major',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'origin': 'foo/bar',
            'timeout': 40
        }
        self.normal_alert = {
            'event': 'node_up',
            'resource': 'net03',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'normal',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'origin': 'foo/quux',
            'timeout': 100
        }
        self.minor_alert = {
            'event': 'node_marginal',
            'resource': 'net04',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'minor',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'origin': 'foo/quux',
            'timeout': 40
        }
        self.ok_alert = {
            'event': 'node_up',
            'resource': 'net04',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'ok',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'origin': 'foo/quux',
            'timeout': 100
        }
        self.warn_alert = {
            'event': 'node_marginal',
            'resource': 'net05',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'warning',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'origin': 'foo/quux',
            'timeout': 50
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.admin_api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='demo-key'
            )
            self.customer_api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='demo-key',
                customer='Foo'
            )
            self.admin_api_key.create()
            self.customer_api_key.create()

    def tearDown(self):
        plugins.plugins.clear()
        db.destroy()

    def test_suppress_blackout(self):

        os.environ['NOTIFICATION_BLACKOUT'] = 'False'
        plugins.plugins['blackout'] = Blackout()

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout
        response = self.client.post('/blackout', data=json.dumps({'environment': 'Production'}), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # suppress alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        self.headers = {
            'Authorization': 'Key %s' % self.customer_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_notification_blackout(self):

        os.environ['NOTIFICATION_BLACKOUT'] = 'True'
        plugins.plugins['blackout'] = Blackout()

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create new blackout
        blackout = {
            'environment': 'Production',
            'service': ['Core']
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # new alert should be status=blackout
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # duplicate alert should be status=blackout
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # duplicate alert should be status=blackout (again)
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # increase severity alert should be status=blackout
        self.prod_alert['severity'] = 'major'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # increase severity alert should be status=blackout (again)
        self.prod_alert['severity'] = 'critical'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # decrease severity alert should be status=blackout
        self.prod_alert['severity'] = 'minor'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # decrease severity alert should be status=blackout (again)
        self.prod_alert['severity'] = 'warning'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # normal severity alert should be status=closed
        self.prod_alert['severity'] = 'ok'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'closed')

        # normal severity alert should be status=closed (again)
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'closed')

        # non-normal severity alert should be status=blackout (again)
        self.prod_alert['severity'] = 'major'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # decrease severity alert should be status=blackout
        self.prod_alert['severity'] = 'minor'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # non-normal severity alert should be status=open
        self.prod_alert['severity'] = 'minor'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'open')

        # normal severity alert should be status=closed
        self.prod_alert['severity'] = 'ok'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'closed')

    def test_previous_status(self):

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create an alert => critical, open
        response = self.client.post('/alert', data=json.dumps(self.fatal_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'critical')
        self.assertEqual(data['alert']['status'], 'open')

        alert_id_1 = data['id']

        # ack the alert => critical, ack
        response = self.client.put('/alert/' + alert_id_1 + '/action',
                                   data=json.dumps({'action': 'ack'}), headers=self.headers)
        self.assertEqual(response.status_code, 200)

        response = self.client.get('/alert/' + alert_id_1, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'critical')
        self.assertEqual(data['alert']['status'], 'ack')

        # create 2nd alert => critical, open
        response = self.client.post('/alert', data=json.dumps(self.critical_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'critical')
        self.assertEqual(data['alert']['status'], 'open')

        alert_id_2 = data['id']

        # shelve 2nd alert => critical, shelved
        response = self.client.put('/alert/' + alert_id_2 + '/action',
                                   data=json.dumps({'action': 'shelve'}), headers=self.headers)
        self.assertEqual(response.status_code, 200)

        response = self.client.get('/alert/' + alert_id_2, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'critical')
        self.assertEqual(data['alert']['status'], 'shelved')

        # create a blackout
        os.environ['NOTIFICATION_BLACKOUT'] = 'yes'
        plugins.plugins['blackout'] = Blackout()

        blackout = {
            'environment': 'Production',
            'service': ['Network']
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # update 1st alert => critical, blackout
        response = self.client.post('/alert', data=json.dumps(self.fatal_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'critical')
        self.assertEqual(data['alert']['status'], 'blackout')

        # create 3rd alert => major, blackout
        response = self.client.post('/alert', data=json.dumps(self.major_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'major')
        self.assertEqual(data['alert']['status'], 'blackout')

        # clear 3rd alert => normal, closed
        response = self.client.post('/alert', data=json.dumps(self.normal_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'normal')
        self.assertEqual(data['alert']['status'], 'closed')

        # create 4th alert => minor, blackout
        response = self.client.post('/alert', data=json.dumps(self.minor_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'minor')
        self.assertEqual(data['alert']['status'], 'blackout')

        # clear 4th alert => ok, closed
        response = self.client.post('/alert', data=json.dumps(self.ok_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'ok')
        self.assertEqual(data['alert']['status'], 'closed')

        # create 5th alert => warning, blackout
        response = self.client.post('/alert', data=json.dumps(self.warn_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'warning')
        self.assertEqual(data['alert']['status'], 'blackout')

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # update 1st alert => critical, ack
        response = self.client.post('/alert', data=json.dumps(self.fatal_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'critical')
        self.assertEqual(data['alert']['status'], 'ack')

        # update 2nd alert => critical, shelved
        response = self.client.post('/alert', data=json.dumps(self.critical_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'critical')
        self.assertEqual(data['alert']['status'], 'shelved')

        # update 3rd alert => normal, closed
        response = self.client.post('/alert', data=json.dumps(self.normal_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'normal')
        self.assertEqual(data['alert']['status'], 'closed')

        # update 4th alert => minor, open
        response = self.client.post('/alert', data=json.dumps(self.minor_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'minor')
        self.assertEqual(data['alert']['status'], 'open')

        # update 5th alert => warning, open
        response = self.client.post('/alert', data=json.dumps(self.warn_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'warning')
        self.assertEqual(data['alert']['status'], 'open')

    def test_whole_environment_blackout(self):

        os.environ['NOTIFICATION_BLACKOUT'] = 'False'
        plugins.plugins['blackout'] = Blackout()

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.dev_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout (for whole development environment)
        blackout = {
            'environment': 'Development'
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # do not suppress production alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # suppress development alert
        response = self.client.post('/alert', data=json.dumps(self.dev_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # do not suppress any alerts
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        response = self.client.post('/alert', data=json.dumps(self.dev_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

    def test_combination_blackout(self):

        os.environ['NOTIFICATION_BLACKOUT'] = 'False'
        plugins.plugins['blackout'] = Blackout()

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout (only for services on a particular host)
        blackout = {
            'environment': 'Production',
            'resource': 'node404',
            'service': ['Network', 'Web']
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # suppress alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout (only for groups of alerts with particular tags)
        blackout = {
            'environment': 'Production',
            'group': 'Network',
            'tags': ['system:web01', 'switch:off']
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # do not suppress alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        self.prod_alert['tags'].append('system:web01')

        # suppress alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.dev_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout (only for resources with a particular tag)
        blackout = {
            'environment': 'Development',
            'resource': 'node404',
            'tags': ['level=40']
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # do not suppress alert
        response = self.client.post('/alert', data=json.dumps(self.dev_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        self.dev_alert['tags'].append('level=40')

        # suppress alert
        response = self.client.post('/alert', data=json.dumps(self.dev_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_origin_blackout(self):

        os.environ['NOTIFICATION_BLACKOUT'] = 'False'
        plugins.plugins['blackout'] = Blackout()

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout (only for an origin)
        blackout = {
            'environment': 'Production',
            'origin': 'foo/bar',
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # suppress alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        # do not suppress alert
        response = self.client.post('/alert', data=json.dumps(self.minor_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout (only for origin with particular tags)
        blackout = {
            'environment': 'Production',
            'tags': ['system:web01', 'switch:off'],
            'origin': 'foo/bar'
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # do not suppress alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        self.prod_alert['tags'].append('system:web01')

        # suppress alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.dev_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout (only for origin with certain event)
        blackout = {
            'environment': 'Development',
            'event': 'node_marginal',
            'origin': 'foo/quux'
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # do not suppress alert
        response = self.client.post('/alert', data=json.dumps(self.dev_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        self.dev_alert['origin'] = 'foo/quux'

        # suppress alert
        response = self.client.post('/alert', data=json.dumps(self.dev_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        # list blackouts
        response = self.client.get('/blackouts', headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_edit_blackout(self):

        # create new blackout
        os.environ['NOTIFICATION_BLACKOUT'] = 'False'
        plugins.plugins['blackout'] = Blackout()

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout (only for services on a particular host)
        blackout = {
            'environment': 'Production',
            'resource': 'node404',
            'service': ['Network', 'Web'],
            'startTime': '2019-01-01T00:00:00.000Z',
            'endTime': '2049-12-31T23:59:59.999Z'
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # suppress alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        # extend blackout period & change environment
        update = {
            'environment': 'Development',
            'event': None,
            'tags': [],
            'endTime': '2099-12-31T23:59:59.999Z'
        }
        response = self.client.put('/blackout/' + blackout_id, data=json.dumps(update), headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['status'], 'ok')

        # check updates worked and didn't change anything else
        response = self.client.get('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['blackout']['environment'], 'Development')
        self.assertEqual(data['blackout']['resource'], 'node404')
        self.assertEqual(data['blackout']['service'], ['Network', 'Web'])
        self.assertEqual(data['blackout']['group'], None)
        self.assertEqual(data['blackout']['startTime'], '2019-01-01T00:00:00.000Z')
        self.assertEqual(data['blackout']['endTime'], '2099-12-31T23:59:59.999Z')

        # suppress alert
        response = self.client.post('/alert', data=json.dumps(self.dev_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

    def test_user_info(self):

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create new blackout
        response = self.client.post('/blackout', data=json.dumps({'environment': 'Production', 'service': [
                                    'Network'], 'text': 'administratively down'}), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['blackout']['user'], '*****@*****.**')
        self.assertIsInstance(DateTime.parse(data['blackout']['createTime']), datetime)
        self.assertEqual(data['blackout']['text'], 'administratively down')
コード例 #42
0
ファイル: test_routing.py プロジェクト: guardian/alerta
class RoutingTestCase(unittest.TestCase):

    def setUp(self):

        # create dummy routing rules
        self.dist = pkg_resources.Distribution(__file__, project_name='alerta-routing', version='0.1')
        s = 'rules = tests.test_routing:rules'
        self.entry_point = pkg_resources.EntryPoint.parse(s, dist=self.dist)
        self.dist._ep_map = {'alerta.routing': {'rules': self.entry_point}}
        pkg_resources.working_set.add(self.dist)

        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'ADMIN_USERS': ['*****@*****.**'],
            'ALLOWED_EMAIL_DOMAINS': ['alerta.io', 'foo.com', 'bar.com'],
            'PD_API_KEYS': {
                'Tyrell Corporation': 'tc-key',
                'Cyberdyne Systems': 'cs-key',
                'Weyland-Yutani': 'wy-key',
                'Zorin Enterprises': 'ze-key'
            },
            'SLACK_API_KEYS': {
                'Soylent Corporation': 'sc-key',
                'Omni Consumer Products': 'ocp-key',
                # 'Dolmansaxlil Shoe Corporation': 'dsc-key'  # use default key
            },
            'API_KEY': 'default-key'
        }

        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.tier1_tc_alert = {
            'event': 'foo1',
            'resource': 'foo1',
            'environment': 'Production',
            'service': ['Web'],
            'customer': 'Tyrell Corporation'  # tier 1
        }

        self.tier1_wy_alert = {
            'event': 'foo1',
            'resource': 'foo1',
            'environment': 'Production',
            'service': ['Web'],
            'customer': 'Weyland-Yutani'  # tier 1
        }

        self.tier2_sc_alert = {
            'event': 'bar1',
            'resource': 'bar1',
            'environment': 'Production',
            'service': ['Web'],
            'customer': 'Soylent Corporation'  # tier 2
        }

        self.tier2_ocp_alert = {
            'event': 'bar1',
            'resource': 'bar1',
            'environment': 'Production',
            'service': ['Web'],
            'customer': 'Omni Consumer Products'  # tier 2
        }

        self.tier2_dsc_alert = {
            'event': 'bar1',
            'resource': 'bar1',
            'environment': 'Production',
            'service': ['Web'],
            'customer': 'Dolmansaxlil Shoe Corporation'  # tier 2
        }

        self.tier3_it_alert = {
            'event': 'bar1',
            'resource': 'bar1',
            'environment': 'Production',
            'service': ['Web'],
            'customer': 'Initech'  # tier 3
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.api_key = ApiKey(
                user='******',
                scopes=[Scope.admin, Scope.read, Scope.write],
                text='admin-key'
            )
            self.api_key.create()

        self.headers = {
            'Authorization': 'Key %s' % self.api_key.key,
            'Content-type': 'application/json'
        }

        # create dummy plugins
        plugins.plugins['pagerduty'] = DummyPagerDutyPlugin()
        plugins.plugins['slack'] = DummySlackPlugin()
        plugins.plugins['config'] = DummyConfigPlugin()

    def tearDown(self):
        self.dist._ep_map.clear()

    def test_config(self):

        os.environ['BOOL_ENVVAR'] = 'yes'
        os.environ['INT_ENVVAR'] = '2020'
        os.environ['FLOAT_ENVVAR'] = '0.99'
        os.environ['LIST_ENVVAR'] = 'up,down,left,right'
        os.environ['STR_ENVVAR'] = 'a string with spaces'
        os.environ['DICT_ENVVAR'] = '{"key":"value", "key2": "value2" }'

        self.app.config.update({
            'BOOL_SETTING': True,
            'INT_SETTING': 1001,
            'FLOAT_SETTING': 7.07,
            'LIST_SETTING': ['a', 2, 'z'],
            'STR_SETTING': ' long string with spaces',
            'DICT_SETTING': {'a': 'dict', 'with': 'three', 'keys': 3},
        })

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.tier1_tc_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        self.assertEqual(data['alert']['attributes']['env']['bool'], True)
        self.assertEqual(data['alert']['attributes']['env']['int'], 2020)
        self.assertEqual(data['alert']['attributes']['env']['float'], 0.99)
        self.assertEqual(data['alert']['attributes']['env']['list'], ['up', 'down', 'left', 'right'])
        self.assertEqual(data['alert']['attributes']['env']['str'], 'a string with spaces')
        self.assertEqual(data['alert']['attributes']['env']['dict'], dict(key='value', key2='value2'))

        self.assertEqual(data['alert']['attributes']['setting']['bool'], True)
        self.assertEqual(data['alert']['attributes']['setting']['int'], 1001)
        self.assertEqual(data['alert']['attributes']['setting']['float'], 7.07)
        self.assertEqual(data['alert']['attributes']['setting']['list'], ['a', 2, 'z'])
        self.assertEqual(data['alert']['attributes']['setting']['str'], ' long string with spaces')
        self.assertEqual(data['alert']['attributes']['setting']['dict'], {'a': 'dict', 'with': 'three', 'keys': 3})

        self.assertEqual(data['alert']['attributes']['default']['bool'], False)
        self.assertEqual(data['alert']['attributes']['default']['int'], 999)
        self.assertEqual(data['alert']['attributes']['default']['float'], 5.55)
        self.assertEqual(data['alert']['attributes']['default']['list'], ['j', 'k'])
        self.assertEqual(data['alert']['attributes']['default']['str'], 'setting')
        self.assertEqual(data['alert']['attributes']['default']['dict'], dict(baz='quux'))

    def test_config_precedence(self):

        os.environ['var1'] = 'env1'
        self.app.config.update({
            'var1': 'setting1',
            'var2': 'setting2'
        })

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.tier1_tc_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        self.assertEqual(data['alert']['attributes']['precedence']['var1'], 'env1')
        self.assertEqual(data['alert']['attributes']['precedence']['var2'], 'setting2')
        self.assertEqual(data['alert']['attributes']['precedence']['var3'], 'default3')

    def test_routing(self):

        # create alert (pagerduty key for Tyrell Corporation)
        response = self.client.post('/alert', data=json.dumps(self.tier1_tc_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['attributes']['NOTIFY'], 'pagerduty')
        self.assertEqual(data['alert']['attributes']['API_KEY'], 'tc-key')

        # create alert (pagerduty key for Weyland-Yutani)
        response = self.client.post('/alert', data=json.dumps(self.tier1_wy_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['attributes']['NOTIFY'], 'pagerduty')
        self.assertEqual(data['alert']['attributes']['API_KEY'], 'wy-key')

        # create alert (slack key for customer Soylent Corporation)
        response = self.client.post('/alert', data=json.dumps(self.tier2_sc_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['attributes']['NOTIFY'], 'slack')
        self.assertEqual(data['alert']['attributes']['API_KEY'], 'sc-key')

        # create alert (slack key for customer Omni Consumer Products)
        response = self.client.post('/alert', data=json.dumps(self.tier2_ocp_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['attributes']['NOTIFY'], 'slack')
        self.assertEqual(data['alert']['attributes']['API_KEY'], 'ocp-key')

        # create alert (use default slack key for Dolmansaxlil Shoe Corporation)
        response = self.client.post('/alert', data=json.dumps(self.tier2_dsc_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['attributes']['NOTIFY'], 'slack')
        self.assertEqual(data['alert']['attributes']['API_KEY'], 'default-key')

        # create alert (no key)
        response = self.client.post('/alert', data=json.dumps(self.tier3_it_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertNotIn('NOTIFY', data['alert']['attributes'])
        self.assertNotIn('API_KEY', data['alert']['attributes'])
コード例 #43
0
ファイル: decorators.py プロジェクト: guardian/alerta
        def wrapped(*args, **kwargs):

            # API Key (Authorization: Key <key>)
            if 'Authorization' in request.headers:
                auth_header = request.headers['Authorization']
                m = re.match(r'Key (\S+)', auth_header)
                key = m.group(1) if m else None
            # API Key (X-API-Key: <key>)
            elif 'X-API-Key' in request.headers:
                key = request.headers['X-API-Key']
            # API Key (/foo?api-key=<key>)
            else:
                key = request.args.get('api-key', None)

            if key:
                key_info = ApiKey.verify_key(key)
                if not key_info:
                    raise ApiError("API key parameter '%s' is invalid" % key, 401)
                g.user_id = None
                g.login = key_info.user
                g.customers = [key_info.customer] if key_info.customer else []
                g.scopes = key_info.scopes  # type: List[Scope]

                if not Permission.is_in_scope(scope, have_scopes=g.scopes):
                    raise ApiError('Missing required scope: %s' % scope.value, 403)
                else:
                    return f(*args, **kwargs)

            # Bearer Token
            auth_header = request.headers.get('Authorization', '')
            m = re.match(r'Bearer (\S+)', auth_header)
            token = m.group(1) if m else None

            if token:
                try:
                    jwt = Jwt.parse(token)
                except DecodeError:
                    raise ApiError('Token is invalid', 401)
                except ExpiredSignature:
                    raise ApiError('Token has expired', 401)
                except InvalidAudience:
                    raise ApiError('Invalid audience', 401)
                g.user_id = jwt.subject
                g.login = jwt.preferred_username
                g.customers = jwt.customers
                g.scopes = jwt.scopes  # type: List[Scope]

                if not Permission.is_in_scope(scope, have_scopes=g.scopes):
                    raise ApiError('Missing required scope: %s' % scope.value, 403)
                else:
                    return f(*args, **kwargs)

            # Basic Auth
            auth_header = request.headers.get('Authorization', '')
            m = re.match(r'Basic (\S+)', auth_header)
            credentials = m.group(1) if m else None

            if credentials:
                try:
                    username, password = base64.b64decode(credentials).decode('utf-8').split(':')
                except Exception as e:
                    raise BasicAuthError('Invalid credentials', 400, errors=[str(e)])

                user = User.check_credentials(username, password)
                if not user:
                    raise BasicAuthError('Authorization required', 401)

                if current_app.config['EMAIL_VERIFICATION'] and not user.email_verified:
                    raise BasicAuthError('email not verified', 401)

                if not_authorized('ALLOWED_EMAIL_DOMAINS', groups=[user.domain]):
                    raise BasicAuthError('Unauthorized domain', 403)

                g.user_id = user.id
                g.login = user.email
                g.customers = get_customers(user.email, groups=[user.domain])
                g.scopes = Permission.lookup(user.email, roles=user.roles)  # type: List[Scope]

                if not Permission.is_in_scope(scope, have_scopes=g.scopes):
                    raise BasicAuthError('Missing required scope: %s' % scope.value, 403)
                else:
                    return f(*args, **kwargs)

            if not current_app.config['AUTH_REQUIRED']:
                g.user_id = None
                g.login = None
                g.customers = []
                g.scopes = []  # type: List[Scope]
                return f(*args, **kwargs)

            # Google App Engine Cron Service
            if request.headers.get('X-Appengine-Cron', False) and request.headers.get('X-Forwarded-For', '') == '0.1.0.1':
                return f(*args, **kwargs)

            raise ApiError('Missing authorization API Key or Bearer Token', 401)
コード例 #44
0
ファイル: test_customers.py プロジェクト: guardian/alerta
class CustomersTestCase(unittest.TestCase):

    def setUp(self):

        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'ADMIN_USERS': ['*****@*****.**'],
            'ALLOWED_EMAIL_DOMAINS': ['alerta.io', 'foo.com', 'bar.com']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.foo_alert = {
            'event': 'foo1',
            'resource': 'foo1',
            'environment': 'Production',
            'service': ['Web']
        }

        self.bar_alert = {
            'event': 'bar1',
            'resource': 'bar1',
            'environment': 'Production',
            'service': ['Web']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.api_key = ApiKey(
                user='******',
                scopes=[Scope.admin, Scope.read, Scope.write],
                text='admin-key'
            )
            self.api_key.create()

        self.admin_headers = {
            'Authorization': 'Key %s' % self.api_key.key,
            'Content-type': 'application/json'
        }

    def tearDown(self):
        db.destroy()

    def test_customers(self):

        # add customer mappings
        payload = {
            'customer': 'Bar Corp',
            'match': 'bar.com'
        }
        response = self.client.post('/customer', data=json.dumps(payload),
                                    content_type='application/json', headers=self.admin_headers)
        self.assertEqual(response.status_code, 201)

        payload = {
            'customer': 'Foo Bar Corp',
            'match': '*****@*****.**'
        }
        response = self.client.post('/customer', data=json.dumps(payload),
                                    content_type='application/json', headers=self.admin_headers)
        self.assertEqual(response.status_code, 201)

        response = self.client.get('/customers', headers=self.admin_headers)
        self.assertEqual(response.status_code, 200)

        # create users
        payload = {
            'name': 'Bar User',
            'email': '*****@*****.**',
            'password': '******',
            'text': ''
        }

        response = self.client.post('/auth/signup', data=json.dumps(payload),
                                    content_type='application/json', headers=self.admin_headers)
        self.assertEqual(response.status_code, 200, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data, 'Failed to create user')

        self.bar_bearer_headers = {
            'Authorization': 'Bearer %s' % data['token'],
            'Content-type': 'application/json'
        }

        payload = {
            'name': 'Foo Bar User',
            'email': '*****@*****.**',
            'password': '******',
            'text': ''
        }

        response = self.client.post('/auth/signup', data=json.dumps(payload),
                                    content_type='application/json', headers=self.admin_headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data, 'Failed to create user')

        self.foobar_bearer_headers = {
            'Authorization': 'Bearer %s' % data['token'],
            'Content-type': 'application/json'
        }

        # create API key for [email protected]
        payload = {
            'user': '******',
            'scopes': ['read', 'write'],
            'text': ''
        }

        response = self.client.post('/key', data=json.dumps(payload),
                                    content_type='application/json', headers=self.bar_bearer_headers)
        self.assertEqual(response.status_code, 201, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data['key'], 'Failed to create read-write key')

        self.bar_api_key_headers = {
            'Authorization': 'Key %s' % data['key'],
            'Content-type': 'application/json'
        }

        # create API keys for [email protected]
        payload = {
            'user': '******',
            'scopes': ['read', 'write'],
            'text': '',
            'customer': 'Foo Bar Corp'
        }

        response = self.client.post('/key', data=json.dumps(payload),
                                    content_type='application/json', headers=self.foobar_bearer_headers)
        self.assertEqual(response.status_code, 201, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data['key'], 'Failed to create read-write key')

        self.foobar_api_key_headers = {
            'Authorization': 'Key %s' % data['key'],
            'Content-type': 'application/json'
        }

        payload = {
            'user': '******',
            'scopes': ['read', 'write'],
            'text': '',
            'customer': 'Bar Corp'
        }

        response = self.client.post('/key', data=json.dumps(payload),
                                    content_type='application/json', headers=self.foobar_bearer_headers)
        self.assertEqual(response.status_code, 201, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data['key'], 'Failed to create read-write key')

        self.foobar_bar_only_api_key_headers = {
            'Authorization': 'Key %s' % data['key'],
            'Content-type': 'application/json'
        }

        # get list of customers for users
        response = self.client.get('/customers', headers=self.bar_api_key_headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual([c['customer'] for c in data['customers']], ['Bar Corp'])

        response = self.client.get('/customers', headers=self.foobar_api_key_headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual([c['customer'] for c in data['customers']], ['Foo Bar Corp'])

        # create alerts using API keys
        response = self.client.post('/alert', data=json.dumps(self.foo_alert), headers=self.bar_api_key_headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['customer'], 'Bar Corp')

        response = self.client.post('/alert', data=json.dumps(self.foo_alert), headers=self.foobar_api_key_headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['customer'], 'Foo Bar Corp')

        response = self.client.post('/alert', data=json.dumps(self.foo_alert),
                                    headers=self.foobar_bar_only_api_key_headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['customer'], 'Bar Corp')

        response = self.client.post('/alert', data=json.dumps(self.foo_alert),
                                    headers=self.foobar_bar_only_api_key_headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['customer'], 'Bar Corp')

        # create alerts using Bearer tokens
        response = self.client.post('/alert', data=json.dumps(self.foo_alert), headers=self.bar_bearer_headers)
        self.assertEqual(response.status_code, 201, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['customer'], 'Bar Corp')

        self.foo_alert['customer'] = 'Foo Bar Corp'
        response = self.client.post('/alert', data=json.dumps(self.foo_alert), headers=self.foobar_bearer_headers)
        self.assertEqual(response.status_code, 201, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['customer'], 'Foo Bar Corp')

    def test_blackouts(self):

        # add customer mappings
        payload = {
            'customer': 'Foo Corp',
            'match': 'foo.com'
        }
        response = self.client.post('/customer', data=json.dumps(payload),
                                    content_type='application/json', headers=self.admin_headers)
        self.assertEqual(response.status_code, 201)

        payload = {
            'customer': 'Bar Corp',
            'match': 'bar.com'
        }
        response = self.client.post('/customer', data=json.dumps(payload),
                                    content_type='application/json', headers=self.admin_headers)
        self.assertEqual(response.status_code, 201)

        # create users
        payload = {
            'name': 'Foo User',
            'email': '*****@*****.**',
            'password': '******',
            'text': ''
        }

        response = self.client.post('/auth/signup', data=json.dumps(payload),
                                    content_type='application/json', headers=self.admin_headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data, 'Failed to create user')

        foo_user_headers = {
            'Authorization': 'Bearer %s' % data['token'],
            'Content-type': 'application/json'
        }

        payload = {
            'name': 'Bar User',
            'email': '*****@*****.**',
            'password': '******',
            'text': ''
        }

        response = self.client.post('/auth/signup', data=json.dumps(payload),
                                    content_type='application/json', headers=self.admin_headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data, 'Failed to create user')

        bar_user_headers = {
            'Authorization': 'Bearer %s' % data['token'],
            'Content-type': 'application/json'
        }

        # create customer blackout by foo user
        response = self.client.post(
            '/blackout', data=json.dumps({'environment': 'Production'}), headers=foo_user_headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # new alert by foo user should be suppressed
        response = self.client.post('/alert', data=json.dumps(self.foo_alert), headers=foo_user_headers)
        self.assertEqual(response.status_code, 202)

        # new alert by bar user should not be suppressed
        response = self.client.post('/alert', data=json.dumps(self.bar_alert), headers=bar_user_headers)
        self.assertEqual(response.status_code, 201)

        # delete blackout by id
        response = self.client.delete('/blackout/' + blackout_id, headers=self.admin_headers)
        self.assertEqual(response.status_code, 200)

        # create global blackout by admin user
        response = self.client.post(
            '/blackout', data=json.dumps({'environment': 'Production'}), headers=self.admin_headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # new alert by foo user should be suppressed
        response = self.client.post('/alert', data=json.dumps(self.foo_alert), headers=foo_user_headers)
        self.assertEqual(response.status_code, 202)

        # new alert by bar user should be suppressed
        response = self.client.post('/alert', data=json.dumps(self.bar_alert), headers=bar_user_headers)
        self.assertEqual(response.status_code, 202)

        # delete blackout by id
        response = self.client.delete('/blackout/' + blackout_id, headers=self.admin_headers)
        self.assertEqual(response.status_code, 200)

    def test_assign_customer(self):

        with self.app.test_request_context('/'):
            self.app.preprocess_request()

            # nothing wanted, assign one
            g.customers = ['Customer1']
            g.scopes = []
            self.assertEqual(assign_customer(wanted=None), 'Customer1')

            # nothing wanted, but too many, throw error
            g.customers = ['Customer1', 'Customer2']
            g.scopes = []
            with self.assertRaises(ApiError) as e:
                assign_customer(wanted=None)
            exc = e.exception
            self.assertEqual(str(exc), 'must define customer as more than one possibility')

            # customer wanted, matches so allow
            g.customers = ['Customer1']
            g.scopes = []
            self.assertEqual(assign_customer(wanted='Customer1'), 'Customer1')

            # customer wanted, in list so allow
            g.customers = ['Customer1', 'Customer2']
            g.scopes = []
            self.assertEqual(assign_customer(wanted='Customer2'), 'Customer2')

            # customer wanted not in list, throw exception
            g.customers = ['Customer1', 'Customer2']
            g.scopes = []
            with self.assertRaises(ApiError) as e:
                assign_customer(wanted='Customer3')
            exc = e.exception
            self.assertEqual(str(exc), "not allowed to set customer to 'Customer3'")

            # no customers, admin scope so allow
            g.customers = []
            g.scopes = ['admin']
            self.assertEqual(assign_customer(wanted=None), None)
            self.assertEqual(assign_customer(wanted='Customer1'), 'Customer1')

            g.customers = ['Customer1', 'Customer2']
            g.scopes = ['admin']
            with self.assertRaises(ApiError) as e:
                assign_customer(wanted=None)
            exc = e.exception
            self.assertEqual(str(exc), 'must define customer as more than one possibility')
            self.assertEqual(assign_customer(wanted='Customer3'), 'Customer3')

            # wrong scope
            g.customers = ['Customer1']
            g.scopes = ['read:keys', 'write:keys']
            with self.assertRaises(ApiError) as e:
                assign_customer(wanted='Customer2', permission=Scope.admin_keys)
            exc = e.exception
            self.assertEqual(str(exc), "not allowed to set customer to 'Customer2'")

            # right scope
            g.customers = ['Customer1']
            g.scopes = ['admin:keys', 'read:keys', 'write:keys']
            self.assertEqual(assign_customer(wanted='Customer2', permission=Scope.admin_keys), 'Customer2')

    def test_invalid_customer(self):

        self.foo_alert['customer'] = ''

        response = self.client.post('/alert', data=json.dumps(self.foo_alert), headers=self.admin_headers)
        self.assertEqual(response.status_code, 400)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['message'], 'customer must not be an empty string')

    def test_edit_customer(self):

        # add customer mappings
        payload = {
            'customer': 'Foo Corp',
            'match': 'foo.com'
        }
        response = self.client.post('/customer', data=json.dumps(payload),
                                    content_type='application/json', headers=self.admin_headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        customer_id = data['id']

        # change customer name
        update = {
            'customer': 'Bar Corp'
        }
        response = self.client.put('/customer/' + customer_id, data=json.dumps(update), headers=self.admin_headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['status'], 'ok')

        # check updates worked and didn't change anything else
        response = self.client.get('/customer/' + customer_id, headers=self.admin_headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['customer']['customer'], 'Bar Corp')
        self.assertEqual(data['customer']['match'], 'foo.com')

        # change customer lookup
        update = {
            'match': 'bar.com'
        }
        response = self.client.put('/customer/' + customer_id, data=json.dumps(update), headers=self.admin_headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['status'], 'ok')

        # check updates worked and didn't change anything else
        response = self.client.get('/customer/' + customer_id, headers=self.admin_headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['customer']['customer'], 'Bar Corp')
        self.assertEqual(data['customer']['match'], 'bar.com')
コード例 #45
0
ファイル: test_blackouts.py プロジェクト: 3IWOH/alerta
class BlackoutsTestCase(unittest.TestCase):

    def setUp(self):

        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.alert = {
            'event': 'node_marginal',
            'resource': 'node404',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'warning',
            'correlate': ['node_down', 'node_marginal', 'node_up']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.admin_api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='demo-key'
            )
            self.customer_api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='demo-key',
                customer='Foo'
            )
            self.admin_api_key.create()
            self.customer_api_key.create()

    def tearDown(self):
        db.destroy()

    def test_suppress_alerts(self):

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout
        response = self.client.post('/blackout', data=json.dumps({"environment": "Production"}), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # suppress alert
        response = self.client.post('/alert', data=json.dumps(self.alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        self.headers = {
            'Authorization': 'Key %s' % self.customer_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)


        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)
コード例 #46
0
class AuthTestCase(unittest.TestCase):
    def setUp(self):

        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'ADMIN_USERS': ['*****@*****.**'],
            'ALLOWED_EMAIL_DOMAINS': ['bonaparte.fr', 'debeauharnais.fr']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.alert = {
            'event': 'Foo',
            'resource': 'Bar',
            'environment': 'Production',
            'service': ['Quux']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.api_key = ApiKey(user='******',
                                  scopes=['admin', 'read', 'write'],
                                  text='demo-key')
            self.api_key.create()

        self.headers = {
            'Authorization': 'Key %s' % self.api_key.key,
            'Content-type': 'application/json'
        }

    def tearDown(self):
        db.destroy()

    def test_401_error(self):

        response = self.client.get('/alerts')
        self.assertEqual(response.status_code, 401)

    def test_readwrite_key(self):

        payload = {'user': '******', 'type': 'read-write'}

        response = self.client.post('/key',
                                    data=json.dumps(payload),
                                    content_type='application/json',
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data['key'], 'Failed to create read-write key')

        rw_api_key = data['key']

        response = self.client.post(
            '/alert',
            data=json.dumps(self.alert),
            content_type='application/json',
            headers={'Authorization': 'Key ' + rw_api_key})
        self.assertEqual(response.status_code, 201)

        response = self.client.get(
            '/alerts', headers={'Authorization': 'Key ' + rw_api_key})
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIn('total', data)

        response = self.client.delete('/key/' + rw_api_key,
                                      headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_readonly_key(self):

        payload = {'user': '******', 'type': 'read-only'}

        response = self.client.post('/key',
                                    data=json.dumps(payload),
                                    content_type='application/json',
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data['key'], 'Failed to create read-only key')

        ro_api_key = data['key']

        response = self.client.post(
            '/alert',
            data=json.dumps(self.alert),
            content_type='application/json',
            headers={'Authorization': 'Key ' + ro_api_key})
        self.assertEqual(response.status_code, 403)

        response = self.client.get(
            '/alerts', headers={'Authorization': 'Key ' + ro_api_key})
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIn('total', data)

        response = self.client.delete('/key/' + ro_api_key,
                                      headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_users(self):

        # add customer mapping
        payload = {'customer': 'Bonaparte Industries', 'match': 'bonaparte.fr'}
        response = self.client.post('/customer',
                                    data=json.dumps(payload),
                                    content_type='application/json',
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)

        payload = {
            'name': 'Napoleon Bonaparte',
            'email': '*****@*****.**',
            'password': '******',
            'text': 'added to circle of trust'
        }

        # create user
        response = self.client.post('/auth/signup',
                                    data=json.dumps(payload),
                                    content_type='application/json',
                                    headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data, 'Failed to create user')

        with self.app.test_request_context():
            jwt = Jwt.parse(data['token'])
        user_id = jwt.subject

        # get user
        response = self.client.get('/users', headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIn(user_id, [u['id'] for u in data['users']])

        # create duplicate user
        response = self.client.post('/auth/signup',
                                    data=json.dumps(payload),
                                    content_type='application/json',
                                    headers=self.headers)
        self.assertEqual(response.status_code, 409)

        # delete user
        response = self.client.delete('/user/' + user_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_login(self):

        name = 'Josephine de Beauharnais'

        payload = {
            'name': name,
            'email': '*****@*****.**',
            'password': '******',
            'text': 'Test login'
        }

        # sign-up user with no customer mapping
        response = self.client.post('/auth/signup',
                                    data=json.dumps(payload),
                                    content_type='application/json')
        self.assertEqual(response.status_code, 403)

        # add customer mapping
        payload = {
            'customer': 'Bonaparte Industries',
            'match': 'debeauharnais.fr'
        }
        response = self.client.post('/customer',
                                    data=json.dumps(payload),
                                    content_type='application/json',
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        customer_id = data['id']

        payload = {'email': '*****@*****.**', 'password': '******'}

        # login now that customer mapping exists
        response = self.client.post('/auth/login',
                                    data=json.dumps(payload),
                                    content_type='application/json')
        # self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIn('token', data)

        token = data['token']

        headers = {
            'Authorization': 'Bearer ' + token,
            'Content-type': 'application/json'
        }

        # create a customer demo key
        payload = {'user': '******', 'type': 'read-only'}

        response = self.client.post('/key',
                                    data=json.dumps(payload),
                                    content_type='application/json',
                                    headers=headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data['key'], 'Failed to create read-only key')

        customer_api_key = data['key']

        response = self.client.get(
            '/alerts', headers={'Authorization': 'Key ' + customer_api_key})
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIn('total', data)

        response = self.client.delete(
            '/key/' + customer_api_key,
            headers={'Authorization': 'Key ' + customer_api_key})
        self.assertEqual(response.status_code, 403)

        response = self.client.delete('/key/' + customer_api_key,
                                      headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # get user
        response = self.client.get('/users', headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIn(name, [u['name'] for u in data['users']])

        user_id = [u['id'] for u in data['users'] if u['name'] == name][0]

        # delete user
        response = self.client.delete('/user/' + user_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # delete customer mapping
        response = self.client.delete('/customer/' + customer_id,
                                      headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_x_api_key(self):

        self.headers = {
            'X-API-Key': self.api_key.key,
            'Content-type': 'application/json'
        }

        payload = {'user': '******', 'type': 'read-write'}

        response = self.client.post('/key',
                                    data=json.dumps(payload),
                                    content_type='application/json',
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data['key'], 'Failed to create read-write key')

        rw_api_key = data['key']

        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    content_type='application/json',
                                    headers={'X-API-Key': rw_api_key})
        self.assertEqual(response.status_code, 201)

        response = self.client.get('/alerts',
                                   headers={'X-API-Key': rw_api_key})
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIn('total', data)

        response = self.client.delete('/key/' + rw_api_key,
                                      headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_basic_auth(self):

        # add customer mapping
        payload = {'customer': 'Bonaparte Industries', 'match': 'bonaparte.fr'}
        response = self.client.post('/customer',
                                    data=json.dumps(payload),
                                    content_type='application/json',
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)

        payload = {
            'name': 'Napoleon Bonaparte',
            'email': '*****@*****.**',
            'password': '******',
            'text': 'added to circle of trust'
        }

        # create user
        response = self.client.post('/auth/signup',
                                    data=json.dumps(payload),
                                    content_type='application/json',
                                    headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # authenticate using basic auth
        headers = {
            'Authorization':
            'Basic ' + base64.b64encode(
                '[email protected]:blackforest'.encode('utf-8')).decode(),
            'Content-type':
            'application/json'
        }

        response = self.client.get('/users', headers=headers)
        self.assertEqual(response.status_code, 403)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['message'],
                         'Missing required scope: admin:users')

        response = self.client.get('/alerts', headers=headers)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['status'], 'ok', response.data)
コード例 #47
0
ファイル: test_blackouts.py プロジェクト: guardian/alerta
    def setUp(self):
        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'PLUGINS': ['reject']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.prod_alert = {
            'resource': 'node404',
            'event': 'node_down',
            'environment': 'Production',
            'severity': 'major',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'service': ['Core', 'Web', 'Network'],
            'group': 'Network',
            'tags': ['level=20', 'switch:off']
        }

        self.dev_alert = {
            'resource': 'node404',
            'event': 'node_marginal',
            'environment': 'Development',
            'severity': 'warning',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'service': ['Core', 'Web', 'Network'],
            'group': 'Network',
            'tags': ['level=20', 'switch:off']
        }

        self.fatal_alert = {
            'event': 'node_down',
            'resource': 'net01',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'critical',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'tags': ['foo'],
            'attributes': {'foo': 'abc def', 'bar': 1234, 'baz': False},
        }
        self.critical_alert = {
            'event': 'node_marginal',
            'resource': 'net02',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'critical',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'timeout': 30
        }
        self.major_alert = {
            'event': 'node_marginal',
            'resource': 'net03',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'major',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'timeout': 40
        }
        self.normal_alert = {
            'event': 'node_up',
            'resource': 'net03',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'normal',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'timeout': 100
        }
        self.minor_alert = {
            'event': 'node_marginal',
            'resource': 'net04',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'minor',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'timeout': 40
        }
        self.ok_alert = {
            'event': 'node_up',
            'resource': 'net04',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'ok',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'timeout': 100
        }
        self.warn_alert = {
            'event': 'node_marginal',
            'resource': 'net05',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'warning',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'timeout': 50
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.admin_api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='demo-key'
            )
            self.customer_api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='demo-key',
                customer='Foo'
            )
            self.admin_api_key.create()
            self.customer_api_key.create()
コード例 #48
0
class BlackoutsTestCase(unittest.TestCase):
    def setUp(self):
        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'PLUGINS': ['reject']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.alert = {
            'resource': 'node404',
            'event': 'node_marginal',
            'environment': 'Production',
            'severity': 'warning',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'service': ['Core', 'Web', 'Network'],
            'group': 'Network',
            'tags': ['level=20', 'switch:off']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.admin_api_key = ApiKey(user='******',
                                        scopes=['admin', 'read', 'write'],
                                        text='demo-key')
            self.customer_api_key = ApiKey(user='******',
                                           scopes=['admin', 'read', 'write'],
                                           text='demo-key',
                                           customer='Foo')
            self.admin_api_key.create()
            self.customer_api_key.create()

    def tearDown(self):
        db.destroy()

    def test_suppress_blackout(self):

        plugins.plugins['blackout'] = SuppressionBlackout()

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout
        response = self.client.post('/blackout',
                                    data=json.dumps(
                                        {'environment': 'Production'}),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # suppress alert
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 202)

        self.headers = {
            'Authorization': 'Key %s' % self.customer_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 202)

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        response = self.client.delete('/blackout/' + blackout_id,
                                      headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_notification_blackout(self):

        plugins.plugins['blackout'] = NotificationBlackout()

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create new blackout
        blackout = {'environment': 'Production', 'service': ['Core']}
        response = self.client.post('/blackout',
                                    data=json.dumps(blackout),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # new alert should be status=blackout
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # duplicate alert should be status=blackout
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # duplicate alert should be status=blackout (again)
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # increase severity alert should be status=blackout
        self.alert['severity'] = 'major'
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # increase severity alert should be status=blackout (again)
        self.alert['severity'] = 'critical'
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # decrease severity alert should be status=blackout
        self.alert['severity'] = 'minor'
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # decrease severity alert should be status=blackout (again)
        self.alert['severity'] = 'warning'
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # normal severity alert should be status=closed
        self.alert['severity'] = 'ok'
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'closed')

        # normal severity alert should be status=closed (again)
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'closed')

        # non-normal severity alert should be status=blackout (again)
        self.alert['severity'] = 'major'
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # decrease severity alert should be status=blackout
        self.alert['severity'] = 'minor'
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id,
                                      headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # non-normal severity alert should be status=open
        self.alert['severity'] = 'minor'
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'open')

        # normal severity alert should be status=closed
        self.alert['severity'] = 'ok'
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'closed')

    def test_combination_blackout(self):

        plugins.plugins['blackout'] = SuppressionBlackout()

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout (only for services on a particular host)
        blackout = {
            'environment': 'Production',
            'resource': 'node404',
            'service': ['Network', 'Web']
        }
        response = self.client.post('/blackout',
                                    data=json.dumps(blackout),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # suppress alert
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 202)

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id,
                                      headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # create alert
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout (only for groups of alerts with particular tags)
        blackout = {
            'environment': 'Production',
            'group': 'Network',
            'tags': ['system:web01', 'switch:off']
        }
        response = self.client.post('/blackout',
                                    data=json.dumps(blackout),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # do not suppress alert
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)

        self.alert['tags'].append('system:web01')

        # suppress alert
        response = self.client.post('/alert',
                                    data=json.dumps(self.alert),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 202)

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id,
                                      headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_user_info(self):

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create new blackout
        response = self.client.post('/blackout',
                                    data=json.dumps({
                                        'environment':
                                        'Production',
                                        'service': ['Network'],
                                        'text':
                                        'administratively down'
                                    }),
                                    headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['blackout']['user'], '*****@*****.**')
        self.assertIsInstance(DateTime.parse(data['blackout']['createTime']),
                              datetime)
        self.assertEqual(data['blackout']['text'], 'administratively down')
コード例 #49
0
ファイル: test_blackouts.py プロジェクト: guardian/alerta
class BlackoutsTestCase(unittest.TestCase):

    def setUp(self):
        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'PLUGINS': ['reject']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.prod_alert = {
            'resource': 'node404',
            'event': 'node_down',
            'environment': 'Production',
            'severity': 'major',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'service': ['Core', 'Web', 'Network'],
            'group': 'Network',
            'tags': ['level=20', 'switch:off']
        }

        self.dev_alert = {
            'resource': 'node404',
            'event': 'node_marginal',
            'environment': 'Development',
            'severity': 'warning',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'service': ['Core', 'Web', 'Network'],
            'group': 'Network',
            'tags': ['level=20', 'switch:off']
        }

        self.fatal_alert = {
            'event': 'node_down',
            'resource': 'net01',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'critical',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'tags': ['foo'],
            'attributes': {'foo': 'abc def', 'bar': 1234, 'baz': False},
        }
        self.critical_alert = {
            'event': 'node_marginal',
            'resource': 'net02',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'critical',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'timeout': 30
        }
        self.major_alert = {
            'event': 'node_marginal',
            'resource': 'net03',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'major',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'timeout': 40
        }
        self.normal_alert = {
            'event': 'node_up',
            'resource': 'net03',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'normal',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'timeout': 100
        }
        self.minor_alert = {
            'event': 'node_marginal',
            'resource': 'net04',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'minor',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'timeout': 40
        }
        self.ok_alert = {
            'event': 'node_up',
            'resource': 'net04',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'ok',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'timeout': 100
        }
        self.warn_alert = {
            'event': 'node_marginal',
            'resource': 'net05',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'warning',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'timeout': 50
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.admin_api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='demo-key'
            )
            self.customer_api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='demo-key',
                customer='Foo'
            )
            self.admin_api_key.create()
            self.customer_api_key.create()

    def tearDown(self):
        db.destroy()

    def test_suppress_blackout(self):

        os.environ['NOTIFICATION_BLACKOUT'] = 'False'
        plugins.plugins['blackout'] = Blackout()

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout
        response = self.client.post('/blackout', data=json.dumps({'environment': 'Production'}), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # suppress alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        self.headers = {
            'Authorization': 'Key %s' % self.customer_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_notification_blackout(self):

        os.environ['NOTIFICATION_BLACKOUT'] = 'True'
        plugins.plugins['blackout'] = Blackout()

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create new blackout
        blackout = {
            'environment': 'Production',
            'service': ['Core']
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # new alert should be status=blackout
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # duplicate alert should be status=blackout
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # duplicate alert should be status=blackout (again)
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # increase severity alert should be status=blackout
        self.prod_alert['severity'] = 'major'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # increase severity alert should be status=blackout (again)
        self.prod_alert['severity'] = 'critical'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # decrease severity alert should be status=blackout
        self.prod_alert['severity'] = 'minor'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # decrease severity alert should be status=blackout (again)
        self.prod_alert['severity'] = 'warning'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # normal severity alert should be status=closed
        self.prod_alert['severity'] = 'ok'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'closed')

        # normal severity alert should be status=closed (again)
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'closed')

        # non-normal severity alert should be status=blackout (again)
        self.prod_alert['severity'] = 'major'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # decrease severity alert should be status=blackout
        self.prod_alert['severity'] = 'minor'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'blackout')

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # non-normal severity alert should be status=open
        self.prod_alert['severity'] = 'minor'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'open')

        # normal severity alert should be status=closed
        self.prod_alert['severity'] = 'ok'
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'closed')

    def test_previous_status(self):

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create an alert => critical, open
        response = self.client.post('/alert', data=json.dumps(self.fatal_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'critical')
        self.assertEqual(data['alert']['status'], 'open')

        alert_id_1 = data['id']

        # ack the alert => critical, ack
        response = self.client.put('/alert/' + alert_id_1 + '/action',
                                   data=json.dumps({'action': 'ack'}), headers=self.headers)
        self.assertEqual(response.status_code, 200)

        response = self.client.get('/alert/' + alert_id_1, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'critical')
        self.assertEqual(data['alert']['status'], 'ack')

        # create 2nd alert => critical, open
        response = self.client.post('/alert', data=json.dumps(self.critical_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'critical')
        self.assertEqual(data['alert']['status'], 'open')

        alert_id_2 = data['id']

        # shelve 2nd alert => critical, shelved
        response = self.client.put('/alert/' + alert_id_2 + '/action',
                                   data=json.dumps({'action': 'shelve'}), headers=self.headers)
        self.assertEqual(response.status_code, 200)

        response = self.client.get('/alert/' + alert_id_2, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'critical')
        self.assertEqual(data['alert']['status'], 'shelved')

        # create a blackout
        os.environ['NOTIFICATION_BLACKOUT'] = 'yes'
        plugins.plugins['blackout'] = Blackout()

        blackout = {
            'environment': 'Production',
            'service': ['Network']
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # update 1st alert => critical, blackout
        response = self.client.post('/alert', data=json.dumps(self.fatal_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'critical')
        self.assertEqual(data['alert']['status'], 'blackout')

        # create 3rd alert => major, blackout
        response = self.client.post('/alert', data=json.dumps(self.major_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'major')
        self.assertEqual(data['alert']['status'], 'blackout')

        # clear 3rd alert => normal, closed
        response = self.client.post('/alert', data=json.dumps(self.normal_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'normal')
        self.assertEqual(data['alert']['status'], 'closed')

        # create 4th alert => minor, blackout
        response = self.client.post('/alert', data=json.dumps(self.minor_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'minor')
        self.assertEqual(data['alert']['status'], 'blackout')

        # clear 4th alert => ok, closed
        response = self.client.post('/alert', data=json.dumps(self.ok_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'ok')
        self.assertEqual(data['alert']['status'], 'closed')

        # create 5th alert => warning, blackout
        response = self.client.post('/alert', data=json.dumps(self.warn_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'warning')
        self.assertEqual(data['alert']['status'], 'blackout')

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # update 1st alert => critical, ack
        response = self.client.post('/alert', data=json.dumps(self.fatal_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'critical')
        self.assertEqual(data['alert']['status'], 'ack')

        # update 2nd alert => critical, shelved
        response = self.client.post('/alert', data=json.dumps(self.critical_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'critical')
        self.assertEqual(data['alert']['status'], 'shelved')

        # update 3rd alert => normal, closed
        response = self.client.post('/alert', data=json.dumps(self.normal_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'normal')
        self.assertEqual(data['alert']['status'], 'closed')

        # update 4th alert => minor, open
        response = self.client.post('/alert', data=json.dumps(self.minor_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'minor')
        self.assertEqual(data['alert']['status'], 'open')

        # update 5th alert => warning, open
        response = self.client.post('/alert', data=json.dumps(self.warn_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['severity'], 'warning')
        self.assertEqual(data['alert']['status'], 'open')

    def test_whole_environment_blackout(self):

        os.environ['NOTIFICATION_BLACKOUT'] = 'False'
        plugins.plugins['blackout'] = Blackout()

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.dev_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout (for whole development environment)
        blackout = {
            'environment': 'Development'
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # do not suppress production alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # suppress development alert
        response = self.client.post('/alert', data=json.dumps(self.dev_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # do not suppress any alerts
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        response = self.client.post('/alert', data=json.dumps(self.dev_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

    def test_combination_blackout(self):

        os.environ['NOTIFICATION_BLACKOUT'] = 'False'
        plugins.plugins['blackout'] = Blackout()

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout (only for services on a particular host)
        blackout = {
            'environment': 'Production',
            'resource': 'node404',
            'service': ['Network', 'Web']
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # suppress alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout (only for groups of alerts with particular tags)
        blackout = {
            'environment': 'Production',
            'group': 'Network',
            'tags': ['system:web01', 'switch:off']
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # do not suppress alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        self.prod_alert['tags'].append('system:web01')

        # suppress alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 202)

        # remove blackout
        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_edit_blackout(self):

        # create new blackout
        os.environ['NOTIFICATION_BLACKOUT'] = 'False'
        plugins.plugins['blackout'] = Blackout()

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create alert
        response = self.client.post('/alert', data=json.dumps(self.prod_alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create blackout (only for services on a particular host)
        blackout = {
            'environment': 'Production',
            'resource': 'node404',
            'service': ['Network', 'Web'],
            'startTime': '2019-01-01T00:00:00.000Z',
            'endTime': '2019-12-31T23:59:59.999Z'
        }
        response = self.client.post('/blackout', data=json.dumps(blackout), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # extend blackout period & change environment
        update = {
            'environment': 'Development',
            'endTime': '2020-12-31T23:59:59.999Z'
        }
        response = self.client.put('/blackout/' + blackout_id, data=json.dumps(update), headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['status'], 'ok')

        # check updates worked and didn't change anything else
        response = self.client.get('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['blackout']['environment'], 'Development')
        self.assertEqual(data['blackout']['resource'], 'node404')
        self.assertEqual(data['blackout']['service'], ['Network', 'Web'])
        self.assertEqual(data['blackout']['group'], None)
        self.assertEqual(data['blackout']['startTime'], '2019-01-01T00:00:00.000Z')
        self.assertEqual(data['blackout']['endTime'], '2020-12-31T23:59:59.999Z')

    def test_user_info(self):

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # create new blackout
        response = self.client.post('/blackout', data=json.dumps({'environment': 'Production', 'service': [
                                    'Network'], 'text': 'administratively down'}), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['blackout']['user'], '*****@*****.**')
        self.assertIsInstance(DateTime.parse(data['blackout']['createTime']), datetime)
        self.assertEqual(data['blackout']['text'], 'administratively down')
コード例 #50
0
ファイル: test_auth.py プロジェクト: guardian/alerta
class AuthTestCase(unittest.TestCase):

    def setUp(self):

        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'ADMIN_USERS': ['*****@*****.**'],
            'ALLOWED_EMAIL_DOMAINS': ['bonaparte.fr', 'debeauharnais.fr', 'manorfarm.ru']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.alert = {
            'event': 'Foo',
            'resource': 'Bar',
            'environment': 'Production',
            'service': ['Quux']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.api_key = ApiKey(
                user='******',
                scopes=[Scope.admin, Scope.read, Scope.write],
                text='demo-key'
            )
            self.api_key.create()

        self.headers = {
            'Authorization': 'Key %s' % self.api_key.key,
            'Content-type': 'application/json'
        }

    def tearDown(self):
        db.destroy()

    def test_401_error(self):

        response = self.client.get('/alerts')
        self.assertEqual(response.status_code, 401)

    def test_readwrite_key(self):

        payload = {
            'user': '******',
            'type': 'read-write'
        }

        response = self.client.post('/key', data=json.dumps(payload),
                                    content_type='application/json', headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data['key'], 'Failed to create read-write key')

        rw_api_key = data['key']

        response = self.client.post('/alert', data=json.dumps(self.alert),
                                    content_type='application/json', headers={'Authorization': 'Key ' + rw_api_key})
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['history'][0]['user'], 'rw-demo-key-user')

        response = self.client.get('/alerts', headers={'Authorization': 'Key ' + rw_api_key})
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIn('total', data)

        response = self.client.get('/key/' + rw_api_key, headers={'Authorization': 'Key ' + rw_api_key})
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['key']['scopes'], ['read', 'write'])

        response = self.client.delete('/key/' + rw_api_key, headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_readonly_key(self):

        payload = {
            'user': '******',
            'type': 'read-only'
        }

        response = self.client.post('/key', data=json.dumps(payload),
                                    content_type='application/json', headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data['key'], 'Failed to create read-only key')

        ro_api_key = data['key']

        response = self.client.post('/alert', data=json.dumps(self.alert),
                                    content_type='application/json', headers={'Authorization': 'Key ' + ro_api_key})
        self.assertEqual(response.status_code, 403)

        response = self.client.get('/alerts', headers={'Authorization': 'Key ' + ro_api_key})
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIn('total', data)

        response = self.client.delete('/key/' + ro_api_key, headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_users(self):

        # add customer mapping
        payload = {
            'customer': 'Bonaparte Industries',
            'match': 'bonaparte.fr'
        }
        response = self.client.post('/customer', data=json.dumps(payload),
                                    content_type='application/json', headers=self.headers)
        self.assertEqual(response.status_code, 201)

        payload = {
            'name': 'Napoleon Bonaparte',
            'email': '*****@*****.**',
            'password': '******',
            'text': 'added to circle of trust'
        }

        # create user
        response = self.client.post('/auth/signup', data=json.dumps(payload),
                                    content_type='application/json', headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data, 'Failed to create user')

        with self.app.test_request_context():
            jwt = Jwt.parse(data['token'])
        user_id = jwt.subject

        # get user
        response = self.client.get('/users', headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIn(user_id, [u['id'] for u in data['users']])

        # create duplicate user
        response = self.client.post('/auth/signup', data=json.dumps(payload),
                                    content_type='application/json', headers=self.headers)
        self.assertEqual(response.status_code, 409)

        # delete user
        response = self.client.delete('/user/' + user_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_login(self):

        name = 'Josephine de Beauharnais'

        payload = {
            'name': name,
            'email': '*****@*****.**',
            'password': '******',
            'text': 'Test login'
        }

        # sign-up user with no customer mapping
        response = self.client.post('/auth/signup', data=json.dumps(payload), content_type='application/json')
        self.assertEqual(response.status_code, 403)

        # add customer mapping
        payload = {
            'customer': 'Bonaparte Industries',
            'match': 'debeauharnais.fr'
        }
        response = self.client.post('/customer', data=json.dumps(payload),
                                    content_type='application/json', headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        customer_id = data['id']

        payload = {
            'email': '*****@*****.**',
            'password': '******'
        }

        # login now that customer mapping exists
        response = self.client.post('/auth/login', data=json.dumps(payload), content_type='application/json')
        # self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIn('token', data)

        token = data['token']

        headers = {
            'Authorization': 'Bearer ' + token,
            'Content-type': 'application/json'
        }

        # create a customer demo key
        payload = {
            'user': '******',
            'type': 'read-only'
        }

        response = self.client.post('/key', data=json.dumps(payload), content_type='application/json', headers=headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data['key'], 'Failed to create read-only key')

        customer_api_key = data['key']

        response = self.client.get('/alerts', headers={'Authorization': 'Key ' + customer_api_key})
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIn('total', data)

        response = self.client.get('/key/' + customer_api_key, headers=headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['key']['scopes'], ['read'])

        response = self.client.delete('/key/' + customer_api_key, headers={'Authorization': 'Key ' + customer_api_key})
        self.assertEqual(response.status_code, 403)

        response = self.client.delete('/key/' + customer_api_key, headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # get user
        response = self.client.get('/users', headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIn(name, [u['name'] for u in data['users']])

        user_id = [u['id'] for u in data['users'] if u['name'] == name][0]

        # delete user
        response = self.client.delete('/user/' + user_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # delete customer mapping
        response = self.client.delete('/customer/' + customer_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_x_api_key(self):

        self.headers = {
            'X-API-Key': self.api_key.key,
            'Content-type': 'application/json'
        }

        payload = {
            'user': '******',
            'type': 'read-write'
        }

        response = self.client.post('/key', data=json.dumps(payload),
                                    content_type='application/json', headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data['key'], 'Failed to create read-write key')

        rw_api_key = data['key']

        response = self.client.post('/alert', data=json.dumps(self.alert),
                                    content_type='application/json', headers={'X-API-Key': rw_api_key})
        self.assertEqual(response.status_code, 201)

        response = self.client.get('/alerts', headers={'X-API-Key': rw_api_key})
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIn('total', data)

        response = self.client.delete('/key/' + rw_api_key, headers=self.headers)
        self.assertEqual(response.status_code, 200)

    def test_edit_api_keys(self):

        self.headers = {
            'Authorization': 'Key %s' % self.api_key.key,
            'Content-type': 'application/json'
        }

        # create api key
        payload = {
            'scopes': [Scope.read, Scope.write_alerts, Scope.write_blackouts],
            'text': 'devops automation key',
            'expireTime': '2099-12-31T23:59:59.999Z'
        }
        response = self.client.post('/key', data=json.dumps(payload), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        api_key_id = data['key']

        # extend blackout period & change environment
        update = {
            'scopes': [Scope.read, Scope.write_blackouts, Scope.write_webhooks],
            'expireTime': '2022-12-31T23:59:59.999Z'
        }
        response = self.client.put('/key/' + api_key_id, data=json.dumps(update), headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['status'], 'ok')

        # check updates worked and didn't change anything else
        response = self.client.get('/key/' + api_key_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['key']['scopes'], [Scope.read, Scope.write_blackouts, Scope.write_webhooks])
        self.assertEqual(data['key']['user'], '*****@*****.**')
        self.assertEqual(data['key']['text'], 'devops automation key')
        self.assertEqual(data['key']['expireTime'], '2022-12-31T23:59:59.999Z')

    def test_basic_auth(self):

        # add customer mapping
        payload = {
            'customer': 'Bonaparte Industries',
            'match': 'bonaparte.fr'
        }
        response = self.client.post('/customer', data=json.dumps(payload),
                                    content_type='application/json', headers=self.headers)
        self.assertEqual(response.status_code, 201)

        payload = {
            'name': 'Napoleon Bonaparte',
            'email': '*****@*****.**',
            'password': '******',
            'text': 'added to circle of trust'
        }

        # create user
        response = self.client.post('/auth/signup', data=json.dumps(payload),
                                    content_type='application/json', headers=self.headers)
        self.assertEqual(response.status_code, 200)

        # authenticate using basic auth
        headers = {
            'Authorization': 'Basic ' + base64.b64encode('[email protected]:blackforest'.encode('utf-8')).decode(),
            'Content-type': 'application/json'
        }

        response = self.client.get('/users', headers=headers)
        self.assertEqual(response.status_code, 403)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['message'], 'Missing required scope: admin:users')

        response = self.client.get('/alerts', headers=headers)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['status'], 'ok', response.data)

    def test_edit_user(self):

        # add customer mapping
        payload = {
            'customer': 'Manor Farm',
            'match': 'manorfarm.ru'
        }
        response = self.client.post('/customer', data=json.dumps(payload),
                                    content_type='application/json', headers=self.headers)
        self.assertEqual(response.status_code, 201)

        payload = {
            'name': 'Snowball',
            'email': '*****@*****.**',
            'password': '******',
            'text': 'Can you not understand that liberty is worth more than ribbons?',
            'attributes': {'two-legs': 'bad', 'hasFourLegs': True, 'isEvil': False}
        }

        # create user
        response = self.client.post('/auth/signup', data=json.dumps(payload), content_type='application/json')
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))

        with self.app.test_request_context():
            jwt = Jwt.parse(data['token'])
        user_id = jwt.subject

        # get user
        response = self.client.get('/user/' + user_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['status'], 'ok')
        self.assertEqual(data['user']['name'], 'Snowball')
        self.assertEqual(data['user']['email'], '*****@*****.**')
        self.assertEqual(data['user']['text'], 'Can you not understand that liberty is worth more than ribbons?')

        # FIXME: attribute keys with None (null) values aren't deleted in postgres

        # change user details
        update = {
            'name': 'Squealer',
            'text': 'Four legs good, two legs bad.',
            'attributes': {'four-legs': 'good', 'isEvil': True}
        }
        response = self.client.put('/user/' + user_id, data=json.dumps(update), headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['status'], 'ok')

        # check updates worked and didn't change anything else
        response = self.client.get('/user/' + user_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['user']['name'], 'Squealer')
        self.assertEqual(data['user']['email'], '*****@*****.**')
        self.assertEqual(data['user']['text'], 'Four legs good, two legs bad.')
        self.assertEqual(data['user']['attributes'], {
            'four-legs': 'good',
            'two-legs': 'bad',
            'hasFourLegs': True,
            'isEvil': True
        })

        # just update attributes
        update = {
            'attributes': {'four-legs': 'double good', 'isEvil': False, 'hasFourLegs': None}
        }
        response = self.client.put('/user/' + user_id + '/attributes', data=json.dumps(update), headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['status'], 'ok')

        # check updates worked and didn't change anything else
        response = self.client.get('/user/' + user_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['user']['name'], 'Squealer')
        self.assertEqual(data['user']['email'], '*****@*****.**')
        self.assertEqual(data['user']['text'], 'Four legs good, two legs bad.')
        self.assertEqual(data['user']['attributes'], {
            'four-legs': 'double good',
            'two-legs': 'bad',
            'isEvil': False
        })
コード例 #51
0
ファイル: test_users.py プロジェクト: guardian/alerta
class UsersTestCase(unittest.TestCase):

    def setUp(self):

        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'ADMIN_USERS': ['*****@*****.**'],
            'ALLOWED_EMAIL_DOMAINS': ['alerta.io', 'doe.com']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.alert = {
            'event': 'Foo',
            'resource': 'Bar',
            'environment': 'Production',
            'service': ['Quux']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.api_key = ApiKey(
                user='******',
                scopes=[Scope.admin, Scope.read, Scope.write],
                text='demo-key'
            )
            self.api_key.create()

        self.headers = {
            'Authorization': 'Key %s' % self.api_key.key,
            'Content-type': 'application/json'
        }

    def tearDown(self):
        db.destroy()

    def test_user(self):

        payload = {
            'name': 'John Doe',
            'email': '*****@*****.**',
            'password': '******',
            'roles': ['operator'],
            'text': 'devops user'
        }

        # create user
        response = self.client.post('/user', data=json.dumps(payload), headers=self.headers)
        self.assertEqual(response.status_code, 201, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['user']['name'], 'John Doe')
        self.assertEqual(data['user']['email'], '*****@*****.**')
        self.assertEqual(data['user']['roles'], ['operator'])
        self.assertEqual(data['user']['email_verified'], False)

        user_id = data['id']

        payload = {
            'role': 'devops'
        }

        # modify user (assign different role)
        response = self.client.put('/user/' + user_id, data=json.dumps(payload), headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))

        # get user
        response = self.client.get('/user/' + user_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['user']['name'], 'John Doe')
        self.assertEqual(data['user']['email'], '*****@*****.**')
        self.assertEqual(data['user']['roles'], ['devops'])
        self.assertEqual(data['user']['email_verified'], False)

        payload = {
            'roles': ['devops', 'operator', 'user']
        }

        # modify user (assign multiple roles)
        response = self.client.put('/user/' + user_id, data=json.dumps(payload), headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))

        # get user
        response = self.client.get('/user/' + user_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['user']['name'], 'John Doe')
        self.assertEqual(data['user']['email'], '*****@*****.**')
        self.assertEqual(data['user']['roles'], ['devops', 'operator', 'user'])
        self.assertEqual(data['user']['email_verified'], False)

    def test_user_attributes(self):

        payload = {
            'name': 'John Doe',
            'email': '*****@*****.**',
            'password': '******',
            'roles': ['operator'],
            'text': 'devops user'
        }

        # create user
        response = self.client.post('/user', data=json.dumps(payload), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['user']['name'], 'John Doe')
        self.assertEqual(data['user']['login'], '*****@*****.**')
        self.assertEqual(data['user']['roles'], ['operator'])
        self.assertEqual(data['user']['email'], '*****@*****.**')
        self.assertEqual(data['user']['email_verified'], False)

        payload = {
            'email': '*****@*****.**',
            'password': '******'
        }

        # login using new user
        response = self.client.post('/auth/login', data=json.dumps(payload), content_type='application/json')
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIn('token', data)

        token = data['token']

        headers = {
            'Authorization': 'Bearer ' + token,
            'Content-type': 'application/json'
        }

        payload = {
            'attributes': {
                'prefs': {
                    'isDark': True
                }
            }
        }
        # set user attribute
        response = self.client.put('/user/me/attributes', data=json.dumps(payload), headers=headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))

        # get user attribute
        response = self.client.get('/user/me/attributes', data=json.dumps(payload), headers=headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['attributes']['prefs'], {'isDark': True})

        payload = {
            'attributes': {
                'prefs': {
                    'isMute': False,
                    'refreshInterval': 5000
                }
            }
        }
        # set user attribute
        response = self.client.put('/user/me/attributes', data=json.dumps(payload), headers=headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))

        # get user attribute
        response = self.client.get('/user/me/attributes', data=json.dumps(payload), headers=headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['attributes']['prefs'], {'isDark': True, 'isMute': False, 'refreshInterval': 5000})

        payload = {
            'attributes': {
                'prefs': {
                    'isMute': None
                }
            }
        }
        # unset user attribute
        response = self.client.put('/user/me/attributes', data=json.dumps(payload), headers=headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))

        # get user attribute
        response = self.client.get('/user/me/attributes', data=json.dumps(payload), headers=headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['attributes']['prefs'], {'isDark': True, 'isMute': None, 'refreshInterval': 5000})
コード例 #52
0
ファイル: test_shelving.py プロジェクト: guardian/alerta
class ShelvingTestCase(unittest.TestCase):

    def setUp(self):
        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'PLUGINS': ['reject']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.alert = {
            'event': 'node_marginal',
            'resource': 'node404',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'warning',
            'correlate': ['node_down', 'node_marginal', 'node_up']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.admin_api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='demo-key'
            )
            self.customer_api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='demo-key',
                customer='Foo'
            )
            self.admin_api_key.create()
            self.customer_api_key.create()

    def tearDown(self):
        db.destroy()

    def test_alarm_shelving(self):

        self.headers = {
            'Authorization': 'Key %s' % self.admin_api_key.key,
            'Content-type': 'application/json'
        }

        # new alert should be status=open
        response = self.client.post('/alert', data=json.dumps(self.alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'open')

        alert_id = data['id']

        # shelve alert
        response = self.client.put('/alert/' + alert_id + '/status',
                                   data=json.dumps({'status': 'shelved'}), headers=self.headers)
        self.assertEqual(response.status_code, 200)
        response = self.client.get('/alert/' + alert_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'shelved')

        # duplicate alert should be status=shelved
        response = self.client.post('/alert', data=json.dumps(self.alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'shelved')

        # duplicate alert should be status=shelved (again)
        response = self.client.post('/alert', data=json.dumps(self.alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'shelved')

        # increase severity alert should stay status=shelved
        self.alert['severity'] = 'major'
        response = self.client.post('/alert', data=json.dumps(self.alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'shelved')

        # shelve alert
        response = self.client.put('/alert/' + alert_id + '/status',
                                   data=json.dumps({'status': 'shelved'}), headers=self.headers)
        self.assertEqual(response.status_code, 200)
        response = self.client.get('/alert/' + alert_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'shelved')

        # decrease severity alert should be status=shelved
        self.alert['severity'] = 'minor'
        response = self.client.post('/alert', data=json.dumps(self.alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'shelved')

        # decrease severity alert should be status=shelved (again)
        self.alert['severity'] = 'warning'
        response = self.client.post('/alert', data=json.dumps(self.alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'shelved')

        # normal severity alert should be status=closed
        self.alert['severity'] = 'ok'
        response = self.client.post('/alert', data=json.dumps(self.alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'closed')

        # normal severity alert should be status=closed (again)
        response = self.client.post('/alert', data=json.dumps(self.alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'closed')

        # normal severity alert should be status=closed
        response = self.client.post('/alert', data=json.dumps(self.alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'closed')

        ###

        # increase severity alert should be status=shelved
        self.alert['severity'] = 'critical'
        response = self.client.post('/alert', data=json.dumps(self.alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'shelved')

        # shelve alert
        response = self.client.put('/alert/' + alert_id + '/status',
                                   data=json.dumps({'status': 'shelved'}), headers=self.headers)
        self.assertEqual(response.status_code, 200)
        response = self.client.get('/alert/' + alert_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'shelved')

        # duplicate alert should be status=shelved
        response = self.client.post('/alert', data=json.dumps(self.alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'shelved')

        # unshelve alert
        response = self.client.put('/alert/' + alert_id + '/status',
                                   data=json.dumps({'status': 'open'}), headers=self.headers)
        self.assertEqual(response.status_code, 200)
        response = self.client.get('/alert/' + alert_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'open')

        # duplicate alert should be status=open
        response = self.client.post('/alert', data=json.dumps(self.alert), headers=self.headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['alert']['status'], 'open')
コード例 #53
0
ファイル: decorators.py プロジェクト: justenb/alerta
        def wrapped(*args, **kwargs):

            # API Key (Authorization: Key <key>)
            if 'Authorization' in request.headers:
                auth_header = request.headers['Authorization']
                m = re.match(r'Key (\S+)', auth_header)
                key = m.group(1) if m else None
            # API Key (X-API-Key: <key>)
            elif 'X-API-Key' in request.headers:
                key = request.headers['X-API-Key']
            # API Key (/foo?api-key=<key>)
            else:
                key = request.args.get('api-key', None)

            if key:
                key_info = ApiKey.verify_key(key)
                if not key_info:
                    raise ApiError("API key parameter '%s' is invalid" % key,
                                   401)
                g.user = key_info.user
                g.customers = [key_info.customer] if key_info.customer else []
                g.scopes = key_info.scopes

                if not Permission.is_in_scope(scope, g.scopes):
                    raise ApiError('Missing required scope: %s' % scope, 403)
                else:
                    return f(*args, **kwargs)

            # Bearer Token
            auth_header = request.headers.get('Authorization', '')
            m = re.match(r'Bearer (\S+)', auth_header)
            token = m.group(1) if m else None

            if token:
                try:
                    jwt = Jwt.parse(token)
                except DecodeError:
                    raise ApiError('Token is invalid', 401)
                except ExpiredSignature:
                    raise ApiError('Token has expired', 401)
                except InvalidAudience:
                    raise ApiError('Invalid audience', 401)
                g.user = jwt.preferred_username
                g.customers = jwt.customers
                g.scopes = jwt.scopes

                if not Permission.is_in_scope(scope, g.scopes):
                    raise ApiError('Missing required scope: %s' % scope, 403)
                else:
                    return f(*args, **kwargs)

            # Basic Auth
            auth_header = request.headers.get('Authorization', '')
            m = re.match(r'Basic (\S+)', auth_header)
            credentials = m.group(1) if m else None

            if credentials:
                try:
                    username, password = base64.b64decode(credentials).decode(
                        'utf-8').split(':')
                except Exception as e:
                    raise BasicAuthError('Invalid credentials',
                                         400,
                                         errors=[str(e)])

                user = User.check_credentials(username, password)
                if not user:
                    raise BasicAuthError('Authorization required', 401)

                if current_app.config[
                        'EMAIL_VERIFICATION'] and not user.email_verified:
                    raise BasicAuthError('email not verified', 401)

                if not_authorized('ALLOWED_EMAIL_DOMAINS',
                                  groups=[user.domain]):
                    raise BasicAuthError('Unauthorized domain', 403)

                g.user = user.email
                g.customers = get_customers(user.email, groups=[user.domain])
                g.scopes = Permission.lookup(user.email, groups=user.roles)

                if not Permission.is_in_scope(scope, g.scopes):
                    raise BasicAuthError('Missing required scope: %s' % scope,
                                         403)
                else:
                    return f(*args, **kwargs)

            if not current_app.config['AUTH_REQUIRED']:
                g.user = None
                g.customers = []
                g.scopes = []
                return f(*args, **kwargs)

            # Google App Engine Cron Service
            if request.headers.get('X-Appengine-Cron',
                                   False) and request.headers.get(
                                       'X-Forwarded-For', '') == '0.1.0.1':
                return f(*args, **kwargs)

            raise ApiError('Missing authorization API Key or Bearer Token',
                           401)
コード例 #54
0
ファイル: test_groups.py プロジェクト: guardian/alerta
class GroupsTestCase(unittest.TestCase):

    def setUp(self):

        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'ADMIN_USERS': ['*****@*****.**'],
            'ALLOWED_EMAIL_DOMAINS': ['alerta.io', 'doe.com']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.alert = {
            'event': 'Foo',
            'resource': 'Bar',
            'environment': 'Production',
            'service': ['Quux']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.api_key = ApiKey(
                user='******',
                scopes=[Scope.admin, Scope.read, Scope.write],
                text='demo-key'
            )
            self.api_key.create()

        self.headers = {
            'Authorization': 'Key %s' % self.api_key.key,
            'Content-type': 'application/json'
        }

    def tearDown(self):
        db.destroy()

    def test_groups(self):

        # create a group
        payload = {
            'name': 'Group 1',
            'text': 'Test group #1'
        }
        response = self.client.post('/group', data=json.dumps(payload), headers=self.headers)
        self.assertEqual(response.status_code, 201, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['group']['name'], 'Group 1')
        self.assertEqual(data['group']['text'], 'Test group #1')

        group_id = data['group']['id']

        # get group
        response = self.client.get('/group/' + group_id, headers=self.headers)
        self.assertEqual(response.status_code, 200, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['group']['name'], 'Group 1')
        self.assertEqual(data['group']['text'], 'Test group #1')

        # create a duplicate group name
        # payload = {
        #     'name': 'Group 1',
        #     'text': 'Test group #1 duplicate'
        # }
        # response = self.client.post('/group', data=json.dumps(payload), headers=self.headers)
        # self.assertEqual(response.status_code, 500, response.data)

        # update a group name, text
        payload = {
            'name': 'Group 1 changed',
            'text': 'Test group #1 changed too'
        }
        response = self.client.put('/group/' + group_id, data=json.dumps(payload), headers=self.headers)
        self.assertEqual(response.status_code, 200, response.data)

        response = self.client.get('/group/' + group_id, headers=self.headers)
        self.assertEqual(response.status_code, 200, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['group']['name'], 'Group 1 changed')
        self.assertEqual(data['group']['text'], 'Test group #1 changed too')

        # create a different group
        payload = {
            'name': 'Group 2',
            'text': 'Test group #2'
        }
        response = self.client.post('/group', data=json.dumps(payload), headers=self.headers)
        self.assertEqual(response.status_code, 201, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['group']['name'], 'Group 2')
        self.assertEqual(data['group']['text'], 'Test group #2')

        group2_id = data['group']['id']

        # list groups
        response = self.client.get('/groups', headers=self.headers)
        self.assertEqual(response.status_code, 200, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertListEqual([g['name'] for g in data['groups']], ['Group 1 changed', 'Group 2'])

        # create a user
        payload = {
            'name': 'John Doe',
            'email': '*****@*****.**',
            'password': '******',
            'roles': ['operator'],
            'text': 'devops user'
        }

        response = self.client.post('/user', data=json.dumps(payload), headers=self.headers)
        self.assertEqual(response.status_code, 201, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['user']['name'], 'John Doe')

        user_id = data['user']['id']

        # add a user to first group
        response = self.client.put('/group/' + group_id + '/user/' + user_id, headers=self.headers)
        self.assertEqual(response.status_code, 200, response.data)
        data = json.loads(response.data.decode('utf-8'))

        # get users for first group
        response = self.client.get('/group/' + group_id + '/users', headers=self.headers)
        self.assertEqual(response.status_code, 200, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertListEqual([u['name'] for u in data['users']], ['John Doe'])

        # create another user
        payload = {
            'name': 'Jane Doe',
            'email': '*****@*****.**',
            'password': '******',
            'roles': ['manager'],
            'text': 'manager'
        }

        response = self.client.post('/user', data=json.dumps(payload), headers=self.headers)
        self.assertEqual(response.status_code, 201, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertEqual(data['user']['name'], 'Jane Doe')

        user2_id = data['user']['id']

        # add another user to first group
        response = self.client.put('/group/' + group_id + '/user/' + user2_id, headers=self.headers)
        self.assertEqual(response.status_code, 200, response.data)
        data = json.loads(response.data.decode('utf-8'))

        # get users for first group again
        response = self.client.get('/group/' + group_id + '/users', headers=self.headers)
        self.assertEqual(response.status_code, 200, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertListEqual([u['name'] for u in data['users']], ['John Doe', 'Jane Doe'])

        # add second user to second group
        response = self.client.put('/group/' + group2_id + '/user/' + user2_id, headers=self.headers)
        self.assertEqual(response.status_code, 200, response.data)
        data = json.loads(response.data.decode('utf-8'))

        # get users for second group
        response = self.client.get('/group/' + group2_id + '/users', headers=self.headers)
        self.assertEqual(response.status_code, 200, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertListEqual([u['name'] for u in data['users']], ['Jane Doe'])

        # get groups for first user
        response = self.client.get('/user/' + user_id + '/groups', headers=self.headers)
        self.assertEqual(response.status_code, 200, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertListEqual([g['name'] for g in data['groups']], ['Group 1 changed'])

        # get groups for second user
        response = self.client.get('/user/' + user2_id + '/groups', headers=self.headers)
        self.assertEqual(response.status_code, 200, response.data)
        data = json.loads(response.data.decode('utf-8'))
        self.assertListEqual([g['name'] for g in data['groups']], ['Group 1 changed', 'Group 2'])

        # delete groups
        response = self.client.delete('/group/' + group_id, headers=self.headers)
        self.assertEqual(response.status_code, 200, response.data)

        response = self.client.delete('/group/' + group2_id, headers=self.headers)
        self.assertEqual(response.status_code, 200, response.data)
コード例 #55
0
    def setUp(self):
        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'PLUGINS': []
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.prod_alert = {
            'resource': 'node404',
            'event': 'node_down',
            'environment': 'Production',
            'severity': 'major',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'service': ['Core', 'Web', 'Network'],
            'group': 'Network',
            'tags': ['level=20', 'switch:off'],
            'origin': 'foo/bar'
        }

        self.dev_alert = {
            'resource': 'node404',
            'event': 'node_marginal',
            'environment': 'Development',
            'severity': 'warning',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'service': ['Core', 'Web', 'Network'],
            'group': 'Network',
            'tags': ['level=20', 'switch:off'],
            'origin': 'foo/bar'
        }

        self.fatal_alert = {
            'event': 'node_down',
            'resource': 'net01',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'critical',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'tags': ['foo'],
            'attributes': {'foo': 'abc def', 'bar': 1234, 'baz': False},
            'origin': 'foo/bar'
        }
        self.critical_alert = {
            'event': 'node_marginal',
            'resource': 'net02',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'critical',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'origin': 'foo/bar',
            'timeout': 30
        }
        self.major_alert = {
            'event': 'node_marginal',
            'resource': 'net03',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'major',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'origin': 'foo/bar',
            'timeout': 40
        }
        self.normal_alert = {
            'event': 'node_up',
            'resource': 'net03',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'normal',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'origin': 'foo/quux',
            'timeout': 100
        }
        self.minor_alert = {
            'event': 'node_marginal',
            'resource': 'net04',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'minor',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'origin': 'foo/quux',
            'timeout': 40
        }
        self.ok_alert = {
            'event': 'node_up',
            'resource': 'net04',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'ok',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'origin': 'foo/quux',
            'timeout': 100
        }
        self.warn_alert = {
            'event': 'node_marginal',
            'resource': 'net05',
            'environment': 'Production',
            'service': ['Network'],
            'severity': 'warning',
            'correlate': ['node_down', 'node_marginal', 'node_up'],
            'origin': 'foo/quux',
            'timeout': 50
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.admin_api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='demo-key'
            )
            self.customer_api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='demo-key',
                customer='Foo'
            )
            self.admin_api_key.create()
            self.customer_api_key.create()
コード例 #56
0
ファイル: test_customers.py プロジェクト: 3IWOH/alerta
class AuthTestCase(unittest.TestCase):

    def setUp(self):

        test_config = {
            'TESTING': True,
            'AUTH_REQUIRED': True,
            'CUSTOMER_VIEWS': True,
            'ADMIN_USERS': ['*****@*****.**'],
            'ALLOWED_EMAIL_DOMAINS': ['alerta.io', 'example.com']
        }
        self.app = create_app(test_config)
        self.client = self.app.test_client()

        self.alert = {
            'event': 'Foo',
            'resource': 'Bar',
            'environment': 'Production',
            'service': ['Quux']
        }

        with self.app.test_request_context('/'):
            self.app.preprocess_request()
            self.api_key = ApiKey(
                user='******',
                scopes=['admin', 'read', 'write'],
                text='admin-key'
            )
            self.api_key.create()

        self.headers = {
            'Authorization': 'Key %s' % self.api_key.key,
            'Content-type': 'application/json'
        }

    def tearDown(self):
        db.destroy()

    def test_blackouts(self):

        # add customer mapping
        payload = {
            'customer': 'Example Corp',
            'match': 'example.com'
        }
        response = self.client.post('/customer', data=json.dumps(payload), content_type='application/json', headers=self.headers)
        self.assertEqual(response.status_code, 201)

        # create user
        payload = {
            'name': 'Example User',
            'email': '*****@*****.**',
            'password': '******',
            'text': ''
        }

        response = self.client.post('/auth/signup', data=json.dumps(payload), content_type='application/json', headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data.decode('utf-8'))
        self.assertIsNotNone(data, 'Failed to create user')

        # use JWT token for user auth
        token = data['token']
        user_headers = {
            'Authorization': 'Bearer %s' % token,
            'Content-type': 'application/json'
        }

        # create user blackout
        response = self.client.post('/blackout', data=json.dumps({"environment": "Production"}), headers=user_headers)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data.decode('utf-8'))

        blackout_id = data['id']

        # delete user blackout by admin
        response = self.client.delete('/blackout/' + blackout_id, headers=self.headers)
        self.assertEqual(response.status_code, 200)