mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-02-05 02:42:26 -05:00
Added current_service to flask context and template context.
Fix all tests and conflicts. Removed comment line.
This commit is contained in:
@@ -3,7 +3,15 @@ import re
|
||||
|
||||
import dateutil
|
||||
import urllib
|
||||
from flask import (Flask, session, Markup, escape, render_template, make_response, current_app)
|
||||
from flask import (
|
||||
Flask,
|
||||
session,
|
||||
Markup,
|
||||
escape,
|
||||
render_template,
|
||||
make_response,
|
||||
current_app,
|
||||
request)
|
||||
from flask._compat import string_types
|
||||
from flask_login import LoginManager
|
||||
from flask_wtf import CsrfProtect
|
||||
@@ -27,6 +35,10 @@ from utils.recipients import validate_phone_number, InvalidPhoneError
|
||||
import app.proxy_fix
|
||||
from config import configs
|
||||
from utils import logging
|
||||
from werkzeug.local import LocalStack, LocalProxy
|
||||
from flask.globals import _lookup_req_object
|
||||
from functools import partial
|
||||
|
||||
|
||||
login_manager = LoginManager()
|
||||
csrf = CsrfProtect()
|
||||
@@ -41,6 +53,9 @@ invite_api_client = InviteApiClient()
|
||||
statistics_api_client = StatisticsApiClient()
|
||||
asset_fingerprinter = AssetFingerprinter()
|
||||
|
||||
# The current service attached to the request stack.
|
||||
current_service = LocalProxy(partial(_lookup_req_object, 'service'))
|
||||
|
||||
|
||||
def create_app():
|
||||
application = Flask(__name__)
|
||||
@@ -82,6 +97,12 @@ def create_app():
|
||||
application.add_template_filter(linkable_name)
|
||||
|
||||
application.after_request(useful_headers_after_request)
|
||||
application.after_request(save_service_after_request)
|
||||
application.before_request(load_service_before_request)
|
||||
|
||||
def _attach_current_service():
|
||||
return {'current_service': current_service}
|
||||
application.context_processor(_attach_current_service)
|
||||
register_errorhandlers(application)
|
||||
|
||||
return application
|
||||
@@ -167,7 +188,26 @@ def load_user(user_id):
|
||||
return user_api_client.get_user(user_id)
|
||||
|
||||
|
||||
# https://www.owasp.org/index.php/List_of_useful_HTTP_headers
|
||||
def load_service_before_request():
|
||||
service_id = request.view_args.get('service_id', None) if request.view_args else None
|
||||
if service_id:
|
||||
from flask.globals import _request_ctx_stack
|
||||
if _request_ctx_stack.top is not None:
|
||||
setattr(
|
||||
_request_ctx_stack.top,
|
||||
'service',
|
||||
service_api_client.get_service(service_id)['data'])
|
||||
|
||||
|
||||
def save_service_after_request(response):
|
||||
# Only save the current session if the request is 200
|
||||
service_id = request.view_args.get('service_id', None) if request.view_args else None
|
||||
if response.status_code == 200 and service_id:
|
||||
session['service_id'] = service_id
|
||||
return response
|
||||
|
||||
|
||||
# https://www.owasp.org/index.php/List_of_useful_HTTP_headers
|
||||
def useful_headers_after_request(response):
|
||||
response.headers.add('X-Frame-Options', 'deny')
|
||||
response.headers.add('X-Content-Type-Options', 'nosniff')
|
||||
|
||||
@@ -35,9 +35,8 @@ def add_service():
|
||||
form = AddServiceForm(service_api_client.find_all_service_email_from)
|
||||
heading = 'Which service do you want to set up notifications for?'
|
||||
if form.validate_on_submit():
|
||||
session['service_name'] = form.name.data
|
||||
email_from = email_safe(session['service_name'])
|
||||
service_id = service_api_client.create_service(service_name=session['service_name'],
|
||||
email_from = email_safe(form.name.data)
|
||||
service_id = service_api_client.create_service(service_name=form.name.data,
|
||||
active=False,
|
||||
limit=current_app.config['DEFAULT_SERVICE_LIMIT'],
|
||||
restricted=True,
|
||||
|
||||
@@ -17,7 +17,6 @@ def documentation():
|
||||
def api_keys(service_id):
|
||||
return render_template(
|
||||
'views/api-keys.html',
|
||||
service_id=service_id,
|
||||
keys=api_key_api_client.get_api_keys(service_id=service_id)['apiKeys']
|
||||
)
|
||||
|
||||
@@ -32,11 +31,10 @@ def create_api_key(service_id):
|
||||
form = CreateKeyForm(key_names)
|
||||
if form.validate_on_submit():
|
||||
secret = api_key_api_client.create_api_key(service_id=service_id, key_name=form.key_name.data)
|
||||
return render_template('views/api-keys/show.html', service_id=service_id, secret=secret,
|
||||
return render_template('views/api-keys/show.html', secret=secret,
|
||||
key_name=form.key_name.data)
|
||||
return render_template(
|
||||
'views/api-keys/create.html',
|
||||
service_id=service_id,
|
||||
key_name=form.key_name
|
||||
)
|
||||
|
||||
@@ -49,7 +47,6 @@ def revoke_api_key(service_id, key_id):
|
||||
if request.method == 'GET':
|
||||
return render_template(
|
||||
'views/api-keys/revoke.html',
|
||||
service_id=service_id,
|
||||
key_name=key_name
|
||||
)
|
||||
elif request.method == 'POST':
|
||||
|
||||
@@ -23,4 +23,7 @@ def show_all_services_or_dashboard():
|
||||
if 1 == len(services):
|
||||
return redirect(url_for('.service_dashboard', service_id=services[0]['id']))
|
||||
else:
|
||||
service_id = session.get('service_id', None)
|
||||
if any([service_id == x['id'] for x in services]):
|
||||
return redirect(url_for('.service_dashboard', service_id=service_id))
|
||||
return redirect(url_for('.choose_service'))
|
||||
|
||||
@@ -2,13 +2,14 @@ from flask import (
|
||||
render_template,
|
||||
session,
|
||||
flash,
|
||||
jsonify
|
||||
jsonify,
|
||||
request
|
||||
)
|
||||
from datetime import date
|
||||
|
||||
from flask_login import login_required
|
||||
from app.main import main
|
||||
from app import (job_api_client, statistics_api_client, service_api_client)
|
||||
from app import (job_api_client, statistics_api_client, service_api_client, current_service)
|
||||
from app.utils import user_has_permissions
|
||||
|
||||
|
||||
@@ -19,14 +20,10 @@ def service_dashboard(service_id):
|
||||
templates = service_api_client.get_service_templates(service_id)['data']
|
||||
jobs = job_api_client.get_job(service_id)['data']
|
||||
|
||||
service = service_api_client.get_service(service_id)
|
||||
session['service_name'] = service['data']['name']
|
||||
session['service_id'] = service['data']['id']
|
||||
|
||||
if session.get('invited_user'):
|
||||
session.pop('invited_user', None)
|
||||
service_name = service['data']['name']
|
||||
message = 'You have successfully accepted your invitation and been added to {}'.format(service_name)
|
||||
message = 'You have successfully accepted your invitation and been added to {}'.format(
|
||||
current_service['name'])
|
||||
flash(message, 'default_with_tick')
|
||||
|
||||
statistics = statistics_api_client.get_statistics_for_service(service_id)['data']
|
||||
@@ -37,7 +34,6 @@ def service_dashboard(service_id):
|
||||
more_jobs_to_show=(len(jobs) > 5),
|
||||
free_text_messages_remaining='250,000',
|
||||
spent_this_month='0.00',
|
||||
service=service['data'],
|
||||
statistics=add_rates_to(statistics),
|
||||
templates=templates,
|
||||
service_id=str(service_id))
|
||||
|
||||
@@ -12,7 +12,11 @@ from flask_login import login_required
|
||||
from werkzeug.datastructures import MultiDict
|
||||
from utils.template import Template
|
||||
|
||||
from app import (job_api_client, notification_api_client, service_api_client)
|
||||
from app import (
|
||||
job_api_client,
|
||||
notification_api_client,
|
||||
service_api_client,
|
||||
current_service)
|
||||
from app.main import main
|
||||
from app.utils import (
|
||||
get_page_from_request,
|
||||
@@ -38,8 +42,7 @@ def view_jobs(service_id):
|
||||
jobs = job_api_client.get_job(service_id)['data']
|
||||
return render_template(
|
||||
'views/jobs/jobs.html',
|
||||
jobs=jobs,
|
||||
service_id=service_id
|
||||
jobs=jobs
|
||||
)
|
||||
|
||||
|
||||
@@ -47,7 +50,6 @@ def view_jobs(service_id):
|
||||
@login_required
|
||||
@user_has_permissions('view_activity', admin_override=True)
|
||||
def view_job(service_id, job_id):
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
job = job_api_client.get_job(service_id, job_id)['data']
|
||||
template = service_api_client.get_service_template(service_id, job['template'])['data']
|
||||
notifications = notification_api_client.get_notifications_for_service(service_id, job_id)
|
||||
@@ -64,10 +66,8 @@ def view_job(service_id, job_id):
|
||||
uploaded_file_name=job['original_file_name'],
|
||||
template=Template(
|
||||
template,
|
||||
prefix=service['name']
|
||||
prefix=current_service['name']
|
||||
),
|
||||
service_id=service_id,
|
||||
service=service,
|
||||
job_id=job_id
|
||||
)
|
||||
|
||||
@@ -76,7 +76,6 @@ def view_job(service_id, job_id):
|
||||
@login_required
|
||||
@user_has_permissions('view_activity')
|
||||
def view_job_updates(service_id, job_id):
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
job = job_api_client.get_job(service_id, job_id)['data']
|
||||
notifications = notification_api_client.get_notifications_for_service(service_id, job_id)
|
||||
finished = job['status'] == 'finished'
|
||||
@@ -135,7 +134,6 @@ def view_notifications(service_id):
|
||||
'page {}'.format(page + 1))
|
||||
return render_template(
|
||||
'views/notifications.html',
|
||||
service_id=service_id,
|
||||
notifications=notifications['notifications'],
|
||||
page=page,
|
||||
prev_page=prev_page,
|
||||
@@ -157,6 +155,5 @@ def view_notification(service_id, job_id, notification_id):
|
||||
][0],
|
||||
delivered_at=now,
|
||||
uploaded_at=now,
|
||||
service_id=service_id,
|
||||
job_id=job_id
|
||||
)
|
||||
|
||||
@@ -37,7 +37,6 @@ roles = {
|
||||
def manage_users(service_id):
|
||||
return render_template(
|
||||
'views/manage-users.html',
|
||||
service_id=service_id,
|
||||
users=user_api_client.get_users_for_service(service_id=service_id),
|
||||
current_user=current_user,
|
||||
invited_users=[
|
||||
@@ -51,7 +50,6 @@ def manage_users(service_id):
|
||||
@login_required
|
||||
@user_has_permissions('manage_users', admin_override=True)
|
||||
def invite_user(service_id):
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
|
||||
form = InviteUserForm(invalid_email_address=current_user.email_address)
|
||||
|
||||
@@ -75,7 +73,6 @@ def invite_user(service_id):
|
||||
|
||||
return render_template(
|
||||
'views/invite-user.html',
|
||||
service_id=service_id,
|
||||
form=form
|
||||
)
|
||||
|
||||
@@ -87,7 +84,6 @@ def edit_user_permissions(service_id, user_id):
|
||||
# TODO we should probably using the service id here in the get user
|
||||
# call as well. eg. /user/<user_id>?&service=service_id
|
||||
user = user_api_client.get_user(user_id)
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
# Need to make the email address read only, or a disabled field?
|
||||
# Do it through the template or the form class?
|
||||
form = PermissionsForm(**{
|
||||
@@ -106,8 +102,7 @@ def edit_user_permissions(service_id, user_id):
|
||||
return render_template(
|
||||
'views/edit-user-permissions.html',
|
||||
user=user,
|
||||
form=form,
|
||||
service_id=service_id
|
||||
form=form
|
||||
)
|
||||
|
||||
|
||||
@@ -116,7 +111,6 @@ def edit_user_permissions(service_id, user_id):
|
||||
@user_has_permissions('manage_users', admin_override=True)
|
||||
def remove_user_from_service(service_id, user_id):
|
||||
user = user_api_client.get_user(user_id)
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
# Need to make the email address read only, or a disabled field?
|
||||
# Do it through the template or the form class?
|
||||
form = PermissionsForm(**{
|
||||
@@ -145,8 +139,7 @@ def remove_user_from_service(service_id, user_id):
|
||||
return render_template(
|
||||
'views/edit-user-permissions.html',
|
||||
user=user,
|
||||
form=form,
|
||||
service_id=service_id
|
||||
form=form
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ from app.main.uploader import (
|
||||
s3upload,
|
||||
s3download
|
||||
)
|
||||
from app import (job_api_client, service_api_client)
|
||||
from app.utils import user_has_permissions, get_errors_for_csv
|
||||
from app import (job_api_client, service_api_client, current_service)
|
||||
from app.utils import (user_has_permissions, get_errors_for_csv)
|
||||
|
||||
|
||||
def get_send_button_text(template_type, number_of_messages):
|
||||
@@ -72,9 +72,6 @@ def get_example_csv_rows(template, number_of_rows=2):
|
||||
'manage_api_keys',
|
||||
admin_override=True, any_=True)
|
||||
def choose_template(service_id, template_type):
|
||||
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
|
||||
if template_type not in ['email', 'sms']:
|
||||
abort(404)
|
||||
|
||||
@@ -83,14 +80,12 @@ def choose_template(service_id, template_type):
|
||||
templates=[
|
||||
Template(
|
||||
template,
|
||||
prefix=service['name']
|
||||
prefix=current_service['name']
|
||||
) for template in service_api_client.get_service_templates(service_id)['data']
|
||||
if template['template_type'] == template_type
|
||||
],
|
||||
template_type=template_type,
|
||||
page_heading=get_page_headings(template_type),
|
||||
service=service,
|
||||
service_id=service_id
|
||||
page_heading=get_page_headings(template_type)
|
||||
)
|
||||
|
||||
|
||||
@@ -98,11 +93,9 @@ def choose_template(service_id, template_type):
|
||||
@login_required
|
||||
@user_has_permissions('send_texts', 'send_emails', 'send_letters')
|
||||
def send_messages(service_id, template_id):
|
||||
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
template = Template(
|
||||
service_api_client.get_service_template(service_id, template_id)['data'],
|
||||
prefix=service['name']
|
||||
prefix=current_service['name']
|
||||
)
|
||||
|
||||
form = CsvUploadForm()
|
||||
@@ -136,9 +129,7 @@ def send_messages(service_id, template_id):
|
||||
template=template,
|
||||
recipient_column=first_column_heading[template.template_type],
|
||||
example=get_example_csv_rows(template),
|
||||
form=form,
|
||||
service=service,
|
||||
service_id=service_id
|
||||
form=form
|
||||
)
|
||||
|
||||
|
||||
@@ -179,8 +170,8 @@ def send_message_to_self(service_id, template_id):
|
||||
session['upload_data'] = {"template_id": template_id, "original_file_name": filedata['file_name']}
|
||||
|
||||
return redirect(url_for('.check_messages',
|
||||
service_id=service_id,
|
||||
upload_id=upload_id,
|
||||
service_id=service_id,
|
||||
template_type=template.template_type))
|
||||
|
||||
|
||||
@@ -201,8 +192,7 @@ def send_from_api(service_id, template_id):
|
||||
return render_template(
|
||||
'views/send-from-api.html',
|
||||
template=template,
|
||||
payload=json.dumps(payload, indent=4),
|
||||
service_id=service_id
|
||||
payload=json.dumps(payload, indent=4)
|
||||
)
|
||||
|
||||
|
||||
@@ -214,8 +204,6 @@ def check_messages(service_id, template_type, upload_id):
|
||||
if not session.get('upload_data'):
|
||||
return redirect(url_for('main.choose_template', service_id=service_id, template_type=template_type))
|
||||
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
|
||||
contents = s3download(service_id, upload_id)
|
||||
if not contents:
|
||||
flash('There was a problem reading your upload file')
|
||||
@@ -227,7 +215,7 @@ def check_messages(service_id, template_type, upload_id):
|
||||
|
||||
template = Template(
|
||||
template,
|
||||
prefix=service['name']
|
||||
prefix=current_service['name']
|
||||
)
|
||||
|
||||
recipients = RecipientCSV(
|
||||
@@ -259,8 +247,6 @@ def check_messages(service_id, template_type, upload_id):
|
||||
),
|
||||
original_file_name=session['upload_data'].get('original_file_name'),
|
||||
send_button_text=get_send_button_text(template.template_type, session['upload_data']['notification_count']),
|
||||
service_id=service_id,
|
||||
service=service,
|
||||
upload_id=upload_id,
|
||||
form=CsvUploadForm()
|
||||
)
|
||||
@@ -272,7 +258,6 @@ def check_messages(service_id, template_type, upload_id):
|
||||
def start_job(service_id, upload_id):
|
||||
|
||||
upload_data = session['upload_data']
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
|
||||
if request.files or not upload_data.get('valid'):
|
||||
# The csv was invalid, validate the csv again
|
||||
@@ -289,5 +274,5 @@ def start_job(service_id, upload_id):
|
||||
)
|
||||
|
||||
return redirect(
|
||||
url_for('main.view_job', service_id=service_id, job_id=upload_id)
|
||||
url_for('main.view_job', job_id=upload_id, service_id=service_id)
|
||||
)
|
||||
|
||||
@@ -18,27 +18,20 @@ from app.main import main
|
||||
from app.utils import user_has_permissions, email_safe
|
||||
from app.main.forms import ConfirmPasswordForm, ServiceNameForm
|
||||
from app import user_api_client
|
||||
from app import current_service
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/service-settings")
|
||||
@login_required
|
||||
@user_has_permissions('manage_settings', admin_override=True)
|
||||
def service_settings(service_id):
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
|
||||
return render_template(
|
||||
'views/service-settings.html',
|
||||
service=service,
|
||||
service_id=service_id
|
||||
)
|
||||
return render_template('views/service-settings.html')
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/service-settings/name", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@user_has_permissions('manage_settings', admin_override=True)
|
||||
def service_name_change(service_id):
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
|
||||
form = ServiceNameForm(service_api_client.find_all_service_email_from)
|
||||
|
||||
if form.validate_on_submit():
|
||||
@@ -47,16 +40,13 @@ def service_name_change(service_id):
|
||||
|
||||
return render_template(
|
||||
'views/service-settings/name.html',
|
||||
service=service,
|
||||
form=form,
|
||||
service_id=service_id)
|
||||
form=form)
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/service-settings/name/confirm", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@user_has_permissions('manage_settings', admin_override=True)
|
||||
def service_name_change_confirm(service_id):
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
|
||||
# Validate password for form
|
||||
def _check_password(pwd):
|
||||
@@ -64,17 +54,17 @@ def service_name_change_confirm(service_id):
|
||||
form = ConfirmPasswordForm(_check_password)
|
||||
|
||||
if form.validate_on_submit():
|
||||
service['name'] = session['service_name_change']
|
||||
service['email_from'] = email_safe(session['service_name_change'])
|
||||
current_service['name'] = session['service_name_change']
|
||||
current_service['email_from'] = email_safe(session['service_name_change'])
|
||||
try:
|
||||
service_api_client.update_service(
|
||||
service['id'],
|
||||
service['name'],
|
||||
service['active'],
|
||||
service['limit'],
|
||||
service['restricted'],
|
||||
service['users'],
|
||||
service['email_from'])
|
||||
current_service['id'],
|
||||
current_service['name'],
|
||||
current_service['active'],
|
||||
current_service['limit'],
|
||||
current_service['restricted'],
|
||||
current_service['users'],
|
||||
current_service['email_from'])
|
||||
except HTTPError as e:
|
||||
error_msg = "Duplicate service name '{}'".format(session['service_name_change'])
|
||||
if e.status_code == 400 and error_msg in e.message['name']:
|
||||
@@ -84,26 +74,21 @@ def service_name_change_confirm(service_id):
|
||||
else:
|
||||
raise e
|
||||
else:
|
||||
session['service_name'] = service['name']
|
||||
session.pop('service_name_change')
|
||||
return redirect(url_for('.service_settings', service_id=service_id))
|
||||
return render_template(
|
||||
'views/service-settings/confirm.html',
|
||||
heading='Change your service name',
|
||||
form=form,
|
||||
service_id=service_id)
|
||||
form=form)
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/service-settings/request-to-go-live", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@user_has_permissions('manage_settings', admin_override=True)
|
||||
def service_request_to_go_live(service_id):
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
if request.method == 'GET':
|
||||
return render_template(
|
||||
'views/service-settings/request-to-go-live.html',
|
||||
service=service,
|
||||
service_id=service_id
|
||||
'views/service-settings/request-to-go-live.html'
|
||||
)
|
||||
elif request.method == 'POST':
|
||||
flash('Thanks your request to go live is being processed', 'default')
|
||||
@@ -115,13 +100,9 @@ def service_request_to_go_live(service_id):
|
||||
@login_required
|
||||
@user_has_permissions('manage_settings', admin_override=True)
|
||||
def service_status_change(service_id):
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
|
||||
if request.method == 'GET':
|
||||
return render_template(
|
||||
'views/service-settings/status.html',
|
||||
service=service,
|
||||
service_id=service_id
|
||||
'views/service-settings/status.html'
|
||||
)
|
||||
elif request.method == 'POST':
|
||||
return redirect(url_for('.service_status_change_confirm', service_id=service_id))
|
||||
@@ -131,43 +112,37 @@ def service_status_change(service_id):
|
||||
@login_required
|
||||
@user_has_permissions('manage_settings', admin_override=True)
|
||||
def service_status_change_confirm(service_id):
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
|
||||
# Validate password for form
|
||||
def _check_password(pwd):
|
||||
return user_api_client.verify_password(current_user.id, pwd)
|
||||
form = ConfirmPasswordForm(_check_password)
|
||||
|
||||
if form.validate_on_submit():
|
||||
service['active'] = True
|
||||
current_service['active'] = True
|
||||
service_api_client.update_service(
|
||||
service['id'],
|
||||
service['name'],
|
||||
service['active'],
|
||||
service['limit'],
|
||||
service['restricted'],
|
||||
service['users'],
|
||||
service['email_from'])
|
||||
current_service['id'],
|
||||
current_service['name'],
|
||||
current_service['active'],
|
||||
current_service['limit'],
|
||||
current_service['restricted'],
|
||||
current_service['users'],
|
||||
current_service['email_from'])
|
||||
return redirect(url_for('.service_settings', service_id=service_id))
|
||||
return render_template(
|
||||
'views/service-settings/confirm.html',
|
||||
heading='Turn off all outgoing notifications',
|
||||
destructive=True,
|
||||
form=form,
|
||||
service_id=service_id)
|
||||
form=form)
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/service-settings/delete", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@user_has_permissions('manage_settings', admin_override=True)
|
||||
def service_delete(service_id):
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
|
||||
if request.method == 'GET':
|
||||
return render_template(
|
||||
'views/service-settings/delete.html',
|
||||
service=service,
|
||||
service_id=service_id
|
||||
'views/service-settings/delete.html'
|
||||
)
|
||||
elif request.method == 'POST':
|
||||
return redirect(url_for('.service_delete_confirm', service_id=service_id))
|
||||
@@ -177,7 +152,6 @@ def service_delete(service_id):
|
||||
@login_required
|
||||
@user_has_permissions('manage_settings', admin_override=True)
|
||||
def service_delete_confirm(service_id):
|
||||
service = service_api_client.get_service(service_id)['data']
|
||||
|
||||
# Validate password for form
|
||||
def _check_password(pwd):
|
||||
@@ -185,12 +159,11 @@ def service_delete_confirm(service_id):
|
||||
form = ConfirmPasswordForm(_check_password)
|
||||
|
||||
if form.validate_on_submit():
|
||||
service = service_api_client.delete_service(service_id)
|
||||
service_api_client.delete_service(service_id)
|
||||
return redirect(url_for('.choose_service'))
|
||||
|
||||
return render_template(
|
||||
'views/service-settings/confirm.html',
|
||||
heading='Delete this service from Notify',
|
||||
destructive=True,
|
||||
form=form,
|
||||
service_id=service_id)
|
||||
form=form)
|
||||
|
||||
@@ -23,8 +23,6 @@ page_headings = {
|
||||
@user_has_permissions('manage_templates', admin_override=True)
|
||||
def add_service_template(service_id, template_type):
|
||||
|
||||
service = service_api_client.get_service(service_id)
|
||||
|
||||
if template_type not in ['sms', 'email']:
|
||||
abort(404)
|
||||
|
||||
@@ -46,7 +44,6 @@ def add_service_template(service_id, template_type):
|
||||
'views/edit-{}-template.html'.format(template_type),
|
||||
form=form,
|
||||
template_type=template_type,
|
||||
service_id=service_id,
|
||||
heading_action='Add'
|
||||
)
|
||||
|
||||
@@ -73,7 +70,6 @@ def edit_service_template(service_id, template_id):
|
||||
return render_template(
|
||||
'views/edit-{}-template.html'.format(template['template_type']),
|
||||
form=form,
|
||||
service_id=service_id,
|
||||
template_id=template_id,
|
||||
template_type=template['template_type'],
|
||||
heading_action='Edit'
|
||||
@@ -101,5 +97,4 @@ def delete_service_template(service_id, template_id):
|
||||
'views/edit-{}-template.html'.format(template['template_type']),
|
||||
h1='Edit template',
|
||||
form=form,
|
||||
service_id=service_id,
|
||||
template_id=template_id)
|
||||
|
||||
@@ -9,7 +9,6 @@ from app.main import main
|
||||
def tour(service_id, page):
|
||||
return render_template(
|
||||
'views/tour/{}.html'.format(page),
|
||||
service_id=service_id, # TODO: fix when Nick’s PR is merged
|
||||
current_page=page,
|
||||
next_page=(page + 1)
|
||||
)
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
<nav class="navigation">
|
||||
<h2 class="navigation-service-name">
|
||||
<a href="{{ url_for('.service_dashboard', service_id=service_id) }}">{{ session.get('service_name', 'Service') }}</a>
|
||||
<a href="{{ url_for('.service_dashboard', service_id=current_service.id) }}">{{ current_service.name }}</a>
|
||||
</h2>
|
||||
{% if current_user.has_permissions(['view_activity'], admin_override=True) %}
|
||||
<ul>
|
||||
<li><a href="{{ url_for('.view_notifications', service_id=service_id, page=1) }}">History</a></li>
|
||||
<li><a href="{{ url_for('.view_notifications', service_id=current_service.id, page=1) }}">History</a></li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if current_user.has_permissions(['view_activity', 'manage_templates', 'manage_api_keys'], admin_override=True, any_=True) %}
|
||||
<ul>
|
||||
<li><a href="{{ url_for('.choose_template', service_id=service_id, template_type='sms') }}">Text message templates</a></li>
|
||||
<li><a href="{{ url_for('.choose_template', service_id=service_id, template_type='email') }}">Email templates</a></li>
|
||||
<li><a href="{{ url_for('.choose_template', service_id=current_service.id, template_type='sms') }}">Text message templates</a></li>
|
||||
<li><a href="{{ url_for('.choose_template', service_id=current_service.id, template_type='email') }}">Email templates</a></li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if current_user.has_permissions(['manage_users', 'manage_settings'], admin_override=True) %}
|
||||
<ul>
|
||||
<li><a href="{{ url_for('.manage_users', service_id=service_id) }}">Team members</a></li>
|
||||
<li><a href="{{ url_for('.service_settings', service_id=service_id) }}">Settings</a></li>
|
||||
<li><a href="{{ url_for('.manage_users', service_id=current_service.id) }}">Team members</a></li>
|
||||
<li><a href="{{ url_for('.service_settings', service_id=current_service.id) }}">Settings</a></li>
|
||||
</ul>
|
||||
{% elif current_user.has_permissions(['view_activity']) %}
|
||||
<ul>
|
||||
<li><a href="{{ url_for('.manage_users', service_id=service_id) }}">Team members</a></li>
|
||||
<li><a href="{{ url_for('.manage_users', service_id=current_service.id) }}">Team members</a></li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if current_user.has_permissions(['manage_api_keys']) %}
|
||||
<ul>
|
||||
<li><a href="{{ url_for('.api_keys', service_id=service_id) }}">API keys</a></li>
|
||||
<li><a href="{{ url_for('.api_keys', service_id=current_service.id) }}">API keys</a></li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if current_user.has_permissions(admin_override=True) %}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
<p>
|
||||
API usage is described in
|
||||
<a href="{{ url_for('.documentation', service_id=service_id) }}">the
|
||||
<a href="{{ url_for('.documentation', service_id=current_service.id) }}">the
|
||||
developer documentation</a>.
|
||||
</p>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
Service ID
|
||||
</h2>
|
||||
<p class="api-key-key">
|
||||
{{ service_id }}
|
||||
{{ current_service.id }}
|
||||
</p>
|
||||
|
||||
{% call(item) list_table(
|
||||
@@ -45,13 +45,13 @@
|
||||
{% endcall %}
|
||||
{% else %}
|
||||
{% call field(align='right', status='error') %}
|
||||
<a href='{{ url_for('.revoke_api_key', service_id=service_id, key_id=item.id) }}'>Revoke</a>
|
||||
<a href='{{ url_for('.revoke_api_key', service_id=current_service.id, key_id=item.id) }}'>Revoke</a>
|
||||
{% endcall %}
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
|
||||
<p class='table-show-more-link'>
|
||||
<a href="{{ url_for('.create_api_key', service_id=service_id) }}">Create a new API key</a>
|
||||
<a href="{{ url_for('.create_api_key', service_id=current_service.id) }}">Create a new API key</a>
|
||||
</p>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -48,8 +48,8 @@
|
||||
{{ email_message(
|
||||
template.subject,
|
||||
template.formatted_as_markup if errors else template.replaced,
|
||||
from_address='{}@notifications.service.gov.uk'.format(service.email_from),
|
||||
from_name=service.name
|
||||
from_address='{}@notifications.service.gov.uk'.format(current_service.email_from),
|
||||
from_name=current_service.name
|
||||
)}}
|
||||
{% elif 'sms' == template.template_type %}
|
||||
<div class="grid-row">
|
||||
@@ -64,10 +64,10 @@
|
||||
{% if errors %}
|
||||
{{file_upload(form.file, button_text='Re-upload your file')}}
|
||||
{% else %}
|
||||
<form method="post" enctype="multipart/form-data" action="{{url_for('main.start_job', service_id=service_id, upload_id=upload_id)}}">
|
||||
<form method="post" enctype="multipart/form-data" action="{{url_for('main.start_job', service_id=current_service.id, upload_id=upload_id)}}">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<input type="submit" class="button" value="{{ send_button_text }}" />
|
||||
<a href="{{url_for('.send_messages', service_id=service_id, template_id=template.id)}}" class="page-footer-back-link">Back</a>
|
||||
<a href="{{url_for('.send_messages', service_id=current_service.id, template_id=template.id)}}" class="page-footer-back-link">Back</a>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
You need a template before you can send
|
||||
{{ 'emails' if 'email' == template_type else 'text messages' }}
|
||||
</p>
|
||||
<a href="{{ url_for('.add_service_template', service_id=service_id, template_type=template_type) }}" class="button">Add a new template</a>
|
||||
<a href="{{ url_for('.add_service_template', service_id=current_service.id, template_type=template_type) }}" class="button">Add a new template</a>
|
||||
{% else %}
|
||||
<p>You need to ask your service manager to add templates before you can send messages</p>
|
||||
{% endif %}
|
||||
@@ -32,7 +32,7 @@
|
||||
</div>
|
||||
{% if current_user.has_permissions(permissions=['manage_templates'], admin_override=True) %}
|
||||
<div class="column-one-third">
|
||||
<a href="{{ url_for('.add_service_template', service_id=service_id, template_type=template_type) }}" class="button align-with-heading">Add new template</a>
|
||||
<a href="{{ url_for('.add_service_template', service_id=current_service.id, template_type=template_type) }}" class="button align-with-heading">Add new template</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -46,7 +46,7 @@
|
||||
template.formatted_as_markup,
|
||||
name=template.name,
|
||||
edit_link=(
|
||||
url_for(".edit_service_template", service_id=service_id, template_id=template.id)
|
||||
url_for(".edit_service_template", service_id=current_service.id, template_id=template.id)
|
||||
if current_user.has_permissions(permissions=['manage_templates'], admin_override=True) else
|
||||
None
|
||||
)
|
||||
@@ -56,7 +56,7 @@
|
||||
template.formatted_as_markup,
|
||||
name=template.name,
|
||||
edit_link=(
|
||||
url_for(".edit_service_template", service_id=service_id, template_id=template.id)
|
||||
url_for(".edit_service_template", service_id=current_service.id, template_id=template.id)
|
||||
if current_user.has_permissions(permissions=['manage_templates'], admin_override=True) else
|
||||
None
|
||||
)
|
||||
@@ -66,11 +66,11 @@
|
||||
<div class="column-one-third">
|
||||
<div class="sms-message-use-links">
|
||||
{% if current_user.has_permissions(permissions=['send_texts', 'send_emails', 'send_letters']) %}
|
||||
<a href="{{ url_for(".send_messages", service_id=service_id, template_id=template.id) }}">Send from a CSV file</a>
|
||||
<a href="{{ url_for(".send_message_to_self", service_id=service_id, template_id=template.id) }}">Send yourself a test</a>
|
||||
<a href="{{ url_for(".send_messages", service_id=current_service.id, template_id=template.id) }}">Send from a CSV file</a>
|
||||
<a href="{{ url_for(".send_message_to_self", service_id=current_service.id, template_id=template.id) }}">Send yourself a test</a>
|
||||
{% endif %}
|
||||
{% if current_user.has_permissions(permissions=['manage_api_keys']) %}
|
||||
<a href="{{ url_for(".send_from_api", service_id=service_id, template_id=template.id) }}">API integration</a>
|
||||
<a href="{{ url_for(".send_from_api", service_id=current_service.id, template_id=template.id) }}">API integration</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
{% extends "withnav_template.html" %}
|
||||
|
||||
{% block page_title %}
|
||||
{{ session.get('service_name', 'Dashboard') }} – GOV.UK Notify
|
||||
{{ current_service.name }} – GOV.UK Notify
|
||||
{% endblock %}
|
||||
|
||||
{% block maincolumn_content %}
|
||||
|
||||
{% if not templates and current_user.has_permissions(['send_texts', 'send_emails', 'send_letters'], any_=True) %}
|
||||
{% include 'views/dashboard/get-started.html' %}
|
||||
{% elif service.restricted %}
|
||||
{% elif current_service.restricted %}
|
||||
<div class="dashboard">
|
||||
{% include 'views/dashboard/trial-mode-banner.html' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<div
|
||||
data-module="update-content"
|
||||
data-resource="{{url_for(".service_dashboard_updates", service_id=service_id)}}"
|
||||
data-resource="{{url_for(".service_dashboard_updates", service_id=current_service.id)}}"
|
||||
data-key="today"
|
||||
data-interval-seconds="10"
|
||||
>
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
{% call banner_wrapper(type='tour') %}
|
||||
<h2 class="heading-large">You’re ready to get started</h2>
|
||||
<p>
|
||||
<a href='{{ url_for(".add_service_template", service_id=service_id, template_type="sms") }}'>
|
||||
<a href='{{ url_for(".add_service_template", service_id=current_service.id, template_type="sms") }}'>
|
||||
Set up a text message template
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href='{{ url_for(".add_service_template", service_id=service_id, template_type="email") }}'>
|
||||
<a href='{{ url_for(".add_service_template", service_id=current_service.id, template_type="email") }}'>
|
||||
Set up an email template
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
field_headings=['File', 'Started', right_aligned_field_heading('Rows')]
|
||||
) %}
|
||||
{% call field() %}
|
||||
<a href="{{ url_for('.view_job', service_id=service_id, job_id=item.id) }}">{{ item.original_file_name }}</a>
|
||||
<a href="{{ url_for('.view_job', service_id=current_service.id, job_id=item.id) }}">{{ item.original_file_name }}</a>
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
{{ item.created_at|format_datetime }}
|
||||
@@ -19,7 +19,7 @@
|
||||
{% if more_jobs_to_show %}
|
||||
{% if current_user.has_permissions(['send_texts', 'send_emails', 'send_letters']) %}
|
||||
<p class="table-show-more-link">
|
||||
<a href="{{ url_for('.view_jobs', service_id=service_id) }}">See all sent batch messages</a>
|
||||
<a href="{{ url_for('.view_jobs', service_id=current_service.id) }}">See all sent batch messages</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
@@ -36,5 +36,4 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -23,7 +23,7 @@ Manage users – GOV.UK Notify
|
||||
|
||||
{{ page_footer(
|
||||
'Save',
|
||||
delete_link=url_for('.remove_user_from_service', service_id=service_id, user_id=user.id) if user or None,
|
||||
delete_link=url_for('.remove_user_from_service', service_id=current_service.id, user_id=user.id) if user or None,
|
||||
delete_link_text='Remove user from service'
|
||||
) }}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
{% if not finished_at %}
|
||||
<div
|
||||
data-module="update-content"
|
||||
data-resource="{{url_for(".view_job_updates", service_id=service_id, job_id=job_id)}}"
|
||||
data-resource="{{url_for(".view_job_updates", service_id=current_service.id, job_id=job_id)}}"
|
||||
data-key="status"
|
||||
>
|
||||
{% endif %}
|
||||
@@ -45,7 +45,7 @@
|
||||
{% if not finished_at %}
|
||||
<div
|
||||
data-module="update-content"
|
||||
data-resource="{{url_for(".view_job_updates", service_id=service_id, job_id=job_id)}}"
|
||||
data-resource="{{url_for(".view_job_updates", service_id=current_service.id, job_id=job_id)}}"
|
||||
data-key="counts"
|
||||
>
|
||||
{% endif %}
|
||||
@@ -57,7 +57,7 @@
|
||||
{% if not finished_at %}
|
||||
<div
|
||||
data-module="update-content"
|
||||
data-resource="{{url_for(".view_job_updates", service_id=service_id, job_id=job_id)}}"
|
||||
data-resource="{{url_for(".view_job_updates", service_id=current_service.id, job_id=job_id)}}"
|
||||
data-key="notifications"
|
||||
>
|
||||
{% endif %}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
field_headings=['Job', 'Time', right_aligned_field_heading('Status')]
|
||||
) %}
|
||||
{% call field() %}
|
||||
<a href="{{ url_for('.view_job', service_id=service_id, job_id=item.id) }}">{{ item.original_file_name }}</a>
|
||||
<a href="{{ url_for('.view_job', service_id=current_service.id, job_id=item.id) }}">{{ item.original_file_name }}</a>
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
{{ item.created_at | format_datetime}}
|
||||
|
||||
@@ -24,7 +24,7 @@ Manage users – GOV.UK Notify
|
||||
</div>
|
||||
{% if current_user.has_permissions(['manage_users']) %}
|
||||
<div class="column-one-third">
|
||||
<a href="{{ url_for('.invite_user', service_id=service_id) }}" class="button align-with-heading">Invite team member</a>
|
||||
<a href="{{ url_for('.invite_user', service_id=current_service.id) }}" class="button align-with-heading">Invite team member</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -41,7 +41,7 @@ Manage users – GOV.UK Notify
|
||||
{% call field(align='right') %}
|
||||
{% if current_user.has_permissions(['manage_users']) %}
|
||||
{% if current_user.id != item.id %}
|
||||
<a href="{{ url_for('.edit_user_permissions', service_id=service_id, user_id=item.id)}}">Edit</a>
|
||||
<a href="{{ url_for('.edit_user_permissions', service_id=current_service.id, user_id=item.id)}}">Edit</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
@@ -60,7 +60,7 @@ Manage users – GOV.UK Notify
|
||||
{% if item.status == 'pending' %}
|
||||
{% call field(align='right') %}
|
||||
{% if current_user.has_permissions(['manage_users']) %}
|
||||
<a href="{{ url_for('.cancel_invited_user', service_id=service_id, invited_user_id=item.id)}}">Cancel invitation</a>
|
||||
<a href="{{ url_for('.cancel_invited_user', service_id=current_service.id, invited_user_id=item.id)}}">Cancel invitation</a>
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
{% else %}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
</div>
|
||||
|
||||
{{ page_footer(
|
||||
secondary_link = url_for('.view_job', service_id=service_id, job_id=job_id),
|
||||
secondary_link = url_for('.view_job', service_id=current_service.id, job_id=job_id),
|
||||
secondary_link_text = 'View other messages in this job'
|
||||
) }}
|
||||
|
||||
|
||||
@@ -31,14 +31,14 @@
|
||||
{{ item.to }}
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
<a href="{{ url_for(".choose_template", service_id=service_id, template_type=item.template.template_type, _anchor=item.template.name|linkable_name) }}">{{ item.template.name }}</a>
|
||||
<a href="{{ url_for(".choose_template", service_id=current_service.id, template_type=item.template.template_type, _anchor=item.template.name|linkable_name) }}">{{ item.template.name }}</a>
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
{{ item.template.template_type }}
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
{% if item.job %}
|
||||
<a href="{{ url_for(".view_job", service_id=service_id, job_id=item.job.id) }}">{{ item.job.original_file_name }}</a>
|
||||
<a href="{{ url_for(".view_job", service_id=current_service.id, job_id=item.job.id) }}">{{ item.job.original_file_name }}</a>
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
{{ email_message(
|
||||
template.subject,
|
||||
template.formatted_as_markup,
|
||||
from_address='{}@notifications.service.gov.uk'.format(service.email_from),
|
||||
from_name=service.name
|
||||
from_address='{}@notifications.service.gov.uk'.format(current_service.email_from),
|
||||
from_name=current_service.name
|
||||
) }}
|
||||
{% endif %}
|
||||
|
||||
@@ -51,10 +51,9 @@
|
||||
{% endcall %}
|
||||
|
||||
<p class="bottom-gutter">
|
||||
<a href="{{ url_for('.get_example_csv', service_id=service_id, template_id=template.id) }}">Download this example</a>
|
||||
<a href="{{ url_for('.get_example_csv', service_id=current_service.id, template_id=template.id) }}">Download this example</a>
|
||||
</p>
|
||||
|
||||
|
||||
{{file_upload(form.file, button_text='Upload your CSV file')}}
|
||||
|
||||
{% endblock %}
|
||||
@@ -12,21 +12,21 @@
|
||||
{{ browse_list([
|
||||
{
|
||||
'title': 'Change your service name',
|
||||
'link': url_for('.service_name_change', service_id=service_id)
|
||||
'link': url_for('.service_name_change', service_id=current_service.id)
|
||||
},
|
||||
{
|
||||
'title': 'Request to go live and turn off sending restrictions',
|
||||
'link': url_for('.service_request_to_go_live', service_id=service_id),
|
||||
'link': url_for('.service_request_to_go_live', service_id=current_service.id),
|
||||
'hint': 'A live service can send notifications to any phone number or email address',
|
||||
} if not service.live else {
|
||||
} if not current_service.live else {
|
||||
},
|
||||
{
|
||||
'title': 'Temporarily suspend API keys',
|
||||
'link': url_for('.service_status_change', service_id=service_id),
|
||||
'link': url_for('.service_status_change', service_id=current_service.id),
|
||||
'destructive': True
|
||||
} if not service.active else {
|
||||
} if not current_service.active else {
|
||||
'title': 'Reactivate API keys',
|
||||
'link': url_for('.service_status_change', service_id=service_id)
|
||||
'link': url_for('.service_status_change', service_id=current_service.id)
|
||||
}
|
||||
]) }}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
{{ page_footer(
|
||||
'Confirm',
|
||||
destructive=destructive,
|
||||
back_link=url_for('.service_settings', service_id=service_id)
|
||||
back_link=url_for('.service_settings', service_id=current_service.id)
|
||||
) }}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
|
||||
<form method="post">
|
||||
{{ page_footer(
|
||||
'Yes, delete ‘{}’'.format(service.name),
|
||||
'Yes, delete ‘{}’'.format(current_service.name),
|
||||
destructive=True,
|
||||
back_link=url_for('.service_settings', service_id=service_id)
|
||||
back_link=url_for('.service_settings', service_id=current_service.id)
|
||||
) }}
|
||||
</form>
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
{{ textbox(form.name) }}
|
||||
{{ page_footer(
|
||||
'Save',
|
||||
back_link=url_for('.service_settings', service_id=service_id),
|
||||
back_link=url_for('.service_settings', service_id=current_service.id),
|
||||
back_link_text='Back to settings'
|
||||
) }}
|
||||
</form>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
{{ page_footer(
|
||||
'Suspend API keys',
|
||||
destructive=True,
|
||||
back_link=url_for('.service_settings', service_id=service_id),
|
||||
back_link=url_for('.service_settings', service_id=current_service.id),
|
||||
back_link_text='Back to settings'
|
||||
) }}
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user