diff --git a/.ds.baseline b/.ds.baseline index 99ca2e7c5..98304c73d 100644 --- a/.ds.baseline +++ b/.ds.baseline @@ -507,7 +507,7 @@ "filename": "tests/app/main/views/test_accept_invite.py", "hashed_secret": "07f0a6c13923fc3b5f0c57ffa2d29b715eb80d71", "is_verified": false, - "line_number": 631, + "line_number": 632, "is_secret": false } ], @@ -601,7 +601,7 @@ "filename": "tests/app/notify_client/test_user_client.py", "hashed_secret": "f2c57870308dc87f432e5912d4de6f8e322721ba", "is_verified": false, - "line_number": 55, + "line_number": 56, "is_secret": false } ], @@ -629,10 +629,10 @@ "filename": "tests/conftest.py", "hashed_secret": "f8377c90fcfd699f0ddbdcb30c2c9183d2d933ea", "is_verified": false, - "line_number": 3266, + "line_number": 3267, "is_secret": false } ] }, - "generated_at": "2025-07-17T07:59:56Z" + "generated_at": "2025-07-21T23:33:47Z" } diff --git a/app/enums.py b/app/enums.py index 3c83fccda..3dd4b0e1c 100644 --- a/app/enums.py +++ b/app/enums.py @@ -73,6 +73,14 @@ class ServicePermission(StrEnum): SEND_MESSAGES = "send_messages" MANAGE_SERVICE = "manage_service" MANAGE_TEMPLATES = "manage_templates" + SEND_TEXTS = "send_texts" + MANAGE_SETTINGS = "manage_settings" + INBOUND_SMS = "inbound_sms" + INTERNATIONAL_SMS = "international_sms" + EMAIL_AUTH = "email_auth" + EDIT_FOLDER_PERMISSIONS = "edit_folder_permissions" + RESEARCH_MODE = "research_mode" + UPLOAD_DOCUMENT = "upload_document" class InvitedUserStatus(StrEnum): diff --git a/app/main/views/api_keys.py b/app/main/views/api_keys.py index f93d2caa1..9040fd3cf 100644 --- a/app/main/views/api_keys.py +++ b/app/main/views/api_keys.py @@ -8,6 +8,7 @@ from app import ( notification_api_client, service_api_client, ) +from app.enums import ServicePermission from app.formatters import email_safe from app.main import main from app.main.forms import CallbackForm, CreateKeyForm, GuestList @@ -26,7 +27,7 @@ dummy_bearer_token = "bearer_token_set" # nosec B105 - this is not a real token def api_integration(service_id): callbacks_link = ( ".api_callbacks" - if current_service.has_permission("inbound_sms") + if current_service.has_permission(ServicePermission.INBOUND_SMS) else ".delivery_status_callback" ) return render_template( @@ -162,7 +163,7 @@ def check_token_against_dummy_bearer(token): @main.route("/services//api/callbacks", methods=["GET"]) @user_has_permissions("manage_api_keys") def api_callbacks(service_id): - if not current_service.has_permission("inbound_sms"): + if not current_service.has_permission(ServicePermission.INBOUND_SMS): return redirect(url_for(".delivery_status_callback", service_id=service_id)) delivery_status_callback, received_text_messages_callback = get_apis() @@ -196,7 +197,7 @@ def delivery_status_callback(service_id): delivery_status_callback = get_delivery_status_callback_details() back_link = ( ".api_callbacks" - if current_service.has_permission("inbound_sms") + if current_service.has_permission(ServicePermission.INBOUND_SMS) else ".api_integration" ) @@ -260,7 +261,7 @@ def get_received_text_messages_callback(): ) @user_has_permissions("manage_api_keys") def received_text_messages_callback(service_id): - if not current_service.has_permission("inbound_sms"): + if not current_service.has_permission(ServicePermission.INBOUND_SMS): return redirect(url_for(".api_integration", service_id=service_id)) received_text_messages_callback = get_received_text_messages_callback() diff --git a/app/main/views/find_users.py b/app/main/views/find_users.py index ef55ad2a4..11d98f3f5 100644 --- a/app/main/views/find_users.py +++ b/app/main/views/find_users.py @@ -2,6 +2,7 @@ from flask import flash, redirect, render_template, request, url_for from flask_login import current_user from app import user_api_client +from app.enums import ServicePermission from app.event_handlers import create_archive_user_event from app.main import main from app.main.forms import AdminSearchUsersByEmailForm, AuthTypeForm @@ -40,7 +41,7 @@ def archive_user(user_id): try: user_api_client.archive_user(user_id) except HTTPError as e: - if e.status_code == 400 and "manage_settings" in e.message: + if e.status_code == 400 and ServicePermission.MANAGE_SETTINGS in e.message: flash( "User can’t be removed from a service - " "check all services have another team member with manage_settings" diff --git a/app/main/views/invites.py b/app/main/views/invites.py index 6831f1db4..e2fe94a5a 100644 --- a/app/main/views/invites.py +++ b/app/main/views/invites.py @@ -2,7 +2,7 @@ from flask import abort, flash, redirect, render_template, session, url_for from flask_login import current_user from markupsafe import Markup -from app.enums import InvitedOrgUserStatus, InvitedUserStatus +from app.enums import InvitedOrgUserStatus, InvitedUserStatus, ServicePermission, AuthType from app.main import main from app.models.organization import Organization from app.models.service import Service @@ -61,10 +61,10 @@ def accept_invite(token): # if the user is a Platform Admin, we silently leave this unchanged to prevent a security # issue where someone could switch their auth type to something less secure if ( - service.has_permission("email_auth") + service.has_permission(ServicePermission.EMAIL_AUTH) and not existing_user.platform_admin ): - if invited_user.auth_type == "email_auth" or ( + if invited_user.auth_type == AuthType.EMAIL_AUTH or ( # they have a phone number, we want them to start using it. # if they dont have a mobile we just ignore that option of the invite existing_user.mobile_number diff --git a/app/main/views/manage_users.py b/app/main/views/manage_users.py index 96e168f20..686672f2b 100644 --- a/app/main/views/manage_users.py +++ b/app/main/views/manage_users.py @@ -73,7 +73,7 @@ def invite_user(service_id, user_id=None): else: user_to_invite = None - service_has_email_auth = current_service.has_permission("email_auth") + service_has_email_auth = current_service.has_permission(ServicePermission.EMAIL_AUTH) if not service_has_email_auth: form.login_authentication.data = "sms_auth" @@ -116,7 +116,7 @@ def invite_user(service_id, user_id=None): @main.route("/services//users/", methods=["GET", "POST"]) @user_has_permissions(ServicePermission.MANAGE_SERVICE) def edit_user_permissions(service_id, user_id): - service_has_email_auth = current_service.has_permission("email_auth") + service_has_email_auth = current_service.has_permission(ServicePermission.EMAIL_AUTH) user = current_service.get_team_member(user_id) mobile_number = None diff --git a/app/main/views/notifications.py b/app/main/views/notifications.py index bd02a81a2..c711eb654 100644 --- a/app/main/views/notifications.py +++ b/app/main/views/notifications.py @@ -94,7 +94,7 @@ def view_notification(service_id, notification_id, error_message=None): updated_at=notification["sent_at"], help=get_help_argument(), notification_id=notification["id"], - can_receive_inbound=(current_service.has_permission("inbound_sms")), + can_receive_inbound=(current_service.has_permission(ServicePermission.INBOUND_SMS)), sent_with_test_key=(notification.get("key_type") == KEY_TYPE_TEST), back_link=back_link, ) diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py index bd51d3f0e..0ce1ae5dc 100644 --- a/app/main/views/service_settings.py +++ b/app/main/views/service_settings.py @@ -57,14 +57,14 @@ from notifications_python_client.errors import HTTPError PLATFORM_ADMIN_SERVICE_PERMISSIONS = OrderedDict( [ ( - "inbound_sms", + ServicePermission.INBOUND_SMS, { "title": "Receive inbound SMS", "requires": "sms", "endpoint": ".service_set_inbound_number", }, ), - ("email_auth", {"title": "Email authentication"}), + (ServicePermission.EMAIL_AUTH, {"title": "Email authentication"}), ] ) @@ -558,7 +558,7 @@ def service_set_inbound_number(service_id): is_default=True, inbound_number_id=form.inbound_number.data, ) - current_service.force_permission("inbound_sms", on=True) + current_service.force_permission(ServicePermission.INBOUND_SMS, on=True) return redirect(url_for(".service_settings", service_id=service_id)) return render_template( diff --git a/app/main/views/user_profile.py b/app/main/views/user_profile.py index ec9e27035..e4aca221c 100644 --- a/app/main/views/user_profile.py +++ b/app/main/views/user_profile.py @@ -13,6 +13,7 @@ from flask import ( from flask_login import current_user from app import user_api_client +from app.enums import AuthType from app.event_handlers import ( create_email_change_event, create_mobile_number_change_event, @@ -179,7 +180,7 @@ def user_profile_mobile_number(): @main.route("/user-profile/mobile-number/delete", methods=["POST"]) @user_is_logged_in def user_profile_mobile_number_delete(): - if current_user.auth_type != "email_auth": + if current_user.auth_type != AuthType.EMAIL_AUTH: abort(403) current_user.update(mobile_number=None) diff --git a/app/models/service.py b/app/models/service.py index 15355809f..09613893b 100644 --- a/app/models/service.py +++ b/app/models/service.py @@ -38,7 +38,7 @@ class Service(JSONModel, SortByNameMixin): "notes", "prefix_sms", "purchase_order_number", - "research_mode", + ServicePermission.RESEARCH_MODE, "service_callback_api", "volume_email", "volume_sms", @@ -50,11 +50,11 @@ class Service(JSONModel, SortByNameMixin): ) ALL_PERMISSIONS = TEMPLATE_TYPES + ( - "edit_folder_permissions", - "email_auth", - "inbound_sms", + ServicePermission.EDIT_FOLDER_PERMISSIONS, + ServicePermission.EMAIL_AUTH, + ServicePermission.INBOUND_SMS, "international_sms", - "upload_document", + ServicePermission.UPLOAD_DOCUMENT, ) @classmethod @@ -440,7 +440,7 @@ class Service(JSONModel, SortByNameMixin): @cached_property def inbound_sms_summary(self): - if not self.has_permission("inbound_sms"): + if not self.has_permission(ServicePermission.INBOUND_SMS): return None return service_api_client.get_inbound_sms_summary(self.id) diff --git a/app/models/user.py b/app/models/user.py index 4ed4a62da..1b04666fb 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -5,7 +5,7 @@ from flask import abort, current_app, request, session from flask_login import AnonymousUserMixin, UserMixin, login_user, logout_user from werkzeug.utils import cached_property -from app.enums import InvitedUserStatus +from app.enums import AuthType, InvitedUserStatus from app.event_handlers import ( create_add_user_to_service_event, create_set_user_permissions_event, @@ -186,7 +186,7 @@ class User(JSONModel, UserMixin): @property def email_auth(self): - return self.auth_type == "email_auth" + return self.auth_type == AuthType.EMAIL_AUTH def reset_failed_login_count(self): user_api_client.reset_failed_login_count(self.id) @@ -546,7 +546,7 @@ class InvitedUser(JSONModel): @property def email_auth(self): - return self.auth_type == "email_auth" + return self.auth_type == AuthType.EMAIL_AUTH @classmethod def from_token(cls, token): diff --git a/app/notify_client/service_api_client.py b/app/notify_client/service_api_client.py index 013bb300b..97d94cae4 100644 --- a/app/notify_client/service_api_client.py +++ b/app/notify_client/service_api_client.py @@ -3,6 +3,7 @@ from datetime import datetime, timezone from flask import current_app +from app.enums import ServicePermission from app.extensions import redis_client from app.notify_client import NotifyAdminAPIClient, _attach_current_user, cache @@ -126,7 +127,7 @@ class ServiceAPIClient(NotifyAdminAPIClient): "purchase_order_number", "rate_limit", "reply_to_email_address", - "research_mode", + ServicePermission.RESEARCH_MODE, "restricted", "sms_sender", "volume_email", diff --git a/app/utils/user_permissions.py b/app/utils/user_permissions.py index ff7c40dad..b3e2ce762 100644 --- a/app/utils/user_permissions.py +++ b/app/utils/user_permissions.py @@ -4,7 +4,7 @@ from app.enums import ServicePermission permission_mappings = { # TODO: consider turning off email-sending permissions during SMS pilot - ServicePermission.SEND_MESSAGES: ["send_texts", "send_emails"], + ServicePermission.SEND_MESSAGES: [ServicePermission.SEND_TEXTS, "send_emails"], ServicePermission.MANAGE_TEMPLATES: [ServicePermission.MANAGE_TEMPLATES], ServicePermission.MANAGE_SERVICE: ["manage_users", "manage_settings"], "manage_api_keys": ["manage_api_keys"], diff --git a/tests/__init__.py b/tests/__init__.py index 0f2827511..9a22f481e 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -81,7 +81,7 @@ def user_json( "send_emails", "manage_users", "manage_templates", - "manage_settings", + ServicePermission.MANAGE_SETTINGS, "manage_api_keys", ] } diff --git a/tests/app/main/test_permissions.py b/tests/app/main/test_permissions.py index 158fffe06..a16cc1243 100644 --- a/tests/app/main/test_permissions.py +++ b/tests/app/main/test_permissions.py @@ -5,6 +5,7 @@ import re import pytest from flask import current_app +from app.enums import ServicePermission from tests import service_json from tests.conftest import ( ORGANISATION_ID, @@ -51,7 +52,7 @@ def test_services_pages_that_org_users_are_allowed_to_see( api_user_active["services"] = user_services api_user_active["organizations"] = user_organizations api_user_active["permissions"] = { - service_id: ["manage_users", "manage_settings"] for service_id in user_services + service_id: ["manage_users", ServicePermission.MANAGE_SETTINGS] for service_id in user_services } service = service_json( name="SERVICE WITH ORG", diff --git a/tests/app/main/views/service_settings/test_service_setting_permissions.py b/tests/app/main/views/service_settings/test_service_setting_permissions.py index b7c945902..ba8c522e1 100644 --- a/tests/app/main/views/service_settings/test_service_setting_permissions.py +++ b/tests/app/main/views/service_settings/test_service_setting_permissions.py @@ -3,6 +3,7 @@ import functools import pytest from flask import url_for +from app.enums import ServicePermission from app.main.views.service_settings import PLATFORM_ADMIN_SERVICE_PERMISSIONS from tests.conftest import normalize_spaces @@ -34,7 +35,7 @@ def test_service_set_permission_requires_platform_admin( client_request.post( "main.service_set_permission", service_id=service_one["id"], - permission="email_auth", + permission=ServicePermission.EMAIL_AUTH, _data={"enabled": "True"}, _expected_status=403, ) @@ -45,25 +46,25 @@ def test_service_set_permission_requires_platform_admin( [ ( [], - "inbound_sms", + ServicePermission.INBOUND_SMS, "True", - ["inbound_sms"], + [ServicePermission.INBOUND_SMS], ), ( - ["inbound_sms"], - "inbound_sms", + [ServicePermission.INBOUND_SMS], + ServicePermission.INBOUND_SMS, "False", [], ), ( [], - "email_auth", + ServicePermission.EMAIL_AUTH, "True", - ["email_auth"], + [ServicePermission.EMAIL_AUTH], ), ( - ["email_auth"], - "email_auth", + [ServicePermission.EMAIL_AUTH], + ServicePermission.EMAIL_AUTH, "False", [], ), @@ -201,7 +202,7 @@ def test_service_setting_link_toggles_index_error( ("permissions", "permissions_text", "visible"), [ ("sms", "inbound SMS", True), - ("inbound_sms", "inbound SMS", False), # no sms parent permission + (ServicePermission.INBOUND_SMS, "inbound SMS", False), # no sms parent permission # also test no permissions set ("", "inbound SMS", False), ], diff --git a/tests/app/main/views/service_settings/test_service_settings.py b/tests/app/main/views/service_settings/test_service_settings.py index 603e914b5..d00f16b11 100644 --- a/tests/app/main/views/service_settings/test_service_settings.py +++ b/tests/app/main/views/service_settings/test_service_settings.py @@ -7,6 +7,7 @@ from flask import url_for from freezegun import freeze_time import app +from app.enums import ServicePermission from notifications_python_client.errors import HTTPError from tests import ( find_element_by_tag_and_partial_text, @@ -196,7 +197,7 @@ def test_send_files_by_email_row_on_settings_page( ], ), ( - ["email", "sms", "email_auth"], + ["email", "sms", ServicePermission.EMAIL_AUTH], [ "Service name service one Change service name", "Send text messages On", @@ -2540,7 +2541,7 @@ def test_send_files_by_email_contact_details_does_not_update_invalid_contact_det error, ): service_one["contact_link"] = "http://example.com/" - service_one["permissions"].append("upload_document") + service_one["permissions"].append(ServicePermission.UPLOAD_DOCUMENT) page = client_request.post( "main.send_files_by_email_contact_details", @@ -2568,7 +2569,7 @@ def test_send_files_by_email_contact_details_does_not_update_invalid_contact_det ), ( "main.service_set_auth_type", - ["email_auth"], + [ServicePermission.EMAIL_AUTH], ( "Your username, password, and multi-factor authentication options are handled by Login.gov." ), @@ -2661,7 +2662,7 @@ def test_set_inbound_sms_when_inbound_number_is_set( user, expected_paragraphs, ): - service_one["permissions"] = ["inbound_sms"] + service_one["permissions"] = [ServicePermission.INBOUND_SMS] mocker.patch( "app.inbound_number_client.get_inbound_sms_number_for_service", return_value={"data": {"number": "2028675309"}}, diff --git a/tests/app/main/views/test_accept_invite.py b/tests/app/main/views/test_accept_invite.py index 77df3a832..499a72e2b 100644 --- a/tests/app/main/views/test_accept_invite.py +++ b/tests/app/main/views/test_accept_invite.py @@ -5,6 +5,7 @@ from flask import url_for from freezegun import freeze_time import app +from app.enums import AuthType, ServicePermission from notifications_python_client.errors import HTTPError from tests import service_json from tests.conftest import ( @@ -747,8 +748,8 @@ def test_existing_user_accepts_and_sets_email_auth( ): sample_invite["email_address"] = api_user_active["email_address"] - service_one["permissions"].append("email_auth") - sample_invite["auth_type"] = "email_auth" + service_one["permissions"].append(ServicePermission.EMAIL_AUTH) + sample_invite["auth_type"] = AuthType.EMAIL_AUTH client_request.get( "main.accept_invite", @@ -762,7 +763,7 @@ def test_existing_user_accepts_and_sets_email_auth( mock_get_existing_user_by_email.assert_called_once_with("test@user.gsa.gov") assert mock_update_user_attribute.call_args_list == [ call(api_user_active["id"], email_access_validated_at="2021-12-12T12:12:12"), - call(api_user_active["id"], auth_type="email_auth"), + call(api_user_active["id"], auth_type=AuthType.EMAIL_AUTH), ] mock_add_user_to_service.assert_called_once_with( ANY, api_user_active["id"], ANY, ANY @@ -782,8 +783,8 @@ def test_platform_admin_user_accepts_and_preserves_auth( mocker, ): sample_invite["email_address"] = platform_admin_user["email_address"] - sample_invite["auth_type"] = "email_auth" - service_one["permissions"].append("email_auth") + sample_invite["auth_type"] = AuthType.EMAIL_AUTH + service_one["permissions"].append(ServicePermission.EMAIL_AUTH) mocker.patch( "app.user_api_client.get_user_by_email", return_value=platform_admin_user @@ -827,9 +828,9 @@ def test_existing_user_doesnt_get_auth_changed_by_service_without_permission( ): sample_invite["email_address"] = api_user_active["email_address"] - assert "email_auth" not in service_one["permissions"] + assert ServicePermission.EMAIL_AUTH not in service_one["permissions"] - sample_invite["auth_type"] = "email_auth" + sample_invite["auth_type"] = AuthType.EMAIL_AUTH client_request.get( "main.accept_invite", @@ -861,9 +862,9 @@ def test_existing_email_auth_user_without_phone_cannot_set_sms_auth( ): sample_invite["email_address"] = api_user_active["email_address"] - service_one["permissions"].append("email_auth") + service_one["permissions"].append(ServicePermission.EMAIL_AUTH) - api_user_active["auth_type"] = "email_auth" + api_user_active["auth_type"] = AuthType.EMAIL_AUTH api_user_active["mobile_number"] = None sample_invite["auth_type"] = "sms_auth" @@ -899,7 +900,7 @@ def test_existing_email_auth_user_with_phone_can_set_sms_auth( mocker, ): sample_invite["email_address"] = api_user_active["email_address"] - service_one["permissions"].append("email_auth") + service_one["permissions"].append(ServicePermission.EMAIL_AUTH) sample_invite["auth_type"] = "sms_auth" client_request.get( diff --git a/tests/app/main/views/test_api_integration.py b/tests/app/main/views/test_api_integration.py index 51592b99e..8ad9f2b39 100644 --- a/tests/app/main/views/test_api_integration.py +++ b/tests/app/main/views/test_api_integration.py @@ -6,6 +6,7 @@ from unittest.mock import call import pytest from flask import url_for +from app.enums import ServicePermission from app.formatters import format_datetime_table from tests import sample_uuid, validate_route_permission from tests.conftest import SERVICE_ONE_ID, normalize_spaces @@ -472,7 +473,7 @@ def test_callback_forms_validation( expected_errors, ): if endpoint == "main.received_text_messages_callback": - service_one["permissions"] = ["inbound_sms"] + service_one["permissions"] = [ServicePermission.INBOUND_SMS] data = { "url": url, @@ -516,7 +517,7 @@ def test_callback_forms_can_be_cleared( ): service_one["service_callback_api"] = [fake_uuid] service_one["inbound_api"] = [fake_uuid] - service_one["permissions"] = ["inbound_sms"] + service_one["permissions"] = [ServicePermission.INBOUND_SMS] mocked_delete = mocker.patch("app.service_api_client.delete") page = client_request.post( @@ -563,7 +564,7 @@ def test_callback_forms_can_be_cleared_when_callback_and_inbound_apis_are_empty( mock_get_empty_service_callback_api, mock_get_empty_service_inbound_api, ): - service_one["permissions"] = ["inbound_sms"] + service_one["permissions"] = [ServicePermission.INBOUND_SMS] mocked_delete = mocker.patch("app.service_api_client.delete") page = client_request.post( @@ -599,7 +600,7 @@ def test_callbacks_button_links_straight_to_delivery_status_if_service_has_no_in expected_link, ): if has_inbound_sms: - service_one["permissions"] = ["inbound_sms"] + service_one["permissions"] = [ServicePermission.INBOUND_SMS] page = client_request.get( "main.api_integration", @@ -640,7 +641,7 @@ def test_back_link_directs_to_api_integration_from_delivery_callback_if_no_inbou client_request, service_one, mocker, has_inbound_sms, expected_link ): if has_inbound_sms: - service_one["permissions"] = ["inbound_sms"] + service_one["permissions"] = [ServicePermission.INBOUND_SMS] page = client_request.get( "main.delivery_status_callback", @@ -671,7 +672,7 @@ def test_create_delivery_status_and_receive_text_message_callbacks( fake_uuid, ): if endpoint == "main.received_text_messages_callback": - service_one["permissions"] = ["inbound_sms"] + service_one["permissions"] = [ServicePermission.INBOUND_SMS] data = { "url": "https://test.url.com/", @@ -739,7 +740,7 @@ def test_update_receive_text_message_callback_details( fake_uuid, ): service_one["inbound_api"] = [fake_uuid] - service_one["permissions"] = ["inbound_sms"] + service_one["permissions"] = [ServicePermission.INBOUND_SMS] data = { "url": "https://test.url.com/", @@ -793,7 +794,7 @@ def test_update_receive_text_message_callback_without_changes_does_not_update( mock_get_valid_service_inbound_api, ): service_one["inbound_api"] = [fake_uuid] - service_one["permissions"] = ["inbound_sms"] + service_one["permissions"] = [ServicePermission.INBOUND_SMS] data = { "user_id": fake_uuid, "url": "https://hello3.gsa.gov", @@ -842,7 +843,7 @@ def test_callbacks_page_works_when_no_apis_set( inbound_url, expected_2nd_table_row, ): - service_one["permissions"] = ["inbound_sms"] + service_one["permissions"] = [ServicePermission.INBOUND_SMS] service_one["inbound_api"] = inbound_api service_one["service_callback_api"] = service_callback_api diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py index c6a1eda08..30ad9a2dc 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -920,7 +920,7 @@ def test_menu_send_messages( mocker, api_user_active, service_one, - ["view_activity", "send_texts", "send_emails", "manage_service"], + ["view_activity", ServicePermission.SEND_TEXTS, "send_emails", "manage_service"], ) page = str(page) assert ( @@ -957,7 +957,7 @@ def test_menu_manage_service( mocker, api_user_active, service_one, - ["view_activity", ServicePermission.MANAGE_TEMPLATES, "manage_users", "manage_settings"], + ["view_activity", ServicePermission.MANAGE_TEMPLATES, "manage_users", ServicePermission.MANAGE_SETTINGS], ) page = str(page) assert ( @@ -994,7 +994,7 @@ def test_menu_main_settings( mocker, api_user_active, service_one, - ["view_activity", "user_profile", "manage_users", "manage_settings"], + ["view_activity", "user_profile", "manage_users", ServicePermission.MANAGE_SETTINGS], ) page = str(page) assert ( diff --git a/tests/app/main/views/test_manage_users.py b/tests/app/main/views/test_manage_users.py index b82fc1279..bd81546e9 100644 --- a/tests/app/main/views/test_manage_users.py +++ b/tests/app/main/views/test_manage_users.py @@ -267,7 +267,7 @@ def test_service_with_no_email_auth_hides_auth_type_options( platform_admin_user, ): if service_has_email_auth: - service_one["permissions"].append("email_auth") + service_one["permissions"].append(ServicePermission.EMAIL_AUTH) client_request.login(platform_admin_user) page = client_request.get(endpoint, service_id=service_one["id"], **extra_args) assert ( @@ -323,7 +323,7 @@ def test_manage_users_page_shows_member_auth_type_if_service_has_email_auth_acti displays_auth_type, ): if service_has_email_auth: - service_one["permissions"].append("email_auth") + service_one["permissions"].append(ServicePermission.EMAIL_AUTH) page = client_request.get("main.manage_users", service_id=service_one["id"]) assert bool(page.select_one(".tick-cross-list-hint")) == displays_auth_type @@ -362,7 +362,7 @@ def test_user_with_no_mobile_number_cant_be_set_to_sms_auth( ): active_user_with_permissions["mobile_number"] = mobile_number - service_one["permissions"].append("email_auth") + service_one["permissions"].append(ServicePermission.EMAIL_AUTH) mocker.patch( "app.user_api_client.get_user", return_value=active_user_with_permissions ) @@ -434,7 +434,7 @@ def test_invite_user_allows_to_choose_auth( service_one, platform_admin_user, ): - service_one["permissions"].append("email_auth") + service_one["permissions"].append(ServicePermission.EMAIL_AUTH) client_request.login(platform_admin_user) page = client_request.get("main.invite_user", service_id=SERVICE_ONE_ID) @@ -615,7 +615,7 @@ def test_cant_edit_user_folder_permissions_for_platform_admin_users( mock_get_template_folders, platform_admin_user, ): - service_one["permissions"] = ["edit_folder_permissions"] + service_one["permissions"] = [ServicePermission.EDIT_FOLDER_PERMISSIONS] mocker.patch("app.user_api_client.get_user", return_value=platform_admin_user) mock_get_template_folders.return_value = [ { @@ -704,7 +704,7 @@ def test_edit_user_permissions_including_authentication_with_email_auth_service( mock_get_template_folders, ): active_user_with_permissions["auth_type"] = "email_auth" - service_one["permissions"].append("email_auth") + service_one["permissions"].append(ServicePermission.EMAIL_AUTH) client_request.post( "main.edit_user_permissions", @@ -748,7 +748,7 @@ def test_edit_user_permissions_shows_authentication_for_email_auth_service( mock_get_template_folders, active_user_with_permissions, ): - service_one["permissions"].append("email_auth") + service_one["permissions"].append(ServicePermission.EMAIL_AUTH) page = client_request.get( "main.edit_user_permissions", @@ -1105,7 +1105,7 @@ def test_invite_user_with_email_auth_service( mock_get_organizations, mock_get_template_folders, ): - service_one["permissions"].append("email_auth") + service_one["permissions"].append(ServicePermission.EMAIL_AUTH) sample_invite["email_address"] = "test@example.gsa.gov" assert is_gov_user(email_address) is gov_user @@ -1386,7 +1386,7 @@ def test_manage_user_page_shows_how_many_folders_user_can_view( folders_user_can_see, expected_message, ): - service_one["permissions"] = ["edit_folder_permissions"] + service_one["permissions"] = [ServicePermission.EDIT_FOLDER_PERMISSIONS] mock_get_template_folders.return_value = [ { "id": "folder-id-1", @@ -1428,7 +1428,7 @@ def test_manage_user_page_doesnt_show_folder_hint_if_service_has_no_folders( mock_get_invites_for_service, api_user_active, ): - service_one["permissions"] = ["edit_folder_permissions"] + service_one["permissions"] = [ServicePermission.EDIT_FOLDER_PERMISSIONS] mock_get_template_folders.return_value = [] page = client_request.get("main.manage_users", service_id=service_one["id"]) diff --git a/tests/app/main/views/test_notifications.py b/tests/app/main/views/test_notifications.py index 2d1ac37b4..e7d60bc2d 100644 --- a/tests/app/main/views/test_notifications.py +++ b/tests/app/main/views/test_notifications.py @@ -4,6 +4,7 @@ import pytest from flask import url_for from freezegun import freeze_time +from app.enums import ServicePermission from tests.conftest import ( SERVICE_ONE_ID, create_active_caseworking_user, @@ -298,8 +299,8 @@ def test_notification_page_does_not_show_cancel_link_for_sms_or_email_notificati ("service_permissions", "template_type", "link_expected"), [ ([], "", False), - (["inbound_sms"], "email", False), - (["inbound_sms"], "sms", True), + ([ServicePermission.INBOUND_SMS], "email", False), + ([ServicePermission.INBOUND_SMS], "sms", True), ], ) def test_notification_page_has_link_to_send_another_for_sms( diff --git a/tests/app/main/views/test_platform_admin.py b/tests/app/main/views/test_platform_admin.py index 5124bd81d..75dc9184b 100644 --- a/tests/app/main/views/test_platform_admin.py +++ b/tests/app/main/views/test_platform_admin.py @@ -8,6 +8,7 @@ import pytest from flask import url_for from freezegun import freeze_time +from app.enums import ServicePermission from app.main.views.platform_admin import ( create_global_stats, format_stats_by_service, @@ -1179,8 +1180,8 @@ def test_get_users_report(client_request, platform_admin_user, mocker): "test service": [ "manage_users", "manage_templates", - "manage_settings", - "send_texts", + ServicePermission.MANAGE_SETTINGS, + ServicePermission.SEND_TEXTS, "send_emails", "manage_api_keys", "view_activity", diff --git a/tests/app/main/views/test_template_folders.py b/tests/app/main/views/test_template_folders.py index 3363b7652..f040301e6 100644 --- a/tests/app/main/views/test_template_folders.py +++ b/tests/app/main/views/test_template_folders.py @@ -605,7 +605,7 @@ def test_get_manage_folder_viewing_permissions_for_users_not_visible_when_no_man mocker, ): active_user_with_permissions["permissions"][SERVICE_ONE_ID] = [ - "send_texts", + ServicePermission.SEND_TEXTS, "send_emails", "manage_templates", "manage_api_keys", @@ -614,7 +614,7 @@ def test_get_manage_folder_viewing_permissions_for_users_not_visible_when_no_man folder_id = str(uuid.uuid4()) team_member = create_active_user_view_permissions(with_unique_id=True) team_member_2 = create_active_user_view_permissions(with_unique_id=True) - service_one["permissions"] += ["edit_folder_permissions"] + service_one["permissions"] += [ServicePermission.EDIT_FOLDER_PERMISSIONS] mock_get_template_folders.return_value = [ { "id": folder_id, @@ -655,7 +655,7 @@ def test_get_manage_folder_viewing_permissions_for_users_not_visible_for_service mocker, ): folder_id = str(uuid.uuid4()) - service_one["permissions"] += ["edit_folder_permissions"] + service_one["permissions"] += [ServicePermission.EDIT_FOLDER_PERMISSIONS] mock_get_template_folders.return_value = [ { "id": folder_id, @@ -859,7 +859,7 @@ def test_manage_folder_users_doesnt_change_permissions_current_user_cannot_manag mocker, ): active_user_with_permissions["permissions"][SERVICE_ONE_ID] = [ - "send_texts", + ServicePermission.SEND_TEXTS, "send_emails", "manage_templates", "manage_api_keys", diff --git a/tests/app/notify_client/test_user_client.py b/tests/app/notify_client/test_user_client.py index 9fccbc340..8e3424246 100644 --- a/tests/app/notify_client/test_user_client.py +++ b/tests/app/notify_client/test_user_client.py @@ -4,6 +4,7 @@ from unittest.mock import call import pytest from app import invite_api_client, service_api_client, user_api_client +from app.enums import ServicePermission from tests import sample_uuid from tests.conftest import SERVICE_ONE_ID @@ -104,7 +105,7 @@ def test_client_converts_admin_permissions_to_db_permissions_on_edit( mock_post.call_args[1]["data"]["permissions"], key=lambda x: x["permission"] ) == sorted( [ - {"permission": "send_texts"}, + {"permission": ServicePermission.SEND_TEXTS}, {"permission": "send_emails"}, {"permission": "view_activity"}, ], @@ -131,7 +132,7 @@ def test_client_converts_admin_permissions_to_db_permissions_on_add_to_service( mock_post.call_args[1]["data"]["permissions"], key=lambda x: x["permission"] ) == sorted( [ - {"permission": "send_texts"}, + {"permission": ServicePermission.SEND_TEXTS}, {"permission": "send_emails"}, {"permission": "view_activity"}, ], diff --git a/tests/app/utils/test_user.py b/tests/app/utils/test_user.py index 39265f161..892f4357d 100644 --- a/tests/app/utils/test_user.py +++ b/tests/app/utils/test_user.py @@ -36,7 +36,7 @@ def test_permissions( request.view_args.update({"service_id": "foo"}) api_user_active["permissions"] = { - "foo": ["manage_users", "manage_templates", "manage_settings"] + "foo": ["manage_users", "manage_templates", ServicePermission.MANAGE_SETTINGS] } api_user_active["services"] = ["foo", "bar"] @@ -66,7 +66,7 @@ def test_permissions_forbidden( request.view_args.update({"service_id": "foo"}) api_user_active["permissions"] = { - "foo": ["manage_users", "manage_templates", "manage_settings"] + "foo": ["manage_users", "manage_templates", ServicePermission.MANAGE_SETTINGS] } api_user_active["services"] = ["foo", "bar"] @@ -179,7 +179,7 @@ def test_user_with_no_permissions_to_service_goes_to_templates( api_user_active, ): api_user_active["permissions"] = { - "foo": ["manage_users", "manage_templates", "manage_settings"] + "foo": ["manage_users", "manage_templates", ServicePermission.MANAGE_SETTINGS] } api_user_active["services"] = ["foo", "bar"] client_request.login(api_user_active) diff --git a/tests/app/utils/test_user_permissions.py b/tests/app/utils/test_user_permissions.py index 402ef8018..e4fd80364 100644 --- a/tests/app/utils/test_user_permissions.py +++ b/tests/app/utils/test_user_permissions.py @@ -16,7 +16,7 @@ from app.utils.user_permissions import ( ), ( [ - "send_texts", + ServicePermission.SEND_TEXTS, "send_emails", "manage_templates", "some_unknown_permission", @@ -46,7 +46,7 @@ def test_translate_permissions_from_ui_to_db(): db_permissions = translate_permissions_from_ui_to_db(ui_permissions) assert db_permissions == { - "send_texts", + ServicePermission.SEND_TEXTS, "send_emails", "manage_templates", "some_unknown_permission", diff --git a/tests/conftest.py b/tests/conftest.py index c1bfbb7ef..3d911c726 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -13,6 +13,7 @@ from dotenv import load_dotenv from flask import Flask, url_for from app import create_app +from app.enums import AuthType, ServicePermission from notifications_python_client.errors import HTTPError from notifications_utils.url_safe_token import generate_token @@ -1021,7 +1022,7 @@ def platform_admin_user(fake_uuid): "send_emails", "manage_users", "manage_templates", - "manage_settings", + ServicePermission.MANAGE_SETTINGS, "manage_api_keys", "view_activity", ] @@ -1045,7 +1046,7 @@ def api_user_active(): @pytest.fixture def api_user_active_email_auth(fake_uuid): - return create_user(id=fake_uuid, auth_type="email_auth") + return create_user(id=fake_uuid, auth_type=AuthType.EMAIL_AUTH) @pytest.fixture @@ -1081,7 +1082,7 @@ def active_user_with_permission_to_two_services(fake_uuid): "send_emails", "manage_users", "manage_templates", - "manage_settings", + ServicePermission.MANAGE_SETTINGS, "manage_api_keys", "view_activity", ] @@ -3188,7 +3189,7 @@ def create_active_user_no_api_key_permission(with_unique_id=False): permissions={ SERVICE_ONE_ID: [ "manage_templates", - "manage_settings", + ServicePermission.MANAGE_SETTINGS, "manage_users", "view_activity", ] @@ -3241,7 +3242,7 @@ def create_service_one_admin(**overrides): "send_emails", "manage_users", "manage_templates", - "manage_settings", + ServicePermission.MANAGE_SETTINGS, "manage_api_keys", "view_activity", ]