import json import hashlib import hmac import logging from flask import Flask, request, abort app = Flask(__name__) class ForgejoWebhookProcessor: def __init__(self, secret_key): self.secret_key = secret_key def validate_webhook(self, payload, signature): """Validate webhook signature""" computed_signature = hmac.new( self.secret_key.encode('utf-8'), payload.encode('utf-8'), hashlib.sha256 ).hexdigest() return hmac.compare_digest(computed_signature, signature) def process_webhook(self, payload): """Process webhook payload""" try: data = json.loads(payload) # Extract key webhook information repository = data.get('repository', {}) commits = data.get('commits', []) ref = data.get('ref', '') # Log basic webhook details logging.info(f"Repository: {repository.get('full_name')}") logging.info(f"Branch: {ref}") logging.info(f"Number of Commits: {len(commits)}") # Custom processing logic here for commit in commits: logging.info(f"Commit: {commit.get('id')}") logging.info(f"Message: {commit.get('message')}") except json.JSONDecodeError: logging.error("Invalid JSON payload") abort(400) @app.route('/forgejo-webhook', methods=['POST']) def webhook(): processor = ForgejoWebhookProcessor('your_secret_key') # Get payload and signature payload = request.get_data(as_text=True) signature = request.headers.get('X-Forgejo-Signature', '') # Validate webhook if not processor.validate_webhook(payload, signature): abort(403) # Process webhook processor.process_webhook(payload) return 'Webhook processed', 200 if __name__ == '__main__': logging.basicConfig(level=logging.INFO) app.run(host="0.0.0.0", port=5001)