Initial commit.
This commit is contained in:
parent
019a53e464
commit
d30292d141
|
@ -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()
|
|
@ -0,0 +1,3 @@
|
||||||
|
flask
|
||||||
|
markupsafe
|
||||||
|
mastodon
|
Loading…
Reference in New Issue