This commit is contained in:
2025-09-23 17:14:11 +03:00
parent 58b4bc47a6
commit 67f9dc73e5

View File

@@ -1,6 +1,8 @@
from io import DEFAULT_BUFFER_SIZE
import os import os
import time import time
import json import json
from psycopg2.sql import NULL
import requests import requests
import psycopg2 as ps import psycopg2 as ps
@@ -8,25 +10,31 @@ def read_file(path):
with open(path, "r", encoding="utf-8") as f: with open(path, "r", encoding="utf-8") as f:
return f.read() return f.read()
def getenv(name): def getenv(name):
try: try:
return os.environ[name] return os.environ[name]
except KeyError: 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) exit(1)
# Import configuration
KANIDM_URL = getenv("KANIDM_URL") KANIDM_URL = getenv("KANIDM_URL")
KANIDM_TOKEN = read_file(getenv("KANIDM_TOKEN_PATH")).strip() 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( conn = ps.connect(
dbname=getenv("POSTGRES_DBNAME"), dbname=getenv("POSTGRES_DBNAME"),
user=getenv("POSTGRES_USER"), user=getenv("POSTGRES_USER"),
host=getenv("POSTGRES_HOST") host=getenv("POSTGRES_HOST")
) )
# Fetch current userdata from database
cur = conn.cursor() cur = conn.cursor()
cur.execute(''' cur.execute('''
SELECT identities.uid, users.id, user_roles.name SELECT identities.uid, users.id, user_roles.name
@@ -39,9 +47,16 @@ cur.execute('''
) )
state = cur.fetchall() 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( kanidm_users_raw = requests.get(
f"{KANIDM_URL}/v1/person", f"{KANIDM_URL}/v1/person",
headers={ headers={
@@ -53,10 +68,35 @@ kanidm_users_raw = requests.get(
for i in kanidm_users_raw: for i in kanidm_users_raw:
i = i["attrs"] i = i["attrs"]
uid = i["name"] for uid in i["name"]: # [user].attrs.name is a list
# if uid in db_users: if uid in users: # Don't apply anything for users who have no mastodon access (sp.matrix.users) or didn't register
# print(uid) for group in i["attrs"]["memberof"]:
print(uid) 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() cur.close()
conn.close() conn.close()
print("[INFO] Final userdata file: ", userdata)
with open(getenv("USERDATA_FILE_PATH"), "w") as f:
f.write(json.dumps(userdata))