bugfix(CON-01)
This commit is contained in:
parent
9f25cfd160
commit
18fb8e32b3
2 changed files with 47 additions and 8 deletions
|
|
@ -191,7 +191,6 @@ class UserConnection(PowerOnModel):
|
|||
json_schema_extra={"frontend_type": "list", "frontend_readonly": True, "frontend_required": False, "label": "Gewährte Berechtigungen"},
|
||||
)
|
||||
|
||||
@computed_field
|
||||
@computed_field
|
||||
@property
|
||||
def connectionReference(self) -> str:
|
||||
|
|
|
|||
|
|
@ -427,13 +427,53 @@ def update_connection(
|
|||
detail=routeApiMsg("Connection not found")
|
||||
)
|
||||
|
||||
# Update connection fields
|
||||
# Merge incoming changes into a dict and re-validate via pydantic.
|
||||
# Direct setattr() bypasses type coercion (PowerOnModel doesn't enable
|
||||
# validate_assignment), which leaves enum fields as raw strings and
|
||||
# later breaks .value access. Also filters out computed / unknown keys.
|
||||
writableFields = set(UserConnection.model_fields.keys())
|
||||
previous = connection.model_dump()
|
||||
merged = dict(previous)
|
||||
for field, value in connection_data.items():
|
||||
if hasattr(connection, field):
|
||||
setattr(connection, field, value)
|
||||
if field in writableFields:
|
||||
merged[field] = value
|
||||
merged["lastChecked"] = getUtcTimestamp()
|
||||
connection = UserConnection.model_validate(merged)
|
||||
|
||||
# Update lastChecked timestamp using UTC timestamp
|
||||
connection.lastChecked = getUtcTimestamp()
|
||||
# If this is a remote (non-local) connection and any identity-bearing
|
||||
# field changed, the stored OAuth tokens no longer match the account.
|
||||
# Force the user to reconnect: mark PENDING and revoke existing tokens.
|
||||
identityFields = ("externalUsername", "externalEmail", "externalId", "authority")
|
||||
authorityValue = (
|
||||
connection.authority.value
|
||||
if hasattr(connection.authority, "value")
|
||||
else str(connection.authority)
|
||||
)
|
||||
isRemote = authorityValue != AuthAuthority.LOCAL.value
|
||||
identityChanged = any(
|
||||
previous.get(field) != merged.get(field) for field in identityFields
|
||||
)
|
||||
if isRemote and identityChanged:
|
||||
connection.status = ConnectionStatus.PENDING
|
||||
connection.expiresAt = None
|
||||
try:
|
||||
existingTokens = interface.db.getRecordset(
|
||||
Token, recordFilter={"connectionId": connectionId}
|
||||
)
|
||||
for token in existingTokens:
|
||||
interface.revokeTokenById(
|
||||
token["id"],
|
||||
revokedBy=currentUser.id,
|
||||
reason="connection identity changed",
|
||||
)
|
||||
logger.info(
|
||||
f"Revoked {len(existingTokens)} token(s) for connection "
|
||||
f"{connectionId} after identity change; reconnect required."
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
f"Failed to revoke tokens for connection {connectionId}: {str(e)}"
|
||||
)
|
||||
|
||||
# Update connection - models now handle timestamp serialization automatically
|
||||
interface.db.recordModify(UserConnection, connectionId, connection.model_dump())
|
||||
|
|
|
|||
Loading…
Reference in a new issue