Refactor API to match database, no _uuid postfixes.

This commit is contained in:
2026-01-27 02:32:46 +00:00
parent 2fadaea19c
commit 3196aa7688
6 changed files with 17 additions and 36 deletions
+1 -1
View File
@@ -72,4 +72,4 @@ async def refresh_session_token(token: str, *, ip: str, user_agent: str):
async def delete_credential(credential_uuid: UUID, auth: str, host: str | None = None): async def delete_credential(credential_uuid: UUID, auth: str, host: str | None = None):
"""Delete a specific credential for the current user.""" """Delete a specific credential for the current user."""
s = await get_session(auth, host=host) s = await get_session(auth, host=host)
db.delete_credential(credential_uuid, s.user_uuid) db.delete_credential(credential_uuid, s.user)
-19
View File
@@ -55,11 +55,6 @@ class Role(msgspec.Struct, dict=True):
role.uuid = uuid7.create() role.uuid = uuid7.create()
return role return role
# Legacy alias for org field
@property
def org_uuid(self) -> UUID:
return self.org
class Org(msgspec.Struct, dict=True): class Org(msgspec.Struct, dict=True):
display_name: str display_name: str
@@ -165,15 +160,6 @@ class Session(msgspec.Struct, dict=True):
def __post_init__(self): def __post_init__(self):
self.key: str | None = None # Convenience field, not serialized self.key: str | None = None # Convenience field, not serialized
# Legacy aliases
@property
def user_uuid(self) -> UUID:
return self.user
@property
def credential_uuid(self) -> UUID:
return self.credential
def metadata(self) -> dict: def metadata(self) -> dict:
"""Return session metadata for backwards compatibility.""" """Return session metadata for backwards compatibility."""
return { return {
@@ -191,11 +177,6 @@ class ResetToken(msgspec.Struct, dict=True):
def __post_init__(self): def __post_init__(self):
self.key: bytes | None = None # Convenience field, not serialized self.key: bytes | None = None # Convenience field, not serialized
# Legacy alias
@property
def user_uuid(self) -> UUID:
return self.user
class SessionContext(msgspec.Struct): class SessionContext(msgspec.Struct):
session: Session session: Session
+6 -6
View File
@@ -1,6 +1,6 @@
import logging import logging
from datetime import timezone from datetime import timezone
from uuid import UUID, uuid4 from uuid import UUID
from fastapi import Body, FastAPI, HTTPException, Request, Response from fastapi import Body, FastAPI, HTTPException, Request, Response
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
@@ -308,7 +308,7 @@ async def admin_update_role_name(
status_code=403, detail="Insufficient permissions", mode="forbidden" status_code=403, detail="Insufficient permissions", mode="forbidden"
) )
role = db.get_role(role_uuid) role = db.get_role(role_uuid)
if role.org_uuid != org_uuid: if role.org != org_uuid:
raise HTTPException(status_code=404, detail="Role not found in organization") raise HTTPException(status_code=404, detail="Role not found in organization")
display_name = payload.get("display_name") display_name = payload.get("display_name")
@@ -340,7 +340,7 @@ async def admin_add_role_permission(
) )
role = db.get_role(role_uuid) role = db.get_role(role_uuid)
if role.org_uuid != org_uuid: if role.org != org_uuid:
raise HTTPException(status_code=404, detail="Role not found in organization") raise HTTPException(status_code=404, detail="Role not found in organization")
# Verify permission exists and org can grant it # Verify permission exists and org can grant it
@@ -376,7 +376,7 @@ async def admin_remove_role_permission(
) )
role = db.get_role(role_uuid) role = db.get_role(role_uuid)
if role.org_uuid != org_uuid: if role.org != org_uuid:
raise HTTPException(status_code=404, detail="Role not found in organization") raise HTTPException(status_code=404, detail="Role not found in organization")
# Sanity check: prevent admin from removing their own access # Sanity check: prevent admin from removing their own access
@@ -419,7 +419,7 @@ async def admin_delete_role(
status_code=403, detail="Insufficient permissions", mode="forbidden" status_code=403, detail="Insufficient permissions", mode="forbidden"
) )
role = db.get_role(role_uuid) role = db.get_role(role_uuid)
if role.org_uuid != org_uuid: if role.org != org_uuid:
raise HTTPException(status_code=404, detail="Role not found in organization") raise HTTPException(status_code=404, detail="Role not found in organization")
# Sanity check: prevent admin from deleting their own role # Sanity check: prevent admin from deleting their own role
@@ -797,7 +797,7 @@ async def admin_delete_user_session(
) )
target_session = db.get_session(session_id) target_session = db.get_session(session_id)
if not target_session or target_session.user_uuid != user_uuid: if not target_session or target_session.user != user_uuid:
raise HTTPException(status_code=404, detail="Session not found") raise HTTPException(status_code=404, detail="Session not found")
db.delete_session(session_id, ctx=ctx) db.delete_session(session_id, ctx=ctx)
+3 -3
View File
@@ -124,7 +124,7 @@ async def token_info(credentials=Depends(bearer_auth)):
except ValueError as e: except ValueError as e:
raise HTTPException(401, str(e)) raise HTTPException(401, str(e))
u = db.get_user_by_uuid(reset_token.user_uuid) u = db.get_user_by_uuid(reset_token.user)
return { return {
"token_type": reset_token.token_type, "token_type": reset_token.token_type,
"display_name": u.display_name, "display_name": u.display_name,
@@ -178,7 +178,7 @@ async def forward_authentication(
.isoformat() .isoformat()
.replace("+00:00", "Z") .replace("+00:00", "Z")
), ),
"Remote-Credential": str(ctx.session.credential_uuid), "Remote-Credential": str(ctx.session.credential),
} }
return Response(status_code=204, headers=remote_headers) return Response(status_code=204, headers=remote_headers)
except authz.AuthException as e: except authz.AuthException as e:
@@ -239,7 +239,7 @@ async def api_user_info(
raise HTTPException(401, str(e)) raise HTTPException(401, str(e))
return await userinfo.format_user_info( return await userinfo.format_user_info(
user_uuid=session_record.user_uuid, user_uuid=session_record.user,
auth=auth, auth=auth,
session_record=session_record, session_record=session_record,
request_host=request.headers.get("host"), request_host=request.headers.get("host"),
+4 -4
View File
@@ -54,7 +54,7 @@ async def user_update_display_name(
raise HTTPException(status_code=400, detail="display_name required") raise HTTPException(status_code=400, detail="display_name required")
if len(new_name) > 64: if len(new_name) > 64:
raise HTTPException(status_code=400, detail="display_name too long") raise HTTPException(status_code=400, detail="display_name too long")
db.update_user_display_name(s.user_uuid, new_name) db.update_user_display_name(s.user, new_name)
return {"status": "ok"} return {"status": "ok"}
@@ -68,7 +68,7 @@ async def api_logout_all(request: Request, response: Response, auth=AUTH_COOKIE)
raise authz.AuthException( raise authz.AuthException(
status_code=401, detail="Session expired", mode="login" status_code=401, detail="Session expired", mode="login"
) )
db.delete_sessions_for_user(s.user_uuid) db.delete_sessions_for_user(s.user)
session.clear_session_cookie(response) session.clear_session_cookie(response)
return {"message": "Logged out from all hosts"} return {"message": "Logged out from all hosts"}
@@ -92,7 +92,7 @@ async def api_delete_session(
) from exc ) from exc
target_session = db.get_session(session_id) target_session = db.get_session(session_id)
if not target_session or target_session.user_uuid != current_session.user_uuid: if not target_session or target_session.user != current_session.user:
raise HTTPException(status_code=404, detail="Session not found") raise HTTPException(status_code=404, detail="Session not found")
db.delete_session(session_id) db.delete_session(session_id)
@@ -137,7 +137,7 @@ async def api_create_link(
token = passphrase.generate() token = passphrase.generate()
expiry = expires() expiry = expires()
db.create_reset_token( db.create_reset_token(
user_uuid=s.user_uuid, user_uuid=s.user,
passphrase=token, passphrase=token,
expiry=expiry, expiry=expiry,
token_type="device addition", token_type="device addition",
+3 -3
View File
@@ -57,11 +57,11 @@ async def websocket_register_add(
f"The reset link for {passkey.instance.rp_name} is invalid or has expired" f"The reset link for {passkey.instance.rp_name} is invalid or has expired"
) )
s = await get_reset(reset) s = await get_reset(reset)
user_uuid = s.user_uuid user_uuid = s.user
else: else:
# Require recent authentication for adding a new passkey # Require recent authentication for adding a new passkey
ctx = await authz.verify(auth, perm=[], host=host, max_age="5m") ctx = await authz.verify(auth, perm=[], host=host, max_age="5m")
user_uuid = ctx.session.user_uuid user_uuid = ctx.session.user
s = ctx.session s = ctx.session
# Get user information and determine effective user_name for this registration # Get user information and determine effective user_name for this registration
@@ -113,7 +113,7 @@ async def websocket_authenticate(ws: WebSocket, auth=AUTH_COOKIE):
if auth: if auth:
try: try:
session = await get_session(auth, host=host) session = await get_session(auth, host=host)
session_user_uuid = session.user_uuid session_user_uuid = session.user
credentials = db.get_credentials_by_user_uuid(session_user_uuid) credentials = db.get_credentials_by_user_uuid(session_user_uuid)
credential_ids = ( credential_ids = (
[c.credential_id for c in credentials] if credentials else None [c.credential_id for c in credentials] if credentials else None