comms: fix guest registration via MAS admin API
This commit is contained in:
parent
70e40b281f
commit
e44ee3ab2d
@ -14,11 +14,14 @@ data:
|
||||
from urllib import error, parse, request
|
||||
|
||||
MAS_BASE = os.environ.get("MAS_BASE", "http://matrix-authentication-service:8080").rstrip("/")
|
||||
MAS_ADMIN_API_BASE = os.environ.get("MAS_ADMIN_API_BASE", "http://matrix-authentication-service:8081/api/admin/v1").rstrip("/")
|
||||
SYNAPSE_BASE = os.environ.get("SYNAPSE_BASE", "http://othrys-synapse-matrix-synapse:8008").rstrip("/")
|
||||
SERVER_NAME = os.environ.get("MATRIX_SERVER_NAME", "live.bstein.dev")
|
||||
|
||||
MAS_ADMIN_CLIENT_ID = os.environ["MAS_ADMIN_CLIENT_ID"]
|
||||
MAS_ADMIN_CLIENT_SECRET_FILE = os.environ.get("MAS_ADMIN_CLIENT_SECRET_FILE", "/etc/mas/admin-client/client_secret")
|
||||
MAS_ADMIN_SCOPE = os.environ.get("MAS_ADMIN_SCOPE", "urn:mas:admin")
|
||||
SESSION_TTL_SEC = int(os.environ.get("SESSION_TTL_SEC", "43200"))
|
||||
|
||||
RATE_WINDOW_SEC = int(os.environ.get("RATE_WINDOW_SEC", "60"))
|
||||
RATE_MAX = int(os.environ.get("RATE_MAX", "30"))
|
||||
@ -93,51 +96,52 @@ data:
|
||||
_admin_token_at = now
|
||||
return _admin_token
|
||||
|
||||
def _gql(admin_token, query, variables):
|
||||
status, payload = _json(
|
||||
"POST",
|
||||
f"{MAS_BASE}/graphql",
|
||||
headers={"Authorization": f"Bearer {admin_token}"},
|
||||
body={"query": query, "variables": variables},
|
||||
timeout=20,
|
||||
)
|
||||
if status != 200:
|
||||
raise RuntimeError("gql_http_failed")
|
||||
if payload.get("errors"):
|
||||
raise RuntimeError("gql_error")
|
||||
return payload.get("data") or {}
|
||||
|
||||
def _generate_localpart():
|
||||
return "guest-" + secrets.token_hex(6)
|
||||
|
||||
def _generate_displayname():
|
||||
return f"{random.choice(ADJ)}-{random.choice(NOUN)}"
|
||||
|
||||
def _add_user(admin_token, username):
|
||||
data = _gql(
|
||||
admin_token,
|
||||
"mutation($input:AddUserInput!){addUser(input:$input){status user{id username}}}",
|
||||
{"input": {"username": username, "skipHomeserverCheck": True}},
|
||||
)
|
||||
res = data.get("addUser") or {}
|
||||
status = res.get("status")
|
||||
user = res.get("user") or {}
|
||||
return status, user.get("id"), user.get("username")
|
||||
|
||||
def _set_display_name(admin_token, user_id, displayname):
|
||||
_gql(
|
||||
admin_token,
|
||||
"mutation($input:SetDisplayNameInput!){setDisplayName(input:$input){status}}",
|
||||
{"input": {"userId": user_id, "displayName": displayname}},
|
||||
def _admin_api(admin_token, method, path, body=None):
|
||||
return _json(
|
||||
method,
|
||||
f"{MAS_ADMIN_API_BASE}{path}",
|
||||
headers={"Authorization": f"Bearer {admin_token}"},
|
||||
body=body,
|
||||
timeout=20,
|
||||
)
|
||||
|
||||
def _create_oauth2_session(admin_token, user_id, scope):
|
||||
data = _gql(
|
||||
def _create_user(admin_token, username):
|
||||
status, payload = _admin_api(admin_token, "POST", "/users", {"username": username})
|
||||
if status != 201:
|
||||
return status, None
|
||||
user = payload.get("data") or {}
|
||||
return status, user.get("id")
|
||||
|
||||
def _create_session(admin_token, user_id, scope):
|
||||
status, payload = _admin_api(
|
||||
admin_token,
|
||||
"mutation($input:CreateOAuth2SessionInput!){createOauth2Session(input:$input){accessToken}}",
|
||||
{"input": {"userId": user_id, "scope": scope, "permanent": False}},
|
||||
"POST",
|
||||
"/personal-sessions",
|
||||
{
|
||||
"actor_user_id": user_id,
|
||||
"human_name": "guest session",
|
||||
"scope": scope,
|
||||
"expires_in": SESSION_TTL_SEC,
|
||||
},
|
||||
)
|
||||
if status != 201:
|
||||
return None
|
||||
return (payload.get("data", {}).get("attributes", {}) or {}).get("access_token")
|
||||
|
||||
def _set_display_name(access_token, user_id, displayname):
|
||||
_json(
|
||||
"PUT",
|
||||
f"{SYNAPSE_BASE}/_matrix/client/v3/profile/{parse.quote(user_id, safe='')}/displayname",
|
||||
headers={"Authorization": f"Bearer {access_token}"},
|
||||
body={"displayname": displayname},
|
||||
timeout=20,
|
||||
)
|
||||
return (data.get("createOauth2Session") or {}).get("accessToken")
|
||||
|
||||
def _rate_check(ip, now):
|
||||
win, cnt = _rate.get(ip, (now, 0))
|
||||
@ -216,21 +220,20 @@ data:
|
||||
mas_user_id = None
|
||||
for _ in range(5):
|
||||
localpart = _generate_localpart()
|
||||
status, mas_user_id, _ = _add_user(admin_token, localpart)
|
||||
if status == "ADDED":
|
||||
status, mas_user_id = _create_user(admin_token, localpart)
|
||||
if status == 201 and mas_user_id:
|
||||
break
|
||||
mas_user_id = None
|
||||
if not mas_user_id or not localpart:
|
||||
raise RuntimeError("add_user_failed")
|
||||
|
||||
try:
|
||||
_set_display_name(admin_token, mas_user_id, displayname)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
access_token = _create_oauth2_session(admin_token, mas_user_id, "urn:matrix:client:api:*")
|
||||
access_token = _create_session(admin_token, mas_user_id, "urn:matrix:client:api:*")
|
||||
if not access_token:
|
||||
raise RuntimeError("session_failed")
|
||||
try:
|
||||
_set_display_name(access_token, f"@{localpart}:{SERVER_NAME}", displayname)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
return self._send_json(502, {"errcode": "M_UNKNOWN", "error": "guest_provision_failed"})
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ spec:
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
checksum/config: guest-register-proxy-4
|
||||
checksum/config: guest-register-proxy-5
|
||||
labels:
|
||||
app.kubernetes.io/name: matrix-guest-register
|
||||
spec:
|
||||
@ -43,6 +43,12 @@ spec:
|
||||
value: 01KDXMVQBQ5JNY6SEJPZW6Z8BM
|
||||
- name: MAS_ADMIN_CLIENT_SECRET_FILE
|
||||
value: /etc/mas/admin-client/client_secret
|
||||
- name: MAS_ADMIN_API_BASE
|
||||
value: http://matrix-authentication-service:8081/api/admin/v1
|
||||
- name: SYNAPSE_BASE
|
||||
value: http://othrys-synapse-matrix-synapse:8008
|
||||
- name: SESSION_TTL_SEC
|
||||
value: "43200"
|
||||
- name: MATRIX_SERVER_NAME
|
||||
value: live.bstein.dev
|
||||
- name: RATE_WINDOW_SEC
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user