data: add site settings model to configure welcome urls (#15846)
This commit is contained in:
parent
d13e801e24
commit
4c7c20ac95
|
@ -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', '0048_page_edit_roles'),
|
||||||
|
]
|
||||||
|
|
||||||
|
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.',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
|
@ -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', '0049_sitesettings'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(create_site_settings),
|
||||||
|
]
|
|
@ -2204,3 +2204,16 @@ def cell_maintain_page_cell_cache(sender, instance=None, **kwargs):
|
||||||
page.save(update_fields=['last_update_timestamp'])
|
page.save(update_fields=['last_update_timestamp'])
|
||||||
return
|
return
|
||||||
page.build_cell_cache()
|
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,
|
||||||
|
)
|
||||||
|
|
|
@ -24,7 +24,7 @@ from django.template import Template, TemplateSyntaxError
|
||||||
from django.template.loader import TemplateDoesNotExist, get_template
|
from django.template.loader import TemplateDoesNotExist, get_template
|
||||||
from django.utils.translation import ugettext_lazy as _
|
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
|
from .fields import ImageIncludingSvgField
|
||||||
|
|
||||||
|
@ -317,3 +317,9 @@ class SiteExportForm(forms.Form):
|
||||||
assets = forms.BooleanField(label=_('Assets'), required=False, initial=True)
|
assets = forms.BooleanField(label=_('Assets'), required=False, initial=True)
|
||||||
asset_files = forms.BooleanField(label=_('Assets Files'), required=False, initial=False)
|
asset_files = forms.BooleanField(label=_('Assets Files'), required=False, initial=False)
|
||||||
payment = forms.BooleanField(label=_('Online Payment'), required=False, initial=True)
|
payment = forms.BooleanField(label=_('Online Payment'), required=False, initial=True)
|
||||||
|
|
||||||
|
|
||||||
|
class SiteSettingsForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = SiteSettings
|
||||||
|
fields = '__all__'
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
<li><a href="{% url 'combo-manager-site-export' %}" rel="popup" data-autoclose-dialog="true">{% trans 'Export Site' %}</a></li>
|
<li><a href="{% url 'combo-manager-site-export' %}" rel="popup" data-autoclose-dialog="true">{% trans 'Export Site' %}</a></li>
|
||||||
<li><a href="{% url 'combo-manager-site-import' %}">{% trans 'Import Site' %}</a></li>
|
<li><a href="{% url 'combo-manager-site-import' %}">{% trans 'Import Site' %}</a></li>
|
||||||
<li><a href="{% url 'combo-manager-invalid-cell-report' %}">{% trans 'Anomaly report' %}</a></li>
|
<li><a href="{% url 'combo-manager-invalid-cell-report' %}">{% trans 'Anomaly report' %}</a></li>
|
||||||
|
<li><a href="{% url 'combo-manager-site-settings' %}" rel="popup" data-autoclose-dialog="true">{% trans 'Site Settings' %}</a></li>
|
||||||
{% for extra_action in extra_actions %}
|
{% for extra_action in extra_actions %}
|
||||||
<li><a href="{{ extra_action.href }}">{{ extra_action.text }}</a></li>
|
<li><a href="{{ extra_action.href }}">{{ extra_action.text }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
{% extends "combo/manager_base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block appbar %}
|
||||||
|
<h2>{% trans "Site Settings" %}</h2>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form.as_p }}
|
||||||
|
<div class="buttons">
|
||||||
|
<button class="submit-button">{% trans "Save" %}</button>
|
||||||
|
<a class="cancel" href="{% url 'combo-manager-homepage' %}">{% trans 'Cancel' %}</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -29,6 +29,7 @@ urlpatterns = [
|
||||||
url(r'^menu.json$', views.menu_json),
|
url(r'^menu.json$', views.menu_json),
|
||||||
url(r'^site-export$', staff_required(views.site_export), name='combo-manager-site-export'),
|
url(r'^site-export$', staff_required(views.site_export), name='combo-manager-site-export'),
|
||||||
url(r'^site-import$', staff_required(views.site_import), name='combo-manager-site-import'),
|
url(r'^site-import$', staff_required(views.site_import), name='combo-manager-site-import'),
|
||||||
|
url(r'^site-settings$', views.site_settings, name='combo-manager-site-settings'),
|
||||||
url(
|
url(
|
||||||
r'^cells/invalid-report/$',
|
r'^cells/invalid-report/$',
|
||||||
staff_required(views.invalid_cell_report),
|
staff_required(views.invalid_cell_report),
|
||||||
|
|
|
@ -46,7 +46,7 @@ from django.views.generic import (
|
||||||
|
|
||||||
from combo import plugins
|
from combo import plugins
|
||||||
from combo.data.library import get_cell_class
|
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 (
|
from combo.data.utils import (
|
||||||
ImportSiteError,
|
ImportSiteError,
|
||||||
MissingSubSlug,
|
MissingSubSlug,
|
||||||
|
@ -75,6 +75,7 @@ from .forms import (
|
||||||
PageVisibilityForm,
|
PageVisibilityForm,
|
||||||
SiteExportForm,
|
SiteExportForm,
|
||||||
SiteImportForm,
|
SiteImportForm,
|
||||||
|
SiteSettingsForm,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -995,3 +996,15 @@ class LinkListOrder(ManagedPageMixin, View):
|
||||||
|
|
||||||
|
|
||||||
link_list_order = LinkListOrder.as_view()
|
link_list_order = LinkListOrder.as_view()
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
|
@ -54,6 +54,7 @@ from combo.data.models import (
|
||||||
ParentContentCell,
|
ParentContentCell,
|
||||||
PostException,
|
PostException,
|
||||||
Redirect,
|
Redirect,
|
||||||
|
SiteSettings,
|
||||||
TextCell,
|
TextCell,
|
||||||
)
|
)
|
||||||
from combo.data.utils import MissingSubSlug, get_page_from_url_parts
|
from combo.data.utils import MissingSubSlug, get_page_from_url_parts
|
||||||
|
@ -459,9 +460,10 @@ def page(request):
|
||||||
if not parts:
|
if not parts:
|
||||||
parts = ['index']
|
parts = ['index']
|
||||||
|
|
||||||
|
site_settings = SiteSettings.objects.get()
|
||||||
if (
|
if (
|
||||||
parts == ['index']
|
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)
|
and (request.user and not request.user.is_anonymous)
|
||||||
):
|
):
|
||||||
profile, dummy = Profile.objects.get_or_create(user=request.user)
|
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
|
# first connection of user, record that and redirect to welcome URL
|
||||||
profile.initial_login_view_timestamp = timezone.now()
|
profile.initial_login_view_timestamp = timezone.now()
|
||||||
profile.save()
|
profile.save()
|
||||||
return HttpResponseRedirect(settings.COMBO_INITIAL_LOGIN_PAGE_PATH)
|
return HttpResponseRedirect(site_settings.initial_login_page_path)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
parts == ['index']
|
parts == ['index']
|
||||||
and settings.COMBO_WELCOME_PAGE_PATH
|
and site_settings.welcome_page_path
|
||||||
and (not request.user or request.user.is_anonymous)
|
and (not request.user or request.user.is_anonymous)
|
||||||
):
|
):
|
||||||
if not request.session.setdefault('visited', False):
|
if not request.session.setdefault('visited', False):
|
||||||
# first visit, the user is not logged in.
|
# first visit, the user is not logged in.
|
||||||
request.session['visited'] = True
|
request.session['visited'] = True
|
||||||
return HttpResponseRedirect(settings.COMBO_WELCOME_PAGE_PATH)
|
return HttpResponseRedirect(site_settings.welcome_page_path)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
page = get_page_from_url_parts(parts, request)
|
page = get_page_from_url_parts(parts, request)
|
||||||
|
|
|
@ -267,12 +267,6 @@ LINGO_NO_ONLINE_PAYMENT_REASONS = {}
|
||||||
|
|
||||||
JSON_CELL_TYPES = {}
|
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
|
# dashboard support
|
||||||
COMBO_DASHBOARD_ENABLED = False
|
COMBO_DASHBOARD_ENABLED = False
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ from combo.data.models import (
|
||||||
Page,
|
Page,
|
||||||
PageSnapshot,
|
PageSnapshot,
|
||||||
ParentContentCell,
|
ParentContentCell,
|
||||||
|
SiteSettings,
|
||||||
TextCell,
|
TextCell,
|
||||||
ValidityInfo,
|
ValidityInfo,
|
||||||
)
|
)
|
||||||
|
@ -2633,3 +2634,17 @@ def test_redirect_to_page_edit(app, admin_user):
|
||||||
|
|
||||||
resp = app.get('/manage/pages/users/xxx/', status=302)
|
resp = app.get('/manage/pages/users/xxx/', status=302)
|
||||||
assert resp.location == '/manage/pages/%s/' % page3.pk
|
assert resp.location == '/manage/pages/%s/' % page3.pk
|
||||||
|
|
||||||
|
|
||||||
|
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/'
|
||||||
|
|
|
@ -33,6 +33,7 @@ from combo.data.models import (
|
||||||
Page,
|
Page,
|
||||||
ParentContentCell,
|
ParentContentCell,
|
||||||
Redirect,
|
Redirect,
|
||||||
|
SiteSettings,
|
||||||
TextCell,
|
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 = Page(title='Initial Login', slug='initial-login', template_name='standard', public=False)
|
||||||
page.save()
|
page.save()
|
||||||
|
|
||||||
with override_settings(COMBO_INITIAL_LOGIN_PAGE_PATH='/initial-login/'):
|
site_settings = SiteSettings.objects.get()
|
||||||
resp = app.get('/', status=200)
|
site_settings.initial_login_page_path = '/initial-login/'
|
||||||
|
site_settings.save()
|
||||||
|
|
||||||
# first visit
|
resp = app.get('/', status=200)
|
||||||
app = login(app)
|
|
||||||
resp = app.get('/', status=302)
|
|
||||||
assert urllib.parse.urlparse(resp.location).path == '/initial-login/'
|
|
||||||
|
|
||||||
# visit again
|
# first visit
|
||||||
resp = app.get('/', status=200)
|
app = login(app)
|
||||||
|
resp = app.get('/', status=302)
|
||||||
|
assert urllib.parse.urlparse(resp.location).path == '/initial-login/'
|
||||||
|
|
||||||
|
# visit again
|
||||||
|
resp = app.get('/', status=200)
|
||||||
|
|
||||||
|
|
||||||
def test_welcome_page(app, admin_user):
|
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 = Page(title='Welcome', slug='welcome', template_name='standard')
|
||||||
page.save()
|
page.save()
|
||||||
|
|
||||||
with override_settings(COMBO_WELCOME_PAGE_PATH='/welcome/'):
|
site_settings = SiteSettings.objects.get()
|
||||||
app.cookiejar.clear()
|
site_settings.welcome_page_path = '/welcome/'
|
||||||
resp = app.get('/', status=302)
|
site_settings.save()
|
||||||
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()
|
resp = app.get('/', status=200)
|
||||||
resp = app.get('/', status=302)
|
|
||||||
assert urllib.parse.urlparse(resp.location).path == '/welcome/'
|
|
||||||
|
|
||||||
app.cookiejar.clear()
|
app.cookiejar.clear()
|
||||||
app = login(app)
|
resp = app.get('/', status=302)
|
||||||
resp = app.get('/', status=200)
|
assert urllib.parse.urlparse(resp.location).path == '/welcome/'
|
||||||
|
|
||||||
|
app.cookiejar.clear()
|
||||||
|
app = login(app)
|
||||||
|
resp = app.get('/', status=200)
|
||||||
|
|
||||||
|
|
||||||
def test_post_cell(app):
|
def test_post_cell(app):
|
||||||
|
|
|
@ -2506,7 +2506,7 @@ def test_view_page_with_wcs_cells_num_queries(app, admin_user):
|
||||||
app.get('/') # load once to populate caches
|
app.get('/') # load once to populate caches
|
||||||
with CaptureQueriesContext(connection) as ctx:
|
with CaptureQueriesContext(connection) as ctx:
|
||||||
app.get('/')
|
app.get('/')
|
||||||
assert len(ctx.captured_queries) == 61
|
assert len(ctx.captured_queries) == 62
|
||||||
|
|
||||||
|
|
||||||
def test_hourly():
|
def test_hourly():
|
||||||
|
|
Loading…
Reference in New Issue