diff --git a/netbox/project-static/js/secrets.js b/netbox/project-static/js/secrets.js index 40f4b5f0c..f2467c365 100644 --- a/netbox/project-static/js/secrets.js +++ b/netbox/project-static/js/secrets.js @@ -92,7 +92,7 @@ $(document).ready(function() { $('#generate_keypair').click(function() { $('#new_keypair_modal').modal('show'); $.ajax({ - url: netbox_api_path + 'secrets/generate-keys/', + url: netbox_api_path + 'secrets/generate-rsa-key-pair/', type: 'GET', dataType: 'json', success: function (response, status) { diff --git a/netbox/secrets/api/urls.py b/netbox/secrets/api/urls.py index d67ea92e4..e8457074c 100644 --- a/netbox/secrets/api/urls.py +++ b/netbox/secrets/api/urls.py @@ -6,15 +6,14 @@ from . import views router = routers.DefaultRouter() + router.register(r'secret-roles', views.SecretRoleViewSet) router.register(r'secrets', views.SecretViewSet) +router.register(r'get-session-key', views.GetSessionKeyViewSet, base_name='get-session-key') +router.register(r'generate-rsa-key-pair', views.GenerateRSAKeyPairViewSet, base_name='generate-rsa-key-pair') urlpatterns = [ url(r'', include(router.urls)), - # Miscellaneous - url(r'^get-session-key/$', views.GetSessionKey.as_view(), name='get_session_key'), - url(r'^generate-keys/$', views.RSAKeyGeneratorView.as_view(), name='generate_keys'), - ] diff --git a/netbox/secrets/api/views.py b/netbox/secrets/api/views.py index 0ac087c63..e2874c9cc 100644 --- a/netbox/secrets/api/views.py +++ b/netbox/secrets/api/views.py @@ -7,14 +7,12 @@ from rest_framework.authentication import BasicAuthentication, SessionAuthentica from rest_framework.permissions import IsAuthenticated from rest_framework.renderers import JSONRenderer from rest_framework.response import Response -from rest_framework.views import APIView -from rest_framework.viewsets import ModelViewSet +from rest_framework.viewsets import ViewSet, ModelViewSet from extras.api.renderers import FormlessBrowsableAPIRenderer, FreeRADIUSClientsRenderer from secrets.filters import SecretFilter from secrets.models import Secret, SecretRole, SessionKey, UserKey from utilities.api import WritableSerializerMixin - from . import serializers @@ -107,13 +105,25 @@ class SecretViewSet(WritableSerializerMixin, ModelViewSet): return Response(serializer.data) -class GetSessionKey(APIView): +class GetSessionKeyViewSet(ViewSet): """ - Cache an encrypted copy of the master key derived from the submitted private key. + Retrieve a temporary session key to use for encrypting and decrypting secrets via the API. The user's private RSA + key is POSTed with the name `private_key`. An example: + + curl -v -X POST -H "Authorization: Token " -H "Accept: application/json; indent=4" \\ + --data-urlencode "private_key@" https://netbox/api/secrets/get-session-key/ + + This request will yield a session key to be included in an `X-Session-Key` header in future requests, as well as its + expiration time: + + { + "expiration_time": "2017-03-09T10:42:23.095267Z", + "session_key": "+8t4SI6XikgVmB5+/urhozx9O5qCQANyOk1MNe6taRf=" + } """ permission_classes = [IsAuthenticated] - def post(self, request): + def create(self, request): # Read private key private_key = request.POST.get('private_key', None) @@ -150,13 +160,18 @@ class GetSessionKey(APIView): return response -class RSAKeyGeneratorView(APIView): +class GenerateRSAKeyPairViewSet(ViewSet): """ - Generate a new RSA key pair for a user. Authenticated because it's a ripe avenue for DoS. + This endpoint can be used to generate a new RSA key pair. The keys are returned in PEM format. + + { + "public_key": "", + "private_key": "" + } """ permission_classes = [IsAuthenticated] - def get(self, request): + def list(self, request): # Determine what size key to generate key_size = request.GET.get('key_size', 2048)