Files
notifications-api/tests/__init__.py
Ben Thorner 49455d9890 Support granular API auth for internal apps
Previously we just had a single array of API keys / secrets, any of
which could be used to get past the "requires_admin_auth" check.
While multiple keys are necessary to allow for rotation, we should
avoid giving other apps access this way (too much privilege).

This converts the existing config vars into a new dictionary, keyed
by client_id. We can then use the dictionary to scope auth for new
API consumers like gov.uk/alerts to just the endpoints they need to
access, while maintaining existing access for the Admin app.

Once the new dictionary is available as a JSON environment variable,
we'll be able to remove the old credentials / config. In the next
commits, we'll look at more tests for the new functionality.
2021-07-29 12:53:02 +01:00

44 lines
1.4 KiB
Python

import uuid
from flask import current_app
from notifications_python_client.authentication import create_jwt_token
from app.dao.api_key_dao import save_model_api_key
from app.dao.services_dao import dao_fetch_service_by_id
from app.models import KEY_TYPE_NORMAL, ApiKey
def create_authorization_header(service_id=None, key_type=KEY_TYPE_NORMAL):
if service_id:
client_id = str(service_id)
secrets = ApiKey.query.filter_by(service_id=service_id, key_type=key_type).all()
if secrets:
secret = secrets[0].secret
else:
service = dao_fetch_service_by_id(service_id)
data = {
'service': service,
'name': uuid.uuid4(),
'created_by': service.created_by,
'key_type': key_type
}
api_key = ApiKey(**data)
save_model_api_key(api_key)
secret = api_key.secret
else:
client_id = current_app.config['ADMIN_CLIENT_USER_NAME']
secret = current_app.config['INTERNAL_CLIENT_API_KEYS'][client_id][0]
token = create_jwt_token(secret=secret, client_id=client_id)
return 'Authorization', 'Bearer {}'.format(token)
def unwrap_function(fn):
"""
Given a function, returns its undecorated original.
"""
while hasattr(fn, '__wrapped__'):
fn = fn.__wrapped__
return fn