From 1c5d7422648080dd1f39bbe4d5f40c120c6fd7e8 Mon Sep 17 00:00:00 2001
From: Paul Marillonnet <pmarillonnet@entrouvert.com>
Date: Thu, 23 Jun 2022 10:19:08 +0200
Subject: [PATCH] manager: provide a new homepage layout (#66497)

---
 .../static/authentic2/manager/css/style.scss  | 22 ++++++++++++++++
 .../authentic2/manager/homepage.html          | 26 +++++++++++++------
 src/authentic2/manager/views.py               | 12 ++++++---
 tests/test_manager.py                         | 14 ++++++++++
 tests/test_manager_authenticators.py          |  4 +--
 tests/test_manager_journal.py                 |  4 +--
 6 files changed, 67 insertions(+), 15 deletions(-)

diff --git a/src/authentic2/manager/static/authentic2/manager/css/style.scss b/src/authentic2/manager/static/authentic2/manager/css/style.scss
index 13edc9af6..5c0815557 100644
--- a/src/authentic2/manager/static/authentic2/manager/css/style.scss
+++ b/src/authentic2/manager/static/authentic2/manager/css/style.scss
@@ -297,3 +297,25 @@ ul#id_scopes li {
       -webkit-column-width: 20em;
       column-width: 20em;
 }
+
+div.a2-manager-main {
+	display: flex;
+	justify-content: space-evenly;
+	& > div {
+		margin: 1em;
+		text-align: center;
+	}
+}
+
+div.a2-manager-id-tools_content {
+	display: flex;
+	flex-direction: column;
+	& > a {
+		margin: 1em;
+		padding: .7em;
+	}
+}
+
+div.a2-manager-id-objects ul.apps {
+	padding: 1em;
+}
diff --git a/src/authentic2/manager/templates/authentic2/manager/homepage.html b/src/authentic2/manager/templates/authentic2/manager/homepage.html
index c598d5138..5566d0c2b 100644
--- a/src/authentic2/manager/templates/authentic2/manager/homepage.html
+++ b/src/authentic2/manager/templates/authentic2/manager/homepage.html
@@ -5,7 +5,7 @@
 {% endblock %}
 
 {% block appbar %}
-  <h2>{% blocktrans %}Here you can manage objects related to organizational units, users, roles and applications.{% endblocktrans %}</h2>
+  <h2>{% blocktrans %}Identity management{% endblocktrans %}</h2>
   {% if user.is_superuser or can_view_journal %}
   <span class="actions">
   <a class="extra-actions-menu-opener"></a>
@@ -14,19 +14,15 @@
     <li><a download href="{% url 'a2-manager-site-export' %}">{% trans 'Export Site' %}</a></li>
     <li><a href="{% url 'a2-manager-site-import' %}" rel="popup">{% trans 'Import Site' %}</a></li>
     {% endif %}
-    {% if user.is_superuser or can_view_journal %}
-    <li><a href="{% url 'a2-manager-journal' %}">{% trans 'Journal' %}</a></li>
-    {% endif %}
-    {% if user.is_superuser %}
-    <li><a href="{% url 'a2-manager-tech-info' %}">{% trans 'Technical information' %}</a></li>
-    {% endif %}
-    <li><a href="{% url 'a2-manager-authenticators' %}">{% trans 'Authenticators' %}</a></li>
   </ul>
   </span>
   {% endif %}
 {% endblock %}
 
 {% block content %}
+ <div class="a2-manager-main">
+  <div class="a2-manager-id-objects">
+   <h3>{% blocktrans %}Objects related to organizational units, users, roles and applications{% endblocktrans %}</h3>
   <ul class="apps">
     {% for entry in entries %}
       <li {% if entry.class %}class="{{ entry.class }}"{% endif %}>
@@ -34,5 +30,19 @@
       </li>
     {% endfor %}
   </ul>
+  </div>
+  <div class="a2-manager-id-tools">
+   <h3>{% blocktrans %}Configuration & technical information{% endblocktrans %}</h3>
+   <div class="a2-manager-id-tools_content">
+    <a id="authn" class="pk-button" href="{% url 'a2-manager-authenticators' %}">{% trans 'Authentication frontends management' %}</a>
+    {% if user.is_superuser or can_view_journal %}
+    <a id="journal" class="pk-button" href="{% url 'a2-manager-journal' %}">{% trans 'Global journal' %}</a>
+    {% endif %}
+    {% if display_tech_info %}
+    <a id="tech-info" class="pk-button" href="{% url 'a2-manager-tech-info' %}">{% trans 'Directory servers’ technical information' %}</a>
+    {% endif %}
+   </div>
+  </div>
   <br style="clear: both;"/>
+ </div>
 {% endblock %}
diff --git a/src/authentic2/manager/views.py b/src/authentic2/manager/views.py
index 1ececc2e4..a4da0cd3e 100644
--- a/src/authentic2/manager/views.py
+++ b/src/authentic2/manager/views.py
@@ -40,6 +40,7 @@ from gadjo.templatetags.gadjo import xstatic
 
 from authentic2 import hooks
 from authentic2.a2_rbac.models import OrganizationalUnit
+from authentic2.backends import ldap_backend
 from authentic2.data_transfer import ImportContext, export_site, import_site
 from authentic2.decorators import json as json_view
 from authentic2.forms.profile import modelform_factory
@@ -595,6 +596,7 @@ class HomepageView(TitleMixin, PermissionMixin, MediaMixin, TemplateView):
             'order': -1,
             'sub': False,
             'slug': 'identity-management',
+            'skip_homepage': True,
         },
         {
             'class': 'icon-organizational-units',
@@ -660,10 +662,16 @@ class HomepageView(TitleMixin, PermissionMixin, MediaMixin, TemplateView):
         return entries
 
     def get_context_data(self, **kwargs):
-        kwargs['entries'] = self.get_homepage_entries()
+        kwargs['entries'] = []
+        for entry in self.get_homepage_entries():
+            if entry.get('skip_homepage', False):
+                continue
+            kwargs['entries'].append(entry)
         kwargs['can_view_journal'] = self.request.user.has_perms(
             ['custom_user.view_user', 'a2_rbac.view_role']
         )
+        if list(ldap_backend.LDAPBackend.get_config()):
+            kwargs['display_tech_info'] = True
         return super().get_context_data(**kwargs)
 
 
@@ -682,8 +690,6 @@ class TechnicalInformationView(TitleMixin, MediaMixin, TemplateView):
     def get_context_data(self, **kwargs):
         import ldap
 
-        from authentic2.backends import ldap_backend
-
         backend = ldap_backend.LDAPBackend
         kwargs['ldap_list'] = []
         for block in backend.get_config():
diff --git a/tests/test_manager.py b/tests/test_manager.py
index 152d481e6..7e0c519df 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -16,6 +16,7 @@
 
 
 import json
+from unittest import mock
 from urllib.parse import urlparse
 
 import pytest
@@ -58,6 +59,19 @@ def test_manager_login(superuser_or_admin, app):
         path = reverse('a2-manager-%s' % section)
         assert manager_home_page.pyquery.remove_namespaces()('.apps a[href=\'%s\']' % path)
 
+    conf_entries = ['authn', 'journal']
+    assert len(manager_home_page.pyquery('div.a2-manager-id-tools_content').children()) == 2
+    for entry in conf_entries:
+        assert manager_home_page.pyquery(f'a#{entry}')
+
+    # mock ldap configuration
+    mocked_config = [{'ldap_uri': 'ldaps://soundsfake.nowhere.null'}]
+    with mock.patch('authentic2.backends.ldap_backend.LDAPBackend.get_config', return_value=mocked_config):
+        # new tech info link appears
+        manager_home_page = app.get(reverse('a2-manager-homepage'))
+        assert len(manager_home_page.pyquery('div.a2-manager-id-tools_content').children()) == 3
+        assert manager_home_page.pyquery('a#tech-info')
+
 
 def test_manager_create_ou(superuser_or_admin, app):
     ou_add = login(app, superuser_or_admin, path=reverse('a2-manager-ou-add'))
diff --git a/tests/test_manager_authenticators.py b/tests/test_manager_authenticators.py
index a55db118f..b249ef42d 100644
--- a/tests/test_manager_authenticators.py
+++ b/tests/test_manager_authenticators.py
@@ -30,9 +30,9 @@ def test_authenticators_authorization(app, simple_user, superuser):
 
     logout(app)
     resp = login(app, superuser, path='/manage/')
-    assert 'Authenticators' in resp.text
+    assert 'Authentication frontends management' in resp.text
 
-    resp = resp.click('Authenticators')
+    resp = resp.click('Authentication frontends management')
     assert 'Authenticators' in resp.text
 
 
diff --git a/tests/test_manager_journal.py b/tests/test_manager_journal.py
index 4f46e5622..069a42471 100644
--- a/tests/test_manager_journal.py
+++ b/tests/test_manager_journal.py
@@ -38,7 +38,7 @@ def test_journal_authorization(app, db, simple_user, admin):
 
     logout(app)
     response = login(app, admin, path='/manage/')
-    assert 'Journal' in response
+    assert 'Global journal' in response
     app.get('/manage/journal/', status=200)
 
 
@@ -341,7 +341,7 @@ def test_global_journal(app, superuser, events):
     # remove event about admin login
     Event.objects.filter(user=superuser).delete()
 
-    response = response.click("Journal")
+    response = response.click("Global journal")
 
     content = extract_journal(response)
 
-- 
2.36.1

