From 13b0e9a038db087ff679faa9741a287c7491845c Mon Sep 17 00:00:00 2001
From: Dan Schultz <slifty@gmail.com>
Date: Tue, 15 Feb 2022 15:52:24 -0500
Subject: [PATCH] Hide the admin button for non-admins

There are several types of user with access to the review dashboard, but
only administrators are allowed to view the administrator pane.

This updates the admin dashboard to only render the admin button for
users with admin permission.  It also adds an ID to the button so
that test can reliably check for the presence of the button.

Issue #2724
---
 .../templates/dashboard/dashboard.html        | 10 +++---
 hypha/apply/dashboard/tests/test_views.py     | 33 +++++++++++++++++++
 hypha/apply/users/tests/factories.py          | 29 +++++++++++++++-
 3 files changed, 67 insertions(+), 5 deletions(-)

diff --git a/hypha/apply/dashboard/templates/dashboard/dashboard.html b/hypha/apply/dashboard/templates/dashboard/dashboard.html
index ce45869e1..c9959afa3 100644
--- a/hypha/apply/dashboard/templates/dashboard/dashboard.html
+++ b/hypha/apply/dashboard/templates/dashboard/dashboard.html
@@ -14,10 +14,12 @@
         {% block page_header %}
             <h1 class="gamma heading heading--no-margin heading--bold">{% trans "Dashboard" %}</h1>
         {% endblock %}
-        <a href="{% url 'wagtailadmin_home' %}" class="button button--primary button--arrow-pixels-white">
-            {% trans "Apply admin" %}
-            <svg><use xlink:href="#arrow-head-pixels--solid"></use></svg>
-        </a>
+        {% if perms.wagtailadmin.access_admin %}
+            <a href="{% url 'wagtailadmin_home' %}" id="wagtail-admin-button" class="button button--primary button--arrow-pixels-white">
+                {% trans "Apply admin" %}
+                <svg><use xlink:href="#arrow-head-pixels--solid"></use></svg>
+            </a>
+        {% endif %}
     </div>
 </div>
 <div class="wrapper wrapper--large wrapper--inner-space-medium">
diff --git a/hypha/apply/dashboard/tests/test_views.py b/hypha/apply/dashboard/tests/test_views.py
index e1bc2ebef..2625333a0 100644
--- a/hypha/apply/dashboard/tests/test_views.py
+++ b/hypha/apply/dashboard/tests/test_views.py
@@ -15,10 +15,13 @@ from hypha.apply.projects.tests.factories import InvoiceFactory, ProjectFactory
 from hypha.apply.review.tests.factories import ReviewFactory, ReviewOpinionFactory
 from hypha.apply.users.groups import APPROVER_GROUP_NAME
 from hypha.apply.users.tests.factories import (
+    AdminFactory,
     ApplicantFactory,
     GroupFactory,
     ReviewerFactory,
     StaffFactory,
+    StaffWithoutWagtailAdminAccessFactory,
+    StaffWithWagtailAdminAccessFactory,
 )
 from hypha.apply.utils.testing.tests import BaseViewTestCase
 
@@ -148,6 +151,26 @@ class TestStaffDashboard(BaseViewTestCase):
         self.assertContains(response, "Projects awaiting approval")
 
 
+class TestStaffDashboardWithWagtailAdminAccess(BaseViewTestCase):
+    user_factory = StaffWithWagtailAdminAccessFactory
+    url_name = 'dashboard:{}'
+    base_view_name = 'dashboard'
+
+    def test_does_show_admin_button_to_staff_with_wagtail_admin_access(self):
+        response = self.get_page()
+        self.assertContains(response, 'wagtail-admin-button')
+
+
+class TestStaffDashboardWithoutWagtailAdminAccess(BaseViewTestCase):
+    user_factory = StaffWithoutWagtailAdminAccessFactory
+    url_name = 'dashboard:{}'
+    base_view_name = 'dashboard'
+
+    def test_doesnt_show_admin_button_to_staff_without_wagtail_admin_access(self):
+        response = self.get_page()
+        self.assertNotContains(response, 'wagtail-admin-button')
+
+
 class TestReviewerDashboard(BaseViewTestCase):
     user_factory = ReviewerFactory
     url_name = 'dashboard:{}'
@@ -171,3 +194,13 @@ class TestReviewerDashboard(BaseViewTestCase):
         response = self.get_page()
         self.assertNotContains(response, submission.title)
         self.assertEquals(response.context['in_review_count'], 0)
+
+
+class TestAdminDashboard(BaseViewTestCase):
+    user_factory = AdminFactory
+    url_name = 'dashboard:{}'
+    base_view_name = 'dashboard'
+
+    def test_does_show_admin_button_to_admins(self):
+        response = self.get_page()
+        self.assertContains(response, 'wagtail-admin-button')
diff --git a/hypha/apply/users/tests/factories.py b/hypha/apply/users/tests/factories.py
index 9d5e925d9..ed84ff026 100644
--- a/hypha/apply/users/tests/factories.py
+++ b/hypha/apply/users/tests/factories.py
@@ -2,7 +2,7 @@ import uuid
 
 import factory
 from django.contrib.auth import get_user_model
-from django.contrib.auth.models import Group
+from django.contrib.auth.models import Group, Permission
 from django.utils.text import slugify
 
 from ..groups import (
@@ -67,6 +67,33 @@ class StaffFactory(OAuthUserFactory):
             self.groups.add(GroupFactory(name=STAFF_GROUP_NAME))
 
 
+def get_wagtail_admin_access_permission():
+    return Permission.objects.get(
+        content_type__app_label='wagtailadmin',
+        codename='access_admin'
+    )
+
+
+class StaffWithWagtailAdminAccessFactory(StaffFactory):
+    @factory.post_generation
+    def groups(self, create, extracted, **kwargs):
+        if create:
+            modifiedStaffGroup = GroupFactory(name=STAFF_GROUP_NAME)
+            wagtail_admin_access_permission = get_wagtail_admin_access_permission()
+            modifiedStaffGroup.permissions.add(wagtail_admin_access_permission)
+            self.groups.add(modifiedStaffGroup)
+
+
+class StaffWithoutWagtailAdminAccessFactory(StaffFactory):
+    @factory.post_generation
+    def groups(self, create, extracted, **kwargs):
+        if create:
+            modifiedStaffGroup = GroupFactory(name=STAFF_GROUP_NAME)
+            wagtail_admin_access_permission = get_wagtail_admin_access_permission()
+            modifiedStaffGroup.permissions.remove(wagtail_admin_access_permission)
+            self.groups.add(modifiedStaffGroup)
+
+
 class FinanceFactory(OAuthUserFactory):
     class Meta:
         exclude = ('slack_temp', )
-- 
GitLab