Renaming of users in registration, profile and admin app.

This commit is contained in:
Leo Vasanko
2025-09-01 18:13:01 -06:00
parent bc87f76d11
commit 37eaffff3f
9 changed files with 232 additions and 21 deletions

View File

@@ -100,6 +100,10 @@ class DatabaseInterface(ABC):
async def create_user(self, user: User) -> None:
"""Create a new user."""
@abstractmethod
async def update_user_display_name(self, user_uuid: UUID, display_name: str) -> None:
"""Update a user's display name."""
# Role operations
@abstractmethod
async def create_role(self, role: Role) -> None:
@@ -312,6 +316,27 @@ class DatabaseInterface(ABC):
async def get_session_context(self, session_key: bytes) -> SessionContext | None:
"""Get complete session context including user, organization, role, and permissions."""
# Combined atomic operations
@abstractmethod
async def create_credential_session(
self,
user_uuid: UUID,
credential: Credential,
reset_key: bytes | None,
session_key: bytes,
session_expires: datetime,
session_info: dict,
display_name: str | None = None,
) -> None:
"""Atomically add a credential and create a session.
Steps (single transaction):
1. Insert credential
2. Optionally delete old session (e.g. reset token) if provided
3. Optionally update user's display name
4. Insert new session referencing the credential
"""
__all__ = [
"User",

View File

@@ -271,6 +271,17 @@ class DB(DatabaseInterface):
async with self.session() as session:
session.add(UserModel.from_dataclass(user))
async def update_user_display_name(self, user_uuid: UUID, display_name: str) -> None:
async with self.session() as session:
stmt = (
update(UserModel)
.where(UserModel.uuid == user_uuid.bytes)
.values(display_name=display_name)
)
result = await session.execute(stmt)
if result.rowcount == 0: # type: ignore[attr-defined]
raise ValueError("User not found")
async def create_role(self, role: Role) -> None:
async with self.session() as session:
# Create role record
@@ -389,6 +400,55 @@ class DB(DatabaseInterface):
)
session.add(credential_model)
async def create_credential_session(
self,
user_uuid: UUID,
credential: Credential,
reset_key: bytes | None,
session_key: bytes,
session_expires: datetime,
session_info: dict,
display_name: str | None = None,
) -> None:
"""Atomic credential + (optional old session delete) + (optional rename) + new session."""
async with self.session() as session:
# Insert credential
session.add(
CredentialModel(
uuid=credential.uuid.bytes,
credential_id=credential.credential_id,
user_uuid=credential.user_uuid.bytes,
aaguid=credential.aaguid.bytes,
public_key=credential.public_key,
sign_count=credential.sign_count,
created_at=credential.created_at,
last_used=credential.last_used,
last_verified=credential.last_verified,
)
)
# Delete old session if provided
if reset_key:
await session.execute(
delete(SessionModel).where(SessionModel.key == reset_key)
)
# Optional rename
if display_name:
await session.execute(
update(UserModel)
.where(UserModel.uuid == user_uuid.bytes)
.values(display_name=display_name)
)
# New session
session.add(
SessionModel(
key=session_key,
user_uuid=user_uuid.bytes,
credential_uuid=credential.uuid.bytes,
expires=session_expires,
info=session_info,
)
)
async def delete_credential(self, uuid: UUID, user_uuid: UUID) -> None:
async with self.session() as session:
stmt = (