Просмотр исходного кода

Closes #20917: Show example API usage for tokens (#20918)

Jeremy Stretch 2 месяцев назад
Родитель
Сommit
7bca9f5d6d

+ 11 - 0
netbox/account/views.py

@@ -25,10 +25,12 @@ from extras.models import Bookmark
 from extras.tables import BookmarkTable, NotificationTable, SubscriptionTable
 from netbox.authentication import get_auth_backend_display, get_saml_idps
 from netbox.config import get_config
+from netbox.ui import layout
 from netbox.views import generic
 from users import forms
 from users.models import UserConfig
 from users.tables import TokenTable
+from users.ui.panels import TokenExamplePanel, TokenPanel
 from utilities.request import safe_for_redirect
 from utilities.string import remove_linebreaks
 from utilities.views import register_model_view
@@ -342,12 +344,21 @@ class UserTokenListView(LoginRequiredMixin, View):
 
 @register_model_view(UserToken)
 class UserTokenView(LoginRequiredMixin, View):
+    layout = layout.SimpleLayout(
+        left_panels=[
+            TokenPanel(),
+        ],
+        right_panels=[
+            TokenExamplePanel(),
+        ],
+    )
 
     def get(self, request, pk):
         token = get_object_or_404(UserToken.objects.filter(user=request.user), pk=pk)
 
         return render(request, 'account/token.html', {
             'object': token,
+            'layout': self.layout,
         })
 
 

+ 9 - 0
netbox/templates/users/panels/token_example.html

@@ -0,0 +1,9 @@
+{% extends 'ui/panels/_base.html' %}
+
+{% block panel_content %}
+<div id="token-example" class="card-body font-monospace">curl -X GET \<br />
+-H "Authorization: {{ object.get_auth_header_prefix }}<mark>&lt;TOKEN&gt;</mark>" \<br />
+-H "Content-Type: application/json" \<br />
+-H "Accept: application/json; indent=4" \<br />
+{{ request.scheme }}://{{ request.get_host }}{% url "api-status" %}</div>
+{% endblock panel_content %}

+ 0 - 69
netbox/templates/users/token.html

@@ -1,73 +1,4 @@
 {% extends 'generic/object.html' %}
-{% load helpers %}
 {% load i18n %}
-{% load render_table from django_tables2 %}
 
 {% block title %}{% trans "Token" %} {{ object }}{% endblock %}
-
-{% block subtitle %}{% endblock %}
-
-{% block content %}
-  <div class="row mb-3">
-    <div class="col-md-6">
-      <div class="card">
-        <h2 class="card-header">{% trans "Token" %}</h2>
-        <table class="table table-hover attr-table">
-          <tr>
-            <th scope="row">{% trans "Version" %}</th>
-            <td>{{ object.version }}</td>
-          </tr>
-          {% if object.version == 1 %}
-            <tr>
-              <th scope="row">{% trans "Token" %}</th>
-              <td>{{ object.partial }}</td>
-            </tr>
-          {% else %}
-            <tr>
-              <th scope="row">{% trans "Key" %}</th>
-              <td>{{ object }}</td>
-            </tr>
-            <tr>
-              <th scope="row">{% trans "Pepper ID" %}</th>
-              <td>{{ object.pepper_id }}</td>
-            </tr>
-          {% endif %}
-          <tr>
-            <th scope="row">{% trans "User" %}</th>
-            <td>
-              <a href="{% url 'users:user' pk=object.user.pk %}">{{ object.user }}</a>
-            </td>
-          </tr>
-          <tr>
-            <th scope="row">{% trans "Description" %}</th>
-            <td>{{ object.description|placeholder }}</td>
-          </tr>
-          <tr>
-            <th scope="row">{% trans "Enabled" %}</th>
-            <td>{% checkmark object.enabled %}</td>
-          </tr>
-          <tr>
-            <th scope="row">{% trans "Write enabled" %}</th>
-            <td>{% checkmark object.write_enabled %}</td>
-          </tr>
-          <tr>
-            <th scope="row">{% trans "Created" %}</th>
-            <td>{{ object.created|isodatetime }}</td>
-          </tr>
-          <tr>
-            <th scope="row">{% trans "Expires" %}</th>
-            <td>{{ object.expires|isodatetime|placeholder }}</td>
-          </tr>
-          <tr>
-            <th scope="row">{% trans "Last used" %}</th>
-            <td>{{ object.last_used|isodatetime|placeholder }}</td>
-          </tr>
-          <tr>
-            <th scope="row">{% trans "Allowed IPs" %}</th>
-            <td>{{ object.allowed_ips|join:", "|placeholder }}</td>
-          </tr>
-        </table>
-      </div>
-    </div>
-  </div>
-{% endblock %}

+ 9 - 0
netbox/users/models/tokens.py

@@ -201,6 +201,15 @@ class Token(models.Model):
         """
         return self.enabled and not self.is_expired
 
+    def get_auth_header_prefix(self):
+        """
+        Return the HTTP Authorization header prefix for this token.
+        """
+        if self.v1:
+            return 'Token '
+        if self.v2:
+            return f'Bearer {TOKEN_PREFIX}{self.key}.'
+
     def clean(self):
         super().clean()
 

+ 0 - 0
netbox/users/ui/__init__.py


+ 25 - 0
netbox/users/ui/panels.py

@@ -0,0 +1,25 @@
+from django.utils.translation import gettext_lazy as _
+
+from netbox.ui import actions, attrs, panels
+
+
+class TokenPanel(panels.ObjectAttributesPanel):
+    version = attrs.NumericAttr('version')
+    key = attrs.TextAttr('key')
+    token = attrs.TextAttr('partial')
+    pepper_id = attrs.NumericAttr('pepper_id')
+    user = attrs.RelatedObjectAttr('user', linkify=True)
+    description = attrs.TextAttr('description')
+    enabled = attrs.BooleanAttr('enabled')
+    write_enabled = attrs.BooleanAttr('write_enabled')
+    expires = attrs.TextAttr('expires')
+    last_used = attrs.TextAttr('last_used')
+    allowed_ips = attrs.TextAttr('allowed_ips')
+
+
+class TokenExamplePanel(panels.Panel):
+    template_name = 'users/panels/token_example.html'
+    title = _('Example Usage')
+    actions = [
+        actions.CopyContent('token-example')
+    ]

+ 10 - 0
netbox/users/views.py

@@ -3,7 +3,9 @@ from django.db.models import Count
 from core.models import ObjectChange
 from core.tables import ObjectChangeTable
 from netbox.object_actions import AddObject, BulkDelete, BulkEdit, BulkExport, BulkImport, BulkRename
+from netbox.ui import layout
 from netbox.views import generic
+from users.ui import panels
 from utilities.query import count_related
 from utilities.views import GetRelatedModelsMixin, register_model_view
 from . import filtersets, forms, tables
@@ -26,6 +28,14 @@ class TokenListView(generic.ObjectListView):
 @register_model_view(Token)
 class TokenView(generic.ObjectView):
     queryset = Token.objects.all()
+    layout = layout.SimpleLayout(
+        left_panels=[
+            panels.TokenPanel(),
+        ],
+        right_panels=[
+            panels.TokenExamplePanel(),
+        ],
+    )
 
 
 @register_model_view(Token, 'add', detail=False)