Refactored code for new service permissions

This commit is contained in:
Ken Tsang
2017-06-23 13:35:08 +01:00
parent f8a3132d8b
commit bcc45ede9c
14 changed files with 74 additions and 66 deletions

View File

@@ -245,7 +245,7 @@ def send_test_step(service_id, template_id, step_index):
current_placeholder, current_placeholder,
dict_to_populate_from=get_normalised_send_test_values_from_session(), dict_to_populate_from=get_normalised_send_test_values_from_session(),
optional_placeholder=optional_placeholder, optional_placeholder=optional_placeholder,
allow_international_phone_numbers=current_service['can_send_international_sms'], allow_international_phone_numbers='international_sms' in current_service['permissions'],
) )
if form.validate_on_submit(): if form.validate_on_submit():
@@ -375,7 +375,7 @@ def _check_messages(service_id, template_type, upload_id, letters_as_pdf=False):
[user.name, user.mobile_number, user.email_address] for user in users [user.name, user.mobile_number, user.email_address] for user in users
) if current_service['restricted'] else None, ) if current_service['restricted'] else None,
remaining_messages=remaining_messages, remaining_messages=remaining_messages,
international_sms=current_service['can_send_international_sms'], international_sms='international_sms' in current_service['permissions'],
) )
if request.args.get('from_test'): if request.args.get('from_test'):

View File

@@ -208,14 +208,24 @@ def service_switch_research_mode(service_id):
return redirect(url_for('.service_settings', service_id=service_id)) return redirect(url_for('.service_settings', service_id=service_id))
def switch_service_permissions(service_id, permission):
permissions = current_service['permissions'].copy()
if permission in permissions:
permissions.remove(permission)
else:
permissions.append(permission)
service_api_client.update_service_with_properties(
service_id,
{'permissions': permissions}
)
@main.route("/services/<service_id>/service-settings/can-send-letters") @main.route("/services/<service_id>/service-settings/can-send-letters")
@login_required @login_required
@user_has_permissions(admin_override=True) @user_has_permissions(admin_override=True)
def service_switch_can_send_letters(service_id): def service_switch_can_send_letters(service_id):
service_api_client.update_service_with_properties( switch_service_permissions(service_id, 'letter')
service_id,
{"can_send_letters": not current_service['can_send_letters']}
)
return redirect(url_for('.service_settings', service_id=service_id)) return redirect(url_for('.service_settings', service_id=service_id))
@@ -223,10 +233,7 @@ def service_switch_can_send_letters(service_id):
@login_required @login_required
@user_has_permissions(admin_override=True) @user_has_permissions(admin_override=True)
def service_switch_can_send_international_sms(service_id): def service_switch_can_send_international_sms(service_id):
service_api_client.update_service_with_properties( switch_service_permissions(service_id, 'international_sms')
service_id,
{"can_send_international_sms": not current_service['can_send_international_sms']}
)
return redirect(url_for('.service_settings', service_id=service_id)) return redirect(url_for('.service_settings', service_id=service_id))
@@ -350,7 +357,7 @@ def service_set_letters(service_id):
@user_has_permissions('manage_settings', admin_override=True) @user_has_permissions('manage_settings', admin_override=True)
def service_set_letter_contact_block(service_id): def service_set_letter_contact_block(service_id):
if not current_service['can_send_letters']: if 'letter' not in current_service['permissions']:
abort(403) abort(403)
form = ServiceLetterContactBlock(letter_contact_block=current_service['letter_contact_block']) form = ServiceLetterContactBlock(letter_contact_block=current_service['letter_contact_block'])

View File

@@ -184,7 +184,7 @@ def view_template_version_preview(service_id, template_id, version, filetype):
def add_template_by_type(service_id): def add_template_by_type(service_id):
form = ChooseTemplateType( form = ChooseTemplateType(
include_letters=current_service['can_send_letters'] include_letters='letter' in current_service['permissions']
) )
if form.validate_on_submit(): if form.validate_on_submit():
@@ -220,7 +220,7 @@ def add_service_template(service_id, template_type):
if template_type not in ['sms', 'email', 'letter']: if template_type not in ['sms', 'email', 'letter']:
abort(404) abort(404)
if not current_service['can_send_letters'] and template_type == 'letter': if 'letter' not in current_service['permissions'] and template_type == 'letter':
abort(403) abort(403)
form = form_objects[template_type]() form = form_objects[template_type]()
@@ -448,5 +448,5 @@ def get_human_readable_delta(from_time, until_time):
def should_show_template(template_type): def should_show_template(template_type):
return ( return (
template_type != 'letter' or template_type != 'letter' or
current_service['can_send_letters'] 'letter' in current_service['permissions']
) )

View File

@@ -88,8 +88,6 @@ class ServiceAPIClient(NotifyAdminAPIClient):
'email_from', 'email_from',
'reply_to_email_address', 'reply_to_email_address',
'research_mode', 'research_mode',
'can_send_letters',
'can_send_international_sms',
'sms_sender', 'sms_sender',
'created_by', 'created_by',
'branding', 'branding',

View File

@@ -2,7 +2,7 @@
<nav> <nav>
<a class="pill-separate-item" href="{{ url_for('.choose_template', service_id=current_service.id) }}"> <a class="pill-separate-item" href="{{ url_for('.choose_template', service_id=current_service.id) }}">
{% if current_service.can_send_letters %} {% if 'letter' in current_service.permissions %}
Write an email, text message or letter Write an email, text message or letter
{% else %} {% else %}
Write an email or text message Write an email or text message

View File

@@ -47,7 +47,7 @@
{% call row() %} {% call row() %}
{{ text_field('International text messages') }} {{ text_field('International text messages') }}
{{ boolean_field(current_service.can_send_international_sms) }} {{ boolean_field('international_sms' in current_service.permissions) }}
{{ edit_field('Change', url_for('.service_set_international_sms', service_id=current_service.id)) }} {{ edit_field('Change', url_for('.service_set_international_sms', service_id=current_service.id)) }}
{% endcall %} {% endcall %}
@@ -70,11 +70,11 @@
{% call row() %} {% call row() %}
{{ text_field('Letters') }} {{ text_field('Letters') }}
{{ boolean_field(current_service.can_send_letters) }} {{ boolean_field('letter' in current_service.permissions) }}
{{ edit_field('Change', url_for('.service_set_letters', service_id=current_service.id)) }} {{ edit_field('Change', url_for('.service_set_letters', service_id=current_service.id)) }}
{% endcall %} {% endcall %}
{% if current_service.can_send_letters %} {% if 'letter' in current_service.permissions %}
{% call row() %} {% call row() %}
{{ text_field('Letter contact details') }} {{ text_field('Letter contact details') }}
{% call field(status='' if current_service.letter_contact_block else 'default') %} {% call field(status='' if current_service.letter_contact_block else 'default') %}
@@ -158,12 +158,12 @@
</li> </li>
<li class="bottom-gutter"> <li class="bottom-gutter">
<a href="{{ url_for('.service_switch_can_send_letters', service_id=current_service.id) }}" class="button"> <a href="{{ url_for('.service_switch_can_send_letters', service_id=current_service.id) }}" class="button">
{{ 'Stop sending letters' if current_service.can_send_letters else 'Allow to send letters' }} {{ 'Stop sending letters' if 'letter' in current_service.permissions else 'Allow to send letters' }}
</a> </a>
</li> </li>
<li class="bottom-gutter"> <li class="bottom-gutter">
<a href="{{ url_for('.service_switch_can_send_international_sms', service_id=current_service.id) }}" class="button"> <a href="{{ url_for('.service_switch_can_send_international_sms', service_id=current_service.id) }}" class="button">
{{ 'Stop sending international sms' if current_service.can_send_international_sms else 'Allow to send international sms' }} {{ 'Stop sending international sms' if 'international_sms' in current_service.permissions else 'Allow international sms' }}
</a> </a>
</li> </li>
{% if current_service.active %} {% if current_service.active %}

View File

@@ -11,7 +11,7 @@
<div class="grid-row"> <div class="grid-row">
<div class="column-five-sixths"> <div class="column-five-sixths">
<h1 class="heading-large">International text messages</h1> <h1 class="heading-large">International text messages</h1>
{% if current_service.can_send_international_sms %} {% if 'international_sms' in current_service.permissions %}
<p> <p>
Your service can send text messages to international phone numbers. Your service can send text messages to international phone numbers.
</p> </p>

View File

@@ -11,7 +11,7 @@
<div class="grid-row"> <div class="grid-row">
<div class="column-five-sixths"> <div class="column-five-sixths">
<h1 class="heading-large">Letters</h1> <h1 class="heading-large">Letters</h1>
{% if current_service.can_send_letters %} {% if 'letter' in current_service.permissions %}
<p> <p>
Your service can send letters. Your service can send letters.
</p> </p>

View File

@@ -17,7 +17,7 @@
{% if current_user.has_permissions(permissions=['manage_templates'], any_=True) %} {% if current_user.has_permissions(permissions=['manage_templates'], any_=True) %}
<p class="bottom-gutter"> <p class="bottom-gutter">
You need a template before you can send You need a template before you can send
{% if current_service.can_send_letters %} {% if 'letter' in current_service.permissions %}
emails, text messages or letters emails, text messages or letters
{%- else -%} {%- else -%}
emails or text messages emails or text messages
@@ -27,7 +27,7 @@
{% else %} {% else %}
<p> <p>
You need to ask your service manager to add templates before you can send You need to ask your service manager to add templates before you can send
{% if current_service.can_send_letters %} {% if 'letter' in current_service.permissions %}
emails, text messages or letters emails, text messages or letters
{%- else -%} {%- else -%}
emails or text messages emails or text messages

View File

@@ -49,14 +49,12 @@ def service_json(
reply_to_email_address=None, reply_to_email_address=None,
sms_sender='GOVUK', sms_sender='GOVUK',
research_mode=False, research_mode=False,
can_send_letters=False,
can_send_international_sms=False,
organisation=None, organisation=None,
branding='govuk', branding='govuk',
created_at=None, created_at=None,
letter_contact_block=None, letter_contact_block=None,
permissions=None,
inbound_api=None, inbound_api=None,
permissions=['email', 'sms'],
): ):
if users is None: if users is None:
users = [] users = []
@@ -75,8 +73,6 @@ def service_json(
'reply_to_email_address': reply_to_email_address, 'reply_to_email_address': reply_to_email_address,
'sms_sender': sms_sender, 'sms_sender': sms_sender,
'research_mode': research_mode, 'research_mode': research_mode,
'can_send_letters': can_send_letters,
'can_send_international_sms': can_send_international_sms,
'organisation': organisation, 'organisation': organisation,
'branding': branding, 'branding': branding,
'created_at': created_at or str(datetime.utcnow()), 'created_at': created_at or str(datetime.utcnow()),

View File

@@ -11,22 +11,24 @@ letters_urls = [
@pytest.mark.parametrize('url', letters_urls) @pytest.mark.parametrize('url', letters_urls)
@pytest.mark.parametrize('can_send_letters, response_code', [ @pytest.mark.parametrize('permissions, response_code', [
(True, 200), (['letter'], 200),
(False, 403) ([], 403)
]) ])
def test_letters_access_restricted( def test_letters_access_restricted(
logged_in_platform_admin_client, logged_in_platform_admin_client,
mocker, mocker,
can_send_letters, permissions,
response_code, response_code,
mock_get_service_templates, mock_get_service_templates,
url, url,
service_one,
): ):
service = service_json(can_send_letters=can_send_letters) service_one['permissions'] = permissions
mocker.patch('app.service_api_client.get_service', return_value={"data": service})
response = logged_in_platform_admin_client.get(url(service_id=service['id'])) mocker.patch('app.service_api_client.get_service', return_value={"data": service_one})
response = logged_in_platform_admin_client.get(url(service_id=service_one['id']))
assert response.status_code == response_code assert response.status_code == response_code
@@ -40,29 +42,30 @@ def test_letters_lets_in_without_permission(
api_user_active, api_user_active,
mock_get_service_templates, mock_get_service_templates,
url, url,
service_one
): ):
service = service_json(can_send_letters=True) service_one['permissions'] = ['letter']
mocker.patch('app.service_api_client.get_service', return_value={"data": service}) mocker.patch('app.service_api_client.get_service', return_value={"data": service_one})
client.login(api_user_active) client.login(api_user_active)
response = client.get(url(service_id=service['id'])) response = client.get(url(service_id=service_one['id']))
assert api_user_active.permissions == {} assert api_user_active.permissions == {}
assert response.status_code == 200 assert response.status_code == 200
@pytest.mark.parametrize('can_send_letters, choices', [ @pytest.mark.parametrize('permissions, choices', [
(True, ['Email', 'Text message', 'Letter']), (['email', 'sms', 'letter'], ['Email', 'Text message', 'Letter']),
(False, ['Email', 'Text message']) (['email', 'sms'], ['Email', 'Text message'])
]) ])
def test_given_option_to_add_letters_if_allowed( def test_given_option_to_add_letters_if_allowed(
logged_in_client, logged_in_client,
service_one, service_one,
mocker, mocker,
can_send_letters, permissions,
choices, choices,
): ):
service_one['can_send_letters'] = can_send_letters service_one['permissions'] = permissions
mocker.patch('app.service_api_client.get_service', return_value={"data": service_one}) mocker.patch('app.service_api_client.get_service', return_value={"data": service_one})
response = logged_in_client.get(url_for('main.add_template_by_type', service_id=service_one['id'])) response = logged_in_client.get(url_for('main.add_template_by_type', service_id=service_one['id']))

View File

@@ -853,7 +853,7 @@ def test_send_test_works_as_letter_preview(
fake_uuid, fake_uuid,
mocker, mocker,
): ):
service_one['can_send_letters'] = True service_one['permissions'] = ['letter']
mocker.patch('app.service_api_client.get_service', return_value={"data": service_one}) mocker.patch('app.service_api_client.get_service', return_value={"data": service_one})
mocker.patch('app.main.views.send.get_page_count_for_letter', return_value=1) mocker.patch('app.main.views.send.get_page_count_for_letter', return_value=1)
mocked_preview = mocker.patch( mocked_preview = mocker.patch(
@@ -1139,7 +1139,7 @@ def test_should_show_preview_letter_message(
fake_uuid, fake_uuid,
mocker, mocker,
): ):
service_one['can_send_letters'] = True service_one['permissions'] = ['letter']
mocker.patch('app.service_api_client.get_service', return_value={"data": service_one}) mocker.patch('app.service_api_client.get_service', return_value={"data": service_one})
mocker.patch('app.main.views.send.get_page_count_for_letter', return_value=1) mocker.patch('app.main.views.send.get_page_count_for_letter', return_value=1)

View File

@@ -91,8 +91,7 @@ def test_should_show_overview_for_service_with_more_things_set(
expected_rows expected_rows
): ):
client.login(active_user_with_permissions, mocker, service_with_reply_to_addresses) client.login(active_user_with_permissions, mocker, service_with_reply_to_addresses)
service_with_reply_to_addresses['permissions'] = permissions service_with_reply_to_addresses['permissions'] = ['email', 'sms', 'inbound_sms', 'international_sms']
service_with_reply_to_addresses['can_send_international_sms'] = True
response = client.get(url_for( response = client.get(url_for(
'main.service_settings', service_id=service_with_reply_to_addresses['id'] 'main.service_settings', service_id=service_with_reply_to_addresses['id']
)) ))
@@ -158,8 +157,11 @@ def test_if_can_receive_inbound_then_cant_change_sms_sender(
response = logged_in_client.get(url_for( response = logged_in_client.get(url_for(
'main.service_settings', service_id=service_one['id'] 'main.service_settings', service_id=service_one['id']
)) ))
assert 'Text message sender SomeNumber Change' not in response.get_data(as_text=True) page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
assert url_for('.service_set_sms_sender', service_id=service_one['id'], rows = page.find_all('tr')
rows_as_text = [" ".join(row.text.split()) for row in rows]
assert 'Text message sender SomeNumber Change' not in rows_as_text
assert url_for('main.service_request_to_go_live', service_id=service_one['id'],
set_inbound_sms=False) not in response.get_data(as_text=True) set_inbound_sms=False) not in response.get_data(as_text=True)
assert 'SomeNumber' in response.get_data(as_text=True) assert 'SomeNumber' in response.get_data(as_text=True)
@@ -170,7 +172,7 @@ def test_letter_contact_block_shows_none_if_not_set(
mocker, mocker,
mock_get_letter_organisations, mock_get_letter_organisations,
): ):
service_one['can_send_letters'] = True service_one['permissions'] = ['letter']
response = logged_in_client.get(url_for( response = logged_in_client.get(url_for(
'main.service_settings', service_id=service_one['id'] 'main.service_settings', service_id=service_one['id']
)) ))
@@ -187,7 +189,7 @@ def test_escapes_letter_contact_block(
mocker, mocker,
mock_get_letter_organisations, mock_get_letter_organisations,
): ):
service_one['can_send_letters'] = True service_one['permissions'] = ['letter']
service_one['letter_contact_block'] = 'foo\nbar<script>alert(1);</script>' service_one['letter_contact_block'] = 'foo\nbar<script>alert(1);</script>'
response = logged_in_client.get(url_for( response = logged_in_client.get(url_for(
'main.service_settings', service_id=service_one['id'] 'main.service_settings', service_id=service_one['id']
@@ -833,7 +835,7 @@ def test_cant_set_letter_contact_block_if_service_cant_send_letters(
service_one, service_one,
method method
): ):
assert not service_one['can_send_letters'] assert 'letter' not in service_one['permissions']
response = getattr(logged_in_client, method)( response = getattr(logged_in_client, method)(
url_for('main.service_set_letter_contact_block', service_id=service_one['id']) url_for('main.service_set_letter_contact_block', service_id=service_one['id'])
) )
@@ -844,7 +846,7 @@ def test_set_letter_contact_block_prepopulates(
logged_in_client, logged_in_client,
service_one service_one
): ):
service_one['can_send_letters'] = True service_one['permissions'] = ['letter']
service_one['letter_contact_block'] = 'foo bar baz waz' service_one['letter_contact_block'] = 'foo bar baz waz'
response = logged_in_client.get(url_for('main.service_set_letter_contact_block', service_id=service_one['id'])) response = logged_in_client.get(url_for('main.service_set_letter_contact_block', service_id=service_one['id']))
assert response.status_code == 200 assert response.status_code == 200
@@ -856,7 +858,7 @@ def test_set_letter_contact_block_saves(
service_one, service_one,
mock_update_service, mock_update_service,
): ):
service_one['can_send_letters'] = True service_one['permissions'] = ['letter']
response = logged_in_client.post( response = logged_in_client.post(
url_for('main.service_set_letter_contact_block', service_id=service_one['id']), url_for('main.service_set_letter_contact_block', service_id=service_one['id']),
data={'letter_contact_block': 'foo bar baz waz'} data={'letter_contact_block': 'foo bar baz waz'}
@@ -871,7 +873,7 @@ def test_set_letter_contact_block_redirects_to_template(
service_one, service_one,
mock_update_service, mock_update_service,
): ):
service_one['can_send_letters'] = True service_one['permissions'] = ['letter']
fake_template_id = uuid.uuid4() fake_template_id = uuid.uuid4()
response = logged_in_client.post( response = logged_in_client.post(
url_for( url_for(
@@ -895,7 +897,7 @@ def test_set_letter_contact_block_has_max_10_lines(
service_one, service_one,
mock_update_service, mock_update_service,
): ):
service_one['can_send_letters'] = True service_one['permissions'] = ['letter']
response = logged_in_client.post( response = logged_in_client.post(
url_for('main.service_set_letter_contact_block', service_id=service_one['id']), url_for('main.service_set_letter_contact_block', service_id=service_one['id']),
data={'letter_contact_block': '\n'.join(map(str, range(0, 11)))} data={'letter_contact_block': '\n'.join(map(str, range(0, 11)))}
@@ -1034,7 +1036,8 @@ def test_switch_service_enable_letters(
assert response.status_code == 302 assert response.status_code == 302
assert response.location == url_for('main.service_settings', service_id=service_one['id'], _external=True) assert response.location == url_for('main.service_settings', service_id=service_one['id'], _external=True)
assert mocked_fn.call_args == call(service_one['id'], {'can_send_letters': True}) assert 'letter' in mocked_fn.call_args[0][1]['permissions']
assert mocked_fn.call_args[0][0] == service_one['id']
def test_switch_service_disable_letters( def test_switch_service_disable_letters(
@@ -1042,7 +1045,7 @@ def test_switch_service_disable_letters(
service_one, service_one,
mocker, mocker,
): ):
service_one['can_send_letters'] = True service_one['permissions'] = ['letter']
mocked_fn = mocker.patch('app.service_api_client.update_service_with_properties', return_value=service_one) mocked_fn = mocker.patch('app.service_api_client.update_service_with_properties', return_value=service_one)
response = logged_in_platform_admin_client.get( response = logged_in_platform_admin_client.get(
@@ -1051,7 +1054,7 @@ def test_switch_service_disable_letters(
assert response.status_code == 302 assert response.status_code == 302
assert response.location == url_for('main.service_settings', service_id=service_one['id'], _external=True) assert response.location == url_for('main.service_settings', service_id=service_one['id'], _external=True)
assert mocked_fn.call_args == call(service_one['id'], {"can_send_letters": False}) assert mocked_fn.call_args == call(service_one['id'], {"permissions": []})
def test_switch_service_enable_international_sms( def test_switch_service_enable_international_sms(
@@ -1067,7 +1070,8 @@ def test_switch_service_enable_international_sms(
assert response.status_code == 302 assert response.status_code == 302
assert response.location == url_for('main.service_settings', service_id=service_one['id'], _external=True) assert response.location == url_for('main.service_settings', service_id=service_one['id'], _external=True)
assert mocked_fn.call_args == call(service_one['id'], {'can_send_international_sms': True}) assert 'international_sms' in mocked_fn.call_args[0][1]['permissions']
assert mocked_fn.call_args[0][0] == service_one['id']
def test_switch_service_disable_international_sms( def test_switch_service_disable_international_sms(
@@ -1075,7 +1079,7 @@ def test_switch_service_disable_international_sms(
service_one, service_one,
mocker, mocker,
): ):
service_one['can_send_international_sms'] = True service_one['permissions'] = ['international_sms']
mocked_fn = mocker.patch('app.service_api_client.update_service_with_properties', return_value=service_one) mocked_fn = mocker.patch('app.service_api_client.update_service_with_properties', return_value=service_one)
response = logged_in_platform_admin_client.get( response = logged_in_platform_admin_client.get(
@@ -1084,7 +1088,7 @@ def test_switch_service_disable_international_sms(
assert response.status_code == 302 assert response.status_code == 302
assert response.location == url_for('main.service_settings', service_id=service_one['id'], _external=True) assert response.location == url_for('main.service_settings', service_id=service_one['id'], _external=True)
assert mocked_fn.call_args == call(service_one['id'], {"can_send_international_sms": False}) assert mocked_fn.call_args == call(service_one['id'], {"permissions": []})
def test_set_new_inbound_api_and_valid_bearer_token_calls_create_inbound_api_endpoint( def test_set_new_inbound_api_and_valid_bearer_token_calls_create_inbound_api_endpoint(

View File

@@ -83,7 +83,7 @@ def mock_get_service(mocker, api_user_active):
@pytest.fixture(scope='function') @pytest.fixture(scope='function')
def mock_get_international_service(mocker, api_user_active): def mock_get_international_service(mocker, api_user_active):
def _get(service_id): def _get(service_id):
service = service_json(service_id, users=[api_user_active.id], can_send_international_sms=True) service = service_json(service_id, users=[api_user_active.id], permissions=['international_sms'])
return {'data': service} return {'data': service}
return mocker.patch('app.service_api_client.get_service', side_effect=_get) return mocker.patch('app.service_api_client.get_service', side_effect=_get)