From da60312da19e952b517f670624bf861016ff991e Mon Sep 17 00:00:00 2001 From: Ludovic Chabant Date: Wed, 16 Oct 2019 16:32:22 +0000 Subject: [PATCH] Moved all OAuth service related code to scmsrht --- gitsrht/service.py | 101 ++------------------------------------------- 1 file changed, 4 insertions(+), 97 deletions(-) diff --git a/gitsrht/service.py b/gitsrht/service.py index 14b90dc..89c4e68 100644 --- a/gitsrht/service.py +++ b/gitsrht/service.py @@ -1,103 +1,10 @@ -from flask import Blueprint, request, url_for from gitsrht.types import User, OAuthToken, SSHKey -from scmsrht.redis import redis -from scmsrht.service import scm_scopes -from srht.api import get_results -from srht.database import db -from srht.config import cfg, get_origin -from srht.flask import csrf_bypass -from srht.oauth import AbstractOAuthService -import json -import requests -import sys +from scmsrht.service import BaseScmOAuthService, make_webhooks_notify_blueprint -origin = cfg("git.sr.ht", "origin") -meta_origin = get_origin("meta.sr.ht") -client_id = cfg("git.sr.ht", "oauth-client-id") -client_secret = cfg("git.sr.ht", "oauth-client-secret") -builds_client_id = cfg("builds.sr.ht", "oauth-client-id", default=None) - -class GitOAuthService(AbstractOAuthService): +class GitOAuthService(BaseScmOAuthService): def __init__(self): - super().__init__(client_id, client_secret, - required_scopes=["profile", "keys"] + ([ - "{}/jobs:write".format(builds_client_id) - ] if builds_client_id else []), - delegated_scopes=scm_scopes, - token_class=OAuthToken, user_class=User) - - def cache_key(self, user, meta_key): - b64key = meta_key["key"].split(" ") - if len(b64key) < 2: - return False - b64key = b64key[1] - cache = { - "user_id": user.id, - "username": user.username, - } - redis.set(f"git.sr.ht.ssh-keys.{b64key}", json.dumps(cache)) - - def ensure_user_sshkey(self, user, meta_key): - """ - Ensures this SSH key is registered with this user, and returns True if - their authorized_keys file needs to be regenerated. - - `meta_key` should be the key object returned from meta.sr.ht. - """ - key = SSHKey.query.filter( - SSHKey.meta_id == meta_key["id"]).one_or_none() - if key: - self.cache_key(user, meta_key) - return False - key = SSHKey() - key.user_id = user.id - key.meta_id = meta_key["id"] - key.key = meta_key["key"] - key.fingerprint = meta_key["fingerprint"] - db.session.add(key) - self.cache_key(user, meta_key) - return True - - def ensure_meta_webhooks(self, user, webhooks): - webhook_url = origin + url_for("webhooks.notify.notify_keys") - webhooks.update({ - webhook_url: ["ssh-key:add", "ssh-key:remove"] - }) - return super().ensure_meta_webhooks(user, webhooks) - - def lookup_or_register(self, token, token_expires, scopes): - user = super().lookup_or_register(token, token_expires, scopes) - db.session.flush() - keys_url = f"{meta_origin}/api/user/ssh-keys" - for key in get_results(keys_url, user.oauth_token): - self.ensure_user_sshkey(user, key) - db.session.commit() - return user + super().__init__("git.sr.ht", OAuthToken, User, SSHKey) oauth_service = GitOAuthService() -webhooks_notify = Blueprint("webhooks.notify", __name__) - -@csrf_bypass -@webhooks_notify.route("/webhook/notify/keys", methods=["POST"]) -def notify_keys(): - payload = json.loads(request.data.decode('utf-8')) - event = request.headers.get("X-Webhook-Event") - if event == "ssh-key:add": - user = User.query.filter( - User.username == payload["owner"]["name"]).one_or_none() - oauth_service.ensure_user_sshkey(user, payload) - db.session.commit() - return "Added user's SSH key, thanks!" - elif event == "ssh-key:remove": - key = SSHKey.query.filter( - SSHKey.meta_id == payload["id"]).one_or_none() - b64key = key.key.split(" ") - if len(b64key) >= 2: - b64key = b64key[1] - redis.delete(f"git.sr.ht.ssh-keys.{b64key}") - if key: - db.session.delete(key) - db.session.commit() - return "Removed user's SSH key, thanks!" - return f"Unexpected event {event}" +webhooks_notify = make_webhooks_notify_blueprint(__name__, oauth_service) -- 2.38.4