Browse Source

#68: Improved permissions-related error handling

Jeremy Stretch 8 years ago
parent
commit
966ea45050

+ 10 - 8
netbox/secrets/api/views.py

@@ -4,6 +4,7 @@ from django.shortcuts import get_object_or_404
 
 from rest_framework import generics
 from rest_framework import status
+from rest_framework.exceptions import PermissionDenied
 from rest_framework.permissions import IsAuthenticated
 from rest_framework.renderers import JSONRenderer
 from rest_framework.response import Response
@@ -108,14 +109,15 @@ class SecretDetailView(generics.GenericAPIView):
                     {'error': ERR_USERKEY_INACTIVE},
                     status=status.HTTP_400_BAD_REQUEST
                 )
-            if secret.decryptable_by(request.user):
-                master_key = uk.get_master_key(private_key)
-                if master_key is None:
-                    return Response(
-                        {'error': ERR_PRIVKEY_INVALID},
-                        status=status.HTTP_400_BAD_REQUEST
-                    )
-                secret.decrypt(master_key)
+            if not secret.decryptable_by(request.user):
+                raise PermissionDenied(detail="You do not have permission to decrypt this secret.")
+            master_key = uk.get_master_key(private_key)
+            if master_key is None:
+                return Response(
+                    {'error': ERR_PRIVKEY_INVALID},
+                    status=status.HTTP_400_BAD_REQUEST
+                )
+            secret.decrypt(master_key)
 
         serializer = self.get_serializer(secret)
         return Response(serializer.data)

+ 0 - 0
netbox/secrets/templatetags/__init__.py


+ 12 - 0
netbox/secrets/templatetags/secret_helpers.py

@@ -0,0 +1,12 @@
+from django import template
+
+
+register = template.Library()
+
+
+@register.filter()
+def decryptable_by(secret, user):
+    """
+    Determine whether a given User is permitted to decrypt a Secret.
+    """
+    return secret.decryptable_by(user)

+ 13 - 6
netbox/templates/secrets/inc/secret_tr.html

@@ -1,13 +1,20 @@
+{% load secret_helpers %}
 <tr>
     <td><a href="{% url 'secrets:secret' pk=secret.pk %}">{{ secret.role }}</a></td>
     <td>{{ secret.name }}</td>
     <td id="secret_{{ secret.pk }}">********</td>
     <td class="text-right">
-        <button class="btn btn-xs btn-success unlock-secret" secret-id="{{ secret.pk }}">
-            <i class="fa fa-lock"></i> Unlock
-        </button>
-        <button class="btn btn-xs btn-danger lock-secret collapse" secret-id="{{ secret.pk }}">
-            <i class="fa fa-unlock-alt"></i> Lock
-        </button>
+        {% if secret|decryptable_by:request.user %}
+            <button class="btn btn-xs btn-success unlock-secret" secret-id="{{ secret.pk }}">
+                <i class="fa fa-lock"></i> Unlock
+            </button>
+            <button class="btn btn-xs btn-danger lock-secret collapse" secret-id="{{ secret.pk }}">
+                <i class="fa fa-unlock-alt"></i> Lock
+            </button>
+        {% else %}
+            <button class="btn btn-xs btn-default" disabled="disabled" title="Permission denied">
+                <i class="fa fa-lock"></i> Unlock
+            </button>
+        {% endif %}
     </td>
 </tr>

+ 27 - 19
netbox/templates/secrets/secret.html

@@ -1,5 +1,6 @@
 {% extends '_base.html' %}
 {% load static from staticfiles %}
+{% load secret_helpers %}
 
 {% block title %}Secret: {{ secret }}{% endblock %}
 
@@ -67,28 +68,35 @@
         </div>
 	</div>
 	<div class="col-md-6">
-        <div class="panel panel-default">
-            <div class="panel-heading">
-                <strong>Secret Data</strong>
-            </div>
-            <div class="panel-body">
-                <form id="secret_form">
-                    {% csrf_token %}
-                </form>
-                <div class="row">
-                    <div class="col-md-2">Secret</div>
-                    <div class="col-md-8" id="secret_{{ secret.pk }}">********</div>
-                    <div class="col-md-2 text-right">
-                        <button class="btn btn-xs btn-success unlock-secret" secret-id="{{ secret.pk }}">
-                            <i class="fa fa-lock"></i> Unlock
-                        </button>
-                        <button class="btn btn-xs btn-danger lock-secret collapse" secret-id="{{ secret.pk }}">
-                            <i class="fa fa-unlock-alt"></i> Lock
-                        </button>
+        {% if secret|decryptable_by:request.user %}
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <strong>Secret Data</strong>
+                </div>
+                <div class="panel-body">
+                    <form id="secret_form">
+                        {% csrf_token %}
+                    </form>
+                    <div class="row">
+                        <div class="col-md-2">Secret</div>
+                        <div class="col-md-8" id="secret_{{ secret.pk }}">********</div>
+                        <div class="col-md-2 text-right">
+                            <button class="btn btn-xs btn-success unlock-secret" secret-id="{{ secret.pk }}">
+                                <i class="fa fa-lock"></i> Unlock
+                            </button>
+                            <button class="btn btn-xs btn-danger lock-secret collapse" secret-id="{{ secret.pk }}">
+                                <i class="fa fa-unlock-alt"></i> Lock
+                            </button>
+                        </div>
                     </div>
                 </div>
             </div>
-        </div>
+        {% else %}
+            <div class="alert alert-warning">
+                <i class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></i>
+                You do not have permission to decrypt this secret.
+            </div>
+        {% endif %}
     </div>
 </div>