Commit fead5a1c authored by Lukas Burgey's avatar Lukas Burgey

Add real REST interface for ssh keys

parent 35dce7ee
......@@ -28,6 +28,8 @@ class ClientAdmin(UserAdmin):
list_filter = (TypeFilter,)
admin.site.register(models.User, ClientAdmin)
admin.site.register(models.SSHPublicKey)
admin.site.unregister(AuthGroup)
......@@ -56,8 +58,6 @@ admin.site.register(EntitlementNameSpace)
admin.site.register(OIDCConfig)
admin.site.register(models.RabbitMQInstance)
admin.site.register(models.User, ClientAdmin)
admin.site.register(models.Site)
admin.site.register(models.Service)
......
import logging
from django.contrib.auth import authenticate
from rest_framework import status
from rest_framework import views
from rest_framework.permissions import AllowAny
from django.shortcuts import get_object_or_404
from rest_framework import status, views, generics, exceptions
from rest_framework.response import Response
from feudal.backend.auth.v1 import OIDCTokenAuthHTTPBackend
from .. import models
......@@ -16,11 +15,11 @@ LOGGER = logging.getLogger(__name__)
EXAMPLE_INPUT = {
'at': '<OpenID Connect Access Token>',
'iss': '<Issuer URI>',
'key_name': '<SSH public key name>',
'key_value': '<Value for a new SSH key (if the key "key_name" does not yet exist)>',
's': '<service identifier>',
'state_target': '<deployed | not_deployed>',
}
......@@ -35,62 +34,74 @@ def _error_response(request, error):
)
class SSHPublicKeyView(generics.RetrieveDestroyAPIView):
authentication_classes = (OIDCTokenAuthHTTPBackend,)
serializer_class = serializers.SSHPublicKeySerializer
def get_object(self):
if 'id' not in self.request.query_params:
raise exceptions.ValidationError('Need "id" parameter')
return get_object_or_404(
self.request.user.ssh_keys.all(),
id=self.request.query_params.get('id'),
)
def perform_destroy(self, instance):
self.request.user.user_remove_key(instance)
class SSHPublicKeyListView(generics.ListCreateAPIView):
authentication_classes = (OIDCTokenAuthHTTPBackend,)
serializer_class = serializers.SSHPublicKeySerializer
def get_queryset(self):
return self.request.user.ssh_keys.all()
def perform_create(self, serializer):
key = serializer.save(user=self.request.user)
self.request.user.user_changed_key_added(key)
class ServiceListView(generics.ListAPIView):
authentication_classes = (OIDCTokenAuthHTTPBackend,)
serializer_class = serializers.ServiceSerializer
def get_queryset(self):
return self.request.user.services.all()
class DeploymentListView(generics.ListCreateAPIView):
authentication_classes = (OIDCTokenAuthHTTPBackend,)
serializer_class = serializers.DeploymentSerializer
def get_queryset(self):
return self.request.user.deployments.all()
def perform_create(self, serializer):
# TODO
pass
# basically obsolete
class ProvisioningView(views.APIView):
permission_classes = (AllowAny,)
authentication_classes = (OIDCTokenAuthHTTPBackend,)
def post(self, request):
for key in ['at', 'iss', 'key_name', 's']:
for key in ['s']:
if key not in request.data:
return _error_response(request, 'Missing key "{}"'.format(key))
access_token = request.data.get('at', '')
issuer_uri = request.data.get('iss', '')
key_name = request.data.get('key_name', '')
service_name = request.data.get('s', '')
state_target = request.data.get('state_target', deployments.DEPLOYED)
user = authenticate(
request,
token=access_token,
issuer_uri=issuer_uri,
)
if user is None:
return _error_response(
request,
'Unable to authenticate user with token "{}" at issuer "{}"'.format(
access_token,
issuer_uri,
),
)
LOGGER.debug("USER-RESTAPI: authenticated user %s using access token", user)
ssh_key = None
try:
ssh_key = user.ssh_keys.get(
name=request.data['key_name'],
)
except models.SSHPublicKey.DoesNotExist:
if 'key_value' not in request.data:
return _error_response(request, 'Need ssh key field "key_value" to create the key "{}"'.format(
key_name,
))
ssh_key = models.SSHPublicKey(
name=request.data['key_name'],
key=request.data['key_value'],
user=user,
)
ssh_key.save()
service = None
try:
service = user.services.get(
service = request.user.services.get(
name=service_name,
)
deployment = deployments.get_deployment(user, service=service)
deployment = deployments.get_deployment(request.user, service=service)
if deployment is not None:
if state_target == deployments.DEPLOYED:
deployment.user_deploy()
......
......@@ -3,4 +3,8 @@ from . import user_rest as views
URLPATTERNS = [
url(r'^prov', views.ProvisioningView.as_view()),
url(r'^ssh-key$', views.SSHPublicKeyView.as_view()),
url(r'^ssh-keys$', views.SSHPublicKeyListView.as_view()),
url(r'^services$', views.ServiceListView.as_view()),
url(r'^deployments$', views.DeploymentListView.as_view()),
]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment