From 4ca9335aae548297d49d7c90e86e603b2b6b7e0f Mon Sep 17 00:00:00 2001
From: Jonathan Weth <git@jonathanweth.de>
Date: Fri, 5 Nov 2021 18:14:01 +0100
Subject: [PATCH] Refactor OAuth2 application management views

---
 aleksis/core/menus.py                         |  2 +-
 aleksis/core/models.py                        |  5 --
 aleksis/core/rules.py                         | 16 ++---
 .../oauth2_provider/application/create.html   |  2 +-
 .../oauth2_provider/application/detail.html   | 59 +++++++++++++++++++
 .../oauth2_provider/application/edit.html     |  2 +-
 .../list.html}                                | 24 ++++----
 .../application_confirm_delete.html           | 27 ---------
 .../oauth2_provider/application_detail.html   | 59 -------------------
 .../templates/oauth2_provider/authorize.html  |  2 +-
 .../authorized-token-delete.html              |  4 +-
 aleksis/core/urls.py                          | 20 ++++---
 aleksis/core/views.py                         | 26 ++++----
 13 files changed, 110 insertions(+), 138 deletions(-)
 create mode 100644 aleksis/core/templates/oauth2_provider/application/detail.html
 rename aleksis/core/templates/oauth2_provider/{application_list.html => application/list.html} (53%)
 delete mode 100644 aleksis/core/templates/oauth2_provider/application_confirm_delete.html
 delete mode 100644 aleksis/core/templates/oauth2_provider/application_detail.html

diff --git a/aleksis/core/menus.py b/aleksis/core/menus.py
index d9fd84b0f..99928d34f 100644
--- a/aleksis/core/menus.py
+++ b/aleksis/core/menus.py
@@ -214,7 +214,7 @@ MENUS = {
                 },
                 {
                     "name": _("OAuth2 Applications"),
-                    "url": "oauth_list",
+                    "url": "oauth2_applications",
                     "icon": "touch_app",
                     "validators": [
                         (
diff --git a/aleksis/core/models.py b/aleksis/core/models.py
index 279a6fc79..3a7e12359 100644
--- a/aleksis/core/models.py
+++ b/aleksis/core/models.py
@@ -982,11 +982,6 @@ class GlobalPermissions(GlobalPermissionModel):
             ("change_site_preferences", _("Can change site preferences")),
             ("change_person_preferences", _("Can change person preferences")),
             ("change_group_preferences", _("Can change group preferences")),
-            ("add_oauth_applications", _("Can add oauth applications")),
-            ("list_oauth_applications", _("Can list oauth applications")),
-            ("view_oauth_applications", _("Can view oauth applications")),
-            ("update_oauth_applications", _("Can update oauth applications")),
-            ("delete_oauth_applications", _("Can delete oauth applications")),
             ("test_pdf", _("Can test PDF generation")),
         )
 
diff --git a/aleksis/core/rules.py b/aleksis/core/rules.py
index e8e5443e1..51a4fb07b 100644
--- a/aleksis/core/rules.py
+++ b/aleksis/core/rules.py
@@ -319,17 +319,17 @@ can_change_password_predicate = is_site_preference_set(section="auth", pref="all
 rules.add_perm("core.can_change_password", can_change_password_predicate)
 
 # OAuth2 permissions
-add_oauth_applications_predicate = has_person & has_global_perm("core.add_oauth_applications")
-rules.add_perm("core.add_oauth_applications_rule", add_oauth_applications_predicate)
+create_oauthapplication_predicate = has_person & has_global_perm("core.add_oauthapplication")
+rules.add_perm("core.create_oauthapplication_rule", create_oauthapplication_predicate)
 
-list_oauth_applications_predicate = has_person & has_global_perm("core.list_oauth_applications")
-rules.add_perm("core.list_oauth_applications_rule", list_oauth_applications_predicate)
+view_oauth_applications_predicate = has_person & has_global_perm("core.view_oauthapplication")
+rules.add_perm("core.view_oauthapplications_rule", view_oauth_applications_predicate)
 
-view_oauth_applications_predicate = has_person & has_global_perm("core.view_oauth_applications")
-rules.add_perm("core.view_oauth_applications_rule", view_oauth_applications_predicate)
+view_oauth_application_predicate = has_person & has_global_perm("core.view_oauthapplication")
+rules.add_perm("core.view_oauthapplication_rule", view_oauth_application_predicate)
 
-update_oauth_applications_predicate = has_person & has_global_perm("core.update_oauth_applications")
-rules.add_perm("core.update_oauth_applications_rule", update_oauth_applications_predicate)
+edit_oauth_application_predicate = has_person & has_global_perm("core.change_oauthapplication")
+rules.add_perm("core.edit_oauthapplication_rule", edit_oauth_application_predicate)
 
 delete_oauth_applications_predicate = has_person & has_global_perm("core.delete_oauth_applications")
 rules.add_perm("core.delete_oauth_applications_rule", delete_oauth_applications_predicate)
diff --git a/aleksis/core/templates/oauth2_provider/application/create.html b/aleksis/core/templates/oauth2_provider/application/create.html
index 38b9a8d02..d81489e92 100644
--- a/aleksis/core/templates/oauth2_provider/application/create.html
+++ b/aleksis/core/templates/oauth2_provider/application/create.html
@@ -10,7 +10,7 @@
     {% csrf_token %}
     {% form form=form %}{% endform %}
     {% include "core/partials/save_button.html" %}
-    <a class="btn waves-effect red waves-light" href="{% url "oauth_list" %}">
+    <a class="btn waves-effect red waves-light" href="{% url "oauth2_applications" %}">
       <i class="material-icons left">clear</i> {% trans "Cancel" %}
     </a>
   </form>
diff --git a/aleksis/core/templates/oauth2_provider/application/detail.html b/aleksis/core/templates/oauth2_provider/application/detail.html
new file mode 100644
index 000000000..4e896dad7
--- /dev/null
+++ b/aleksis/core/templates/oauth2_provider/application/detail.html
@@ -0,0 +1,59 @@
+{% extends "core/base.html" %}
+
+{% load i18n %}
+
+{% block browser_title %}{% blocktrans %}OAuth2 Application{% endblocktrans %}{% endblock %}
+{% block page_title %}
+  <a href="{% url "oauth2_applications" %}"
+     class="btn-flat primary-color-text waves-light waves-effect">
+    <i class="material-icons left">chevron_left</i> {% trans "Back" %}
+  </a>
+  {{ application.name }}
+{% endblock %}
+
+{% block content %}
+  <a class="btn orange waves-effect waves-light btn-margin" href="{% url "edit_oauth2_application" application.id %}">
+    <i class="material-icons left">edit</i>
+    {% trans "Edit" %}
+  </a>
+  <a class="btn red waves-effect waves-light btn-margin" href="{% url "delete_oauth2_application" application.id %}">
+    <i class="material-icons left">delete</i>
+    {% trans "Delete" %}
+  </a>
+  <table class="responsive-table">
+    <tbody>
+    <tr>
+      <th>
+        {% trans "Client id" %}
+      </th>
+      <td>
+        <code class="break-word">{{ application.client_id }}</code>
+      </td>
+    </tr>
+    <tr>
+      <th>
+        {% trans "Client secret" %}
+      </th>
+      <td>
+        <code class="break-word">{{ application.client_secret }}</code>
+      </td>
+    </tr>
+    <tr>
+      <th>
+        {% trans "Client type" %}
+      </th>
+      <td>
+        {{ application.client_type }}
+      </td>
+    </tr>
+    <tr>
+      <th>
+        {% trans "Redirect URIs" %}
+      </th>
+      <td>
+        {{ application.redirect_uris }}
+      </td>
+    </tr>
+    </tbody>
+  </table>
+{% endblock %}
diff --git a/aleksis/core/templates/oauth2_provider/application/edit.html b/aleksis/core/templates/oauth2_provider/application/edit.html
index ac2b7d346..6755d2420 100644
--- a/aleksis/core/templates/oauth2_provider/application/edit.html
+++ b/aleksis/core/templates/oauth2_provider/application/edit.html
@@ -10,7 +10,7 @@
     {% csrf_token %}
     {% form form=form %}{% endform %}
     {% include "core/partials/save_button.html" %}
-    <a class="btn waves-effect red waves-light" href="{% url "oauth_detail" application.id %}">
+    <a class="btn waves-effect red waves-light" href="{% url "oauth2_application" application.id %}">
       <i class="material-icons left">clear</i> {% trans "Cancel" %}
     </a>
   </form>
diff --git a/aleksis/core/templates/oauth2_provider/application_list.html b/aleksis/core/templates/oauth2_provider/application/list.html
similarity index 53%
rename from aleksis/core/templates/oauth2_provider/application_list.html
rename to aleksis/core/templates/oauth2_provider/application/list.html
index 894315940..06f1a95c4 100644
--- a/aleksis/core/templates/oauth2_provider/application_list.html
+++ b/aleksis/core/templates/oauth2_provider/application/list.html
@@ -3,24 +3,22 @@
 {% load i18n %}
 
 {% block browser_title %}{% blocktrans %}OAuth2 Applications{% endblocktrans %}{% endblock %}
+{% block page_title %}{% blocktrans %}OAuth2 Applications{% endblocktrans %}{% endblock %}
 
 {% block content %}
-  <h1>{% blocktrans %}OAuth2 applications{% endblocktrans %}</h1>
   <a href="{% url "register_oauth_application" %}" class="btn green waves-effect waves-light">
     <i class="material-icons left">add</i>
     {% blocktrans %}Register new application{% endblocktrans %}
   </a>
-  <ul class="collection">
-  {% for application in applications %}
-      <li class="collection-item">
-        <div>
-          <a href="{% url "oauth_detail" application.id %}">{{ application.name }}</a>
-        </div>
-      </li>
-  {% empty %}
-      <li class="collection-item flow-text">
+  <div class="collection">
+    {% for application in applications %}
+      <a class="collection-item" href="{% url "oauth2_application" application.id %}">
+        {{ application.name }}
+      </a>
+      {% empty %}
+      <div class="collection-item flow-text">
         {% blocktrans %}No applications defined.{% endblocktrans %}
-      </li>
-  {% endfor %}
-  </ul>
+      </div>
+    {% endfor %}
+  </div>
 {% endblock %}
diff --git a/aleksis/core/templates/oauth2_provider/application_confirm_delete.html b/aleksis/core/templates/oauth2_provider/application_confirm_delete.html
deleted file mode 100644
index f72a5be61..000000000
--- a/aleksis/core/templates/oauth2_provider/application_confirm_delete.html
+++ /dev/null
@@ -1,27 +0,0 @@
-{% extends "core/base.html" %}
-
-{% load i18n %}
-
-{% block browser_title %}{% trans "Delete application" %}{% endblock %}
-{% block page_title %}{% trans "Delete application" %}{% endblock %}
-
-{% block content %}
-  <div class="alert info">
-    <p>
-      <i class="material-icons left">warning</i>
-      {% blocktrans with application_name=application.name %}Are you sure to delete the application {{ application_name }}?{% endblocktrans %}
-    </p>
-  </div>
-
-  <form method="post" action="{% url 'oauth2_provider:delete' application.pk %}">
-    {% csrf_token %}
-    <button type="submit" class="btn waves-effect waves-light red">
-      <i class="material-icons left">delete</i>
-      {% trans "Delete" %}
-    </button>
-    <a class="btn waves-effect waves-light" href="{% url "oauth2_provider:list" %}">
-      <i class="material-icons left">close</i>
-      {% trans "Cancel" %}
-    </a>
-  </form>
-{% endblock %}
diff --git a/aleksis/core/templates/oauth2_provider/application_detail.html b/aleksis/core/templates/oauth2_provider/application_detail.html
deleted file mode 100644
index 093bc3719..000000000
--- a/aleksis/core/templates/oauth2_provider/application_detail.html
+++ /dev/null
@@ -1,59 +0,0 @@
-{% extends "core/base.html" %}
-
-{% load i18n %}
-
-{% block browser_title %}{% blocktrans %}OAuth2 Applications{% endblocktrans %}{% endblock %}
-{% block page_title %}
-    <a href="{% url "oauth_list" %}"
-       class="btn-flat primary-color-text waves-light waves-effect">
-      <i class="material-icons left">chevron_left</i> {% trans "Back" %}
-    </a>
-    {{ application.name }}
-{% endblock %}
-
-{% block content %}
-  <a class="btn waves-effect waves-light btn-margin" href="{% url "edit_oauth_application" application.id %}">
-    <i class="material-icons left">edit</i>
-    {% trans "Edit" %}
-  </a>
-  <a class="btn red waves-effect waves-light btn-margin" href="{% url "oauth_delete" application.id %}">
-    <i class="material-icons left">delete_forever</i>
-    {% trans "Delete" %}
-  </a>
-  <table class="responsive-table">
-    <tbody>
-      <tr>
-        <th>
-          {% trans "Client id" %}
-        </td>
-        <td>
-          <code class="break-word">{{ application.client_id }}</code>
-        </td>
-      </tr>
-      <tr>
-        <th>
-          {% trans "Client secret"%}
-        </td>
-        <td>
-          <code class="break-word">{{ application.client_secret }}</code>
-        </td>
-      </tr>
-      <tr>
-        <th>
-          {% trans "Client type"%}
-        </td>
-        <td>
-          {{ application.client_type }}
-        </td>
-      </tr>
-      <tr>
-        <th>
-          {% trans "Redirect URIs"%}
-        </td>
-        <td>
-          {{ application.redirect_uris }}
-        </td>
-      </tr>
-    </tbody>
-  </table>
-{% endblock %}
diff --git a/aleksis/core/templates/oauth2_provider/authorize.html b/aleksis/core/templates/oauth2_provider/authorize.html
index 5eaf31510..48b996837 100644
--- a/aleksis/core/templates/oauth2_provider/authorize.html
+++ b/aleksis/core/templates/oauth2_provider/authorize.html
@@ -32,7 +32,7 @@
             <button type="submit" class="btn green waves-effect waves-light btn-margin">
               <i class="material-icons left">done_all</i> {% trans "Allow" %}
             </button>
-            <a class="btn red waves-effect waves-light btn-margin" href="{% block app-form-back-url %}{% url "oauth_detail" application.id %}{% endblock app-form-back-url %}">
+            <a class="btn red waves-effect waves-light btn-margin" href="{% block app-form-back-url %}{% url "oauth2_application" application.id %}{% endblock app-form-back-url %}">
               <i class="material-icons left">cancel</i> {% trans "Disallow" %}
             </a>
           </form>
diff --git a/aleksis/core/templates/oauth2_provider/authorized-token-delete.html b/aleksis/core/templates/oauth2_provider/authorized-token-delete.html
index f65882298..7f6f25920 100644
--- a/aleksis/core/templates/oauth2_provider/authorized-token-delete.html
+++ b/aleksis/core/templates/oauth2_provider/authorized-token-delete.html
@@ -15,11 +15,11 @@
 
   <form method="post">
     {% csrf_token %}
-    <a class="btn waves-effect waves-light red" href="{% url "oauth_list" %}">
+    <a class="btn waves-effect waves-light red" href="{% url "oauth2_applications" %}">
       <i class="material-icons left">delete</i>
       {% trans "Revoke" %}
     </a>
-    <a class="btn waves-effect waves-light" href="{% url "oauth_list" %}">
+    <a class="btn waves-effect waves-light" href="{% url "oauth2_applications" %}">
       <i class="material-icons left">cancel</i>
       {% trans "Cancel" %}
     </a>
diff --git a/aleksis/core/urls.py b/aleksis/core/urls.py
index 85f91a2cc..22bbdd344 100644
--- a/aleksis/core/urls.py
+++ b/aleksis/core/urls.py
@@ -102,20 +102,26 @@ urlpatterns = [
         ConnectDiscoveryInfoView.as_view(),
         name="oidc_configuration",
     ),
-    path("oauth/applications/", views.OAuth2List.as_view(), name="oauth_list"),
+    path("oauth2/applications/", views.OAuth2ListView.as_view(), name="oauth2_applications"),
     path(
-        "oauth/applications/register/",
+        "oauth2/applications/register/",
         views.OAuth2RegisterView.as_view(),
         name="register_oauth_application",
     ),
-    path("oauth/applications/<int:pk>/detail", views.OAuth2Detail.as_view(), name="oauth_detail"),
-    path("oauth/applications/<int:pk>/delete", views.OAuth2Delete.as_view(), name="oauth_delete"),
     path(
-        "oauth/applications/<int:pk>/edit/",
+        "oauth2/applications/<int:pk>/", views.OAuth2DetailView.as_view(), name="oauth2_application"
+    ),
+    path(
+        "oauth2/applications/<int:pk>/delete/",
+        views.OAuth2DeleteView.as_view(),
+        name="delete_oauth2_application",
+    ),
+    path(
+        "oauth2/applications/<int:pk>/edit/",
         views.OAuth2EditView.as_view(),
-        name="edit_oauth_application",
+        name="edit_oauth2_application",
     ),
-    path("oauth/", include("oauth2_provider.urls", namespace="oauth2_provider")),
+    path("oauth2/", include("oauth2_provider.urls", namespace="oauth2_provider")),
     path("__i18n__/", include("django.conf.urls.i18n")),
     path(
         "ckeditor/upload/",
diff --git a/aleksis/core/views.py b/aleksis/core/views.py
index 1a73deee1..e0135bda5 100644
--- a/aleksis/core/views.py
+++ b/aleksis/core/views.py
@@ -1033,44 +1033,44 @@ class EditDashboardView(PermissionRequiredMixin, View):
         return render(request, "core/edit_dashboard.html", context=context)
 
 
-class OAuth2List(PermissionRequiredMixin, ListView):
+class OAuth2ListView(PermissionRequiredMixin, ListView):
     """List view for all the applications."""
 
-    permission_required = "core.list_oauth_applications_rule"
+    permission_required = "core.view_oauthapplications_rule"
     context_object_name = "applications"
-    template_name = "oauth2_provider/application_list.html"
+    template_name = "oauth2_provider/application/list.html"
 
     def get_queryset(self):
         return OAuthApplication.objects.all()
 
 
-class OAuth2Detail(PermissionRequiredMixin, DetailView):
+class OAuth2DetailView(PermissionRequiredMixin, DetailView):
     """Detail view for an application instance."""
 
     context_object_name = "application"
-    permission_required = "core.view_oauth_applications_rule"
-    template_name = "oauth2_provider/application_detail.html"
+    permission_required = "core.view_oauthapplication_rule"
+    template_name = "oauth2_provider/application/detail.html"
 
     def get_queryset(self):
         return OAuthApplication.objects.all()
 
 
-class OAuth2Delete(PermissionRequiredMixin, DeleteView):
+class OAuth2DeleteView(PermissionRequiredMixin, AdvancedDeleteView):
     """View used to delete an application."""
 
-    permission_required = "core.delete_oauth_applications_rule"
+    permission_required = "core.delete_oauthapplication_rule"
     context_object_name = "application"
-    success_url = reverse_lazy("oauth_list")
-    template_name = "oauth2_provider/application_confirm_delete.html"
+    success_url = reverse_lazy("oauth2_applications")
+    template_name = "core/pages/delete.html"
 
     def get_queryset(self):
         return OAuthApplication.objects.all()
 
 
 class OAuth2EditView(PermissionRequiredMixin, AdvancedEditView):
-    """View used to update an application."""
+    """View used to edit an application."""
 
-    permission_required = "core.update_oauth_applications_rule"
+    permission_required = "core.edit_oauthapplication_rule"
     context_object_name = "application"
     template_name = "oauth2_provider/application/edit.html"
     form_class = OAuthApplicationForm
@@ -1082,7 +1082,7 @@ class OAuth2EditView(PermissionRequiredMixin, AdvancedEditView):
 class OAuth2RegisterView(PermissionRequiredMixin, AdvancedCreateView):
     """View used to register an application."""
 
-    permission_required = "core.add_oauth_applications_rule"
+    permission_required = "core.create_oauthapplication_rule"
     context_object_name = "application"
     template_name = "oauth2_provider/application/create.html"
     form_class = OAuthApplicationForm
-- 
GitLab