ready for user test 1.00

This commit is contained in:
ValueOn AG 2025-09-01 23:37:11 +02:00
parent 30e539a49b
commit 237d9b5752
2 changed files with 120 additions and 5 deletions

View file

@ -156,6 +156,25 @@ class UserConnection(BaseModel, ModelMixin):
frontend_readonly=True,
frontend_required=False
)
tokenStatus: Optional[str] = Field(
None,
description="Current token status: active, expired, none",
frontend_type="select",
frontend_readonly=True,
frontend_required=False,
frontend_options=[
{"value": "active", "label": {"en": "Active", "fr": "Actif"}},
{"value": "expired", "label": {"en": "Expired", "fr": "Expiré"}},
{"value": "none", "label": {"en": "None", "fr": "Aucun"}}
]
)
tokenExpiresAt: Optional[float] = Field(
None,
description="When the current token expires (UTC timestamp in seconds)",
frontend_type="timestamp",
frontend_readonly=True,
frontend_required=False
)
# Register labels for UserConnection
register_model_labels(
@ -171,7 +190,9 @@ register_model_labels(
"status": {"en": "Status", "fr": "Statut"},
"connectedAt": {"en": "Connected At", "fr": "Connecté le"},
"lastChecked": {"en": "Last Checked", "fr": "Dernière vérification"},
"expiresAt": {"en": "Expires At", "fr": "Expire le"}
"expiresAt": {"en": "Expires At", "fr": "Expire le"},
"tokenStatus": {"en": "Connection Status", "fr": "Statut de connexion"},
"tokenExpiresAt": {"en": "Expires At", "fr": "Expire le"}
}
)

View file

@ -15,7 +15,7 @@ from datetime import datetime
import logging
import json
from modules.interfaces.interfaceAppModel import User, UserConnection, AuthAuthority, ConnectionStatus
from modules.interfaces.interfaceAppModel import User, UserConnection, AuthAuthority, ConnectionStatus, Token
from modules.security.auth import getCurrentUser, limiter
from modules.interfaces.interfaceAppObjects import getInterface, getRootInterface
from modules.shared.timezoneUtils import get_utc_timestamp
@ -23,6 +23,57 @@ from modules.shared.timezoneUtils import get_utc_timestamp
# Configure logger
logger = logging.getLogger(__name__)
def get_token_status_for_connection(interface, connection_id: str) -> tuple[str, Optional[float]]:
"""
Get token status and expiration for a connection.
Args:
interface: The database interface
connection_id: The connection ID to check
Returns:
tuple: (token_status, token_expires_at)
- token_status: 'active', 'expired', or 'none'
- token_expires_at: UTC timestamp or None
"""
try:
# Query tokens table for the latest token for this connection
tokens = interface.db.getRecordset(
table="tokens",
recordFilter={"connectionId": connection_id}
)
if not tokens:
return "none", None
# Find the most recent token (highest createdAt timestamp)
latest_token = None
latest_created_at = 0
for token_data in tokens:
created_at = token_data.get("createdAt", 0)
if created_at > latest_created_at:
latest_created_at = created_at
latest_token = token_data
if not latest_token:
return "none", None
# Check if token is expired
expires_at = latest_token.get("expiresAt")
if not expires_at:
return "none", None
current_time = get_utc_timestamp()
if expires_at <= current_time:
return "expired", expires_at
else:
return "active", expires_at
except Exception as e:
logger.error(f"Error getting token status for connection {connection_id}: {str(e)}")
return "none", None
router = APIRouter(
prefix="/api/connections",
tags=["Manage Connections"],
@ -47,7 +98,32 @@ async def get_connections(
# SECURITY FIX: All users (including admins) can only see their own connections
# This prevents admin from seeing other users' connections and causing confusion
return interface.getUserConnections(currentUser.id)
connections = interface.getUserConnections(currentUser.id)
# Enhance each connection with token status information
enhanced_connections = []
for connection in connections:
# Get token status for this connection
token_status, token_expires_at = get_token_status_for_connection(interface, connection.id)
# Create enhanced connection with token status
enhanced_connection = UserConnection(
id=connection.id,
userId=connection.userId,
authority=connection.authority,
externalId=connection.externalId,
externalUsername=connection.externalUsername,
externalEmail=connection.externalEmail,
status=connection.status,
connectedAt=connection.connectedAt,
lastChecked=connection.lastChecked,
expiresAt=connection.expiresAt,
tokenStatus=token_status,
tokenExpiresAt=token_expires_at
)
enhanced_connections.append(enhanced_connection)
return enhanced_connections
except Exception as e:
logger.error(f"Error getting connections: {str(e)}")
@ -164,8 +240,26 @@ async def update_connection(
# Clear cache to ensure fresh data
interface.db.clearTableCache("connections")
# Get updated connection
return connection
# Get token status for the updated connection
token_status, token_expires_at = get_token_status_for_connection(interface, connectionId)
# Create enhanced connection with token status
enhanced_connection = UserConnection(
id=connection.id,
userId=connection.userId,
authority=connection.authority,
externalId=connection.externalId,
externalUsername=connection.externalUsername,
externalEmail=connection.externalEmail,
status=connection.status,
connectedAt=connection.connectedAt,
lastChecked=connection.lastChecked,
expiresAt=connection.expiresAt,
tokenStatus=token_status,
tokenExpiresAt=token_expires_at
)
return enhanced_connection
except HTTPException:
raise