comms: mint guest tokens via MAS login
This commit is contained in:
parent
b86800cd6d
commit
59305ca27c
@ -7,7 +7,7 @@ Core flow
|
||||
- Synapse is the homeserver; MAS fronts login, Synapse serves client/server APIs.
|
||||
- Element Web provides the main UI; Element Call embeds LiveKit for group video.
|
||||
- LiveKit handles SFU media; Coturn provides TURN for NAT traversal.
|
||||
- matrix-guest-register provides guest accounts + guest sessions (no Keycloak).
|
||||
- matrix-guest-register provisions MAS guest accounts and performs MAS password login to mint device-bound guest tokens (no Keycloak).
|
||||
|
||||
Operational jobs
|
||||
- mas-db-ensure-job: ensures MAS database role/database + secret in comms.
|
||||
|
||||
@ -21,8 +21,6 @@ data:
|
||||
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"))
|
||||
_rate = {} # ip -> [window_start, count]
|
||||
@ -126,21 +124,30 @@ data:
|
||||
user = payload.get("data") or {}
|
||||
return status, user.get("id")
|
||||
|
||||
def _create_session(admin_token, user_id, scope):
|
||||
status, payload = _admin_api(
|
||||
def _set_password(admin_token, user_id, password):
|
||||
status, _payload = _admin_api(
|
||||
admin_token,
|
||||
"POST",
|
||||
"/personal-sessions",
|
||||
{
|
||||
"actor_user_id": user_id,
|
||||
"human_name": "guest session",
|
||||
"scope": scope,
|
||||
"expires_in": SESSION_TTL_SEC,
|
||||
},
|
||||
f"/users/{parse.quote(user_id)}/set-password",
|
||||
{"password": password},
|
||||
)
|
||||
if status != 201:
|
||||
return None
|
||||
return (payload.get("data", {}).get("attributes", {}) or {}).get("access_token")
|
||||
return status in (200, 204)
|
||||
|
||||
def _login_password(username, password):
|
||||
payload = {
|
||||
"type": "m.login.password",
|
||||
"identifier": {"type": "m.id.user", "user": f"@{username}:{SERVER_NAME}"},
|
||||
"password": password,
|
||||
}
|
||||
status, data = _json(
|
||||
"POST",
|
||||
f"{MAS_BASE}/_matrix/client/v3/login",
|
||||
body=payload,
|
||||
timeout=20,
|
||||
)
|
||||
if status != 200:
|
||||
return None, None
|
||||
return data.get("access_token"), data.get("device_id")
|
||||
|
||||
def _set_display_name(access_token, user_id, displayname):
|
||||
_json(
|
||||
@ -235,9 +242,12 @@ data:
|
||||
if not mas_user_id or not localpart:
|
||||
raise RuntimeError("add_user_failed")
|
||||
|
||||
access_token = _create_session(admin_token, mas_user_id, "urn:matrix:client:api:*")
|
||||
password = secrets.token_urlsafe(18)
|
||||
if not _set_password(admin_token, mas_user_id, password):
|
||||
raise RuntimeError("set_password_failed")
|
||||
access_token, device_id = _login_password(localpart, password)
|
||||
if not access_token:
|
||||
raise RuntimeError("session_failed")
|
||||
raise RuntimeError("login_failed")
|
||||
try:
|
||||
_set_display_name(access_token, f"@{localpart}:{SERVER_NAME}", displayname)
|
||||
except Exception:
|
||||
@ -248,7 +258,7 @@ data:
|
||||
resp = {
|
||||
"user_id": f"@{localpart}:{SERVER_NAME}",
|
||||
"access_token": access_token,
|
||||
"device_id": "guest_device",
|
||||
"device_id": device_id or "guest_device",
|
||||
"home_server": SERVER_NAME,
|
||||
}
|
||||
return self._send_json(200, resp)
|
||||
|
||||
@ -47,8 +47,6 @@ spec:
|
||||
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