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