116 lines
5.0 KiB
Python
116 lines
5.0 KiB
Python
from __future__ import annotations
|
|
from pathlib import Path
|
|
from flask import current_app
|
|
from app.extensions import db
|
|
from app.models.setting import AppSetting
|
|
from app.services.company_service import CompanyService
|
|
|
|
|
|
class SettingsService:
|
|
@staticmethod
|
|
def _user_scope_key(key: str, user_id=None):
|
|
from flask_login import current_user
|
|
if user_id is None and getattr(current_user, 'is_authenticated', False):
|
|
user_id = current_user.id
|
|
return f'user.{user_id}.{key}' if user_id else key
|
|
|
|
@staticmethod
|
|
def _scope_key(key: str, company_id=None):
|
|
if company_id is None:
|
|
company = CompanyService.get_current_company()
|
|
company_id = company.id if company else None
|
|
return f'company.{company_id}.{key}' if company_id else key
|
|
|
|
@staticmethod
|
|
def get(key, default=None, company_id=None):
|
|
scoped = AppSetting.get(SettingsService._scope_key(key, company_id), default=None)
|
|
if scoped is not None:
|
|
return scoped
|
|
return AppSetting.get(key, default=default)
|
|
|
|
@staticmethod
|
|
def get_secret(key, default=None, company_id=None):
|
|
scoped = AppSetting.get(SettingsService._scope_key(key, company_id), default=None, decrypt=True)
|
|
if scoped is not None:
|
|
return scoped
|
|
return AppSetting.get(key, default=default, decrypt=True)
|
|
|
|
@staticmethod
|
|
def set_many(mapping: dict[str, tuple[object, bool] | object], company_id=None):
|
|
for key, value in mapping.items():
|
|
if isinstance(value, tuple):
|
|
raw, encrypt = value
|
|
else:
|
|
raw, encrypt = value, False
|
|
AppSetting.set(SettingsService._scope_key(key, company_id), raw, encrypt=encrypt)
|
|
db.session.commit()
|
|
|
|
@staticmethod
|
|
def storage_path(key: str, fallback: Path):
|
|
value = SettingsService.get(key)
|
|
if value:
|
|
path = Path(value)
|
|
if not path.is_absolute():
|
|
path = Path(current_app.root_path).parent / path
|
|
path.mkdir(parents=True, exist_ok=True)
|
|
return path
|
|
fallback.mkdir(parents=True, exist_ok=True)
|
|
return fallback
|
|
|
|
@staticmethod
|
|
def read_only_enabled(company_id=None) -> bool:
|
|
from flask_login import current_user
|
|
company = CompanyService.get_current_company()
|
|
cid = company_id or (company.id if company else None)
|
|
truly_global_ro = AppSetting.get('app.read_only_mode', 'false') == 'true'
|
|
company_ro = AppSetting.get(f'company.{cid}.app.read_only_mode', 'false') == 'true' if cid else False
|
|
user_ro = getattr(current_user, 'is_authenticated', False) and cid and current_user.is_company_readonly(cid)
|
|
return truly_global_ro or company_ro or bool(user_ro)
|
|
|
|
@staticmethod
|
|
def get_user(key, default=None, user_id=None):
|
|
return AppSetting.get(SettingsService._user_scope_key(key, user_id), default=default)
|
|
|
|
@staticmethod
|
|
def get_user_secret(key, default=None, user_id=None):
|
|
return AppSetting.get(SettingsService._user_scope_key(key, user_id), default=default, decrypt=True)
|
|
|
|
@staticmethod
|
|
def set_many_user(mapping: dict[str, tuple[object, bool] | object], user_id=None):
|
|
for key, value in mapping.items():
|
|
if isinstance(value, tuple):
|
|
raw, encrypt = value
|
|
else:
|
|
raw, encrypt = value, False
|
|
AppSetting.set(SettingsService._user_scope_key(key, user_id), raw, encrypt=encrypt)
|
|
db.session.commit()
|
|
|
|
@staticmethod
|
|
def get_preference(scope_name: str, default='global', user_id=None):
|
|
return AppSetting.get(SettingsService._user_scope_key(f'pref.{scope_name}.mode', user_id), default=default)
|
|
|
|
@staticmethod
|
|
def set_preference(scope_name: str, mode: str, user_id=None):
|
|
AppSetting.set(SettingsService._user_scope_key(f'pref.{scope_name}.mode', user_id), mode)
|
|
db.session.commit()
|
|
|
|
@staticmethod
|
|
def get_effective(key, default=None, company_id=None, user_id=None, scope_name=None, user_default='global'):
|
|
scope_name = scope_name or key.split('.', 1)[0]
|
|
mode = SettingsService.get_preference(scope_name, default=user_default, user_id=user_id)
|
|
if mode == 'user':
|
|
value = SettingsService.get_user(key, default=None, user_id=user_id)
|
|
if value not in [None, '']:
|
|
return value
|
|
return SettingsService.get(key, default=default, company_id=company_id)
|
|
|
|
@staticmethod
|
|
def get_effective_secret(key, default=None, company_id=None, user_id=None, scope_name=None, user_default='global'):
|
|
scope_name = scope_name or key.split('.', 1)[0]
|
|
mode = SettingsService.get_preference(scope_name, default=user_default, user_id=user_id)
|
|
if mode == 'user':
|
|
value = SettingsService.get_user_secret(key, default=None, user_id=user_id)
|
|
if value not in [None, '']:
|
|
return value
|
|
return SettingsService.get_secret(key, default=default, company_id=company_id)
|