push
This commit is contained in:
115
app/services/settings_service.py
Normal file
115
app/services/settings_service.py
Normal file
@@ -0,0 +1,115 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user