From e913695da39a3705054cf3467970593335c7c577 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Fri, 8 Mar 2019 02:41:26 +0100 Subject: [PATCH 8/9] add debug application (#29240) --- hobo/debug/__init__.py | 0 hobo/debug/forms.py | 55 +++++++++++++++++ hobo/debug/templates/hobo/debug_home.html | 26 ++++++++ hobo/debug/urls.py | 23 ++++++++ hobo/debug/views.py | 72 +++++++++++++++++++++++ hobo/settings.py | 1 + hobo/templates/hobo/home.html | 1 + hobo/urls.py | 2 + tests/test_manager.py | 28 +++++++++ 9 files changed, 208 insertions(+) create mode 100644 hobo/debug/__init__.py create mode 100644 hobo/debug/forms.py create mode 100644 hobo/debug/templates/hobo/debug_home.html create mode 100644 hobo/debug/urls.py create mode 100644 hobo/debug/views.py diff --git a/hobo/debug/__init__.py b/hobo/debug/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hobo/debug/forms.py b/hobo/debug/forms.py new file mode 100644 index 0000000..d00cd54 --- /dev/null +++ b/hobo/debug/forms.py @@ -0,0 +1,55 @@ +# hobo - portal to configure and deploy applications +# Copyright (C) 2015-2019 Entr'ouvert +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from django import forms +from django.core.validators import validate_ipv46_address +from django.core.exceptions import ValidationError +from django.utils.translation import ugettext_lazy as _ + + +def validate_space_separated_ips(value): + errors = [] + for ip in value: + try: + validate_ipv46_address(ip) + except ValidationError as e: + errors.append(e) + if errors: + raise ValidationError(errors) + + +class MultipleIPAddressField(forms.CharField): + default_validators = [validate_space_separated_ips] + + def to_python(self, value): + if value in self.empty_values: + return [] + return value.split() + + def prepare_value(self, value): + if not value: + return '' + return ' '.join(value) + + +class SettingsForm(forms.Form): + debug_log = forms.BooleanField( + required=False, + label=_('Debug log')) + debug_ips = MultipleIPAddressField( + label=_('Internal IP adresses'), + required=False, + help_text=_('List of IP adresses for which to enable debugging')) diff --git a/hobo/debug/templates/hobo/debug_home.html b/hobo/debug/templates/hobo/debug_home.html new file mode 100644 index 0000000..e307730 --- /dev/null +++ b/hobo/debug/templates/hobo/debug_home.html @@ -0,0 +1,26 @@ +{% extends "hobo/base.html" %} +{% load i18n %} + +{% block breadcrumb %} +{{ block.super }} +{% trans "Debugging" %} +{% endblock %} + +{% block appbar %} +

{% trans 'Debugging' %}

+{% endblock %} + +{% block content %} + +
+{% csrf_token %} +{{ form.as_p }} + +
+ + +
+
+ +{% endblock %} diff --git a/hobo/debug/urls.py b/hobo/debug/urls.py new file mode 100644 index 0000000..f91bad6 --- /dev/null +++ b/hobo/debug/urls.py @@ -0,0 +1,23 @@ +# hobo - portal to configure and deploy applications +# Copyright (C) 2015-2019 Entr'ouvert +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from django.conf.urls import url + +from . import views + +urlpatterns = [ + url(r'^$', views.home, name='debug-home'), +] diff --git a/hobo/debug/views.py b/hobo/debug/views.py new file mode 100644 index 0000000..cbd74ec --- /dev/null +++ b/hobo/debug/views.py @@ -0,0 +1,72 @@ +# hobo - portal to configure and deploy applications +# Copyright (C) 2015-2019 Entr'ouvert +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from django.core.urlresolvers import reverse_lazy +from django.views.generic import FormView +from django.utils.functional import cached_property + +from hobo.environment.utils import get_setting_variable + +from .forms import SettingsForm + + +class HomeView(FormView): + template_name = 'hobo/debug_home.html' + form_class = SettingsForm + success_url = reverse_lazy('debug-home') + + @cached_property + def debug_log_variable(self): + return get_setting_variable('DEBUG_LOG') + + @cached_property + def debug_ips_variable(self): + return get_setting_variable('INTERNAL_IPS') + + def get_initial(self): + initial = super(HomeView, self).get_initial() + initial['debug_log'] = bool(self.debug_log_variable.json) + initial['debug_ips'] = self.debug_ips_variable.json + return initial + + @property + def current_ip(self): + return self.request.META.get('REMOTE_ADDR') or None + + def get_context_data(self, **kwargs): + ctx = super(HomeView, self).get_context_data(**kwargs) + ctx['current_ip_debug'] = self.current_ip in self.debug_ips_variable.json + return ctx + + def toggle_value(self, l, value): + if value in l: + return [x for x in l if x != value] + else: + return l + [value] + + def form_valid(self, form): + debug_log = form.cleaned_data['debug_log'] + self.debug_log_variable.json = debug_log + self.debug_log_variable.save() + + debug_ips = form.cleaned_data['debug_ips'] + if 'toggle-current-ip' in self.request.POST: + debug_ips = self.toggle_value(debug_ips, self.current_ip) + self.debug_ips_variable.json = debug_ips + self.debug_ips_variable.save() + return super(HomeView, self).form_valid(form) + +home = HomeView.as_view() diff --git a/hobo/settings.py b/hobo/settings.py index 997ba2c..db3d164 100644 --- a/hobo/settings.py +++ b/hobo/settings.py @@ -41,6 +41,7 @@ INSTALLED_APPS = ( 'rest_framework', 'mellon', 'gadjo', + 'hobo.debug', 'hobo.environment', 'hobo.franceconnect', 'hobo.matomo', diff --git a/hobo/templates/hobo/home.html b/hobo/templates/hobo/home.html index 14b6e46..5ebc5be 100644 --- a/hobo/templates/hobo/home.html +++ b/hobo/templates/hobo/home.html @@ -13,6 +13,7 @@
  • {% trans 'User tracking' %}
  • {% trans 'Services' %}
  • {% trans 'Variables' %}
  • +
  • {% trans 'Debugging' %}
  • {% endblock %} diff --git a/hobo/urls.py b/hobo/urls.py index d98dab5..c125b15 100644 --- a/hobo/urls.py +++ b/hobo/urls.py @@ -27,6 +27,7 @@ from .matomo.urls import urlpatterns as matomo_urls from .profile.urls import urlpatterns as profile_urls from .theme.urls import urlpatterns as theme_urls from .emails.urls import urlpatterns as emails_urls +from .debug.urls import urlpatterns as debug_urls admin.autodiscover() @@ -38,6 +39,7 @@ urlpatterns = [ url(r'^matomo/', decorated_includes(admin_required, include(matomo_urls))), url(r'^theme/', decorated_includes(admin_required, include(theme_urls))), url(r'^emails/', decorated_includes(admin_required, include(emails_urls))), + url(r'^debug/', decorated_includes(admin_required, include(debug_urls))), url(r'^api/health/$', health_json, name='health-json'), url(r'^menu.json$', menu_json, name='menu_json'), url(r'^hobos.json$', hobo), diff --git a/tests/test_manager.py b/tests/test_manager.py index b42e99a..57b5f7b 100644 --- a/tests/test_manager.py +++ b/tests/test_manager.py @@ -84,3 +84,31 @@ def test_add_attribute(logged_app, admin_user, kind): def test_attribute_kind_not_restricted_at_model_level(db): assert models.AttributeDefinition.objects.create(label='test', kind='somestring') + + +def test_debug_home(logged_app): + from hobo.environment.utils import get_setting_variable, get_installed_services_dict + + IPS = '99.99.99.99 77.77.77.77' + IP_LIST = ['99.99.99.99', '77.77.77.77'] + + page = logged_app.get('/debug/') + page.form['debug_log'] = True + page.form['debug_ips'] = IPS + page = page.form.submit().follow() + + assert get_setting_variable('DEBUG_LOG').json is True + assert get_setting_variable('INTERNAL_IPS').json == IP_LIST + hobo_json = get_installed_services_dict() + assert hobo_json['variables']['SETTING_DEBUG_LOG'] is True + assert hobo_json['variables']['SETTING_INTERNAL_IPS'] == IP_LIST + + page.form['debug_log'] = False + page.form['debug_ips'] = '' + page = page.form.submit().follow() + + assert get_setting_variable('DEBUG_LOG').json is False + assert get_setting_variable('INTERNAL_IPS').json == [] + hobo_json = get_installed_services_dict() + assert hobo_json['variables']['SETTING_DEBUG_LOG'] is False + assert hobo_json['variables']['SETTING_INTERNAL_IPS'] == [] -- 2.20.1