Skip to content

Instantly share code, notes, and snippets.

@ricekab
Created October 23, 2022 13:55
Show Gist options
  • Save ricekab/abeab41b3b4771d9f2bd5ce4e9a2e2f0 to your computer and use it in GitHub Desktop.
Save ricekab/abeab41b3b4771d9f2bd5ce4e9a2e2f0 to your computer and use it in GitHub Desktop.
A small Python Flask server to perform HMAC verification.
"""
This is for development purposes only! Uses the werkzeug WSGI server that Flask ships with.
"""
import hmac
import logging
import hashlib
from flask import Flask, request
# Just tagging onto the dev server logger
l = logging.getLogger('werkzeug')
app = Flask(__name__)
def _verify_payload(payload, secret_key, signature):
if secret_key and signature:
_hmac = hmac.new(bytes(secret_key, encoding='utf-8'),
payload,
hashlib.sha1).hexdigest()
l.info(f'Calculated signature: {_hmac}')
if _hmac == signature:
return True
msg = 'HMAC verification failed, payload is malformed or tampered!'
l.warning(msg)
return False
else:
l.warning('Missing signature or secret key!')
return False
@app.route('/redminewebhook/<project>', methods=['POST'])
def webhookentry(project):
l.info(f'Project: {project}') # Defined in the URL
algo = request.headers.get('X-RedmineWebhook-HMAC-Alg', None)
signature = request.headers.get('X-RedmineWebhook-HMAC-Signature', None)
l.info(f'Alg: {algo}')
l.info(f'Signature: {signature}')
payload = request.get_data()
# # If you want payload output in the logs:
# payload_json = request.get_json()
# l.info('Payload:')
# l.info(payload)
# l.info('Payload (json):')
# l.info(payload_json)
# # -----
# Hard-coded secret key for testing.
# Hard-coded alg to sha1.
hmac_is_ok = _verify_payload(payload,
secret_key="abc123",
signature=signature)
l.info(f'HMAC verification succeeded: {hmac_is_ok}')
return "OK", 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment