0008-add-debug-application-29240.patch
hobo/debug/forms.py | ||
---|---|---|
1 |
# hobo - portal to configure and deploy applications |
|
2 |
# Copyright (C) 2015-2019 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
from django import forms |
|
18 |
from django.core.validators import validate_ipv46_address |
|
19 |
from django.core.exceptions import ValidationError |
|
20 |
from django.utils.translation import ugettext_lazy as _ |
|
21 | ||
22 | ||
23 |
def validate_space_separated_ips(value): |
|
24 |
errors = [] |
|
25 |
for ip in value: |
|
26 |
try: |
|
27 |
validate_ipv46_address(ip) |
|
28 |
except ValidationError as e: |
|
29 |
errors.append(e) |
|
30 |
if errors: |
|
31 |
raise ValidationError(errors) |
|
32 | ||
33 | ||
34 |
class MultipleIPAddressField(forms.CharField): |
|
35 |
default_validators = [validate_space_separated_ips] |
|
36 | ||
37 |
def to_python(self, value): |
|
38 |
if value in self.empty_values: |
|
39 |
return [] |
|
40 |
return value.split() |
|
41 | ||
42 |
def prepare_value(self, value): |
|
43 |
if not value: |
|
44 |
return '' |
|
45 |
return ' '.join(value) |
|
46 | ||
47 | ||
48 |
class SettingsForm(forms.Form): |
|
49 |
debug_log = forms.BooleanField( |
|
50 |
required=False, |
|
51 |
label=_('Debug log')) |
|
52 |
debug_ips = MultipleIPAddressField( |
|
53 |
label=_('Debug IPS'), |
|
54 |
required=False, |
|
55 |
help_text=_('List of IPs for which to enable debugging')) |
hobo/debug/templates/hobo/debug_home.html | ||
---|---|---|
1 |
{% extends "hobo/base.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block breadcrumb %} |
|
5 |
{{ block.super }} |
|
6 |
<a href="{% url 'debug-home' %}">{% trans "Debugging" %}</a> |
|
7 |
{% endblock %} |
|
8 | ||
9 |
{% block appbar %} |
|
10 |
<h2>{% trans 'Debugging' %}</h2> |
|
11 |
{% endblock %} |
|
12 | ||
13 |
{% block content %} |
|
14 | ||
15 |
<form method="post"> |
|
16 |
{% csrf_token %} |
|
17 |
{{ form.as_p }} |
|
18 | ||
19 |
<div class="buttons"> |
|
20 |
<button class="submit-button">{% trans "Save" %}</button> |
|
21 |
<button class="submit-button" |
|
22 |
name="toggle-current-ip">{% if current_ip_debug %}{% trans "Remove current IP" %}{% else %}{% trans "Add current IP" %}{% endif %} - {{ view.current_ip }}</button> |
|
23 |
</div> |
|
24 |
</form> |
|
25 | ||
26 |
{% endblock %} |
hobo/debug/urls.py | ||
---|---|---|
1 |
# hobo - portal to configure and deploy applications |
|
2 |
# Copyright (C) 2015-2019 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
from django.conf.urls import url |
|
18 | ||
19 |
from . import views |
|
20 | ||
21 |
urlpatterns = [ |
|
22 |
url(r'^$', views.home, name='debug-home'), |
|
23 |
] |
hobo/debug/views.py | ||
---|---|---|
1 |
# hobo - portal to configure and deploy applications |
|
2 |
# Copyright (C) 2015-2019 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
from django.core.urlresolvers import reverse_lazy |
|
18 |
from django.views.generic import FormView |
|
19 |
from django.utils.functional import cached_property |
|
20 | ||
21 |
from hobo.environment.utils import get_setting_variable |
|
22 | ||
23 |
from .forms import SettingsForm |
|
24 | ||
25 | ||
26 |
class HomeView(FormView): |
|
27 |
template_name = 'hobo/debug_home.html' |
|
28 |
form_class = SettingsForm |
|
29 |
success_url = reverse_lazy('debug-home') |
|
30 | ||
31 |
@cached_property |
|
32 |
def debug_log_variable(self): |
|
33 |
return get_setting_variable('DEBUG_LOG') |
|
34 | ||
35 |
@cached_property |
|
36 |
def debug_ips_variable(self): |
|
37 |
return get_setting_variable('INTERNAL_IPS') |
|
38 | ||
39 |
def get_initial(self): |
|
40 |
initial = super(HomeView, self).get_initial() |
|
41 |
initial['debug_log'] = bool(self.debug_log_variable.json) |
|
42 |
initial['debug_ips'] = self.debug_ips_variable.json |
|
43 |
return initial |
|
44 | ||
45 |
@property |
|
46 |
def current_ip(self): |
|
47 |
return self.request.META.get('REMOTE_ADDR') or None |
|
48 | ||
49 |
def get_context_data(self, **kwargs): |
|
50 |
ctx = super(HomeView, self).get_context_data(**kwargs) |
|
51 |
ctx['current_ip_debug'] = self.current_ip in self.debug_ips_variable.json |
|
52 |
return ctx |
|
53 | ||
54 |
def toggle_value(self, l, value): |
|
55 |
if value in l: |
|
56 |
return [x for x in l if x != value] |
|
57 |
else: |
|
58 |
return l + [value] |
|
59 | ||
60 |
def form_valid(self, form): |
|
61 |
debug_log = form.cleaned_data['debug_log'] |
|
62 |
self.debug_log_variable.json = debug_log |
|
63 |
self.debug_log_variable.save() |
|
64 | ||
65 |
debug_ips = form.cleaned_data['debug_ips'] |
|
66 |
if 'toggle-current-ip' in self.request.POST: |
|
67 |
debug_ips = self.toggle_value(debug_ips, self.current_ip) |
|
68 |
self.debug_ips_variable.json = debug_ips |
|
69 |
self.debug_ips_variable.save() |
|
70 |
return super(HomeView, self).form_valid(form) |
|
71 | ||
72 |
home = HomeView.as_view() |
hobo/settings.py | ||
---|---|---|
39 | 39 |
'rest_framework', |
40 | 40 |
'mellon', |
41 | 41 |
'gadjo', |
42 |
'hobo.debug', |
|
42 | 43 |
'hobo.environment', |
43 | 44 |
'hobo.franceconnect', |
44 | 45 |
'hobo.profile', |
hobo/templates/hobo/home.html | ||
---|---|---|
12 | 12 |
<li><a href="{% url 'franceconnect-home' %}">FranceConnect</a></li> |
13 | 13 |
<li><a href="{% url 'environment-home' %}">{% trans 'Services' %}</a></li> |
14 | 14 |
<li><a href="{% url 'environment-variables' %}">{% trans 'Variables' %}</a></li> |
15 |
<li><a href="{% url 'debug-home' %}">{% trans 'Debugging' %}</a></li> |
|
15 | 16 |
</ul> |
16 | 17 |
</span> |
17 | 18 |
{% endblock %} |
hobo/urls.py | ||
---|---|---|
26 | 26 |
from .profile.urls import urlpatterns as profile_urls |
27 | 27 |
from .theme.urls import urlpatterns as theme_urls |
28 | 28 |
from .emails.urls import urlpatterns as emails_urls |
29 |
from .debug.urls import urlpatterns as debug_urls |
|
29 | 30 | |
30 | 31 |
admin.autodiscover() |
31 | 32 | |
... | ... | |
36 | 37 |
url(r'^franceconnect/', decorated_includes(admin_required, include(franceconnect_urls))), |
37 | 38 |
url(r'^theme/', decorated_includes(admin_required, include(theme_urls))), |
38 | 39 |
url(r'^emails/', decorated_includes(admin_required, include(emails_urls))), |
40 |
url(r'^debug/', decorated_includes(admin_required, include(debug_urls))), |
|
39 | 41 |
url(r'^api/health/$', health_json, name='health-json'), |
40 | 42 |
url(r'^menu.json$', menu_json, name='menu_json'), |
41 | 43 |
url(r'^hobos.json$', hobo), |
tests/test_manager.py | ||
---|---|---|
84 | 84 | |
85 | 85 |
def test_attribute_kind_not_restricted_at_model_level(db): |
86 | 86 |
assert models.AttributeDefinition.objects.create(label='test', kind='somestring') |
87 | ||
88 | ||
89 |
def test_debug_home(logged_app): |
|
90 |
from hobo.environment.utils import get_setting_variable, get_installed_services_dict |
|
91 | ||
92 |
IPS = '99.99.99.99 77.77.77.77' |
|
93 |
IP_LIST = ['99.99.99.99', '77.77.77.77'] |
|
94 | ||
95 |
page = logged_app.get('/debug/') |
|
96 |
page.form['debug_log'] = True |
|
97 |
page.form['debug_ips'] = IPS |
|
98 |
page = page.form.submit().follow() |
|
99 | ||
100 |
assert get_setting_variable('DEBUG_LOG').json is True |
|
101 |
assert get_setting_variable('INTERNAL_IPS').json == IP_LIST |
|
102 |
hobo_json = get_installed_services_dict() |
|
103 |
assert hobo_json['variables']['SETTING_DEBUG_LOG'] is True |
|
104 |
assert hobo_json['variables']['SETTING_INTERNAL_IPS'] == IP_LIST |
|
105 | ||
106 |
page.form['debug_log'] = False |
|
107 |
page.form['debug_ips'] = '' |
|
108 |
page = page.form.submit().follow() |
|
109 | ||
110 |
assert get_setting_variable('DEBUG_LOG').json is False |
|
111 |
assert get_setting_variable('INTERNAL_IPS').json == [] |
|
112 |
hobo_json = get_installed_services_dict() |
|
113 |
assert hobo_json['variables']['SETTING_DEBUG_LOG'] is False |
|
114 |
assert hobo_json['variables']['SETTING_INTERNAL_IPS'] == [] |
|
87 |
- |