From 1be9d3d6f21b6f7e262471a7f4ad7952070485ae Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Wed, 25 Aug 2021 17:23:23 +0200 Subject: [PATCH] data: add site settings model to configure welcome urls (#15846) --- combo/data/migrations/0048_sitesettings.py | 38 ++++++++++++++++ .../migrations/0049_populate_site_settings.py | 25 +++++++++++ combo/data/models.py | 13 ++++++ combo/manager/forms.py | 8 +++- .../manager/templates/combo/manager_home.html | 1 + .../templates/combo/site_settings.html | 18 ++++++++ combo/manager/urls.py | 1 + combo/manager/views.py | 15 ++++++- combo/public/views.py | 10 +++-- combo/settings.py | 6 --- tests/test_manager.py | 15 +++++++ tests/test_public.py | 45 +++++++++++-------- tests/test_wcs.py | 2 +- 13 files changed, 165 insertions(+), 32 deletions(-) create mode 100644 combo/data/migrations/0048_sitesettings.py create mode 100644 combo/data/migrations/0049_populate_site_settings.py create mode 100644 combo/manager/templates/combo/site_settings.html diff --git a/combo/data/migrations/0048_sitesettings.py b/combo/data/migrations/0048_sitesettings.py new file mode 100644 index 00000000..0dfba4fa --- /dev/null +++ b/combo/data/migrations/0048_sitesettings.py @@ -0,0 +1,38 @@ +# Generated by Django 2.2.19 on 2021-08-25 14:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('data', '0047_auto_20210723_1318'), + ] + + operations = [ + migrations.CreateModel( + name='SiteSettings', + fields=[ + ( + 'id', + models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + ( + 'initial_login_page_path', + models.CharField( + max_length=100, + verbose_name='Initial login page path', + help_text='Page to redirect to the first time user logs in.', + ), + ), + ( + 'welcome_page_path', + models.CharField( + max_length=100, + verbose_name='Welcome page path', + help_text='Page to redirect to on the first visit, to suggest user to log in.', + ), + ), + ], + ), + ] diff --git a/combo/data/migrations/0049_populate_site_settings.py b/combo/data/migrations/0049_populate_site_settings.py new file mode 100644 index 00000000..5e826371 --- /dev/null +++ b/combo/data/migrations/0049_populate_site_settings.py @@ -0,0 +1,25 @@ +# Generated by Django 2.2.19 on 2021-08-31 10:10 + +from django.conf import settings +from django.db import migrations + + +def create_site_settings(apps, schema_editor): + SiteSettings = apps.get_model('data', 'SiteSettings') + site_settings = SiteSettings.objects.create() + if hasattr(settings, 'COMBO_INITIAL_LOGIN_PAGE_PATH'): + site_settings.initial_login_page_path = settings.COMBO_INITIAL_LOGIN_PAGE_PATH or '' + if hasattr(settings, 'COMBO_WELCOME_PAGE_PATH'): + site_settings.welcome_page_path = settings.COMBO_WELCOME_PAGE_PATH or '' + site_settings.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('data', '0048_sitesettings'), + ] + + operations = [ + migrations.RunPython(create_site_settings), + ] diff --git a/combo/data/models.py b/combo/data/models.py index f5dd43ca..d7054ab7 100644 --- a/combo/data/models.py +++ b/combo/data/models.py @@ -2134,3 +2134,16 @@ def cell_maintain_page_cell_cache(sender, instance=None, **kwargs): page.save(update_fields=['last_update_timestamp']) return page.build_cell_cache() + + +class SiteSettings(models.Model): + initial_login_page_path = models.CharField( + _('Initial login page path'), + help_text=_('Page to redirect to the first time user logs in.'), + max_length=100, + ) + welcome_page_path = models.CharField( + _('Welcome page path'), + help_text=_('Page to redirect to on the first visit, to suggest user to log in.'), + max_length=100, + ) diff --git a/combo/manager/forms.py b/combo/manager/forms.py index 9b8e931c..0bab0c1b 100644 --- a/combo/manager/forms.py +++ b/combo/manager/forms.py @@ -24,7 +24,7 @@ from django.template import Template, TemplateSyntaxError from django.template.loader import TemplateDoesNotExist, get_template from django.utils.translation import ugettext_lazy as _ -from combo.data.models import Page, ParentContentCell, compile_sub_slug +from combo.data.models import Page, ParentContentCell, SiteSettings, compile_sub_slug from .fields import ImageIncludingSvgField @@ -279,3 +279,9 @@ class SiteExportForm(forms.Form): assets = forms.BooleanField(label=_('Assets'), required=False, initial=True) asset_files = forms.BooleanField(label=_('Assets Files'), required=False, initial=False) payment = forms.BooleanField(label=_('Online Payment'), required=False, initial=True) + + +class SiteSettingsForm(forms.ModelForm): + class Meta: + model = SiteSettings + fields = '__all__' diff --git a/combo/manager/templates/combo/manager_home.html b/combo/manager/templates/combo/manager_home.html index 204a6c2f..e4c47489 100644 --- a/combo/manager/templates/combo/manager_home.html +++ b/combo/manager/templates/combo/manager_home.html @@ -10,6 +10,7 @@
  • {% trans 'Export Site' %}
  • {% trans 'Import Site' %}
  • {% trans 'Anomaly report' %}
  • +
  • {% trans 'Site Settings' %}
  • {% for extra_action in extra_actions %}
  • {{ extra_action.text }}
  • {% endfor %} diff --git a/combo/manager/templates/combo/site_settings.html b/combo/manager/templates/combo/site_settings.html new file mode 100644 index 00000000..0e3bedb8 --- /dev/null +++ b/combo/manager/templates/combo/site_settings.html @@ -0,0 +1,18 @@ +{% extends "combo/manager_base.html" %} +{% load i18n %} + +{% block appbar %} +

    {% trans "Site Settings" %}

    +{% endblock %} + +{% block content %} + +
    + {% csrf_token %} + {{ form.as_p }} +
    + + {% trans 'Cancel' %} +
    +
    +{% endblock %} diff --git a/combo/manager/urls.py b/combo/manager/urls.py index 1e1f09b4..91b28750 100644 --- a/combo/manager/urls.py +++ b/combo/manager/urls.py @@ -29,6 +29,7 @@ urlpatterns = [ url(r'^menu.json$', views.menu_json), url(r'^site-export$', views.site_export, name='combo-manager-site-export'), url(r'^site-import$', views.site_import, name='combo-manager-site-import'), + url(r'^site-settings$', views.site_settings, name='combo-manager-site-settings'), url(r'^cells/invalid-report/$', views.invalid_cell_report, name='combo-manager-invalid-cell-report'), url(r'^pages/add/$', views.page_add, name='combo-manager-page-add'), url(r'^pages/(?P\d+)/$', views.page_view, name='combo-manager-page-view'), diff --git a/combo/manager/views.py b/combo/manager/views.py index c462a3f1..9f3c8a13 100644 --- a/combo/manager/views.py +++ b/combo/manager/views.py @@ -45,7 +45,7 @@ from django.views.generic import ( from combo import plugins from combo.data.library import get_cell_class -from combo.data.models import CellBase, LinkListCell, Page, PageSnapshot, ParentContentCell +from combo.data.models import CellBase, LinkListCell, Page, PageSnapshot, ParentContentCell, SiteSettings from combo.data.utils import ImportSiteError, export_site, export_site_tar, import_site, import_site_tar from .forms import ( @@ -63,6 +63,7 @@ from .forms import ( PageVisibilityForm, SiteExportForm, SiteImportForm, + SiteSettingsForm, ) @@ -918,3 +919,15 @@ def link_list_order(request, page_pk, cell_reference): PageSnapshot.take(cell.page, request=request, comment=_('reordered cells')) return HttpResponse(status=204) + + +class SiteSettingsView(UpdateView): + form_class = SiteSettingsForm + template_name = 'combo/site_settings.html' + success_url = reverse_lazy('combo-manager-homepage') + + def get_object(self): + return SiteSettings.objects.get() + + +site_settings = SiteSettingsView.as_view() diff --git a/combo/public/views.py b/combo/public/views.py index 0cd93d60..78c3766a 100644 --- a/combo/public/views.py +++ b/combo/public/views.py @@ -54,6 +54,7 @@ from combo.data.models import ( ParentContentCell, PostException, Redirect, + SiteSettings, TextCell, extract_context_from_sub_slug, ) @@ -459,9 +460,10 @@ def page(request): if not parts: parts = ['index'] + site_settings = SiteSettings.objects.get() if ( parts == ['index'] - and settings.COMBO_INITIAL_LOGIN_PAGE_PATH + and site_settings.initial_login_page_path and (request.user and not request.user.is_anonymous) ): profile, dummy = Profile.objects.get_or_create(user=request.user) @@ -469,17 +471,17 @@ def page(request): # first connection of user, record that and redirect to welcome URL profile.initial_login_view_timestamp = timezone.now() profile.save() - return HttpResponseRedirect(settings.COMBO_INITIAL_LOGIN_PAGE_PATH) + return HttpResponseRedirect(site_settings.initial_login_page_path) if ( parts == ['index'] - and settings.COMBO_WELCOME_PAGE_PATH + and site_settings.welcome_page_path and (not request.user or request.user.is_anonymous) ): if not request.session.setdefault('visited', False): # first visit, the user is not logged in. request.session['visited'] = True - return HttpResponseRedirect(settings.COMBO_WELCOME_PAGE_PATH) + return HttpResponseRedirect(site_settings.welcome_page_path) pages = {} for page in Page.objects.filter(slug__in=parts): diff --git a/combo/settings.py b/combo/settings.py index edd90e46..02c5ff70 100644 --- a/combo/settings.py +++ b/combo/settings.py @@ -267,12 +267,6 @@ LINGO_NO_ONLINE_PAYMENT_REASONS = {} JSON_CELL_TYPES = {} -# page to redirect the first time the user logs in. -COMBO_INITIAL_LOGIN_PAGE_PATH = None - -# page to redirect on the first visit, to suggest user to log in. -COMBO_WELCOME_PAGE_PATH = None - # dashboard support COMBO_DASHBOARD_ENABLED = False diff --git a/tests/test_manager.py b/tests/test_manager.py index 264f20d9..7eb49992 100644 --- a/tests/test_manager.py +++ b/tests/test_manager.py @@ -40,6 +40,7 @@ from combo.data.models import ( Page, PageSnapshot, ParentContentCell, + SiteSettings, TextCell, ValidityInfo, ) @@ -2486,3 +2487,17 @@ def test_edit_link_list_order(app, admin_user): for i, item in enumerate(items): item.refresh_from_db() assert item.order == new_order[i] + + +def test_site_settings(app, admin_user): + app = login(app) + + resp = app.get('/manage/') + resp = resp.click('Site Settings') + resp.form['welcome_page_path'] = '/welcome/' + resp.form['initial_login_page_path'] = '/initial-login/' + resp.form.submit() + + site_settings = SiteSettings.objects.get() + assert site_settings.welcome_page_path == '/welcome/' + assert site_settings.initial_login_page_path == '/initial-login/' diff --git a/tests/test_public.py b/tests/test_public.py index 72e1ff29..8ddd5bf4 100644 --- a/tests/test_public.py +++ b/tests/test_public.py @@ -33,6 +33,7 @@ from combo.data.models import ( Page, ParentContentCell, Redirect, + SiteSettings, TextCell, ) @@ -647,16 +648,19 @@ def test_initial_login_page(app, admin_user): page = Page(title='Initial Login', slug='initial-login', template_name='standard', public=False) page.save() - with override_settings(COMBO_INITIAL_LOGIN_PAGE_PATH='/initial-login/'): - resp = app.get('/', status=200) + site_settings = SiteSettings.objects.get() + site_settings.initial_login_page_path = '/initial-login/' + site_settings.save() - # first visit - app = login(app) - resp = app.get('/', status=302) - assert urllib.parse.urlparse(resp.location).path == '/initial-login/' + resp = app.get('/', status=200) + + # first visit + app = login(app) + resp = app.get('/', status=302) + assert urllib.parse.urlparse(resp.location).path == '/initial-login/' - # visit again - resp = app.get('/', status=200) + # visit again + resp = app.get('/', status=200) def test_welcome_page(app, admin_user): @@ -666,20 +670,23 @@ def test_welcome_page(app, admin_user): page = Page(title='Welcome', slug='welcome', template_name='standard') page.save() - with override_settings(COMBO_WELCOME_PAGE_PATH='/welcome/'): - app.cookiejar.clear() - resp = app.get('/', status=302) - assert urllib.parse.urlparse(resp.location).path == '/welcome/' + site_settings = SiteSettings.objects.get() + site_settings.welcome_page_path = '/welcome/' + site_settings.save() - resp = app.get('/', status=200) + app.cookiejar.clear() + resp = app.get('/', status=302) + assert urllib.parse.urlparse(resp.location).path == '/welcome/' - app.cookiejar.clear() - resp = app.get('/', status=302) - assert urllib.parse.urlparse(resp.location).path == '/welcome/' + resp = app.get('/', status=200) + + app.cookiejar.clear() + resp = app.get('/', status=302) + assert urllib.parse.urlparse(resp.location).path == '/welcome/' - app.cookiejar.clear() - app = login(app) - resp = app.get('/', status=200) + app.cookiejar.clear() + app = login(app) + resp = app.get('/', status=200) def test_post_cell(app): diff --git a/tests/test_wcs.py b/tests/test_wcs.py index dc03af6a..1d30f834 100644 --- a/tests/test_wcs.py +++ b/tests/test_wcs.py @@ -2420,7 +2420,7 @@ def test_view_page_with_wcs_cells_num_queries(app, admin_user): app.get('/') # load once to populate caches with CaptureQueriesContext(connection) as ctx: app.get('/') - assert len(ctx.captured_queries) == 61 + assert len(ctx.captured_queries) == 62 def test_hourly(): -- 2.20.1