more improvements

This commit is contained in:
Moon Man 2024-10-05 17:08:54 +00:00
parent a5084161c5
commit 54488c5b12
1 changed files with 32 additions and 22 deletions

54
auth.py
View File

@ -15,6 +15,7 @@ SECRET = os.environ["SECRET"]
ZULIP = f"https://{os.environ['ZULIP']}/accounts/login/jwt/" ZULIP = f"https://{os.environ['ZULIP']}/accounts/login/jwt/"
REDIRECT = f"https://{os.environ['ZULIP']}/fedi-auth/callback" REDIRECT = f"https://{os.environ['ZULIP']}/fedi-auth/callback"
DB = os.environ.get("DB", "/var/lib/fedi-zulip/db/applications") DB = os.environ.get("DB", "/var/lib/fedi-zulip/db/applications")
scopes = ["read"]
print(f""" print(f"""
Zulip is: {os.environ['ZULIP']} Zulip is: {os.environ['ZULIP']}
@ -27,29 +28,33 @@ cur = con.cursor()
zulip_client = zulip.Client() zulip_client = zulip.Client()
def get_zulip_user(handle): def get_zulip_user(handle):
print(f"Querying Zulip for handle: {handle}")
zulip_client.call_endpoint( zulip_client.call_endpoint(
url=f"/users/{handle}", url=f"/users/{handle}",
method="GET" method="GET"
) )
def create_zulip_user(handle): def create_zulip_user(handle):
password = ''.join(random.choices(string.ascii_uppercase + string.digits, k=40)) print(f"Creating Zulip user with handle: {handle}")
return zulip_client.create_user({ password = ''.join(random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits, k=40))
full_name = handle.split('@')[0]
payload = {
"email": handle, "email": handle,
"password": password, "password": password,
"full_name": handle.split('@')[0] "full_name": full_name
}) }
def get_or_create_zulip_user(handle): response = zulip_client.create_user(payload)
user = get_zulip_user(handle)
if user is None: if response["result"] == "success":
print(f"User: {handle} created.") print(f"Zulip user ID: {response.user_id} created for handle: {handle}")
user = create_zulip_user(handle) return True
elif response["result"] == "error" and response["msg"] == f"Email '{handle}' already in use":
print(response["msg"] + ", this is okay.")
return True
else: else:
print(f"User: {handle} already exists.") print(response["msg"])
return False
return user
cur.execute("CREATE TABLE IF NOT EXISTS applications(instance TEXT PRIMARY KEY, client TEXT, secret TEXT, disabled BOOLEAN DEFAULT FALSE)") cur.execute("CREATE TABLE IF NOT EXISTS applications(instance TEXT PRIMARY KEY, client TEXT, secret TEXT, disabled BOOLEAN DEFAULT FALSE)")
@ -72,7 +77,7 @@ def index():
<h1>Login to Pleroma Chat Using Handle</h1> <h1>Login to Pleroma Chat Using Handle</h1>
<p> <p>
You can use this page to login to {os.environ['ZULIP']} using your You can use this page to login to {os.environ['ZULIP']} using your
Pleroma, Akkoma or Mastodon handle. Format is <code>nickname@server</code>. Pleroma, Akkoma or Mastodon handle. Format is <code>nickname@server.tld</code>.
</p> </p>
<form action="/fedi-auth/login" method="post"> <form action="/fedi-auth/login" method="post">
<label for="nickname">Fediverse handle</label> <label for="nickname">Fediverse handle</label>
@ -93,10 +98,10 @@ def login():
try: try:
app = get_application(instance) app = get_application(instance)
if app == None: if app == None:
print(f"There is no OAuth application for {instance} so creating one.", flush=True) print(f"There is no OAuth application for {instance} so creating one.")
(client, secret) = Mastodon.create_app( (client, secret) = Mastodon.create_app(
"zulip", "zulip",
scopes=["read"], scopes=scopes,
redirect_uris=REDIRECT, redirect_uris=REDIRECT,
api_base_url=f"https://{instance}", api_base_url=f"https://{instance}",
) )
@ -112,7 +117,7 @@ def login():
print(f"Getting login URI for {instance}.", flush=True) print(f"Getting login URI for {instance}.", flush=True)
oauth = Mastodon.auth_request_url( oauth = Mastodon.auth_request_url(
masto, masto,
scopes=["read"], scopes=scopes,
force_login=True, force_login=True,
redirect_uris=REDIRECT, redirect_uris=REDIRECT,
state=instance, state=instance,
@ -138,13 +143,18 @@ def callback():
client_secret=app[1], client_secret=app[1],
api_base_url=f"https://{instance}", api_base_url=f"https://{instance}",
) )
Mastodon.log_in(masto, code=oauth, scopes=["read"]) Mastodon.log_in(masto, code=oauth, scopes=scopes)
creds = Mastodon.account_verify_credentials(masto) creds = Mastodon.account_verify_credentials(masto)
print(creds)
if hasattr(creds, "error"):
print(f"Verifying credentials for instance: {instance} error: {creds.error}")
return Response("fail", status=400)
handle = f"{creds.acct}@{instance}" handle = f"{creds.acct}@{instance}"
zulip_user = get_or_create_zulip_user(handle) success = create_zulip_user(handle, creds.avatar_static)
print(zulip_user) if not success:
return Response("fail", status=400)
token = jwt.encode( token = jwt.encode(
{"email": handle}, {"email": handle},
@ -155,9 +165,9 @@ def callback():
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<body> <body>
<p>Please wait while you are logged in...</p>
<form name="zulip" action="{ZULIP}" method="post"> <form name="zulip" action="{ZULIP}" method="post">
<input type="hidden" name="token" value={escape(token)}> <input type="hidden" name="token" value={escape(token)}>
<button>login to zulip</button>
</form> </form>
<script type="text/javascript"> <script type="text/javascript">
document.zulip.submit(); document.zulip.submit();