diff --git a/passerelle/apps/ovh/migrations/0009_auto_20200730_1047.py b/passerelle/apps/ovh/migrations/0009_auto_20200730_1047.py
index 4f3d597d..a3be3ad4 100644
--- a/passerelle/apps/ovh/migrations/0009_auto_20200730_1047.py
+++ b/passerelle/apps/ovh/migrations/0009_auto_20200730_1047.py
@@ -15,7 +15,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='ovhsmsgateway',
name='application_key',
- field=models.CharField(blank=True, help_text='Random token obtained from OVH.', max_length=16, verbose_name='Application key'),
+ field=models.CharField(blank=True, max_length=16, verbose_name='Application key'),
),
migrations.AddField(
model_name='ovhsmsgateway',
@@ -25,7 +25,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='ovhsmsgateway',
name='consumer_key',
- field=models.CharField(blank=True, help_text='Obtained at the same time as "Application key".', max_length=32, verbose_name='Consumer key'),
+ field=models.CharField(blank=True, help_text='Automatically obtained from OVH, should not be filled manually.', max_length=32, verbose_name='Consumer key'),
),
migrations.AlterField(
model_name='ovhsmsgateway',
diff --git a/passerelle/apps/ovh/models.py b/passerelle/apps/ovh/models.py
index 27959e1e..2a07ddd6 100644
--- a/passerelle/apps/ovh/models.py
+++ b/passerelle/apps/ovh/models.py
@@ -44,7 +44,6 @@ class OVHSMSGateway(SMSResource):
verbose_name=_('Application key'),
max_length=16,
blank=True,
- help_text=_('Random token obtained from OVH.'),
)
application_secret = models.CharField(
verbose_name=_('Application secret'),
@@ -56,7 +55,7 @@ class OVHSMSGateway(SMSResource):
verbose_name=_('Consumer key'),
max_length=32,
blank=True,
- help_text=_('Obtained at the same time as "Application key".'),
+ help_text=_('Automatically obtained from OVH, should not be filled manually.'),
)
username = models.CharField(
@@ -131,7 +130,7 @@ class OVHSMSGateway(SMSResource):
@property
def uses_new_api(self):
- return self.application_key and self.consumer_key and self.application_secret
+ return self.application_key and self.application_secret
def request(self, method, endpoint, **kwargs):
url = self.API_URL % {'serviceName': self.account, 'login': self.username}
diff --git a/passerelle/apps/ovh/templates/ovh/ovhsmsgateway_detail.html b/passerelle/apps/ovh/templates/ovh/ovhsmsgateway_detail.html
index 926dfdf8..6279de79 100644
--- a/passerelle/apps/ovh/templates/ovh/ovhsmsgateway_detail.html
+++ b/passerelle/apps/ovh/templates/ovh/ovhsmsgateway_detail.html
@@ -2,7 +2,14 @@
{% load i18n passerelle %}
{% block description %}
+{% if object.uses_new_api and not object.consumer_key %}
+
+{% endif %}
+
{{ block.super }}
+
{% if object.uses_new_api %}
{% if object.credit_left %}
diff --git a/passerelle/apps/ovh/urls.py b/passerelle/apps/ovh/urls.py
new file mode 100644
index 00000000..5d800b2b
--- /dev/null
+++ b/passerelle/apps/ovh/urls.py
@@ -0,0 +1,10 @@
+from django.conf.urls import url
+
+from . import views
+
+management_urlpatterns = [
+ url(r'^(?P[\w,-]+)/request_token/$',
+ views.RequestTokenView.as_view(), name='ovh-request-token'),
+ url(r'^(?P[\w,-]+)/confirm_token/(?P[a-z0-9-]+)/$',
+ views.ConfirmTokenView.as_view(), name='ovh-confirm-token'),
+]
diff --git a/passerelle/apps/ovh/views.py b/passerelle/apps/ovh/views.py
new file mode 100644
index 00000000..1c52e3b5
--- /dev/null
+++ b/passerelle/apps/ovh/views.py
@@ -0,0 +1,48 @@
+import requests
+import uuid
+from urllib.parse import urljoin
+
+from django.conf import settings
+from django.contrib import messages
+from django.shortcuts import reverse
+from django.utils.translation import ugettext_lazy as _
+from django.views.generic.base import RedirectView
+
+from .models import OVHSMSGateway
+
+
+class RequestTokenView(RedirectView):
+ def get_redirect_url(self, *args, **kwargs):
+ connector = OVHSMSGateway.objects.get(slug=kwargs["slug"])
+
+ request_id = uuid.uuid4()
+ confirm_token_url = reverse('ovh-confirm-token', kwargs={'slug': connector.slug, 'uuid': request_id})
+ data = {
+ "accessRules": [
+ {"method": "GET", "path": "/sms/%s/" % connector.account},
+ {"method": "POST", "path": "/sms/%s/jobs/" % connector.account},
+ ],
+ "redirection": self.request.build_absolute_uri(confirm_token_url),
+ }
+ headers = {"X-Ovh-Application": connector.application_key}
+
+ resp = requests.post('https://eu.api.ovh.com/1.0/auth/credential', json=data, headers=headers)
+ result = resp.json()
+
+ self.request.session['ovh-token-%s' % request_id] = result['consumerKey']
+ return result['validationUrl']
+
+
+class ConfirmTokenView(RedirectView):
+ def get_redirect_url(self, *args, **kwargs):
+ connector = OVHSMSGateway.objects.get(slug=kwargs["slug"])
+ consumer_key = self.request.session.get('ovh-token-%s' % kwargs['uuid'])
+
+ if consumer_key:
+ connector.consumer_key = consumer_key
+ connector.save()
+ messages.success(self.request, _('Successfuly completed connector configuration.'))
+ else:
+ messages.warning(self.request, _('Could not complete connector configuration, please try again.'))
+
+ return connector.get_absolute_url()
diff --git a/tests/test_sms.py b/tests/test_sms.py
index 69535796..5759775c 100644
--- a/tests/test_sms.py
+++ b/tests/test_sms.py
@@ -1,8 +1,10 @@
import isodate
+import json
import mock
import pytest
from requests import RequestException
+from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse
@@ -340,3 +342,34 @@ def test_ovh_alert_emails(app, freezer, mailoutbox):
with utils.mock_url(ovh_url, resp, 200) as mocked:
connector.hourly()
assert len(mailoutbox) == 1
+
+
+def test_ovh_token_request(admin_user, app):
+ connector = OVHSMSGateway.objects.create(
+ slug='test-ovh', title='Test OVH', account='sms-test42',
+ application_key='RHrTdU2oTsrVC0pu',
+ application_secret='CLjtS69tTcPgCKxedeoZlgMSoQGSiXMa',
+ )
+
+ app = login(app)
+ resp = app.get(connector.get_absolute_url())
+ assert 'not operational yet' in resp.text
+
+ ovh_request_token_url = 'https://eu.api.ovh.com/1.0/auth/credential'
+ ovh_response = {
+ 'consumerKey': 'xyz',
+ 'validationUrl': 'https://eu.api.ovh.com/auth/?credentialToken=iQ1joJE',
+ }
+ with utils.mock_url(ovh_request_token_url, ovh_response, 302) as mocked:
+ resp = resp.click('request access')
+ assert resp.url == 'https://eu.api.ovh.com/auth/?credentialToken=iQ1joJE'
+
+ request = mocked.handlers[0].call['requests'][0]
+ body = json.loads(request.body.decode())
+ assert 'accessRules' in body
+ redirect_url = body['redirection'][len('http://testserver'):]
+
+ resp = app.get(redirect_url).follow()
+ assert 'Successfuly completed connector configuration' in resp.text
+ connector.refresh_from_db()
+ assert connector.consumer_key == 'xyz'