2023-08-14 15:32:22 -07:00
|
|
|
|
import json
|
2021-05-19 08:21:35 +01:00
|
|
|
|
import uuid
|
2020-02-18 14:48:23 +00:00
|
|
|
|
from datetime import datetime
|
2021-07-08 14:10:58 +01:00
|
|
|
|
from unittest import mock
|
2016-03-01 10:34:27 +00:00
|
|
|
|
|
2021-03-10 13:55:06 +00:00
|
|
|
|
import pytest
|
2022-05-03 12:11:37 +01:00
|
|
|
|
from flask import current_app
|
2016-06-16 10:43:41 +01:00
|
|
|
|
from freezegun import freeze_time
|
2016-03-01 10:34:27 +00:00
|
|
|
|
|
2023-08-25 08:10:33 -07:00
|
|
|
|
from app.dao.service_user_dao import dao_get_service_user, dao_update_service_user
|
2024-02-21 14:14:45 -05:00
|
|
|
|
from app.enums import AuthType, KeyType, NotificationType, PermissionType
|
2024-01-16 15:12:57 -05:00
|
|
|
|
from app.models import Notification, Permission, User
|
2021-03-10 13:55:06 +00:00
|
|
|
|
from tests.app.db import (
|
2023-07-10 11:06:29 -07:00
|
|
|
|
create_organization,
|
2021-03-10 13:55:06 +00:00
|
|
|
|
create_service,
|
|
|
|
|
|
create_template_folder,
|
|
|
|
|
|
create_user,
|
|
|
|
|
|
)
|
2016-01-11 15:07:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-10-30 11:53:55 +00:00
|
|
|
|
def test_get_user_list(admin_request, sample_service):
|
2016-01-11 15:07:13 +00:00
|
|
|
|
"""
|
|
|
|
|
|
Tests GET endpoint '/' to retrieve entire user list.
|
|
|
|
|
|
"""
|
2023-08-23 10:35:43 -07:00
|
|
|
|
json_resp = admin_request.get("user.get_user")
|
2017-10-30 11:53:55 +00:00
|
|
|
|
|
|
|
|
|
|
# it may have the notify user in the DB still :weary:
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert len(json_resp["data"]) >= 1
|
2017-02-16 17:44:04 +00:00
|
|
|
|
sample_user = sample_service.users[0]
|
2024-01-17 17:28:46 -05:00
|
|
|
|
expected_permissions = PermissionType.defaults()
|
2023-08-23 10:35:43 -07:00
|
|
|
|
fetched = next(x for x in json_resp["data"] if x["id"] == str(sample_user.id))
|
|
|
|
|
|
|
|
|
|
|
|
assert sample_user.name == fetched["name"]
|
|
|
|
|
|
assert sample_user.mobile_number == fetched["mobile_number"]
|
|
|
|
|
|
assert sample_user.email_address == fetched["email_address"]
|
|
|
|
|
|
assert sample_user.state == fetched["state"]
|
|
|
|
|
|
assert sorted(expected_permissions) == sorted(
|
|
|
|
|
|
fetched["permissions"][str(sample_service.id)]
|
|
|
|
|
|
)
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-14 15:32:22 -07:00
|
|
|
|
def test_get_all_users(admin_request):
|
|
|
|
|
|
create_user()
|
2023-08-23 10:35:43 -07:00
|
|
|
|
json_resp = admin_request.get("user.get_all_users")
|
2023-08-14 15:32:22 -07:00
|
|
|
|
json_resp_str = json.dumps(json_resp)
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert "Test User" in json_resp_str
|
|
|
|
|
|
assert "+12028675309" in json_resp_str
|
2023-08-14 15:32:22 -07:00
|
|
|
|
|
|
|
|
|
|
|
2023-07-10 11:06:29 -07:00
|
|
|
|
def test_get_user(admin_request, sample_service, sample_organization):
|
2016-01-11 15:07:13 +00:00
|
|
|
|
"""
|
|
|
|
|
|
Tests GET endpoint '/<user_id>' to retrieve a single service.
|
|
|
|
|
|
"""
|
2017-02-16 17:44:04 +00:00
|
|
|
|
sample_user = sample_service.users[0]
|
2023-07-10 11:06:29 -07:00
|
|
|
|
sample_user.organizations = [sample_organization]
|
2023-08-23 10:35:43 -07:00
|
|
|
|
json_resp = admin_request.get("user.get_user", user_id=sample_user.id)
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
2024-01-17 17:28:46 -05:00
|
|
|
|
expected_permissions = PermissionType.defaults()
|
2023-08-23 10:35:43 -07:00
|
|
|
|
fetched = json_resp["data"]
|
|
|
|
|
|
|
|
|
|
|
|
assert fetched["id"] == str(sample_user.id)
|
|
|
|
|
|
assert fetched["name"] == sample_user.name
|
|
|
|
|
|
assert fetched["mobile_number"] == sample_user.mobile_number
|
|
|
|
|
|
assert fetched["email_address"] == sample_user.email_address
|
|
|
|
|
|
assert fetched["state"] == sample_user.state
|
2024-01-16 15:12:57 -05:00
|
|
|
|
assert fetched["auth_type"] == AuthType.SMS
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert fetched["permissions"].keys() == {str(sample_service.id)}
|
|
|
|
|
|
assert fetched["services"] == [str(sample_service.id)]
|
|
|
|
|
|
assert fetched["organizations"] == [str(sample_organization.id)]
|
|
|
|
|
|
assert fetched["can_use_webauthn"] is False
|
|
|
|
|
|
assert sorted(fetched["permissions"][str(sample_service.id)]) == sorted(
|
|
|
|
|
|
expected_permissions
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_get_user_doesnt_return_inactive_services_and_orgs(
|
|
|
|
|
|
admin_request, sample_service, sample_organization
|
|
|
|
|
|
):
|
2018-03-06 17:47:29 +00:00
|
|
|
|
"""
|
|
|
|
|
|
Tests GET endpoint '/<user_id>' to retrieve a single service.
|
|
|
|
|
|
"""
|
|
|
|
|
|
sample_service.active = False
|
2023-07-10 11:06:29 -07:00
|
|
|
|
sample_organization.active = False
|
2018-03-06 17:47:29 +00:00
|
|
|
|
|
|
|
|
|
|
sample_user = sample_service.users[0]
|
2023-07-10 11:06:29 -07:00
|
|
|
|
sample_user.organizations = [sample_organization]
|
2018-03-06 17:47:29 +00:00
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
json_resp = admin_request.get("user.get_user", user_id=sample_user.id)
|
2018-03-06 17:47:29 +00:00
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
fetched = json_resp["data"]
|
2018-03-06 17:47:29 +00:00
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert fetched["id"] == str(sample_user.id)
|
|
|
|
|
|
assert fetched["services"] == []
|
|
|
|
|
|
assert fetched["organizations"] == []
|
|
|
|
|
|
assert fetched["permissions"] == {}
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_post_user(admin_request, notify_db_session):
|
2016-01-11 15:07:13 +00:00
|
|
|
|
"""
|
|
|
|
|
|
Tests POST endpoint '/' to create a user.
|
|
|
|
|
|
"""
|
2022-05-03 12:11:37 +01:00
|
|
|
|
User.query.delete()
|
2017-02-16 17:44:04 +00:00
|
|
|
|
data = {
|
|
|
|
|
|
"name": "Test User",
|
2023-08-16 07:19:18 -07:00
|
|
|
|
"email_address": "user@digital.fake.gov",
|
2017-02-16 17:44:04 +00:00
|
|
|
|
"password": "password",
|
2023-01-04 16:35:25 -05:00
|
|
|
|
"mobile_number": "+12028675309",
|
2017-02-16 17:44:04 +00:00
|
|
|
|
"logged_in_at": None,
|
|
|
|
|
|
"state": "active",
|
|
|
|
|
|
"failed_login_count": 0,
|
2017-10-30 11:53:55 +00:00
|
|
|
|
"permissions": {},
|
2024-01-16 15:12:57 -05:00
|
|
|
|
"auth_type": AuthType.EMAIL,
|
2017-02-16 17:44:04 +00:00
|
|
|
|
}
|
2023-08-23 10:35:43 -07:00
|
|
|
|
json_resp = admin_request.post("user.create_user", _data=data, _expected_status=201)
|
2022-05-03 12:11:37 +01:00
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
user = User.query.filter_by(email_address="user@digital.fake.gov").first()
|
2022-05-06 15:25:14 +01:00
|
|
|
|
assert user.check_password("password")
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert json_resp["data"]["email_address"] == user.email_address
|
|
|
|
|
|
assert json_resp["data"]["id"] == str(user.id)
|
2024-01-16 15:12:57 -05:00
|
|
|
|
assert user.auth_type == AuthType.EMAIL
|
2017-10-30 11:53:55 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_post_user_without_auth_type(admin_request, notify_db_session):
|
2022-05-03 12:11:37 +01:00
|
|
|
|
User.query.delete()
|
2017-10-30 11:53:55 +00:00
|
|
|
|
data = {
|
|
|
|
|
|
"name": "Test User",
|
2023-08-16 07:19:18 -07:00
|
|
|
|
"email_address": "user@digital.fake.gov",
|
2017-10-30 11:53:55 +00:00
|
|
|
|
"password": "password",
|
2023-01-04 16:35:25 -05:00
|
|
|
|
"mobile_number": "+12028675309",
|
2017-10-30 11:53:55 +00:00
|
|
|
|
"permissions": {},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
json_resp = admin_request.post("user.create_user", _data=data, _expected_status=201)
|
2017-10-30 11:53:55 +00:00
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
user = User.query.filter_by(email_address="user@digital.fake.gov").first()
|
|
|
|
|
|
assert json_resp["data"]["id"] == str(user.id)
|
2024-01-16 15:12:57 -05:00
|
|
|
|
assert user.auth_type == AuthType.SMS
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_post_user_missing_attribute_email(admin_request, notify_db_session):
|
2016-01-11 18:09:10 +00:00
|
|
|
|
"""
|
|
|
|
|
|
Tests POST endpoint '/' missing attribute email.
|
|
|
|
|
|
"""
|
2022-05-03 12:11:37 +01:00
|
|
|
|
User.query.delete()
|
2017-02-16 17:44:04 +00:00
|
|
|
|
data = {
|
|
|
|
|
|
"name": "Test User",
|
|
|
|
|
|
"password": "password",
|
2023-01-04 16:35:25 -05:00
|
|
|
|
"mobile_number": "+12028675309",
|
2017-02-16 17:44:04 +00:00
|
|
|
|
"logged_in_at": None,
|
|
|
|
|
|
"state": "active",
|
|
|
|
|
|
"failed_login_count": 0,
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"permissions": {},
|
2017-02-16 17:44:04 +00:00
|
|
|
|
}
|
2023-08-23 10:35:43 -07:00
|
|
|
|
json_resp = admin_request.post("user.create_user", _data=data, _expected_status=400)
|
2022-05-03 12:11:37 +01:00
|
|
|
|
|
2017-02-16 17:44:04 +00:00
|
|
|
|
assert User.query.count() == 0
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert {"email_address": ["Missing data for required field."]} == json_resp[
|
|
|
|
|
|
"message"
|
|
|
|
|
|
]
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_create_user_missing_attribute_password(admin_request, notify_db_session):
|
2016-01-19 11:38:29 +00:00
|
|
|
|
"""
|
|
|
|
|
|
Tests POST endpoint '/' missing attribute password.
|
|
|
|
|
|
"""
|
2022-05-03 12:11:37 +01:00
|
|
|
|
User.query.delete()
|
2017-02-16 17:44:04 +00:00
|
|
|
|
data = {
|
|
|
|
|
|
"name": "Test User",
|
2023-08-16 07:19:18 -07:00
|
|
|
|
"email_address": "user@digital.fake.gov",
|
2023-01-04 16:35:25 -05:00
|
|
|
|
"mobile_number": "+12028675309",
|
2017-02-16 17:44:04 +00:00
|
|
|
|
"logged_in_at": None,
|
|
|
|
|
|
"state": "active",
|
|
|
|
|
|
"failed_login_count": 0,
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"permissions": {},
|
2017-02-16 17:44:04 +00:00
|
|
|
|
}
|
2023-08-23 10:35:43 -07:00
|
|
|
|
json_resp = admin_request.post("user.create_user", _data=data, _expected_status=400)
|
2017-02-16 17:44:04 +00:00
|
|
|
|
assert User.query.count() == 0
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert {"password": ["Missing data for required field."]} == json_resp["message"]
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_can_create_user_with_email_auth_and_no_mobile(
|
|
|
|
|
|
admin_request, notify_db_session
|
|
|
|
|
|
):
|
2017-11-09 14:18:47 +00:00
|
|
|
|
data = {
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"name": "Test User",
|
|
|
|
|
|
"email_address": "user@digital.fake.gov",
|
|
|
|
|
|
"password": "password",
|
|
|
|
|
|
"mobile_number": None,
|
2024-01-16 15:12:57 -05:00
|
|
|
|
"auth_type": AuthType.EMAIL,
|
2017-11-09 14:18:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
json_resp = admin_request.post("user.create_user", _data=data, _expected_status=201)
|
2017-11-09 14:18:47 +00:00
|
|
|
|
|
2024-01-16 15:12:57 -05:00
|
|
|
|
assert json_resp["data"]["auth_type"] == AuthType.EMAIL
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert json_resp["data"]["mobile_number"] is None
|
2017-11-09 14:18:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_cannot_create_user_with_sms_auth_and_no_mobile(
|
|
|
|
|
|
admin_request, notify_db_session
|
|
|
|
|
|
):
|
2017-11-09 14:18:47 +00:00
|
|
|
|
data = {
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"name": "Test User",
|
|
|
|
|
|
"email_address": "user@digital.fake.gov",
|
|
|
|
|
|
"password": "password",
|
|
|
|
|
|
"mobile_number": None,
|
2024-01-16 15:12:57 -05:00
|
|
|
|
"auth_type": AuthType.SMS,
|
2017-11-09 14:18:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
json_resp = admin_request.post("user.create_user", _data=data, _expected_status=400)
|
2017-11-09 14:18:47 +00:00
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert (
|
|
|
|
|
|
json_resp["message"]
|
2024-01-29 16:09:27 -05:00
|
|
|
|
== "Mobile number must be set if auth_type is set to AuthType.SMS"
|
2023-08-23 10:35:43 -07:00
|
|
|
|
)
|
2017-11-09 14:18:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_cannot_create_user_with_empty_strings(admin_request, notify_db_session):
|
|
|
|
|
|
data = {
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"name": "",
|
|
|
|
|
|
"email_address": "",
|
|
|
|
|
|
"password": "password",
|
|
|
|
|
|
"mobile_number": "",
|
2024-01-16 15:12:57 -05:00
|
|
|
|
"auth_type": AuthType.EMAIL,
|
2017-11-09 14:18:47 +00:00
|
|
|
|
}
|
2023-08-23 10:35:43 -07:00
|
|
|
|
resp = admin_request.post("user.create_user", _data=data, _expected_status=400)
|
|
|
|
|
|
assert resp["message"] == {
|
|
|
|
|
|
"email_address": ["Not a valid email address"],
|
|
|
|
|
|
"mobile_number": [
|
|
|
|
|
|
"Invalid phone number: The string supplied did not seem to be a phone number."
|
|
|
|
|
|
],
|
|
|
|
|
|
"name": ["Invalid name"],
|
2017-11-09 14:18:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"user_attribute, user_value",
|
|
|
|
|
|
[
|
|
|
|
|
|
("name", "New User"),
|
|
|
|
|
|
("email_address", "newuser@mail.com"),
|
|
|
|
|
|
("mobile_number", "+4407700900460"),
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_post_user_attribute(admin_request, sample_user, user_attribute, user_value):
|
2016-11-07 17:42:23 +00:00
|
|
|
|
assert getattr(sample_user, user_attribute) != user_value
|
2023-08-23 10:35:43 -07:00
|
|
|
|
update_dict = {user_attribute: user_value}
|
2016-11-07 17:42:23 +00:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
json_resp = admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.update_user_attribute", user_id=sample_user.id, _data=update_dict
|
2022-05-03 12:11:37 +01:00
|
|
|
|
)
|
2016-11-07 17:42:23 +00:00
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert json_resp["data"][user_attribute] == user_value
|
2022-05-03 12:11:37 +01:00
|
|
|
|
assert getattr(sample_user, user_attribute) == user_value
|
2016-11-07 17:42:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"user_attribute, user_value, arguments",
|
|
|
|
|
|
[
|
|
|
|
|
|
("name", "New User", None),
|
|
|
|
|
|
(
|
|
|
|
|
|
"email_address",
|
|
|
|
|
|
"newuser@mail.com",
|
|
|
|
|
|
dict(
|
|
|
|
|
|
api_key_id=None,
|
2024-02-21 14:14:45 -05:00
|
|
|
|
key_type=KeyType.NORMAL,
|
2024-02-20 17:00:54 -05:00
|
|
|
|
notification_type=NotificationType.EMAIL,
|
2024-01-22 10:55:09 -08:00
|
|
|
|
personalisation={},
|
2023-08-23 10:35:43 -07:00
|
|
|
|
recipient="newuser@mail.com",
|
|
|
|
|
|
reply_to_text="notify@gov.uk",
|
|
|
|
|
|
service=mock.ANY,
|
|
|
|
|
|
template_id=uuid.UUID("c73f1d71-4049-46d5-a647-d013bdeca3f0"),
|
|
|
|
|
|
template_version=1,
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
"mobile_number",
|
|
|
|
|
|
"+4407700900460",
|
|
|
|
|
|
dict(
|
|
|
|
|
|
api_key_id=None,
|
2024-02-21 14:14:45 -05:00
|
|
|
|
key_type=KeyType.NORMAL,
|
2024-02-20 17:00:54 -05:00
|
|
|
|
notification_type=NotificationType.SMS,
|
2024-01-22 10:55:09 -08:00
|
|
|
|
personalisation={},
|
2023-08-23 10:35:43 -07:00
|
|
|
|
recipient="+4407700900460",
|
|
|
|
|
|
reply_to_text="testing",
|
|
|
|
|
|
service=mock.ANY,
|
|
|
|
|
|
template_id=uuid.UUID("8a31520f-4751-4789-8ea1-fe54496725eb"),
|
|
|
|
|
|
template_version=1,
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
2019-02-26 16:25:04 +00:00
|
|
|
|
def test_post_user_attribute_with_updated_by(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
admin_request,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
sample_user,
|
|
|
|
|
|
user_attribute,
|
|
|
|
|
|
user_value,
|
|
|
|
|
|
arguments,
|
|
|
|
|
|
team_member_email_edit_template,
|
|
|
|
|
|
team_member_mobile_edit_template,
|
2019-02-26 16:25:04 +00:00
|
|
|
|
):
|
2023-08-16 07:19:18 -07:00
|
|
|
|
updater = create_user(name="Service Manago", email="notify_manago@digital.fake.gov")
|
2019-02-26 16:25:04 +00:00
|
|
|
|
assert getattr(sample_user, user_attribute) != user_value
|
2023-08-23 10:35:43 -07:00
|
|
|
|
update_dict = {user_attribute: user_value, "updated_by": str(updater.id)}
|
|
|
|
|
|
mock_persist_notification = mocker.patch("app.user.rest.persist_notification")
|
|
|
|
|
|
mocker.patch("app.user.rest.send_notification_to_queue")
|
2022-05-03 12:11:37 +01:00
|
|
|
|
json_resp = admin_request.post(
|
2024-02-21 11:27:38 -05:00
|
|
|
|
"user.update_user_attribute",
|
|
|
|
|
|
user_id=sample_user.id,
|
|
|
|
|
|
_data=update_dict,
|
2022-05-03 12:11:37 +01:00
|
|
|
|
)
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert json_resp["data"][user_attribute] == user_value
|
2019-02-26 16:25:04 +00:00
|
|
|
|
if arguments:
|
|
|
|
|
|
mock_persist_notification.assert_called_once_with(**arguments)
|
|
|
|
|
|
else:
|
|
|
|
|
|
mock_persist_notification.assert_not_called()
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-02-17 09:52:04 +00:00
|
|
|
|
def test_post_user_attribute_with_updated_by_sends_notification_to_international_from_number(
|
2022-05-03 12:11:37 +01:00
|
|
|
|
admin_request, mocker, sample_user, team_member_mobile_edit_template
|
2021-02-17 09:52:04 +00:00
|
|
|
|
):
|
|
|
|
|
|
updater = create_user(name="Service Manago")
|
2023-08-23 10:35:43 -07:00
|
|
|
|
update_dict = {"mobile_number": "+601117224412", "updated_by": str(updater.id)}
|
|
|
|
|
|
mocker.patch("app.user.rest.send_notification_to_queue")
|
2021-02-17 09:52:04 +00:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
admin_request.post(
|
2024-02-21 11:27:38 -05:00
|
|
|
|
"user.update_user_attribute",
|
|
|
|
|
|
user_id=sample_user.id,
|
|
|
|
|
|
_data=update_dict,
|
2022-05-03 12:11:37 +01:00
|
|
|
|
)
|
2021-02-17 09:52:04 +00:00
|
|
|
|
|
|
|
|
|
|
notification = Notification.query.first()
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert (
|
|
|
|
|
|
notification.reply_to_text
|
|
|
|
|
|
== current_app.config["NOTIFY_INTERNATIONAL_SMS_SENDER"]
|
|
|
|
|
|
)
|
2021-02-17 09:52:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_archive_user(mocker, admin_request, sample_user):
|
2023-08-23 10:35:43 -07:00
|
|
|
|
archive_mock = mocker.patch("app.user.rest.dao_archive_user")
|
2019-05-21 15:59:23 +01:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
admin_request.post(
|
2024-02-21 11:27:38 -05:00
|
|
|
|
"user.archive_user",
|
|
|
|
|
|
user_id=sample_user.id,
|
|
|
|
|
|
_expected_status=204,
|
2019-05-21 15:59:23 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
archive_mock.assert_called_once_with(sample_user)
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_archive_user_when_user_does_not_exist_gives_404(
|
|
|
|
|
|
mocker, admin_request, fake_uuid, notify_db_session
|
|
|
|
|
|
):
|
|
|
|
|
|
archive_mock = mocker.patch("app.user.rest.dao_archive_user")
|
2019-05-21 15:59:23 +01:00
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
admin_request.post("user.archive_user", user_id=fake_uuid, _expected_status=404)
|
2019-05-21 15:59:23 +01:00
|
|
|
|
|
|
|
|
|
|
archive_mock.assert_not_called()
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_archive_user_when_user_cannot_be_archived(mocker, admin_request, sample_user):
|
2023-08-23 10:35:43 -07:00
|
|
|
|
mocker.patch("app.dao.users_dao.user_can_be_archived", return_value=False)
|
2019-05-21 15:59:23 +01:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
json_resp = admin_request.post(
|
2024-02-21 11:27:38 -05:00
|
|
|
|
"user.archive_user",
|
|
|
|
|
|
user_id=sample_user.id,
|
|
|
|
|
|
_expected_status=400,
|
2019-05-21 15:59:23 +01:00
|
|
|
|
)
|
|
|
|
|
|
msg = "User can’t be removed from a service - check all services have another team member with manage_settings"
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert json_resp["message"] == msg
|
2019-05-21 15:59:23 +01:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_get_user_by_email(admin_request, sample_service):
|
2017-02-16 17:44:04 +00:00
|
|
|
|
sample_user = sample_service.users[0]
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
json_resp = admin_request.get("user.get_by_email", email=sample_user.email_address)
|
2022-05-03 12:11:37 +01:00
|
|
|
|
|
2024-01-17 17:28:46 -05:00
|
|
|
|
expected_permissions = PermissionType.defaults()
|
2023-08-23 10:35:43 -07:00
|
|
|
|
fetched = json_resp["data"]
|
|
|
|
|
|
|
|
|
|
|
|
assert str(sample_user.id) == fetched["id"]
|
|
|
|
|
|
assert sample_user.name == fetched["name"]
|
|
|
|
|
|
assert sample_user.mobile_number == fetched["mobile_number"]
|
|
|
|
|
|
assert sample_user.email_address == fetched["email_address"]
|
|
|
|
|
|
assert sample_user.state == fetched["state"]
|
|
|
|
|
|
assert sorted(expected_permissions) == sorted(
|
|
|
|
|
|
fetched["permissions"][str(sample_service.id)]
|
|
|
|
|
|
)
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_get_user_by_email_not_found_returns_404(admin_request, sample_user):
|
|
|
|
|
|
json_resp = admin_request.get(
|
2024-02-21 11:27:38 -05:00
|
|
|
|
"user.get_by_email",
|
|
|
|
|
|
email="no_user@digital.fake.gov",
|
|
|
|
|
|
_expected_status=404,
|
2022-05-03 12:11:37 +01:00
|
|
|
|
)
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert json_resp["result"] == "error"
|
|
|
|
|
|
assert json_resp["message"] == "No result found"
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_get_user_by_email_bad_url_returns_404(admin_request, sample_user):
|
2023-08-23 10:35:43 -07:00
|
|
|
|
json_resp = admin_request.get("user.get_by_email", _expected_status=400)
|
|
|
|
|
|
assert json_resp["result"] == "error"
|
|
|
|
|
|
assert json_resp["message"] == "Invalid request. Email query string param required"
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
2021-03-05 12:38:14 +00:00
|
|
|
|
def test_fetch_user_by_email(admin_request, notify_db_session):
|
2023-08-23 10:35:43 -07:00
|
|
|
|
user = create_user(email="foo@bar.com")
|
2021-03-05 12:38:14 +00:00
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
create_user(email="foo@bar.com.other_email")
|
|
|
|
|
|
create_user(email="other_email.foo@bar.com")
|
2021-03-05 12:38:14 +00:00
|
|
|
|
|
|
|
|
|
|
resp = admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.fetch_user_by_email",
|
|
|
|
|
|
_data={"email": user.email_address},
|
|
|
|
|
|
_expected_status=200,
|
2021-03-05 12:38:14 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert resp["data"]["id"] == str(user.id)
|
|
|
|
|
|
assert resp["data"]["email_address"] == user.email_address
|
2021-03-05 12:38:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_fetch_user_by_email_not_found_returns_404(admin_request, notify_db_session):
|
2023-08-23 10:35:43 -07:00
|
|
|
|
create_user(email="foo@bar.com.other_email")
|
2021-03-05 12:38:14 +00:00
|
|
|
|
|
|
|
|
|
|
resp = admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.fetch_user_by_email",
|
|
|
|
|
|
_data={"email": "doesnt@exist.com"},
|
|
|
|
|
|
_expected_status=404,
|
2021-03-05 12:38:14 +00:00
|
|
|
|
)
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert resp["result"] == "error"
|
|
|
|
|
|
assert resp["message"] == "No result found"
|
2021-03-05 12:38:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_fetch_user_by_email_without_email_returns_400(
|
|
|
|
|
|
admin_request, notify_db_session
|
|
|
|
|
|
):
|
2021-03-05 12:38:14 +00:00
|
|
|
|
resp = admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.fetch_user_by_email", _data={}, _expected_status=400
|
2021-03-05 12:38:14 +00:00
|
|
|
|
)
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert resp["result"] == "error"
|
|
|
|
|
|
assert resp["message"] == {"email": ["Missing data for required field."]}
|
2021-03-05 12:38:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_get_user_with_permissions(admin_request, sample_user_service_permission):
|
|
|
|
|
|
json_resp = admin_request.get(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.get_user",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
user_id=str(sample_user_service_permission.user.id),
|
|
|
|
|
|
)
|
2023-08-23 10:35:43 -07:00
|
|
|
|
permissions = json_resp["data"]["permissions"]
|
|
|
|
|
|
assert (
|
|
|
|
|
|
sample_user_service_permission.permission
|
|
|
|
|
|
in permissions[str(sample_user_service_permission.service.id)]
|
|
|
|
|
|
)
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_set_user_permissions(admin_request, sample_user, sample_service):
|
|
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.set_permissions",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
user_id=str(sample_user.id),
|
|
|
|
|
|
service_id=str(sample_service.id),
|
2024-02-08 17:15:03 -05:00
|
|
|
|
_data={"permissions": [{"permission": PermissionType.MANAGE_SETTINGS}]},
|
2022-05-03 12:11:37 +01:00
|
|
|
|
_expected_status=204,
|
|
|
|
|
|
)
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
2024-01-16 15:12:57 -05:00
|
|
|
|
permission = Permission.query.filter_by(
|
|
|
|
|
|
permission=PermissionType.MANAGE_SETTINGS
|
|
|
|
|
|
).first()
|
2017-02-16 17:44:04 +00:00
|
|
|
|
assert permission.user == sample_user
|
|
|
|
|
|
assert permission.service == sample_service
|
2024-01-16 15:12:57 -05:00
|
|
|
|
assert permission.permission == PermissionType.MANAGE_SETTINGS
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_set_user_permissions_multiple(admin_request, sample_user, sample_service):
|
2023-08-23 10:35:43 -07:00
|
|
|
|
data = {
|
|
|
|
|
|
"permissions": [
|
2024-01-16 15:12:57 -05:00
|
|
|
|
{"permission": PermissionType.MANAGE_SETTINGS},
|
|
|
|
|
|
{"permission": PermissionType.MANAGE_TEMPLATES},
|
2023-08-23 10:35:43 -07:00
|
|
|
|
]
|
|
|
|
|
|
}
|
2022-05-03 12:11:37 +01:00
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.set_permissions",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
user_id=str(sample_user.id),
|
|
|
|
|
|
service_id=str(sample_service.id),
|
|
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=204,
|
|
|
|
|
|
)
|
2019-02-21 14:48:24 +00:00
|
|
|
|
|
2024-01-16 15:12:57 -05:00
|
|
|
|
permission = Permission.query.filter_by(
|
|
|
|
|
|
permission=PermissionType.MANAGE_SETTINGS
|
|
|
|
|
|
).first()
|
2019-02-21 14:48:24 +00:00
|
|
|
|
assert permission.user == sample_user
|
|
|
|
|
|
assert permission.service == sample_service
|
2024-01-16 15:12:57 -05:00
|
|
|
|
assert permission.permission == PermissionType.MANAGE_SETTINGS
|
|
|
|
|
|
permission = Permission.query.filter_by(
|
|
|
|
|
|
permission=PermissionType.MANAGE_TEMPLATES
|
|
|
|
|
|
).first()
|
2019-02-21 14:48:24 +00:00
|
|
|
|
assert permission.user == sample_user
|
|
|
|
|
|
assert permission.service == sample_service
|
2024-01-16 15:12:57 -05:00
|
|
|
|
assert permission.permission == PermissionType.MANAGE_TEMPLATES
|
2019-02-21 14:48:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_set_user_permissions_remove_old(admin_request, sample_user, sample_service):
|
2024-01-16 15:12:57 -05:00
|
|
|
|
data = {"permissions": [{"permission": PermissionType.MANAGE_SETTINGS}]}
|
2022-05-03 12:11:37 +01:00
|
|
|
|
|
|
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.set_permissions",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
user_id=str(sample_user.id),
|
|
|
|
|
|
service_id=str(sample_service.id),
|
|
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=204,
|
|
|
|
|
|
)
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
2019-02-22 11:26:44 +00:00
|
|
|
|
query = Permission.query.filter_by(user=sample_user)
|
|
|
|
|
|
assert query.count() == 1
|
2024-01-16 15:12:57 -05:00
|
|
|
|
assert query.first().permission == PermissionType.MANAGE_SETTINGS
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_set_user_folder_permissions(admin_request, sample_user, sample_service):
|
2019-02-22 11:26:44 +00:00
|
|
|
|
tf1 = create_template_folder(sample_service)
|
|
|
|
|
|
tf2 = create_template_folder(sample_service)
|
2023-08-23 10:35:43 -07:00
|
|
|
|
data = {"permissions": [], "folder_permissions": [str(tf1.id), str(tf2.id)]}
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.set_permissions",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
user_id=str(sample_user.id),
|
|
|
|
|
|
service_id=str(sample_service.id),
|
|
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=204,
|
|
|
|
|
|
)
|
2019-02-22 11:26:44 +00:00
|
|
|
|
|
|
|
|
|
|
service_user = dao_get_service_user(sample_user.id, sample_service.id)
|
|
|
|
|
|
assert len(service_user.folders) == 2
|
|
|
|
|
|
assert tf1 in service_user.folders
|
|
|
|
|
|
assert tf2 in service_user.folders
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_set_user_folder_permissions_when_user_does_not_belong_to_service(
|
|
|
|
|
|
admin_request, sample_user
|
|
|
|
|
|
):
|
2019-02-22 11:26:44 +00:00
|
|
|
|
service = create_service()
|
|
|
|
|
|
tf1 = create_template_folder(service)
|
|
|
|
|
|
tf2 = create_template_folder(service)
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
data = {"permissions": [], "folder_permissions": [str(tf1.id), str(tf2.id)]}
|
2019-02-22 11:26:44 +00:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.set_permissions",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
user_id=str(sample_user.id),
|
|
|
|
|
|
service_id=str(service.id),
|
|
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=404,
|
|
|
|
|
|
)
|
2019-02-22 11:26:44 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_set_user_folder_permissions_does_not_affect_permissions_for_other_services(
|
2022-05-03 12:11:37 +01:00
|
|
|
|
admin_request,
|
2019-02-22 11:26:44 +00:00
|
|
|
|
sample_user,
|
|
|
|
|
|
sample_service,
|
|
|
|
|
|
):
|
|
|
|
|
|
tf1 = create_template_folder(sample_service)
|
|
|
|
|
|
tf2 = create_template_folder(sample_service)
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
service_2 = create_service(sample_user, service_name="other service")
|
2019-02-22 11:26:44 +00:00
|
|
|
|
tf3 = create_template_folder(service_2)
|
|
|
|
|
|
|
|
|
|
|
|
sample_service_user = dao_get_service_user(sample_user.id, sample_service.id)
|
|
|
|
|
|
sample_service_user.folders = [tf1]
|
|
|
|
|
|
dao_update_service_user(sample_service_user)
|
|
|
|
|
|
|
|
|
|
|
|
service_2_user = dao_get_service_user(sample_user.id, service_2.id)
|
|
|
|
|
|
service_2_user.folders = [tf3]
|
|
|
|
|
|
dao_update_service_user(service_2_user)
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
data = {"permissions": [], "folder_permissions": [str(tf2.id)]}
|
2019-02-22 11:26:44 +00:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.set_permissions",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
user_id=str(sample_user.id),
|
|
|
|
|
|
service_id=str(sample_service.id),
|
|
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=204,
|
|
|
|
|
|
)
|
2019-02-22 11:26:44 +00:00
|
|
|
|
|
|
|
|
|
|
assert sample_service_user.folders == [tf2]
|
|
|
|
|
|
assert service_2_user.folders == [tf3]
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_update_user_folder_permissions(admin_request, sample_user, sample_service):
|
2019-02-22 11:26:44 +00:00
|
|
|
|
tf1 = create_template_folder(sample_service)
|
|
|
|
|
|
tf2 = create_template_folder(sample_service)
|
|
|
|
|
|
tf3 = create_template_folder(sample_service)
|
|
|
|
|
|
|
|
|
|
|
|
service_user = dao_get_service_user(sample_user.id, sample_service.id)
|
|
|
|
|
|
service_user.folders = [tf1, tf2]
|
|
|
|
|
|
dao_update_service_user(service_user)
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
data = {"permissions": [], "folder_permissions": [str(tf2.id), str(tf3.id)]}
|
2019-02-22 11:26:44 +00:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.set_permissions",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
user_id=str(sample_user.id),
|
|
|
|
|
|
service_id=str(sample_service.id),
|
|
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=204,
|
|
|
|
|
|
)
|
2019-02-22 11:26:44 +00:00
|
|
|
|
|
|
|
|
|
|
assert len(service_user.folders) == 2
|
|
|
|
|
|
assert tf2 in service_user.folders
|
|
|
|
|
|
assert tf3 in service_user.folders
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_remove_user_folder_permissions(admin_request, sample_user, sample_service):
|
2019-02-22 11:26:44 +00:00
|
|
|
|
tf1 = create_template_folder(sample_service)
|
|
|
|
|
|
tf2 = create_template_folder(sample_service)
|
|
|
|
|
|
|
|
|
|
|
|
service_user = dao_get_service_user(sample_user.id, sample_service.id)
|
|
|
|
|
|
service_user.folders = [tf1, tf2]
|
|
|
|
|
|
dao_update_service_user(service_user)
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
data = {"permissions": [], "folder_permissions": []}
|
2019-02-22 11:26:44 +00:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.set_permissions",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
user_id=str(sample_user.id),
|
|
|
|
|
|
service_id=str(sample_service.id),
|
|
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=204,
|
|
|
|
|
|
)
|
2019-02-22 11:26:44 +00:00
|
|
|
|
|
|
|
|
|
|
assert service_user.folders == []
|
2016-03-07 14:34:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-06-16 10:43:41 +01:00
|
|
|
|
@freeze_time("2016-01-01 11:09:00.061258")
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_send_user_reset_password_should_send_reset_password_link(
|
|
|
|
|
|
admin_request, sample_user, mocker, password_reset_email_template
|
|
|
|
|
|
):
|
|
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
|
|
|
|
|
data = {"email": sample_user.email_address}
|
2017-11-27 14:36:54 +00:00
|
|
|
|
notify_service = password_reset_email_template.service
|
2016-03-07 14:34:53 +00:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.send_user_reset_password",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=204,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2016-12-20 11:55:26 +00:00
|
|
|
|
notification = Notification.query.first()
|
2023-08-23 10:35:43 -07:00
|
|
|
|
mocked.assert_called_once_with(
|
|
|
|
|
|
[str(notification.id)], queue="notify-internal-tasks"
|
|
|
|
|
|
)
|
|
|
|
|
|
assert (
|
|
|
|
|
|
notification.reply_to_text
|
|
|
|
|
|
== notify_service.get_default_reply_to_email_address()
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"data, expected_url",
|
|
|
|
|
|
(
|
|
|
|
|
|
(
|
|
|
|
|
|
{
|
|
|
|
|
|
"email": "notify@digital.fake.gov",
|
|
|
|
|
|
},
|
|
|
|
|
|
("http://localhost:6012/new-password/"),
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
{
|
|
|
|
|
|
"email": "notify@digital.fake.gov",
|
|
|
|
|
|
"admin_base_url": "https://different.example.com",
|
|
|
|
|
|
},
|
|
|
|
|
|
("https://different.example.com/new-password/"),
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
)
|
2022-02-02 16:42:55 +00:00
|
|
|
|
@freeze_time("2016-01-01 11:09:00.061258")
|
|
|
|
|
|
def test_send_user_reset_password_should_use_provided_base_url(
|
|
|
|
|
|
admin_request,
|
|
|
|
|
|
sample_user,
|
|
|
|
|
|
password_reset_email_template,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
data,
|
|
|
|
|
|
expected_url,
|
|
|
|
|
|
):
|
2023-08-23 10:35:43 -07:00
|
|
|
|
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
2022-02-02 16:42:55 +00:00
|
|
|
|
|
|
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.send_user_reset_password",
|
2022-02-02 16:42:55 +00:00
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=204,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert Notification.query.first().personalisation["url"].startswith(expected_url)
|
2022-02-02 16:42:55 +00:00
|
|
|
|
|
|
|
|
|
|
|
2020-10-05 16:49:50 +01:00
|
|
|
|
@freeze_time("2016-01-01 11:09:00.061258")
|
|
|
|
|
|
def test_send_user_reset_password_reset_password_link_contains_redirect_link_if_present_in_request(
|
2022-05-03 12:11:37 +01:00
|
|
|
|
admin_request, sample_user, mocker, password_reset_email_template
|
2020-10-05 16:49:50 +01:00
|
|
|
|
):
|
2023-08-23 10:35:43 -07:00
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
|
|
|
|
|
data = {"email": sample_user.email_address, "next": "blob"}
|
2022-05-03 12:11:37 +01:00
|
|
|
|
|
|
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.send_user_reset_password",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=204,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2020-10-05 16:49:50 +01:00
|
|
|
|
notification = Notification.query.first()
|
|
|
|
|
|
assert "?next=blob" in notification.content
|
2023-08-23 10:35:43 -07:00
|
|
|
|
mocked.assert_called_once_with(
|
|
|
|
|
|
[str(notification.id)], queue="notify-internal-tasks"
|
|
|
|
|
|
)
|
2020-10-05 16:49:50 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_send_user_reset_password_should_return_400_when_email_is_missing(
|
|
|
|
|
|
admin_request, mocker
|
|
|
|
|
|
):
|
|
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
2022-05-03 12:11:37 +01:00
|
|
|
|
data = {}
|
2016-07-08 10:57:20 +01:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
json_resp = admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.send_user_reset_password",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=400,
|
|
|
|
|
|
)
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert json_resp["message"] == {"email": ["Missing data for required field."]}
|
2016-12-20 11:55:26 +00:00
|
|
|
|
assert mocked.call_count == 0
|
2016-07-08 10:57:20 +01:00
|
|
|
|
|
2016-12-20 11:55:26 +00:00
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_send_user_reset_password_should_return_400_when_user_doesnot_exist(
|
|
|
|
|
|
admin_request, mocker
|
|
|
|
|
|
):
|
|
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
|
|
|
|
|
bad_email_address = "bad@email.gov.uk"
|
|
|
|
|
|
data = {"email": bad_email_address}
|
2016-03-07 14:34:53 +00:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
json_resp = admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.send_user_reset_password",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=404,
|
|
|
|
|
|
)
|
2016-03-07 14:34:53 +00:00
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert json_resp["message"] == "No result found"
|
2016-12-20 11:55:26 +00:00
|
|
|
|
assert mocked.call_count == 0
|
2016-03-07 15:21:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_send_user_reset_password_should_return_400_when_data_is_not_email_address(
|
|
|
|
|
|
admin_request, mocker
|
|
|
|
|
|
):
|
|
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
|
|
|
|
|
bad_email_address = "bad.email.gov.uk"
|
|
|
|
|
|
data = {"email": bad_email_address}
|
2016-03-07 15:21:05 +00:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
json_resp = admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.send_user_reset_password",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=400,
|
|
|
|
|
|
)
|
2016-03-07 15:21:05 +00:00
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert json_resp["message"] == {"email": ["Not a valid email address"]}
|
2016-12-20 11:55:26 +00:00
|
|
|
|
assert mocked.call_count == 0
|
2016-07-07 17:23:07 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_send_already_registered_email(
|
|
|
|
|
|
admin_request, sample_user, already_registered_template, mocker
|
|
|
|
|
|
):
|
|
|
|
|
|
data = {"email": sample_user.email_address}
|
|
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
2017-11-27 14:36:54 +00:00
|
|
|
|
notify_service = already_registered_template.service
|
2016-07-07 17:23:07 +01:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.send_already_registered_email",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
user_id=str(sample_user.id),
|
|
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=204,
|
|
|
|
|
|
)
|
2016-07-08 10:57:20 +01:00
|
|
|
|
|
2016-12-19 17:35:13 +00:00
|
|
|
|
notification = Notification.query.first()
|
2023-08-23 10:35:43 -07:00
|
|
|
|
mocked.assert_called_once_with(
|
|
|
|
|
|
([str(notification.id)]), queue="notify-internal-tasks"
|
|
|
|
|
|
)
|
|
|
|
|
|
assert (
|
|
|
|
|
|
notification.reply_to_text
|
|
|
|
|
|
== notify_service.get_default_reply_to_email_address()
|
|
|
|
|
|
)
|
2016-07-08 10:57:20 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_send_already_registered_email_returns_400_when_data_is_missing(
|
|
|
|
|
|
admin_request, sample_user
|
|
|
|
|
|
):
|
2022-05-03 12:11:37 +01:00
|
|
|
|
data = {}
|
2017-02-16 17:44:04 +00:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
json_resp = admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.send_already_registered_email",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
user_id=str(sample_user.id),
|
|
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=400,
|
|
|
|
|
|
)
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert json_resp["message"] == {"email": ["Missing data for required field."]}
|
2016-10-12 13:06:39 +01:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_send_user_confirm_new_email_returns_204(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
admin_request, sample_user, change_email_confirmation_template, mocker
|
2022-05-03 12:11:37 +01:00
|
|
|
|
):
|
2023-08-23 10:35:43 -07:00
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
|
|
|
|
|
new_email = "new_address@dig.gov.uk"
|
|
|
|
|
|
data = {"email": new_email}
|
2017-11-27 14:36:54 +00:00
|
|
|
|
notify_service = change_email_confirmation_template.service
|
2016-12-19 15:19:05 +00:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.send_user_confirm_new_email",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
user_id=str(sample_user.id),
|
|
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=204,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2016-12-19 15:33:30 +00:00
|
|
|
|
notification = Notification.query.first()
|
|
|
|
|
|
mocked.assert_called_once_with(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
([str(notification.id)]), queue="notify-internal-tasks"
|
|
|
|
|
|
)
|
|
|
|
|
|
assert (
|
|
|
|
|
|
notification.reply_to_text
|
|
|
|
|
|
== notify_service.get_default_reply_to_email_address()
|
|
|
|
|
|
)
|
2016-12-19 15:19:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_send_user_confirm_new_email_returns_400_when_email_missing(
|
|
|
|
|
|
admin_request, sample_user, mocker
|
|
|
|
|
|
):
|
|
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
2022-05-03 12:11:37 +01:00
|
|
|
|
data = {}
|
|
|
|
|
|
|
|
|
|
|
|
json_resp = admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.send_user_confirm_new_email",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
user_id=str(sample_user.id),
|
|
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=400,
|
|
|
|
|
|
)
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert json_resp["message"] == {"email": ["Missing data for required field."]}
|
2016-12-19 15:33:30 +00:00
|
|
|
|
mocked.assert_not_called()
|
2017-02-07 11:27:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
@freeze_time("2020-02-14T12:00:00")
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_update_user_password_saves_correctly(admin_request, sample_service):
|
2017-02-07 11:27:13 +00:00
|
|
|
|
sample_user = sample_service.users[0]
|
2023-08-23 10:35:43 -07:00
|
|
|
|
new_password = "1234567890"
|
|
|
|
|
|
data = {"_password": "1234567890"}
|
2017-02-16 15:20:30 +00:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
json_resp = admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.update_password", user_id=str(sample_user.id), _data=data
|
2022-05-03 12:11:37 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert json_resp["data"]["password_changed_at"] is not None
|
|
|
|
|
|
data = {"password": new_password}
|
2022-05-03 12:11:37 +01:00
|
|
|
|
|
|
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.verify_user_password",
|
2022-05-03 12:11:37 +01:00
|
|
|
|
user_id=str(sample_user.id),
|
|
|
|
|
|
_data=data,
|
2023-08-23 10:35:43 -07:00
|
|
|
|
_expected_status=204,
|
2022-05-03 12:11:37 +01:00
|
|
|
|
)
|
2017-02-16 15:20:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-11-09 14:18:47 +00:00
|
|
|
|
def test_activate_user(admin_request, sample_user):
|
2023-08-23 10:35:43 -07:00
|
|
|
|
sample_user.state = "pending"
|
2017-11-09 14:18:47 +00:00
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
resp = admin_request.post("user.activate_user", user_id=sample_user.id)
|
2017-11-09 14:18:47 +00:00
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert resp["data"]["id"] == str(sample_user.id)
|
|
|
|
|
|
assert resp["data"]["state"] == "active"
|
|
|
|
|
|
assert sample_user.state == "active"
|
2017-11-09 14:18:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_activate_user_fails_if_already_active(admin_request, sample_user):
|
2023-08-23 10:35:43 -07:00
|
|
|
|
resp = admin_request.post(
|
|
|
|
|
|
"user.activate_user", user_id=sample_user.id, _expected_status=400
|
|
|
|
|
|
)
|
|
|
|
|
|
assert resp["message"] == "User already active"
|
|
|
|
|
|
assert sample_user.state == "active"
|
2017-11-09 14:18:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-10-31 10:36:53 +00:00
|
|
|
|
def test_update_user_auth_type(admin_request, sample_user):
|
2024-01-29 16:09:27 -05:00
|
|
|
|
assert sample_user.auth_type == AuthType.SMS
|
2017-10-31 10:36:53 +00:00
|
|
|
|
resp = admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.update_user_attribute",
|
2017-10-31 10:36:53 +00:00
|
|
|
|
user_id=sample_user.id,
|
2024-01-29 16:09:27 -05:00
|
|
|
|
_data={"auth_type": AuthType.EMAIL},
|
2017-10-31 10:36:53 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert resp["data"]["id"] == str(sample_user.id)
|
2024-01-29 16:09:27 -05:00
|
|
|
|
assert resp["data"]["auth_type"] == AuthType.EMAIL
|
2017-11-09 14:27:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-11-09 14:18:47 +00:00
|
|
|
|
def test_can_set_email_auth_and_remove_mobile_at_same_time(admin_request, sample_user):
|
2024-01-16 15:12:57 -05:00
|
|
|
|
sample_user.auth_type = AuthType.SMS
|
2017-11-09 14:27:24 +00:00
|
|
|
|
|
2017-11-09 14:18:47 +00:00
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.update_user_attribute",
|
2017-11-09 14:18:47 +00:00
|
|
|
|
user_id=sample_user.id,
|
|
|
|
|
|
_data={
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"mobile_number": None,
|
2024-01-16 15:12:57 -05:00
|
|
|
|
"auth_type": AuthType.EMAIL,
|
2023-08-23 10:35:43 -07:00
|
|
|
|
},
|
2017-11-09 14:18:47 +00:00
|
|
|
|
)
|
2017-11-09 14:27:24 +00:00
|
|
|
|
|
2017-11-09 14:18:47 +00:00
|
|
|
|
assert sample_user.mobile_number is None
|
2024-01-16 15:12:57 -05:00
|
|
|
|
assert sample_user.auth_type == AuthType.EMAIL
|
2017-11-09 14:27:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-11-09 14:18:47 +00:00
|
|
|
|
def test_cannot_remove_mobile_if_sms_auth(admin_request, sample_user):
|
2024-01-16 15:12:57 -05:00
|
|
|
|
sample_user.auth_type = AuthType.SMS
|
2017-11-09 14:18:47 +00:00
|
|
|
|
|
|
|
|
|
|
json_resp = admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.update_user_attribute",
|
2017-11-09 14:18:47 +00:00
|
|
|
|
user_id=sample_user.id,
|
2023-08-23 10:35:43 -07:00
|
|
|
|
_data={"mobile_number": None},
|
|
|
|
|
|
_expected_status=400,
|
2017-11-09 14:18:47 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert (
|
|
|
|
|
|
json_resp["message"]
|
2024-01-29 16:09:27 -05:00
|
|
|
|
== "Mobile number must be set if auth_type is set to AuthType.SMS"
|
2023-08-23 10:35:43 -07:00
|
|
|
|
)
|
2017-11-09 14:18:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_can_remove_mobile_if_email_auth(admin_request, sample_user):
|
2024-01-16 15:12:57 -05:00
|
|
|
|
sample_user.auth_type = AuthType.EMAIL
|
2017-11-09 14:18:47 +00:00
|
|
|
|
|
|
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.update_user_attribute",
|
2017-11-09 14:18:47 +00:00
|
|
|
|
user_id=sample_user.id,
|
2023-08-23 10:35:43 -07:00
|
|
|
|
_data={"mobile_number": None},
|
2017-11-09 14:18:47 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
assert sample_user.mobile_number is None
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_cannot_update_user_with_mobile_number_as_empty_string(
|
|
|
|
|
|
admin_request, sample_user
|
|
|
|
|
|
):
|
2024-01-16 15:12:57 -05:00
|
|
|
|
sample_user.auth_type = AuthType.EMAIL
|
2017-11-09 14:18:47 +00:00
|
|
|
|
|
|
|
|
|
|
resp = admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.update_user_attribute",
|
2017-11-09 14:18:47 +00:00
|
|
|
|
user_id=sample_user.id,
|
2023-08-23 10:35:43 -07:00
|
|
|
|
_data={"mobile_number": ""},
|
|
|
|
|
|
_expected_status=400,
|
2017-11-09 14:18:47 +00:00
|
|
|
|
)
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert resp["message"]["mobile_number"] == [
|
|
|
|
|
|
"Invalid phone number: The string supplied did not seem to be a phone number."
|
|
|
|
|
|
]
|
2017-11-10 15:24:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_cannot_update_user_password_using_attributes_method(
|
|
|
|
|
|
admin_request, sample_user
|
|
|
|
|
|
):
|
2017-11-10 15:24:37 +00:00
|
|
|
|
resp = admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.update_user_attribute",
|
2017-11-10 15:24:37 +00:00
|
|
|
|
user_id=sample_user.id,
|
2023-08-23 10:35:43 -07:00
|
|
|
|
_data={"password": "foo"},
|
|
|
|
|
|
_expected_status=400,
|
2017-11-10 15:24:37 +00:00
|
|
|
|
)
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert resp == {
|
|
|
|
|
|
"message": {"_schema": ["Unknown field name password"]},
|
|
|
|
|
|
"result": "error",
|
|
|
|
|
|
}
|
2018-03-13 13:07:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_get_orgs_and_services_nests_services(admin_request, sample_user):
|
2023-08-23 10:35:43 -07:00
|
|
|
|
org1 = create_organization(name="org1")
|
|
|
|
|
|
org2 = create_organization(name="org2")
|
|
|
|
|
|
service1 = create_service(service_name="service1")
|
|
|
|
|
|
service2 = create_service(service_name="service2")
|
|
|
|
|
|
service3 = create_service(service_name="service3")
|
2018-03-13 13:07:02 +00:00
|
|
|
|
|
|
|
|
|
|
org1.services = [service1, service2]
|
|
|
|
|
|
org2.services = []
|
|
|
|
|
|
|
2023-07-10 11:06:29 -07:00
|
|
|
|
sample_user.organizations = [org1, org2]
|
2018-03-13 13:07:02 +00:00
|
|
|
|
sample_user.services = [service1, service2, service3]
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
resp = admin_request.get(
|
|
|
|
|
|
"user.get_organizations_and_services_for_user", user_id=sample_user.id
|
|
|
|
|
|
)
|
2018-03-13 13:07:02 +00:00
|
|
|
|
|
2019-06-12 10:34:15 +01:00
|
|
|
|
assert set(resp.keys()) == {
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"organizations",
|
|
|
|
|
|
"services",
|
2018-03-13 13:07:02 +00:00
|
|
|
|
}
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert resp["organizations"] == [
|
2019-06-12 10:34:15 +01:00
|
|
|
|
{
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"name": org1.name,
|
|
|
|
|
|
"id": str(org1.id),
|
|
|
|
|
|
"count_of_live_services": 2,
|
2019-06-12 10:34:15 +01:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"name": org2.name,
|
|
|
|
|
|
"id": str(org2.id),
|
|
|
|
|
|
"count_of_live_services": 0,
|
2019-06-12 10:34:15 +01:00
|
|
|
|
},
|
|
|
|
|
|
]
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert resp["services"] == [
|
2019-06-12 10:34:15 +01:00
|
|
|
|
{
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"name": service1.name,
|
|
|
|
|
|
"id": str(service1.id),
|
|
|
|
|
|
"restricted": False,
|
|
|
|
|
|
"organization": str(org1.id),
|
2019-06-12 10:34:15 +01:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"name": service2.name,
|
|
|
|
|
|
"id": str(service2.id),
|
|
|
|
|
|
"restricted": False,
|
|
|
|
|
|
"organization": str(org1.id),
|
2019-06-12 10:34:15 +01:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"name": service3.name,
|
|
|
|
|
|
"id": str(service3.id),
|
|
|
|
|
|
"restricted": False,
|
|
|
|
|
|
"organization": None,
|
2019-06-12 10:34:15 +01:00
|
|
|
|
},
|
|
|
|
|
|
]
|
2018-03-13 13:07:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_get_orgs_and_services_only_returns_active(admin_request, sample_user):
|
2023-08-23 10:35:43 -07:00
|
|
|
|
org1 = create_organization(name="org1", active=True)
|
|
|
|
|
|
org2 = create_organization(name="org2", active=False)
|
2018-03-13 13:07:02 +00:00
|
|
|
|
|
|
|
|
|
|
# in an active org
|
2023-08-23 10:35:43 -07:00
|
|
|
|
service1 = create_service(service_name="service1", active=True)
|
|
|
|
|
|
service2 = create_service(service_name="service2", active=False)
|
2018-03-13 13:07:02 +00:00
|
|
|
|
# active but in an inactive org
|
2023-08-23 10:35:43 -07:00
|
|
|
|
service3 = create_service(service_name="service3", active=True)
|
2018-03-13 13:07:02 +00:00
|
|
|
|
# not in an org
|
2023-08-23 10:35:43 -07:00
|
|
|
|
service4 = create_service(service_name="service4", active=True)
|
|
|
|
|
|
service5 = create_service(service_name="service5", active=False)
|
2018-03-13 13:07:02 +00:00
|
|
|
|
|
|
|
|
|
|
org1.services = [service1, service2]
|
|
|
|
|
|
org2.services = [service3]
|
|
|
|
|
|
|
2023-07-10 11:06:29 -07:00
|
|
|
|
sample_user.organizations = [org1, org2]
|
2018-03-13 13:07:02 +00:00
|
|
|
|
sample_user.services = [service1, service2, service3, service4, service5]
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
resp = admin_request.get(
|
|
|
|
|
|
"user.get_organizations_and_services_for_user", user_id=sample_user.id
|
|
|
|
|
|
)
|
2018-03-13 13:07:02 +00:00
|
|
|
|
|
2019-06-12 10:34:15 +01:00
|
|
|
|
assert set(resp.keys()) == {
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"organizations",
|
|
|
|
|
|
"services",
|
2018-03-13 13:07:02 +00:00
|
|
|
|
}
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert resp["organizations"] == [
|
2019-06-12 10:34:15 +01:00
|
|
|
|
{
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"name": org1.name,
|
|
|
|
|
|
"id": str(org1.id),
|
|
|
|
|
|
"count_of_live_services": 1,
|
2019-06-12 10:34:15 +01:00
|
|
|
|
}
|
|
|
|
|
|
]
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert resp["services"] == [
|
2019-06-12 10:34:15 +01:00
|
|
|
|
{
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"name": service1.name,
|
|
|
|
|
|
"id": str(service1.id),
|
|
|
|
|
|
"restricted": False,
|
|
|
|
|
|
"organization": str(org1.id),
|
2019-06-12 10:34:15 +01:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"name": service3.name,
|
|
|
|
|
|
"id": str(service3.id),
|
|
|
|
|
|
"restricted": False,
|
|
|
|
|
|
"organization": str(org2.id),
|
2019-06-12 10:34:15 +01:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"name": service4.name,
|
|
|
|
|
|
"id": str(service4.id),
|
|
|
|
|
|
"restricted": False,
|
|
|
|
|
|
"organization": None,
|
2019-06-12 10:34:15 +01:00
|
|
|
|
},
|
|
|
|
|
|
]
|
2018-03-13 13:07:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_get_orgs_and_services_only_shows_users_orgs_and_services(
|
|
|
|
|
|
admin_request, sample_user
|
|
|
|
|
|
):
|
|
|
|
|
|
other_user = create_user(email="other@user.com")
|
2018-03-13 13:07:02 +00:00
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
org1 = create_organization(name="org1")
|
|
|
|
|
|
org2 = create_organization(name="org2")
|
|
|
|
|
|
service1 = create_service(service_name="service1")
|
|
|
|
|
|
service2 = create_service(service_name="service2")
|
2018-03-13 13:07:02 +00:00
|
|
|
|
|
|
|
|
|
|
org1.services = [service1]
|
|
|
|
|
|
|
2023-07-10 11:06:29 -07:00
|
|
|
|
sample_user.organizations = [org2]
|
2018-03-13 13:07:02 +00:00
|
|
|
|
sample_user.services = [service1]
|
|
|
|
|
|
|
2023-07-10 11:06:29 -07:00
|
|
|
|
other_user.organizations = [org1, org2]
|
2018-03-13 13:07:02 +00:00
|
|
|
|
other_user.services = [service1, service2]
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
resp = admin_request.get(
|
|
|
|
|
|
"user.get_organizations_and_services_for_user", user_id=sample_user.id
|
|
|
|
|
|
)
|
2018-03-13 13:07:02 +00:00
|
|
|
|
|
2019-06-12 10:34:15 +01:00
|
|
|
|
assert set(resp.keys()) == {
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"organizations",
|
|
|
|
|
|
"services",
|
2018-03-13 13:07:02 +00:00
|
|
|
|
}
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert resp["organizations"] == [
|
2019-06-12 10:34:15 +01:00
|
|
|
|
{
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"name": org2.name,
|
|
|
|
|
|
"id": str(org2.id),
|
|
|
|
|
|
"count_of_live_services": 0,
|
2019-06-12 10:34:15 +01:00
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
# 'services' always returns the org_id no matter whether the user
|
|
|
|
|
|
# belongs to that org or not
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert resp["services"] == [
|
2019-06-12 10:34:15 +01:00
|
|
|
|
{
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"name": service1.name,
|
|
|
|
|
|
"id": str(service1.id),
|
|
|
|
|
|
"restricted": False,
|
|
|
|
|
|
"organization": str(org1.id),
|
2019-06-12 10:34:15 +01:00
|
|
|
|
}
|
|
|
|
|
|
]
|
2018-07-09 17:25:13 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_find_users_by_email_finds_user_by_partial_email(
|
|
|
|
|
|
notify_db_session, admin_request
|
|
|
|
|
|
):
|
|
|
|
|
|
create_user(email="findel.mestro@foo.com")
|
|
|
|
|
|
create_user(email="me.ignorra@foo.com")
|
2022-05-03 12:11:37 +01:00
|
|
|
|
data = {"email": "findel"}
|
2018-07-09 17:25:13 +01:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
users = admin_request.post(
|
|
|
|
|
|
"user.find_users_by_email",
|
|
|
|
|
|
_data=data,
|
2018-07-09 17:25:13 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert len(users["data"]) == 1
|
|
|
|
|
|
assert users["data"][0]["email_address"] == "findel.mestro@foo.com"
|
2018-07-09 17:25:13 +01:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_find_users_by_email_finds_user_by_full_email(notify_db_session, admin_request):
|
2023-08-23 10:35:43 -07:00
|
|
|
|
create_user(email="findel.mestro@foo.com")
|
|
|
|
|
|
create_user(email="me.ignorra@foo.com")
|
2022-05-03 12:11:37 +01:00
|
|
|
|
data = {"email": "findel.mestro@foo.com"}
|
2018-07-09 17:25:13 +01:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
users = admin_request.post(
|
|
|
|
|
|
"user.find_users_by_email",
|
|
|
|
|
|
_data=data,
|
2018-07-09 17:25:13 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert len(users["data"]) == 1
|
|
|
|
|
|
assert users["data"][0]["email_address"] == "findel.mestro@foo.com"
|
2018-07-09 17:25:13 +01:00
|
|
|
|
|
|
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
def test_find_users_by_email_handles_no_results(notify_db_session, admin_request):
|
2023-08-23 10:35:43 -07:00
|
|
|
|
create_user(email="findel.mestro@foo.com")
|
|
|
|
|
|
create_user(email="me.ignorra@foo.com")
|
2022-05-03 12:11:37 +01:00
|
|
|
|
data = {"email": "rogue"}
|
2018-07-09 17:25:13 +01:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
users = admin_request.post(
|
|
|
|
|
|
"user.find_users_by_email",
|
|
|
|
|
|
_data=data,
|
2018-07-09 17:25:13 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert users["data"] == []
|
2018-07-09 17:25:13 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_search_for_users_by_email_handles_incorrect_data_format(
|
|
|
|
|
|
notify_db_session, admin_request
|
|
|
|
|
|
):
|
|
|
|
|
|
create_user(email="findel.mestro@foo.com")
|
2022-05-03 12:11:37 +01:00
|
|
|
|
data = {"email": 1}
|
2018-07-09 17:25:13 +01:00
|
|
|
|
|
2022-05-03 12:11:37 +01:00
|
|
|
|
json = admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.find_users_by_email", _data=data, _expected_status=400
|
2018-07-09 17:25:13 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
assert json["message"] == {"email": ["Not a valid string."]}
|
2021-02-25 08:10:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"number, expected_reply_to",
|
|
|
|
|
|
[
|
|
|
|
|
|
("403-123-4567", "Notify"),
|
|
|
|
|
|
("+30 123 4567 7890", "Notify"),
|
|
|
|
|
|
("+27 123 4569 2312", "notify_international_sender"),
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
def test_get_sms_reply_to_for_notify_service(
|
|
|
|
|
|
team_member_mobile_edit_template, number, expected_reply_to
|
|
|
|
|
|
):
|
2021-02-25 08:10:52 +00:00
|
|
|
|
# need to import locally to avoid db session errors,
|
|
|
|
|
|
# if this import is with the other imports at the top of the file
|
|
|
|
|
|
# the imports happen in the wrong order and you'll see "dummy session" errors
|
|
|
|
|
|
from app.user.rest import get_sms_reply_to_for_notify_service
|
2023-08-23 10:35:43 -07:00
|
|
|
|
|
|
|
|
|
|
reply_to = get_sms_reply_to_for_notify_service(
|
|
|
|
|
|
number, team_member_mobile_edit_template
|
|
|
|
|
|
)
|
|
|
|
|
|
assert (
|
|
|
|
|
|
reply_to == current_app.config["NOTIFY_INTERNATIONAL_SMS_SENDER"]
|
|
|
|
|
|
if expected_reply_to == "notify_international_sender"
|
|
|
|
|
|
else current_app.config["FROM_NUMBER"]
|
|
|
|
|
|
)
|
2021-05-17 20:32:01 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
@freeze_time("2020-01-01 11:00")
|
|
|
|
|
|
def test_complete_login_after_webauthn_authentication_attempt_resets_login_if_successful(
|
|
|
|
|
|
admin_request, sample_user
|
|
|
|
|
|
):
|
2021-05-17 20:32:01 +01:00
|
|
|
|
sample_user.failed_login_count = 1
|
|
|
|
|
|
|
|
|
|
|
|
assert sample_user.current_session_id is None
|
|
|
|
|
|
assert sample_user.logged_in_at is None
|
|
|
|
|
|
|
|
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.complete_login_after_webauthn_authentication_attempt",
|
2021-05-17 20:32:01 +01:00
|
|
|
|
user_id=sample_user.id,
|
2023-08-23 10:35:43 -07:00
|
|
|
|
_data={"successful": True},
|
|
|
|
|
|
_expected_status=204,
|
2021-05-17 20:32:01 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
assert sample_user.current_session_id is not None
|
|
|
|
|
|
assert sample_user.failed_login_count == 0
|
|
|
|
|
|
assert sample_user.logged_in_at == datetime(2020, 1, 1, 11, 0)
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-06-02 11:13:53 +01:00
|
|
|
|
def test_complete_login_after_webauthn_authentication_attempt_returns_204_when_not_successful(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
admin_request, sample_user
|
2021-06-02 11:13:53 +01:00
|
|
|
|
):
|
2021-05-17 20:32:01 +01:00
|
|
|
|
# when unsuccessful this endpoint is used to bump the failed count. the endpoint still worked
|
|
|
|
|
|
# properly so should return 204 (no content).
|
|
|
|
|
|
sample_user.failed_login_count = 1
|
|
|
|
|
|
|
|
|
|
|
|
assert sample_user.current_session_id is None
|
|
|
|
|
|
assert sample_user.logged_in_at is None
|
|
|
|
|
|
|
|
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.complete_login_after_webauthn_authentication_attempt",
|
2021-05-17 20:32:01 +01:00
|
|
|
|
user_id=sample_user.id,
|
2023-08-23 10:35:43 -07:00
|
|
|
|
_data={"successful": False},
|
|
|
|
|
|
_expected_status=204,
|
2021-05-17 20:32:01 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
assert sample_user.current_session_id is None
|
|
|
|
|
|
assert sample_user.failed_login_count == 2
|
|
|
|
|
|
assert sample_user.logged_in_at is None
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-06-02 11:13:53 +01:00
|
|
|
|
def test_complete_login_after_webauthn_authentication_attempt_raises_403_if_max_login_count_exceeded(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
admin_request, sample_user
|
2021-06-02 11:13:53 +01:00
|
|
|
|
):
|
2021-05-17 20:32:01 +01:00
|
|
|
|
# when unsuccessful this endpoint is used to bump the failed count. the endpoint still worked
|
|
|
|
|
|
# properly so should return 204 (no content).
|
|
|
|
|
|
sample_user.failed_login_count = 10
|
|
|
|
|
|
|
|
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.complete_login_after_webauthn_authentication_attempt",
|
2021-05-17 20:32:01 +01:00
|
|
|
|
user_id=sample_user.id,
|
2023-08-23 10:35:43 -07:00
|
|
|
|
_data={"successful": True},
|
|
|
|
|
|
_expected_status=403,
|
2021-05-17 20:32:01 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
assert sample_user.current_session_id is None
|
|
|
|
|
|
assert sample_user.failed_login_count == 10
|
|
|
|
|
|
assert sample_user.logged_in_at is None
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-23 10:35:43 -07:00
|
|
|
|
def test_complete_login_after_webauthn_authentication_attempt_raises_400_if_schema_invalid(
|
|
|
|
|
|
admin_request,
|
|
|
|
|
|
):
|
2021-05-17 20:32:01 +01:00
|
|
|
|
admin_request.post(
|
2023-08-23 10:35:43 -07:00
|
|
|
|
"user.complete_login_after_webauthn_authentication_attempt",
|
2021-05-17 20:32:01 +01:00
|
|
|
|
user_id=uuid.uuid4(),
|
2023-08-23 10:35:43 -07:00
|
|
|
|
_data={"successful": "True"},
|
|
|
|
|
|
_expected_status=400,
|
2021-05-17 20:32:01 +01:00
|
|
|
|
)
|