Initial commit.

This commit is contained in:
Moon Man 2024-10-05 10:49:36 +04:00
parent 019a53e464
commit d30292d141
2 changed files with 118 additions and 0 deletions

115
auth.py Normal file
View File

@ -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"""
<!DOCTYPE html>
<html lang="en">
<body>
<h1>Login to Pleroma Chat Using Handle</h1>
<p>
You can use this page to login to {os.environ['ZULIP']} using your
Pleroma, Akkoma or Mastodon handle. Format is <code>nickname@server</code>.
</p>
<form action="/login" method="post">
<label for="nickname">Fediverse handle</label>
<br>
<input type="email" id="nickname" name="nickname">
<button>login</button>
</form>
</body>
</html>
"""
@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"""
<!DOCTYPE html>
<html lang="en">
<body>
<form name="zulip" action="{ZULIP}" method="post">
<input type="hidden" name="token" value={escape(token)}>
<button>login to zulip</button>
</form>
<script type="text/javascript">
document.zulip.submit();
</script>
</body>
</html>
"""
except:
pass
return Response("fail", status=400)
http_server = WSGIServer(("127.0.0.1", PORT), app)
http_server.serve_forever()

3
requirements.txt Normal file
View File

@ -0,0 +1,3 @@
flask
markupsafe
mastodon