I've written a couple of functions to check if a consumer of the API should be authenticated to use it or not.
Have I done anything blatantly wrong here?
Config
API_CONSUMERS = [{'name': 'localhost',
'host': '12.0.0.1:5000',
'api_key': 'Ahth2ea5Ohngoop5'},
{'name': 'localhost2',
'host': '127.0.0.1:5001',
'api_key': 'Ahth2ea5Ohngoop6'}]
Exceptions
class BaseException(Exception):
def __init__(self, logger, *args, **kwargs):
super(BaseException, self).__init__(*args, **kwargs)
logger.info(self.message)
class UnknownHostException(BaseException):
pass
class MissingHashException(BaseException):
pass
class HashMismatchException(BaseException):
pass
Authentication methods
import hashlib
from flask import request
from services.exceptions import (UnknownHostException, MissingHashException,
HashMismatchException)
def is_authenticated(app):
"""
Checks that the consumers host is valid, the request has a hash and the
hash is the same when we excrypt the data with that hosts api key
Arguments:
app -- instance of the application
"""
consumers = app.config.get('API_CONSUMERS')
host = request.host
try:
api_key = next(d['api_key'] for d in consumers if d['host'] == host)
except StopIteration:
raise UnknownHostException(
app.logger, 'Authentication failed: Unknown Host (' + host + ')')
if not request.headers.get('hash'):
raise MissingHashException(
app.logger, 'Authentication failed: Missing Hash (' + host + ')')
hash = calculate_hash(request.method, api_key)
if hash != request.headers.get('hash'):
raise HashMismatchException(
app.logger, 'Authentication failed: Hash Mismatch (' + host + ')')
return True
def calculate_hash(method, api_key):
"""
Calculates the hash using either the url or the request content,
plus the hosts api key
Arguments:
method -- request method
api_key -- api key for this host
"""
if request.method == 'GET':
data_to_hash = request.base_url + '?' + request.query_string
elif request.method == 'POST':
data_to_hash = request.data
data_to_hash += api_key
return hashlib.sha1(data_to_hash).hexdigest()