multitenant: add loader to get settings from theme (#26636)

This commit is contained in:
Frédéric Péters 2018-09-23 15:14:55 +02:00
parent d51ccaaa48
commit 44dbfbeed8
7 changed files with 80 additions and 21 deletions

View File

@ -7,7 +7,7 @@ recursive-include hobo/emails/templates *.html *.txt
recursive-include hobo/locale *.po *.mo
recursive-include hobo/environment/locale *.po *.mo
recursive-include hobo/agent/authentic2/locale *.po *.mo
recursive-include tests *.py
recursive-include tests *.py *.json
recursive-include hobo/contrib/ozwillo/scripts *.py
recursive-include hobo/contrib/ozwillo/examples *.json
include hobo/contrib/ozwillo/README.rst

View File

@ -278,6 +278,7 @@ if PROJECT_NAME != 'wcs':
TENANT_SETTINGS_LOADERS = (
'hobo.multitenant.settings_loaders.TemplateVars',
'hobo.multitenant.settings_loaders.KnownServices',
'hobo.multitenant.settings_loaders.ThemeSettings',
'hobo.multitenant.settings_loaders.CORSSettings',
'hobo.multitenant.settings_loaders.SharedThemeSettings',
'hobo.multitenant.settings_loaders.Mellon',

View File

@ -7,6 +7,8 @@ from django.conf import settings
from django.utils.encoding import smart_bytes
from django.utils.six.moves.urllib import parse as urlparse
from hobo.theme.utils import get_theme
class FileBaseSettingsLoader(object):
"""
@ -33,6 +35,28 @@ class FileBaseSettingsLoader(object):
raise NotImplemented
class SettingsDictUpdateMixin(object):
def do_update(self, tenant_settings, key, value):
old_value = getattr(tenant_settings, key, {})
new_value = old_value.copy()
new_value.update(value)
setattr(tenant_settings, key, new_value)
def do_extend(self, tenant_settings, key, value):
new_value = list(getattr(tenant_settings, key, []))
new_value.extend(value)
setattr(tenant_settings, key, new_value)
def handle_settings(self, tenant_settings, new_settings):
for key in new_settings:
if '.' in key:
real_key, op = key.rsplit('.', 1)
method = getattr(self, 'do_%s' % op)
method(tenant_settings, real_key, new_settings[key])
else:
setattr(tenant_settings, key, new_settings[key])
class KnownServices(FileBaseSettingsLoader):
FILENAME = 'hobo.json'
@ -172,6 +196,24 @@ class CORSSettings(FileBaseSettingsLoader):
tenant_settings.CORS_ORIGIN_WHITELIST = whitelist
class ThemeSettings(SettingsDictUpdateMixin):
def get_new_time(self, tenant):
return 0
def update_settings(self, tenant_settings, tenant):
theme_id = tenant_settings.TEMPLATE_VARS.get('theme')
if not theme_id:
return
theme = get_theme(theme_id)
if not theme:
return
module_name = settings.SETTINGS_MODULE.split('.')[0]
module_settings = theme.get('settings', {}).get(module_name)
if not module_settings:
return
self.handle_settings(tenant_settings, module_settings)
class SharedThemeSettings(FileBaseSettingsLoader):
FILENAME = 'hobo.json'
@ -297,30 +339,12 @@ class SiteBaseUrl(object):
# Generic loaders (not recommended)
#
class SettingsJSON(FileBaseSettingsLoader):
class SettingsJSON(FileBaseSettingsLoader, SettingsDictUpdateMixin):
FILENAME = 'settings.json'
def do_update(self, tenant_settings, key, value):
old_value = getattr(tenant_settings, key, {})
new_value = old_value.copy()
new_value.update(value)
setattr(tenant_settings, key, new_value)
def do_extend(self, tenant_settings, key, value):
new_value = list(getattr(tenant_settings, key, []))
new_value.extend(value)
setattr(tenant_settings, key, new_value)
def update_settings_from_path(self, tenant_settings, path):
with open(path) as f:
json_settings = json.load(f)
for key in json_settings:
if '.' in key:
real_key, op = key.rsplit('.', 1)
method = getattr(self, 'do_%s' % op)
method(tenant_settings, real_key, json_settings[key])
else:
setattr(tenant_settings, key, json_settings[key])
self.handle_settings(tenant_settings, json.load(f))
class DictAdapter(dict):

View File

@ -29,6 +29,7 @@ def tenants(transactional_db, request, settings):
'variables': {
'hobo_test_variable': True,
'other_variable': 'foo',
'theme': 'publik',
},
'services': [
{'slug': 'test',

View File

@ -0,0 +1,15 @@
[
{
"id": "publik",
"label": "Publik",
"variables": {
"css_variant": "publik",
"theme_color": "#E80E89"
},
"settings": {
"fake": {
"HELLO": "world"
}
}
}
]

View File

@ -60,3 +60,5 @@ LOGGING = None
UPDATE_ME = {'x': 1}
EXTEND_ME = [1]
THEMES_DIRECTORY = os.path.join(os.path.dirname(__file__), 'files')

View File

@ -12,6 +12,7 @@ from django.core.cache import cache, caches
from tenant_schemas.utils import tenant_context
import utilities
from hobo.theme.utils import set_theme, get_themes
def test_tenant_middleware(tenants, client, settings):
settings.ALLOWED_HOSTS.append('invalid.example.net')
@ -95,6 +96,21 @@ def test_tenant_cors_settings(tenants, settings, client):
with pytest.raises(AttributeError):
django.conf.settings.CORS_ORIGIN_WHITELIST
def test_tenant_theme_settings(tenants, settings, client):
from hobo.multitenant.models import Tenant
django.conf.settings.clear_tenants_settings()
with utilities.patch_default_settings(settings,
TENANT_SETTINGS_LOADERS=('hobo.multitenant.settings_loaders.TemplateVars',
'hobo.multitenant.settings_loaders.ThemeSettings')):
settings.SETTINGS_MODULE = 'fake.settings'
with tenant_context(tenants[0]):
# check it's defined when moving into the schema
assert django.conf.settings.TEMPLATE_VARS
assert django.conf.settings.TEMPLATE_VARS['theme'] == 'publik'
assert django.conf.settings.HELLO == 'world'
def test_multithreading(tenants, settings, client):
settings.clear_tenants_settings()