diff --git a/mastodon-kanidm-sync.py b/mastodon-kanidm-sync.py index 9ff1fb1..0b7442c 100644 --- a/mastodon-kanidm-sync.py +++ b/mastodon-kanidm-sync.py @@ -1,6 +1,8 @@ +from io import DEFAULT_BUFFER_SIZE import os import time import json +from psycopg2.sql import NULL import requests import psycopg2 as ps @@ -8,25 +10,31 @@ def read_file(path): with open(path, "r", encoding="utf-8") as f: return f.read() - def getenv(name): try: return os.environ[name] except KeyError: - print(f"Missing environment variable {name}. You should NOT run this script by hand, please use systemd mastodon-kanidm-sync.service.") + print(f"[ERROR] Missing environment variable {name}. You should NOT run this script by hand, please use systemd mastodon-kanidm-sync.service.") exit(1) +# Import configuration KANIDM_URL = getenv("KANIDM_URL") KANIDM_TOKEN = read_file(getenv("KANIDM_TOKEN_PATH")).strip() -# USERDATA = read_file(getenv("USERDATA_FILE_PATH")).strip() +USERDATA = read_file(getenv("USERDATA_FILE_PATH")).strip() +# Fetch configuration from userdata file +# Userdata file is json list with information about what users are configured by kanidm +userdata = json.loads(USERDATA) + +# Load database conn = ps.connect( dbname=getenv("POSTGRES_DBNAME"), user=getenv("POSTGRES_USER"), host=getenv("POSTGRES_HOST") ) +# Fetch current userdata from database cur = conn.cursor() cur.execute(''' SELECT identities.uid, users.id, user_roles.name @@ -39,9 +47,16 @@ cur.execute(''' ) state = cur.fetchall() -print(state) # DEBUG -print(type(state)) # DEBUG +users = {} +for i in state: + users[i[0]] = { + "id": i[1], + "role": i[2], + "isKanidmUser": False + } + +# Fetch Kanidm userdata kanidm_users_raw = requests.get( f"{KANIDM_URL}/v1/person", headers={ @@ -53,10 +68,35 @@ kanidm_users_raw = requests.get( for i in kanidm_users_raw: i = i["attrs"] - uid = i["name"] - # if uid in db_users: - # print(uid) - print(uid) + for uid in i["name"]: # [user].attrs.name is a list + if uid in users: # Don't apply anything for users who have no mastodon access (sp.matrix.users) or didn't register + for group in i["attrs"]["memberof"]: + if group.startswith("sp.matrix.admins@"): + if uid not in userdata: + userdata.append(uid) + users[uid]["isKanidmUser"] = True + users[uid]["role"] = "Admin" + print(f"[INFO] {uid} got role Admin") + break + elif group.startswith("sp.matrix.moderators@"): + if uid not in userdata: + userdata.append(uid) + users[uid]["isKanidmUser"] = True + users[uid]["role"] = "Moderator" + print(f"[INFO] {uid} got role Moderator") + break + elif uid in userdata: + # If user, who previously had a role, has no roles set by Kanidm, delete them from userdata list so allow setting roles directly by mastodon + users[uid]["isKanidmUser"] = True + users[uid]["role"] = None + userdata.remove(uid) + print(f"[INFO] {uid} has no roles") + +print("[DEBUG] ", users) # DEBUG cur.close() conn.close() + +print("[INFO] Final userdata file: ", userdata) +with open(getenv("USERDATA_FILE_PATH"), "w") as f: + f.write(json.dumps(userdata))