From 771f9166305c42788c3a4863dca3d24ce2059940 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Tue, 8 May 2018 14:06:26 +0100 Subject: [PATCH] Add URLs to download the agreement without login MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So that we can share these URLs in an email we’re sending out. --- app/main/views/agreement.py | 23 ++++++++++++++++++- app/navigation.py | 6 +++++ app/templates/views/agreement-public.html | 27 +++++++++++++++++++++++ tests/app/main/views/test_agreement.py | 27 +++++++++++++++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 app/templates/views/agreement-public.html diff --git a/app/main/views/agreement.py b/app/main/views/agreement.py index ffa016f6e..cb58c236f 100644 --- a/app/main/views/agreement.py +++ b/app/main/views/agreement.py @@ -1,4 +1,4 @@ -from flask import render_template, send_file +from flask import abort, render_template, request, send_file, url_for from flask_login import login_required from app.main import main @@ -28,3 +28,24 @@ def download_agreement(): return send_file(**get_mou( AgreementInfo.from_current_user().crown_status_or_404 )) + + +@main.route('/agreement/', endpoint='public_agreement') +@main.route('/agreement/.pdf', endpoint='public_download_agreement') +def public_agreement(variant): + + if variant not in {'crown', 'non-crown'}: + abort(404) + + if request.endpoint == 'main.public_download_agreement': + return send_file(**get_mou( + organisation_is_crown=(variant == 'crown') + )) + + agreement_info = AgreementInfo.from_current_user() + + return render_template( + 'views/agreement-public.html', + owner=agreement_info.owner, + download_link=url_for('.public_download_agreement', variant=variant), + ) diff --git a/app/navigation.py b/app/navigation.py index b38eeb0ee..2ce4a7fda 100644 --- a/app/navigation.py +++ b/app/navigation.py @@ -169,6 +169,8 @@ class HeaderNavigation(Navigation): 'old_using_notify', 'organisation_dashboard', 'organisation_settings', + 'public_agreement', + 'public_download_agreement', 'received_text_messages_callback', 'redact_template', 'register', @@ -414,6 +416,8 @@ class MainNavigation(Navigation): 'organisations', 'platform_admin', 'pricing', + 'public_agreement', + 'public_download_agreement', 'redact_template', 'register', 'register_from_invite', @@ -578,6 +582,8 @@ class OrgNavigation(Navigation): 'organisations', 'platform_admin', 'pricing', + 'public_agreement', + 'public_download_agreement', 'received_text_messages_callback', 'redact_template', 'register', diff --git a/app/templates/views/agreement-public.html b/app/templates/views/agreement-public.html new file mode 100644 index 000000000..4f49c0b61 --- /dev/null +++ b/app/templates/views/agreement-public.html @@ -0,0 +1,27 @@ +{% extends "withoutnav_template.html" %} +{% from "components/sub-navigation.html" import sub_navigation %} + +{% block per_page_title %} + Download the GOV.UK Notify data sharing and financial agreement +{% endblock %} + +{% block maincolumn_content %} + +
+
+ +

+ Download the GOV.UK Notify data sharing and financial agreement +

+ +

+ Download the agreement{% if owner %} for {{ owner }}{% endif %}. +

+

+ The agreement contains commercially sensitive information, so don’t share it more widely than you need to. +

+ +
+
+ +{% endblock %} diff --git a/tests/app/main/views/test_agreement.py b/tests/app/main/views/test_agreement.py index d84b556aa..c29d394ca 100644 --- a/tests/app/main/views/test_agreement.py +++ b/tests/app/main/views/test_agreement.py @@ -102,3 +102,30 @@ def test_agreement_requires_login( assert response.status_code == 302 assert response.location == 'http://localhost/sign-in?next=%2Fagreement.pdf' assert mock_get_s3_object.call_args_list == [] + + +@pytest.mark.parametrize('endpoint', ( + 'main.public_agreement', + 'main.public_download_agreement', +)) +@pytest.mark.parametrize('variant, expected_status', ( + ('crown', 200), + ('non-crown', 200), + ('foo', 404), +)) +def test_show_public_agreement_page( + client, + mocker, + endpoint, + variant, + expected_status, +): + mocker.patch( + 'app.main.s3_client.get_s3_object', + return_value=_MockS3Object() + ) + response = client.get(url_for( + endpoint, + variant=variant, + )) + assert response.status_code == expected_status