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

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 extras.tables import BookmarkTable, NotificationTable, SubscriptionTable
 from netbox.authentication import get_auth_backend_display, get_saml_idps
 from netbox.authentication import get_auth_backend_display, get_saml_idps
 from netbox.config import get_config
 from netbox.config import get_config
+from netbox.ui import layout
 from netbox.views import generic
 from netbox.views import generic
 from users import forms
 from users import forms
 from users.models import UserConfig
 from users.models import UserConfig
 from users.tables import TokenTable
 from users.tables import TokenTable
+from users.ui.panels import TokenExamplePanel, TokenPanel
 from utilities.request import safe_for_redirect
 from utilities.request import safe_for_redirect
 from utilities.string import remove_linebreaks
 from utilities.string import remove_linebreaks
 from utilities.views import register_model_view
 from utilities.views import register_model_view
@@ -342,12 +344,21 @@ class UserTokenListView(LoginRequiredMixin, View):
 
 
 @register_model_view(UserToken)
 @register_model_view(UserToken)
 class UserTokenView(LoginRequiredMixin, View):
 class UserTokenView(LoginRequiredMixin, View):
+    layout = layout.SimpleLayout(
+        left_panels=[
+            TokenPanel(),
+        ],
+        right_panels=[
+            TokenExamplePanel(),
+        ],
+    )
 
 
     def get(self, request, pk):
     def get(self, request, pk):
         token = get_object_or_404(UserToken.objects.filter(user=request.user), pk=pk)
         token = get_object_or_404(UserToken.objects.filter(user=request.user), pk=pk)
 
 
         return render(request, 'account/token.html', {
         return render(request, 'account/token.html', {
             'object': token,
             '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' %}
 {% extends 'generic/object.html' %}
-{% load helpers %}
 {% load i18n %}
 {% load i18n %}
-{% load render_table from django_tables2 %}
 
 
 {% block title %}{% trans "Token" %} {{ object }}{% endblock %}
 {% 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
         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):
     def clean(self):
         super().clean()
         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.models import ObjectChange
 from core.tables import ObjectChangeTable
 from core.tables import ObjectChangeTable
 from netbox.object_actions import AddObject, BulkDelete, BulkEdit, BulkExport, BulkImport, BulkRename
 from netbox.object_actions import AddObject, BulkDelete, BulkEdit, BulkExport, BulkImport, BulkRename
+from netbox.ui import layout
 from netbox.views import generic
 from netbox.views import generic
+from users.ui import panels
 from utilities.query import count_related
 from utilities.query import count_related
 from utilities.views import GetRelatedModelsMixin, register_model_view
 from utilities.views import GetRelatedModelsMixin, register_model_view
 from . import filtersets, forms, tables
 from . import filtersets, forms, tables
@@ -26,6 +28,14 @@ class TokenListView(generic.ObjectListView):
 @register_model_view(Token)
 @register_model_view(Token)
 class TokenView(generic.ObjectView):
 class TokenView(generic.ObjectView):
     queryset = Token.objects.all()
     queryset = Token.objects.all()
+    layout = layout.SimpleLayout(
+        left_panels=[
+            panels.TokenPanel(),
+        ],
+        right_panels=[
+            panels.TokenExamplePanel(),
+        ],
+    )
 
 
 
 
 @register_model_view(Token, 'add', detail=False)
 @register_model_view(Token, 'add', detail=False)