From 155af563f96d625fb253bc21ab21d6225ebd9bb3 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE
Date: Wed, 27 Mar 2019 17:12:30 +0100
Subject: [PATCH 4/4] matomo: manage automatic configuration (#19743)
---
hobo/matomo/templates/hobo/matomo_home.html | 74 ++++++++----
hobo/matomo/views.py | 19 ++-
tests/test_matomo_views.py | 125 ++++++++++++++++++++
3 files changed, 195 insertions(+), 23 deletions(-)
create mode 100644 tests/test_matomo_views.py
diff --git a/hobo/matomo/templates/hobo/matomo_home.html b/hobo/matomo/templates/hobo/matomo_home.html
index e1c87e7..02bfb95 100644
--- a/hobo/matomo/templates/hobo/matomo_home.html
+++ b/hobo/matomo/templates/hobo/matomo_home.html
@@ -36,6 +36,11 @@
{% if not enabled %}
+ {% if error != '' %}
+
+ {{ error }}
+
+ {% endif %}
{% trans "Support is currently disabled." %}
@@ -43,42 +48,71 @@
{% trans 'Automatic' %}
{% else %}
-
-{% if cnil_ack_level == 'success' %}
+ {% if tracking_js != '' %}
+ {% if cnil_ack_level == 'success' %}
suivi des recommandations CNIL
-{% elif cnil_ack_level == 'warning' %}
+ {% elif cnil_ack_level == 'warning' %}
suivi des recommandations CNIL
-{% elif cnil_ack_level == 'error' %}
+ {% elif cnil_ack_level == 'error' %}
suivi des recommandations CNIL
-{% endif %}
+ {% endif %}
+ {% endif %}
-{% if mode == 'manual' %}
-
- {% trans "Manual mode." %}
-
-{% endif %}
-
-{% if mode == 'auto' %}
-
- {% trans "Automatic mode." %}
-
-{% endif %}
+ {% if mode == 'manual' %}
+
+ {% trans "Manual mode" %}
+
+ {% endif %}
-{% endif %}
+ {% if mode == 'auto' %}
+
+
+ {% trans "Automatic mode" %}
+
+
+
+ {% endif %}
+{% endif %}
{% endblock %}
diff --git a/hobo/matomo/views.py b/hobo/matomo/views.py
index f9552b9..236c7ba 100644
--- a/hobo/matomo/views.py
+++ b/hobo/matomo/views.py
@@ -14,6 +14,8 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
+import hashlib
+
from django.core.urlresolvers import reverse_lazy
from django.views.generic import RedirectView, FormView
@@ -44,8 +46,18 @@ class HomeView(FormView):
context = super(HomeView, self).get_context_data(**kwargs)
context['enabled'] = bool(get_variable('matomo_enable').json)
context['mode'] = get_variable('matomo_mode').json
+ context['error'] = get_variable('matomo_error').value
tracking_js = get_variable('cnil_compliant_visits_tracking_js').value
context['cnil_ack_level'] = compute_cnil_acknowledgment_level(tracking_js)
+ context['tracking_js'] = tracking_js
+
+ if context['mode'] == 'auto':
+ matomo_setings = get_matomo_settings()
+ tenant_name, unused = get_tenant_name_and_public_urls()
+ password = get_variable('matomo_password').value
+ context['matomo_url'] = matomo_setings[0]
+ context['matomo_user_login'] = tenant_name
+ context['matomo_password'] = hashlib.md5(password).hexdigest()
return context
home = HomeView.as_view()
@@ -74,12 +86,13 @@ class EnableAutoView(FormView):
success_url = reverse_lazy('matomo-home')
def form_valid(self, form):
- variable = get_variable('matomo_enable')
- variable.value = 'true'
- variable.save()
variable = get_variable('matomo_mode')
variable.value = 'auto'
variable.save()
+ if auto_configure_matomo():
+ variable = get_variable('matomo_enable')
+ variable.value = 'true'
+ variable.save()
return super(EnableAutoView, self).form_valid(form)
enable_auto = EnableAutoView.as_view()
diff --git a/tests/test_matomo_views.py b/tests/test_matomo_views.py
new file mode 100644
index 0000000..e8e9695
--- /dev/null
+++ b/tests/test_matomo_views.py
@@ -0,0 +1,125 @@
+# -*- coding: utf-8 -*-
+
+import mock
+import pytest
+from requests import Response
+from webtest import TestApp
+
+from django.conf import settings
+from django.contrib.auth.models import User
+from django.test import override_settings
+
+from hobo.environment.models import Variable, Wcs, Combo, Fargo
+from hobo.wsgi import application
+
+pytestmark = pytest.mark.django_db
+
+CONFIG = {'URL': 'https://matomo.test', 'TOKEN_AUTH': '1234'}
+
+GET_SITE_NOT_ALREADY_THERE = """
+
+
+
+"""
+
+ADD_SITE_SUCCESS = """
+42
+"""
+
+ADD_USER_SUCCESS = """
+
+
+
+"""
+
+JAVASCRIPT_TAG = """
+<!-- Matomo -->
+<script type="text/javascript">
+ var _paq = window._paq || [];
+ /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
+ _paq.push(['trackPageView']);
+ _paq.push(['enableLinkTracking']);
+ (function() {
+ var u="//matomo-test.entrouvert.org/";
+ _paq.push(['setTrackerUrl', u+'piwik.php']);
+ _paq.push(['setSiteId', '7']);
+ var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
+ g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
+ })();
+</script>
+<!-- End Matomo Code -->
+
+"""
+
+@pytest.fixture
+def admin_user():
+ try:
+ user = User.objects.get(username='admin')
+ except User.DoesNotExist:
+ user = User.objects.create_superuser('admin', email=None, password='admin')
+ return user
+
+def login(app, username='admin', password='admin'):
+ login_page = app.get('/login/')
+ login_form = login_page.forms[0]
+ login_form['username'] = username
+ login_form['password'] = password
+ resp = login_form.submit()
+ assert resp.status_int == 302
+ return app
+
+def test_unlogged_access():
+ # connect while not being logged in
+ app = TestApp(application)
+ resp = app.get('/matomo/', status=302)
+ assert resp.location.endswith('/login/?next=/matomo/')
+
+def test_access(admin_user):
+ app = login(TestApp(application))
+ assert app.get('/matomo/', status=200)
+
+def test_disable(admin_user):
+ app = login(TestApp(application))
+ resp1 = app.get('/matomo/disable', status=200)
+ resp2 = resp1.form.submit()
+ assert resp2.location.endswith('/matomo/')
+
+def test_enable_manual(admin_user):
+ """scenario where user manually paste a javascript code"""
+ app = login(TestApp(application))
+ resp1 = app.get('/matomo/enable-manual', status=200)
+ resp2 = resp1.form.submit().follow()
+ resp2.form['tracking_js'] = '...js_code...'
+ resp3 = resp2.form.submit().follow()
+ assert resp3.body.find('"warningnotice">\n suivi des recommandations CNIL') != -1
+
+def auto_conf_mocked_post(url, **kwargs):
+ contents = [GET_SITE_NOT_ALREADY_THERE,
+ ADD_SITE_SUCCESS,
+ ADD_USER_SUCCESS,
+ JAVASCRIPT_TAG]
+ response = Response()
+ response._content = contents[auto_conf_mocked_post.cpt]
+ response.status_code = 200
+
+ auto_conf_mocked_post.cpt += 1
+ return response
+
+@mock.patch('requests.post', side_effect=auto_conf_mocked_post)
+def test_enable_auto(mocked_post, admin_user):
+ """automatic scenario"""
+ Combo.objects.create(base_url='https://combo.dev.publik.love',
+ template_name='portal-user')
+ Wcs.objects.create(base_url='https://wcs.dev.publik.love')
+ Fargo.objects.create(base_url='https://fargo.dev.publik.love')
+
+ auto_conf_mocked_post.cpt = 0
+ with override_settings(MATOMO_FEED=CONFIG):
+ app = login(TestApp(application))
+ resp1 = app.get('/matomo/enable-auto', status=200)
+ resp2 = resp1.form.submit()
+
+ # call utils.py::auto_configure_matomo()
+ resp3 = resp2.follow()
+ print resp3.body
+ assert resp3.body.find('"successnotice">\n suivi des recommandations CNIL') != -1
--
2.20.1