This commit is contained in:
ValueOn AG 2026-03-28 18:28:35 +01:00
parent 75484c0f73
commit 20d2bf215f
5 changed files with 42 additions and 11 deletions

View file

@ -181,7 +181,7 @@ class TokenManager:
# Only allow a new refresh if at least 10 minutes passed since the token was created/refreshed
try:
nowTs = getUtcTimestamp()
createdTs = parseTimestamp(oldToken.createdAt, default=0.0)
createdTs = parseTimestamp(oldToken.sysCreatedAt, default=0.0)
secondsSinceLastRefresh = nowTs - createdTs
if secondsSinceLastRefresh < 10 * 60:
logger.info(

View file

@ -77,6 +77,19 @@ TEMPLATE_ROLES = [
{"context": "DATA", "item": None, "view": True, "read": "m", "create": "m", "update": "m", "delete": "m"},
]
},
{
"roleLabel": "automation2-admin",
"description": {
"en": "Automation2 Admin - Full UI and API for the instance; data remains user-scoped (MY)",
"de": "Automation2 Admin - Volle UI und API für die Instanz; Daten weiterhin benutzerspezifisch (MY)",
"fr": "Administrateur Automation2 - UI et API complets pour l'instance; donnees limitees a l'utilisateur (MY)",
},
"accessRules": [
{"context": "UI", "item": None, "view": True},
{"context": "RESOURCE", "item": None, "view": True},
{"context": "DATA", "item": None, "view": True, "read": "m", "create": "m", "update": "m", "delete": "m"},
],
},
]

View file

@ -2858,8 +2858,8 @@ class AppObjects:
# Ensure token has required fields
if not token.id:
token.id = str(uuid.uuid4())
if not token.createdAt:
token.createdAt = getUtcTimestamp()
if not token.sysCreatedAt:
token.sysCreatedAt = getUtcTimestamp()
# If replace_existing is True, delete old access tokens for this user and authority first
if replace_existing:
@ -2892,12 +2892,7 @@ class AppObjects:
)
# Continue with saving the new token even if deletion fails
# Convert to dict and ensure all fields are properly set
token_dict = token.model_dump()
# Ensure userId is set to current user
# Convert to dict and ensure all fields are properly set
token_dict = token.model_dump()
# Ensure userId is set to current user
token_dict["userId"] = self.currentUser.id
# Save to database
@ -2936,8 +2931,8 @@ class AppObjects:
# Ensure token has required fields
if not token.id:
token.id = str(uuid.uuid4())
if not token.createdAt:
token.createdAt = getUtcTimestamp()
if not token.sysCreatedAt:
token.sysCreatedAt = getUtcTimestamp()
# Convert to dict and ensure all fields are properly set
token_dict = token.model_dump()

View file

@ -333,7 +333,8 @@ class ChatService:
token_status = "expired"
else:
# Check if this token was recently refreshed (within last 5 minutes)
time_since_creation = current_time - token.createdAt if hasattr(token, 'createdAt') else 0
createdTs = getattr(token, "sysCreatedAt", None)
time_since_creation = (current_time - createdTs) if createdTs else 0
if time_since_creation < 300: # 5 minutes
token_status = "valid (refreshed)"
else:

View file

@ -21,6 +21,18 @@ from typing import Optional, List
logger = logging.getLogger(__name__)
def _ensureUamTablesMatchModels(dbConnector) -> None:
"""Run connector schema sync so sys* columns exist before we CREATE INDEX on them."""
if not hasattr(dbConnector, "_ensureTableExists"):
return
try:
from modules.datamodels.datamodelInvitation import Invitation
dbConnector._ensureTableExists(Invitation)
except Exception as e:
logger.debug(f"_ensureUamTablesMatchModels: {e}")
def _getConnection(dbConnector):
"""Get a connection from the DatabaseConnector.
@ -176,6 +188,11 @@ def applyMultiTenantOptimizations(dbConnector, tables: Optional[List[str]] = Non
except Exception as autoErr:
logger.debug(f"Could not set autocommit: {autoErr}")
try:
_ensureUamTablesMatchModels(dbConnector)
except Exception as preIdxErr:
logger.debug(f"Pre-index table ensure: {preIdxErr}")
try:
with conn.cursor() as cursor:
# Apply indexes
@ -214,6 +231,11 @@ def applyIndexesOnly(dbConnector, tables: Optional[List[str]] = None) -> int:
originalAutocommit = conn.autocommit
conn.autocommit = True
try:
_ensureUamTablesMatchModels(dbConnector)
except Exception as preIdxErr:
logger.debug(f"Pre-index table ensure: {preIdxErr}")
try:
with conn.cursor() as cursor:
return _applyIndexes(cursor, tables)