From d31fbc89ed0965063caa480f8800eda686e53b76 Mon Sep 17 00:00:00 2001
From: Christophe Siraut <csiraut@entrouvert.com>
Date: Fri, 21 Jun 2019 13:10:03 +0200
Subject: [PATCH] environment: add service creation api (#31449)

---
 hobo/environment/views.py | 24 +++++++++++++++++++++++-
 hobo/urls.py              |  2 ++
 tests/test_environment.py | 37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/hobo/environment/views.py b/hobo/environment/views.py
index 19f2cea..4f1d16a 100644
--- a/hobo/environment/views.py
+++ b/hobo/environment/views.py
@@ -8,9 +8,13 @@ from django.http import HttpResponse, HttpResponseRedirect, Http404
 from django.shortcuts import get_object_or_404
 from django.views.generic.base import TemplateView
 from django.views.generic.edit import CreateView, UpdateView, DeleteView
+from django.views.decorators.csrf import csrf_exempt
+from rest_framework.decorators import api_view, permission_classes, authentication_classes
+from rest_framework.authentication import SessionAuthentication, BasicAuthentication
+from rest_framework.permissions import IsAuthenticated
 
 from .models import Variable, AVAILABLE_SERVICES
-from . import forms, utils
+from . import forms, models, utils
 
 
 class AvailableService(object):
@@ -104,6 +108,24 @@ class VariableDeleteView(DeleteView):
         return reverse_lazy('environment-home')
 
 
+@csrf_exempt
+@authentication_classes((SessionAuthentication, BasicAuthentication))
+@permission_classes((IsAuthenticated,))
+def ServiceCreateApi(request, service):
+    from django.http import JsonResponse
+    if request.method != 'POST' or service not in [s.Extra.service_id for s in AVAILABLE_SERVICES]:
+        return JsonResponse({'error': 1, 'data': {'message': ''}})
+    klass = getattr(models, service.title())
+    try:
+        data = {k: v for k, v in request.POST.iteritems()}
+        obj = klass(**data)
+        obj.save()
+        #notify_agents(None)
+        return JsonResponse({'error': 0, 'data': {'id': obj.id}})
+    except Exception:
+        return JsonResponse({'error': 1, 'data': {'message': 'failed'}})
+
+
 class ServiceCreateView(CreateView):
     success_url = reverse_lazy('environment-home')
 
diff --git a/hobo/urls.py b/hobo/urls.py
index da16e21..9840683 100644
--- a/hobo/urls.py
+++ b/hobo/urls.py
@@ -7,6 +7,7 @@ admin.autodiscover()
 from .views import admin_required, login, login_local, logout, home, health_json, menu_json, hobo
 from .urls_utils import decorated_includes
 from .environment.urls import urlpatterns as environment_urls
+from .environment.views import ServiceCreateApi
 from .franceconnect.urls import urlpatterns as franceconnect_urls
 from .matomo.urls import urlpatterns as matomo_urls
 from .profile.urls import urlpatterns as profile_urls
@@ -27,6 +28,7 @@ urlpatterns = [
                                              include(theme_urls))),
     url(r'^emails/', decorated_includes(admin_required, include(emails_urls))),
     url(r'^api/health/$', health_json, name='health-json'),
+    url(r'^api/sites/create/(?P<service>\w+)/$', ServiceCreateApi, name='api-create-service'),
     url(r'^menu.json$', menu_json, name='menu_json'),
     url(r'^hobos.json$', hobo),
     url(r'^admin/', include(admin.site.urls)),
diff --git a/tests/test_environment.py b/tests/test_environment.py
index 0c8517d..18081da 100644
--- a/tests/test_environment.py
+++ b/tests/test_environment.py
@@ -1,12 +1,26 @@
 # -*- coding: utf-8 -*-
+import json
 import pytest
 
+from django.contrib.auth.models import User
 from django.core.exceptions import ValidationError
 from django.utils import timezone
+
 from hobo.environment.models import AVAILABLE_SERVICES, Combo, Passerelle
 
 pytestmark = pytest.mark.django_db
 
+
+def login(app, username='admin', password='password'):
+    login_page = app.get('/login/')
+    login_form = login_page.forms[0]
+    login_form['username'] = username
+    login_form['password'] = password
+    resp = login_form.submit()
+    assert resp.status_int == 302
+    return app
+
+
 def test_service_id():
     for service in AVAILABLE_SERVICES:
         assert service.Extra.service_id
@@ -58,3 +72,26 @@ def test_base_url_field_validator():
             combo = Combo(base_url=url, slug='wesh_'+str(cpt), **kwargs)
             combo.full_clean()
             combo.save()
+
+
+def test_service_create_api(transactional_db, app, admin_user):
+    app = login(app)
+    response = app.post('/api/sites/create/foobar/')
+    content = json.loads(response.text)
+    assert 'error' in content.keys()
+    assert content.get('error') == 1
+
+    response = app.post('/api/sites/create/combo/', params={'foo': 'bar'})
+    content = json.loads(response.text)
+    assert 'error' in content.keys()
+    assert content.get('error') == 1
+
+    response = app.post('/api/sites/create/combo/', params={'title': 'foo', 'slug': 'foo', 'base_url': 'http://example.net/'})
+    content = json.loads(response.text)
+    assert 'error' in content.keys()
+    assert content.get('error') == 0
+    assert 'data' in content.keys()
+    assert 'id' in content.get('data')
+
+    obj = Combo.objects.get(id=content['data']['id'])
+    assert obj.base_url == 'http://example.net/'
-- 
2.20.1

