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