From 0a3f675b77574d947be9fc5dba39191f425ef759 Mon Sep 17 00:00:00 2001 From: Nick Satterly Date: Sat, 8 May 2021 11:50:34 +0200 Subject: [PATCH 1/2] Support user-defined API keys --- alertaclient/api.py | 4 +++- alertaclient/commands/cmd_key.py | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/alertaclient/api.py b/alertaclient/api.py index c0a7540..fce1bb6 100644 --- a/alertaclient/api.py +++ b/alertaclient/api.py @@ -265,7 +265,7 @@ def delete_heartbeat(self, id): return self.http.delete('/heartbeat/%s' % id) # API Keys - def create_key(self, username, scopes=None, expires=None, text='', customer=None): + def create_key(self, username, scopes=None, expires=None, text='', customer=None, **kwargs): data = { 'user': username, 'scopes': scopes or list(), @@ -274,6 +274,8 @@ def create_key(self, username, scopes=None, expires=None, text='', customer=None } if expires: data['expireTime'] = DateTime.iso8601(expires) + if kwargs.get('key'): + data['key'] = kwargs['key'] r = self.http.post('/key', data) return ApiKey.parse(r['data']) diff --git a/alertaclient/commands/cmd_key.py b/alertaclient/commands/cmd_key.py index 58819e9..a58cc0b 100644 --- a/alertaclient/commands/cmd_key.py +++ b/alertaclient/commands/cmd_key.py @@ -5,6 +5,7 @@ @click.command('key', short_help='Create API key') +@click.option('--api-key', '-K', help='User-defined API Key. [default: random string]') @click.option('--username', '-u', help='User (Admin only)') @click.option('--scope', 'scopes', multiple=True, help='List of permissions eg. admin:keys, write:alerts') @click.option('--duration', metavar='SECONDS', type=int, help='Duration API key is valid') @@ -12,7 +13,7 @@ @click.option('--customer', metavar='STRING', help='Customer') @click.option('--delete', '-D', metavar='ID', help='Delete API key using ID or KEY') @click.pass_obj -def cli(obj, username, scopes, duration, text, customer, delete): +def cli(obj, api_key, username, scopes, duration, text, customer, delete): """Create or delete an API key.""" client = obj['client'] if delete: @@ -20,7 +21,7 @@ def cli(obj, username, scopes, duration, text, customer, delete): else: try: expires = datetime.utcnow() + timedelta(seconds=duration) if duration else None - key = client.create_key(username, scopes, expires, text, customer) + key = client.create_key(username, scopes, expires, text, customer, key=api_key) except Exception as e: click.echo('ERROR: {}'.format(e), err=True) sys.exit(1) From 6473d2efbfbb0f2b5e2e1fa4fa699d88b154d070 Mon Sep 17 00:00:00 2001 From: Nick Satterly Date: Sat, 8 May 2021 11:54:35 +0200 Subject: [PATCH 2/2] Add tests for user-defined API key --- tests/integration/test_keys.py | 3 ++- tests/unit/test_keys.py | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/integration/test_keys.py b/tests/integration/test_keys.py index d0bc75d..639c7c2 100644 --- a/tests/integration/test_keys.py +++ b/tests/integration/test_keys.py @@ -23,8 +23,9 @@ def test_key(self): self.assertEqual(api_key.text, 'Updated Ops API Key') api_key = self.client.create_key( - username='key@alerta.io', scopes=[Scope.admin], text='Admin API Key' + username='key@alerta.io', scopes=[Scope.admin], text='Admin API Key', key='admin-key' ) + self.assertEqual(api_key.key, 'admin-key') api_keys = self.client.get_keys(query=[('user', 'key@alerta.io')]) self.assertEqual(len(api_keys), 2) diff --git a/tests/unit/test_keys.py b/tests/unit/test_keys.py index dbaa3fd..2951a66 100644 --- a/tests/unit/test_keys.py +++ b/tests/unit/test_keys.py @@ -28,7 +28,7 @@ def setUp(self): "type": "read-write", "user": "johndoe@example.com" }, - "key": "BpSG0Ck5JCqk5TJiuBSLAWuTs03QKc_527T5cDtw", + "key": "demo-key", "status": "ok" } """ @@ -36,7 +36,7 @@ def setUp(self): @requests_mock.mock() def test_key(self, m): m.post('http://localhost:8080/key', text=self.key) - api_key = self.client.create_key(username='johndoe@example.com', scopes=[ - 'write:alerts', 'admin:keys'], text='Ops API Key') + api_key = self.client.create_key(username='johndoe@example.com', scopes=['write:alerts', 'admin:keys'], + text='Ops API Key', key='demo-key') self.assertEqual(api_key.user, 'johndoe@example.com') self.assertEqual(sorted(api_key.scopes), sorted(['write:alerts', 'admin:keys']))