diff --git a/auth.py b/auth.py new file mode 100644 index 0000000..2e30dfb --- /dev/null +++ b/auth.py @@ -0,0 +1,115 @@ +from flask import Flask, Response, redirect +from flask import request +from markupsafe import escape +from mastodon import Mastodon +from email.headerregistry import Address +import jwt +import shelve +from gevent.pywsgi import WSGIServer +import os + +SECRET = os.environ["SECRET"] +ZULIP = f"https://{os.environ['ZULIP']}/accounts/login/jwt/" +REDIRECT = f"https://{os.environ['ZULIP']}/callback" +SHELVE_LOCATION = os.environ.get("DB_DIR", "/var/lib/fedi-zulip") +PORT = int(os.environ.get("PORT", "5000")) + +app = Flask(__name__) + +@app.get("/") +def index(): + return f""" + + + +

Login to Pleroma Chat Using Handle

+

+ You can use this page to login to {os.environ['ZULIP']} using your + Pleroma, Akkoma or Mastodon handle. Format is nickname@server. +

+
+ +
+ + +
+ + +""" + + +@app.post("/login") +def login(): + instance = Address(addr_spec=request.form["nickname"]).domain + try: + with shelve.open(SHELVE_LOCATION) as apps: + app = apps.get(instance) + if app == None: + (client, secret) = Mastodon.create_app( + "zulip", + scopes=["read"], + redirect_uris=REDIRECT, + api_base_url=f"https://{instance}", + ) + apps[instance] = (client, secret) + + (client, secret) = apps[instance] + masto = Mastodon( + client_id=client, + client_secret=secret, + api_base_url=f"https://{instance}", + ) + oauth = Mastodon.auth_request_url( + masto, + scopes=["read"], + force_login=True, + redirect_uris=REDIRECT, + state=instance, + ) + return redirect(oauth) + except Exception as e: + print(e) + return Response("fail", status=400) + + +@app.get("/callback") +def callback(): + oauth = request.args.get("code") + instance = request.args.get("state") + if oauth != None and instance != None: + try: + with shelve.open(SHELVE_LOCATION) as apps: + app = apps.get(instance) + if app != None: + masto = Mastodon( + client_id=app[0], + client_secret=app[1], + api_base_url=f"https://{instance}", + ) + Mastodon.log_in(masto, code=oauth, scopes=["read"]) + creds = Mastodon.account_verify_credentials(masto) + token = jwt.encode( + {"email": f"{creds.acct}@{instance}"}, + SECRET, + algorithm="HS256", + ) + return f""" + + + +
+ + +
+ + + + """ + except: + pass + return Response("fail", status=400) + +http_server = WSGIServer(("127.0.0.1", PORT), app) +http_server.serve_forever() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..ebfa02f --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +flask +markupsafe +mastodon