Moved all OAuth service related code to scmsrht

This commit is contained in:
Ludovic Chabant 2019-10-16 16:32:22 +00:00 committed by Drew DeVault
parent fd7d8c4fb0
commit da60312da1
1 changed files with 4 additions and 97 deletions

View File

@ -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)