added webhooks, moved app name and verison to simple config file
This commit is contained in:
@@ -7,8 +7,8 @@ for sensitive values like passwords and API tokens.
|
||||
|
||||
import json
|
||||
import os
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
import bcrypt
|
||||
from cryptography.fernet import Fernet
|
||||
@@ -32,6 +32,11 @@ class SettingsManager:
|
||||
'encryption_key',
|
||||
}
|
||||
|
||||
# Keys that are read-only (managed by developer, not user-editable)
|
||||
READ_ONLY_KEYS = {
|
||||
'encryption_key',
|
||||
}
|
||||
|
||||
def __init__(self, db_session: Session, encryption_key: Optional[bytes] = None):
|
||||
"""
|
||||
Initialize the settings manager.
|
||||
@@ -69,11 +74,11 @@ class SettingsManager:
|
||||
return new_key
|
||||
|
||||
def _store_raw(self, key: str, value: str) -> None:
|
||||
"""Store a setting without encryption (internal use only)."""
|
||||
"""Store a setting without encryption (internal use only). Bypasses read-only check."""
|
||||
setting = self.db.query(Setting).filter_by(key=key).first()
|
||||
if setting:
|
||||
setting.value = value
|
||||
setting.updated_at = datetime.utcnow()
|
||||
setting.updated_at = datetime.now(timezone.utc)
|
||||
else:
|
||||
setting = Setting(key=key, value=value)
|
||||
self.db.add(setting)
|
||||
@@ -128,7 +133,11 @@ class SettingsManager:
|
||||
|
||||
return value
|
||||
|
||||
def set(self, key: str, value: Any, encrypt: bool = None) -> None:
|
||||
def _is_read_only(self, key: str) -> bool:
|
||||
"""Check if a setting key is read-only."""
|
||||
return key in self.READ_ONLY_KEYS
|
||||
|
||||
def set(self, key: str, value: Any, encrypt: bool = None, allow_read_only: bool = False) -> None:
|
||||
"""
|
||||
Set a setting value.
|
||||
|
||||
@@ -136,7 +145,15 @@ class SettingsManager:
|
||||
key: Setting key
|
||||
value: Setting value (will be JSON-encoded if dict/list)
|
||||
encrypt: Force encryption on/off (None = auto-detect from ENCRYPTED_KEYS)
|
||||
allow_read_only: If True, allows setting read-only keys (internal use only)
|
||||
|
||||
Raises:
|
||||
ValueError: If attempting to set a read-only key without allow_read_only=True
|
||||
"""
|
||||
# Prevent modification of read-only keys unless explicitly allowed
|
||||
if not allow_read_only and self._is_read_only(key):
|
||||
raise ValueError(f"Setting '{key}' is read-only and cannot be modified via API")
|
||||
|
||||
# Convert complex types to JSON
|
||||
if isinstance(value, (dict, list)):
|
||||
value_str = json.dumps(value)
|
||||
@@ -153,7 +170,7 @@ class SettingsManager:
|
||||
setting = self.db.query(Setting).filter_by(key=key).first()
|
||||
if setting:
|
||||
setting.value = value_str
|
||||
setting.updated_at = datetime.utcnow()
|
||||
setting.updated_at = datetime.now(timezone.utc)
|
||||
else:
|
||||
setting = Setting(key=key, value=value_str)
|
||||
self.db.add(setting)
|
||||
@@ -251,7 +268,8 @@ class SettingsManager:
|
||||
for key, value in defaults.items():
|
||||
# Only set if doesn't exist
|
||||
if self.db.query(Setting).filter_by(key=key).first() is None:
|
||||
self.set(key, value)
|
||||
# Use allow_read_only=True for initializing defaults
|
||||
self.set(key, value, allow_read_only=True)
|
||||
|
||||
|
||||
class PasswordManager:
|
||||
|
||||
Reference in New Issue
Block a user