hub.sr.ht/hubsrht/blueprints/webhooks.py

220 lines
8.3 KiB
Python
Raw Normal View History

2020-03-31 17:17:19 +02:00
import json
from datetime import datetime
2020-04-20 23:11:58 +02:00
from flask import Blueprint, request, current_app
2020-04-06 22:15:52 +02:00
from hubsrht.types import Event, EventType, MailingList, SourceRepo, RepoType
from hubsrht.types import Tracker, User
2020-04-20 23:11:58 +02:00
from srht.config import get_origin
2020-03-31 17:17:19 +02:00
from srht.database import db
from srht.flask import csrf_bypass
2020-03-24 15:26:15 +01:00
webhooks = Blueprint("webhooks", __name__)
2020-04-20 23:11:58 +02:00
_gitsrht = get_origin("git.sr.ht", external=True, default=None)
_hgsrht = get_origin("hg.sr.ht", external=True, default=None)
_todosrht = get_origin("todo.sr.ht", external=True, default=None)
_listssrht = get_origin("lists.sr.ht", external=True, default=None)
2020-03-31 17:17:19 +02:00
@csrf_bypass
2020-04-06 22:15:52 +02:00
@webhooks.route("/webhooks/git-user/<int:user_id>", methods=["POST"])
def git_user(user_id):
2020-03-31 17:17:19 +02:00
event = request.headers.get("X-Webhook-Event")
payload = json.loads(request.data.decode("utf-8"))
2020-04-06 22:15:52 +02:00
user = User.query.get(user_id)
if not user:
return "I don't recognize this user.", 404
2020-03-31 17:17:19 +02:00
if event == "repo:update":
repo = (SourceRepo.query
.filter(SourceRepo.remote_id == payload["id"])
2020-04-06 22:15:52 +02:00
.filter(SourceRepo.repo_type == RepoType.git)).one_or_none()
2020-03-31 17:17:19 +02:00
if not repo:
2020-04-06 22:15:52 +02:00
return "I don't recognize this git repo.", 404
2020-04-06 19:21:13 +02:00
repo.name = payload["name"]
repo.description = payload["description"]
repo.project.updated = datetime.utcnow()
2020-04-06 19:21:13 +02:00
db.session.commit()
return f"Updated local:{repo.id}/remote:{repo.remote_id}. Thanks!", 200
elif event == "repo:delete":
2020-04-06 22:15:52 +02:00
repo = (SourceRepo.query
.filter(SourceRepo.remote_id == payload["id"])
.filter(SourceRepo.repo_type == RepoType.git)).one_or_none()
if not repo:
return "I don't recognize this git repo.", 404
if repo.project.summary_repo_id == repo.id:
repo.project.summary_repo = None
db.session.commit()
db.session.delete(repo)
repo.project.updated = datetime.utcnow()
db.session.commit()
return f"Deleted local:{repo.id}/remote:{repo.remote_id}. Thanks!", 200
2020-04-06 22:15:52 +02:00
else:
raise NotImplementedError()
@csrf_bypass
@webhooks.route("/webhooks/git-repo/<int:repo_id>", methods=["POST"])
def git_repo(repo_id):
event = request.headers.get("X-Webhook-Event")
payload = json.loads(request.data.decode("utf-8"))
repo = SourceRepo.query.get(repo_id)
if not repo:
return "I don't recognize that repository.", 404
if event == "repo:post-update":
2020-04-20 23:11:58 +02:00
# XXX: This isn't right for Hg, but Hg doesn't have webhooks yet anyway
commit_sha = payload["refs"][0]["new"]["id"][:7]
commit_url = repo.url() + f"/commit/{commit_sha}"
commit_message = payload["refs"][0]["new"]["message"].split("\n")[0]
pusher_name = payload['pusher']['canonical_name']
if repo.repo_type == RepoType.git:
pusher_url = f"{_gitsrht}/{pusher_name}"
elif repo.repo_type == RepoType.hg:
pusher_url = f"{_hgsrht}/{pusher_name}"
repo_name = repo.owner.canonical_name + "/" + repo.name
pusher = current_app.oauth_service.lookup_user(payload['pusher']['name'])
event = Event()
event.event_type = EventType.external_event
event.source_repo_id = repo.id
event.project_id = repo.project_id
event.user_id = pusher.id
event.external_source = "git.sr.ht"
event.external_summary = (
f"<a href='{commit_url}'>{commit_sha}</a> " +
f"<code>{commit_message}</code>")
event.external_details = (
f"<a href='{pusher_url}'>{pusher_name}</a> pushed to " +
f"<a href='{repo.url()}'>{repo_name}</a> git")
db.session.add(event)
db.session.commit()
return "Thanks!"
2020-04-06 22:15:52 +02:00
else:
2020-04-06 19:21:13 +02:00
raise NotImplementedError()
@csrf_bypass
2020-04-06 22:15:52 +02:00
@webhooks.route("/webhooks/hg-user/<int:user_id>", methods=["POST"])
def hg_user(user_id):
2020-04-06 19:21:13 +02:00
event = request.headers.get("X-Webhook-Event")
payload = json.loads(request.data.decode("utf-8"))
2020-04-06 22:15:52 +02:00
user = User.query.get(user_id)
if not user:
return "I don't recognize this user.", 404
2020-04-06 19:21:13 +02:00
if event == "repo:update":
repo = (SourceRepo.query
.filter(SourceRepo.id == payload["id"])
2020-04-06 22:15:52 +02:00
.filter(SourceRepo.repo_type == RepoType.hg)).one_or_none()
2020-04-06 19:21:13 +02:00
if not repo:
return "I don't recognize that repository.", 404
2020-03-31 17:17:19 +02:00
repo.name = payload["name"]
repo.description = payload["description"]
repo.project.updated = datetime.utcnow()
2020-03-31 17:17:19 +02:00
db.session.commit()
return f"Updated local:{repo.id}/remote:{repo.remote_id}. Thanks!", 200
elif event == "repo:delete":
repo = (SourceRepo.query
.filter(SourceRepo.remote_id == payload["id"])
.filter(SourceRepo.repo_type == RepoType.hg)).one_or_none()
if not repo:
return "I don't recognize this hg repo.", 404
if repo.project.summary_repo_id == repo.id:
repo.project.summary_repo = None
db.session.commit()
db.session.delete(repo)
repo.project.updated = datetime.utcnow()
db.session.commit()
return f"Deleted local:{repo.id}/remote:{repo.remote_id}. Thanks!", 200
2020-04-06 22:15:52 +02:00
else:
2020-03-31 22:09:33 +02:00
raise NotImplementedError()
2020-03-25 15:08:29 +01:00
2020-03-31 17:17:19 +02:00
@csrf_bypass
@webhooks.route("/webhooks/mailing-list", methods=["POST"])
2020-03-31 22:09:33 +02:00
def mailing_list():
2020-03-31 17:17:19 +02:00
event = request.headers.get("X-Webhook-Event")
payload = json.loads(request.data.decode("utf-8"))
if event == "list:update":
ml = (MailingList.query
.filter(MailingList.remote_id == payload["id"])
.one_or_none())
if not ml:
return "I don't recognize that mailing list.", 404
ml.name = payload["name"]
ml.description = payload["description"]
ml.project.updated = datetime.utcnow()
2020-03-31 17:17:19 +02:00
db.session.commit()
return f"Updated local:{ml.id}/remote:{ml.remote_id}. Thanks!", 200
elif event == "list:delete":
raise NotImplementedError()
2020-03-31 22:09:33 +02:00
elif event == "post:received":
raise NotImplementedError()
elif event == "patchset:received":
raise NotImplementedError()
2020-04-06 22:15:52 +02:00
else:
raise NotImplementedError()
2020-04-02 15:24:29 +02:00
@csrf_bypass
2020-04-06 22:15:52 +02:00
@webhooks.route("/webhooks/todo-user/<int:user_id>", methods=["POST"])
def todo_user(user_id):
2020-04-02 15:24:29 +02:00
event = request.headers.get("X-Webhook-Event")
payload = json.loads(request.data.decode("utf-8"))
2020-04-06 22:15:52 +02:00
user = User.query.get(user_id)
2020-04-06 22:15:52 +02:00
if not user:
return "I don't recognize this tracker.", 404
2020-04-02 15:24:29 +02:00
if event == "tracker:update":
2020-04-02 16:13:01 +02:00
tracker = (Tracker.query
.filter(Tracker.remote_id == payload["id"])
.one_or_none())
2020-04-06 22:15:52 +02:00
if not tracker:
return "I don't recognize this tracker.", 404
tracker.name = payload["name"]
tracker.description = payload["description"]
tracker.project.updated = datetime.utcnow()
2020-04-06 22:15:52 +02:00
db.session.commit()
return f"Updated local:{tracker.id}/remote:{tracker.remote_id}. Thanks!", 200
elif event == "tracker:delete":
tracker = (Tracker.query
.filter(Tracker.remote_id == payload["id"])
.one_or_none())
2020-04-02 16:13:01 +02:00
if not tracker:
return "I don't recognize this tracker.", 404
tracker.project.updated = datetime.utcnow()
db.session.delete(tracker)
db.session.commit()
return f"Deleted local:{tracker.id}/remote:{tracker.remote_id}. Thanks!", 200
2020-04-06 22:15:52 +02:00
else:
raise NotImplementedError()
@csrf_bypass
@webhooks.route("/webhooks/todo-tracker/<int:tracker_id>", methods=["POST"])
def todo_tracker(tracker_id):
event = request.headers.get("X-Webhook-Event")
payload = json.loads(request.data.decode("utf-8"))
tracker = Tracker.query.get(tracker_id)
if not tracker:
return "I don't recognize this tracker.", 404
if event == "ticket:create":
2020-04-02 15:24:29 +02:00
raise NotImplementedError()
else:
raise NotImplementedError()
2020-04-06 22:15:52 +02:00
@csrf_bypass
@webhooks.route("/webhooks/todo-ticket/<int:tracker_id>/ticket", methods=["POST"])
def todo_ticket(tracker_id):
event = request.headers.get("X-Webhook-Event")
payload = json.loads(request.data.decode("utf-8"))
tracker = Tracker.query.get(tracker_id)
if not tracker:
return "I don't recognize this tracker.", 404
if event == "event:create":
raise NotImplementedError()
else:
raise NotImplementedError()