Merge pull request #552 from alphagov/primary-providers

Added provider management pages in.
This commit is contained in:
minglis
2016-05-11 16:49:47 +01:00
10 changed files with 446 additions and 15 deletions

View File

@@ -39,6 +39,7 @@ from app.notify_client.status_api_client import StatusApiClient
from app.notify_client.template_statistics_api_client import TemplateStatisticsApiClient
from app.notify_client.user_api_client import UserApiClient
from app.notify_client.events_api_client import EventsApiClient
from app.notify_client.provider_client import ProviderClient
login_manager = LoginManager()
csrf = CsrfProtect()
@@ -53,6 +54,7 @@ invite_api_client = InviteApiClient()
statistics_api_client = StatisticsApiClient()
template_statistics_client = TemplateStatisticsApiClient()
events_api_client = EventsApiClient()
provider_client = ProviderClient()
asset_fingerprinter = AssetFingerprinter()
# The current service attached to the request stack.
@@ -78,6 +80,7 @@ def create_app():
statistics_api_client.init_app(application)
template_statistics_client.init_app(application)
events_api_client.init_app(application)
provider_client.init_app(application)
login_manager.init_app(application)
login_manager.login_view = 'main.sign_in'

View File

@@ -25,5 +25,6 @@ from app.main.views import (
invites,
all_services,
tour,
feedback
feedback,
providers
)

View File

@@ -4,14 +4,15 @@ from notifications_utils.recipients import (
InvalidPhoneError
)
from wtforms import (
validators,
StringField,
PasswordField,
ValidationError,
TextAreaField,
FileField,
BooleanField,
HiddenField
)
HiddenField,
IntegerField)
from wtforms.fields.html5 import EmailField, TelField
from wtforms.validators import (DataRequired, Email, Length, Regexp)
@@ -27,7 +28,6 @@ def email_address(label='Email address'):
class UKMobileNumber(TelField):
def pre_validate(self, form):
try:
validate_phone_number(self.data)
@@ -74,7 +74,6 @@ class LoginForm(Form):
class RegisterUserForm(Form):
name = StringField('Full name',
validators=[DataRequired(message='Cant be empty')])
email_address = email_address()
@@ -92,14 +91,12 @@ class RegisterUserFromInviteForm(Form):
class PermissionsForm(Form):
send_messages = BooleanField("Send messages from existing templates")
manage_service = BooleanField("Modify this service, its team, and its templates")
manage_api_keys = BooleanField("Create and revoke API keys")
class InviteUserForm(PermissionsForm):
email_address = email_address('Email address')
def __init__(self, invalid_email_address, *args, **kwargs):
@@ -184,7 +181,6 @@ class ServiceNameForm(Form):
class ConfirmPasswordForm(Form):
def __init__(self, validate_password_func, *args, **kwargs):
self.validate_password_func = validate_password_func
super(ConfirmPasswordForm, self).__init__(*args, **kwargs)
@@ -211,7 +207,6 @@ class SMSTemplateForm(Form):
class EmailTemplateForm(SMSTemplateForm):
subject = TextAreaField(
u'Subject',
validators=[DataRequired(message="Cant be empty")])
@@ -226,7 +221,6 @@ class NewPasswordForm(Form):
class ChangePasswordForm(Form):
def __init__(self, validate_password_func, *args, **kwargs):
self.validate_password_func = validate_password_func
super(ChangePasswordForm, self).__init__(*args, **kwargs)
@@ -241,7 +235,7 @@ class ChangePasswordForm(Form):
class CsvUploadForm(Form):
file = FileField('Add recipients', validators=[DataRequired(
message='Please pick a file'), CsvFileValidator()])
message='Please pick a file'), CsvFileValidator()])
class ChangeNameForm(Form):
@@ -249,7 +243,6 @@ class ChangeNameForm(Form):
class ChangeEmailForm(Form):
def __init__(self, validate_email_func, *args, **kwargs):
self.validate_email_func = validate_email_func
super(ChangeEmailForm, self).__init__(*args, **kwargs)
@@ -263,7 +256,6 @@ class ChangeEmailForm(Form):
class ConfirmEmailForm(Form):
def __init__(self, validate_code_func, *args, **kwargs):
self.validate_code_func = validate_code_func
super(ConfirmEmailForm, self).__init__(*args, **kwargs)
@@ -281,7 +273,6 @@ class ChangeMobileNumberForm(Form):
class ConfirmMobileNumberForm(Form):
def __init__(self, validate_code_func, *args, **kwargs):
self.validate_code_func = validate_code_func
super(ConfirmMobileNumberForm, self).__init__(*args, **kwargs)
@@ -309,7 +300,6 @@ class CreateKeyForm(Form):
class Feedback(Form):
name = StringField('Name')
email_address = StringField('Email address')
feedback = TextAreaField(u'', validators=[DataRequired(message="Cant be empty")])
@@ -320,3 +310,7 @@ class RequestToGoLiveForm(Form):
'',
validators=[DataRequired(message="Cant be empty")]
)
class ProviderForm(Form):
priority = IntegerField('Priority', [validators.NumberRange(min=1, max=100, message="Must be between 1 and 100")])

View File

@@ -0,0 +1,35 @@
from flask import (
render_template, url_for)
from flask_login import (
login_required,
)
from werkzeug.utils import redirect
from app.main import main
from app.main.forms import ProviderForm
from app.utils import user_has_permissions
from app import provider_client
@main.route("/providers")
@login_required
@user_has_permissions(admin_override=True)
def view_providers():
providers = provider_client.get_all_providers()['provider_details']
email_providers = [email for email in providers if email['notification_type'] == 'email']
sms_providers = [sms for sms in providers if sms['notification_type'] == 'sms']
return render_template('views/providers.html', email_providers=email_providers, sms_providers=sms_providers)
@main.route("/provider/<provider_id>", methods=['GET', 'POST'])
@login_required
@user_has_permissions(admin_override=True)
def view_provider(provider_id):
provider = provider_client.get_provider_by_id(provider_id)['provider_details']
form = ProviderForm(active=provider['active'], priority=provider['priority'])
if form.validate_on_submit():
provider_client.update_provider(provider_id, form.priority.data)
return redirect(url_for('.view_providers'))
return render_template('views/provider.html', form=form, provider=provider)

View File

@@ -0,0 +1,33 @@
from notifications_python_client.base import BaseAPIClient
from app.notify_client import _attach_current_user
class ProviderClient(BaseAPIClient):
def __init__(self, base_url=None, client_id=None, secret=None):
super(self.__class__, self).__init__(
base_url=base_url or 'base_url',
client_id=client_id or 'client_id',
secret=secret or 'secret'
)
def init_app(self, app):
self.base_url = app.config['API_HOST_NAME']
self.client_id = app.config['ADMIN_CLIENT_USER_NAME']
self.secret = app.config['ADMIN_CLIENT_SECRET']
def get_all_providers(self):
return self.get(
url='/provider-details'
)
def get_provider_by_id(self, provider_id):
return self.get(
url='/provider-details/{}'.format(provider_id)
)
def update_provider(self, provider_id, priority):
data = {
"priority": priority
}
_attach_current_user(data)
return self.post(url='/provider-details/{}'.format(provider_id), data=data)

View File

@@ -19,5 +19,8 @@
{% if current_user.has_permissions(admin_override=True) %}
<li><a href="{{ url_for('.show_all_services') }}"> List all services </a></li>
{% endif %}
{% if current_user.has_permissions(admin_override=True) %}
<li><a href="{{ url_for('.view_providers') }}">View providers</a></li>
{% endif %}
</ul>
</nav>

View File

@@ -0,0 +1,32 @@
{% extends "withoutnav_template.html" %}
{% from "components/table.html" import list_table, field, text_field, link_field, right_aligned_field_heading, hidden_field_heading %}
{% from "components/textbox.html" import textbox %}
{% from "components/page-footer.html" import page_footer %}
{% block page_title %}
Provider - {{provider.display_name}} GOV.UK Notify
{% endblock %}
{% block maincolumn_content %}
<div class="grid-row">
<div class="column-three-quarters">
<h1 class="heading-large">{{provider.display_name}}</h1>
<p>Update provider:</p>
<ul class="list-bullet">
<li>We only send from the highest priority provider</li>
</ul>
<form method="post">
{{ textbox(form.priority) }}
{{ page_footer('Save', back_link=url_for('.view_providers'), back_link_text="Back to providers") }}
</form>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,65 @@
{% extends "withoutnav_template.html" %}
{% from "components/table.html" import list_table, field, text_field, link_field, right_aligned_field_heading, hidden_field_heading %}
{% block page_title %}
Providers GOV.UK Notify
{% endblock %}
{% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-large">Providers</h1>
<p>
Providers on Notify
</p>
<h2 class="heading-medium">SMS</h2>
{% call(item, row_number) list_table(
sms_providers,
caption="SMS providers",
caption_visible=False,
empty_message='No email providers',
field_headings=['Provider', 'Priority', 'Active', ''],
field_headings_visible=True
) %}
{{ text_field(item.display_name) }}
{{ text_field(item.priority) }}
{{ text_field(item.active) }}
{{ link_field('change', url_for('main.view_provider', provider_id=item.id)) }}
{% endcall %}
<h2 class="heading-medium">Email</h2>
{% call(item, row_number) list_table(
email_providers,
caption="Email providers",
caption_visible=False,
empty_message='No email providers',
field_headings=['Provider', 'Priority', 'Active', ''],
field_headings_visible=True
) %}
{{ text_field(item.display_name) }}
{{ text_field(item.priority) }}
{{ text_field(item.active) }}
{{ link_field('change', url_for('main.view_provider', provider_id=item.id)) }}
{% endcall %}
</div>
</div>
{% endblock %}