ovh: ease setup with new API (#47851)

This commit is contained in:
Valentin Deniaud 2020-10-15 18:18:34 +02:00
parent efb1919004
commit 4fe1eb5c1d
6 changed files with 102 additions and 5 deletions

View File

@ -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',

View File

@ -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}

View File

@ -2,7 +2,14 @@
{% load i18n passerelle %}
{% block description %}
{% if object.uses_new_api and not object.consumer_key %}
<div class="warningnotice">{% trans "Connector is not operational yet, as access needs to be obtained from OVH for the specified account." %}
<a href="{% url "ovh-request-token" slug=object.slug %}">{% trans "Click here to request access." %}</a>
</div>
{% endif %}
{{ block.super }}
{% if object.uses_new_api %}
<p>
{% if object.credit_left %}

View File

@ -0,0 +1,10 @@
from django.conf.urls import url
from . import views
management_urlpatterns = [
url(r'^(?P<slug>[\w,-]+)/request_token/$',
views.RequestTokenView.as_view(), name='ovh-request-token'),
url(r'^(?P<slug>[\w,-]+)/confirm_token/(?P<uuid>[a-z0-9-]+)/$',
views.ConfirmTokenView.as_view(), name='ovh-confirm-token'),
]

View File

@ -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()

View File

@ -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'