Merge pull request #1327 from alphagov/create-inbound-api

Create inbound api
This commit is contained in:
kentsanggds
2017-06-22 12:36:28 +01:00
committed by GitHub
7 changed files with 350 additions and 10 deletions

View File

@@ -9,6 +9,7 @@ from notifications_utils.recipients import (
)
from notifications_utils.columns import Columns
from wtforms import (
widgets,
validators,
StringField,
PasswordField,
@@ -651,6 +652,21 @@ class PlaceholderForm(Form):
pass
class PasswordFieldShowHasContent(StringField):
widget = widgets.PasswordInput(hide_value=False)
class ServiceInboundApiForm(Form):
url = StringField("Inbound sms url",
validators=[DataRequired(message='Cant be empty'),
Regexp(regex="^https.*",
message='Must be a valid https url')]
)
bearer_token = PasswordFieldShowHasContent("Bearer token",
validators=[DataRequired(message='Cant be empty'),
Length(min=10, message='Must be at least 10 characters')])
def get_placeholder_form_instance(
placeholder_name,
dict_to_populate_from,

View File

@@ -1,3 +1,5 @@
from urllib.parse import urlparse
import requests
from flask import (
render_template,
@@ -30,10 +32,21 @@ from app.main.forms import (
ServiceLetterContactBlock,
ServiceBrandingOrg,
LetterBranding,
)
ServiceInboundApiForm)
from app import user_api_client, current_service, organisations_client
dummy_bearer_token = 'bearer_token_set'
def get_inbound_api():
if current_service['inbound_api']:
return service_api_client.get_service_inbound_api(
current_service['id'],
current_service.get('inbound_api')[0]
)
@main.route("/services/<service_id>/service-settings")
@login_required
@user_has_permissions('manage_settings', admin_override=True)
@@ -43,6 +56,15 @@ def service_settings(service_id):
organisation = organisations_client.get_organisation(current_service['organisation'])['organisation']
else:
organisation = None
inbound_api = get_inbound_api()
if inbound_api:
parsed_url = urlparse(inbound_api.get('url')) if inbound_api else ''
inbound_api_url = '{uri.scheme}://{uri.netloc}{elide_token}'.format(
uri=parsed_url, elide_token='...' if parsed_url.path else '')
else:
inbound_api_url = ''
return render_template(
'views/service-settings.html',
organisation=organisation,
@@ -50,6 +72,7 @@ def service_settings(service_id):
current_service.get('dvla_organisation', '001')
),
can_receive_inbound=('inbound_sms' in current_service['permissions']),
inbound_api_url=inbound_api_url,
letter_contact_block=Field(current_service['letter_contact_block'], html='escape')
)
@@ -268,6 +291,7 @@ def service_set_reply_to_email(service_id):
@user_has_permissions('manage_settings', admin_override=True)
def service_set_sms_sender(service_id):
form = ServiceSmsSender()
if form.validate_on_submit():
set_inbound_sms = request.args.get('set_inbound_sms', False)
if set_inbound_sms == 'True':
@@ -410,3 +434,41 @@ def get_branding_as_dict(organisations):
'colour': organisation['colour']
} for organisation in organisations
}
@main.route("/services/<service_id>/service-settings/set-inbound-api", methods=['GET', 'POST'])
@login_required
@user_has_permissions('manage_settings', admin_override=True)
def service_set_inbound_api(service_id):
if 'inbound_sms' not in current_service['permissions']:
abort(403)
inbound_api = get_inbound_api()
form = ServiceInboundApiForm(
url=inbound_api.get('url') if inbound_api else '',
bearer_token=dummy_bearer_token if inbound_api else ''
)
if form.validate_on_submit():
if inbound_api:
if inbound_api.get('url') != form.url.data or form.bearer_token.data != dummy_bearer_token:
service_api_client.update_service_inbound_api(
service_id,
url=form.url.data,
bearer_token=form.bearer_token.data if form.bearer_token.data != dummy_bearer_token else '',
user_id=current_user.id,
inbound_api_id=inbound_api.get('id')
)
else:
service_api_client.create_service_inbound_api(
service_id,
url=form.url.data,
bearer_token=form.bearer_token.data,
user_id=current_user.id
)
return redirect(url_for('.service_settings', service_id=service_id))
return render_template(
'views/service-settings/set-inbound-api.html',
form=form,
)

View File

@@ -266,6 +266,30 @@ class ServiceAPIClient(NotifyAdminAPIClient):
'/service/{}/inbound-sms/summary'.format(service_id)
)
def create_service_inbound_api(self, service_id, url, bearer_token, user_id):
data = {
"url": url,
"bearer_token": bearer_token,
"updated_by_id": user_id
}
return self.post("/service/{}/inbound-api".format(service_id), data)
def update_service_inbound_api(self, service_id, url, bearer_token, user_id, inbound_api_id):
data = {
"url": url,
"updated_by_id": user_id
}
if bearer_token:
data['bearer_token'] = bearer_token
return self.post("/service/{}/inbound-api/{}".format(service_id, inbound_api_id), data)
def get_service_inbound_api(self, service_id, inbound_sms_api_id):
return self.get(
"/service/{}/inbound-api/{}".format(
service_id, inbound_sms_api_id
)
)['data']
class ServicesBrowsableItem(BrowsableItem):
@property

View File

@@ -57,6 +57,17 @@
{{ edit_field('Change', url_for('.service_set_inbound_sms', service_id=current_service.id)) }}
{% endcall %}
{% if can_receive_inbound %}
{% call row() %}
{{ text_field('API endpoint for received text messages') }}
{{ text_field(
'None' if not inbound_api_url else inbound_api_url,
status='' if inbound_api_url else 'default'
) }}
{{ edit_field('Change', url_for('.service_set_inbound_api', service_id=current_service.id)) }}
{% endcall %}
{% endif %}
{% call row() %}
{{ text_field('Letters') }}
{{ boolean_field(current_service.can_send_letters) }}
@@ -72,6 +83,7 @@
{{ edit_field('Change', url_for('.service_set_letter_contact_block', service_id=current_service.id)) }}
{% endcall %}
{% endif %}
{% endcall %}
</div>

View File

@@ -0,0 +1,38 @@
{% extends "withnav_template.html" %}
{% from "components/textbox.html" import textbox %}
{% from "components/page-footer.html" import page_footer %}
{% block service_page_title %}
Inbound api
{% endblock %}
{% block maincolumn_content %}
<div class="grid-row">
<div class="column-five-sixths">
<h1 class="heading-large">API endpoint for received text messages</h1>
<p>
This is the https url that the inbound SMS messages will be posted to
and the bearer token used in the authorisation header of the request.
</p>
<form method="post">
{{ textbox(
form.url,
width='2-3',
hint='Valid https url'
) }}
{{ textbox(
form.bearer_token,
width='1-4',
hint='At least 10 characters'
) }}
{{ page_footer(
'Save',
back_link=url_for('.service_settings', service_id=current_service.id),
back_link_text='Back to settings'
) }}
</form>
</div>
</div>
{% endblock %}