diff --git a/app/main/views/find_users.py b/app/main/views/find_users.py
index 2947b0a41..3016da327 100644
--- a/app/main/views/find_users.py
+++ b/app/main/views/find_users.py
@@ -1,4 +1,4 @@
-from flask import render_template, request
+from flask import flash, redirect, render_template, request, url_for
from flask_login import login_required
from app import user_api_client
@@ -37,3 +37,15 @@ def user_information(user_id):
user=user,
services=services,
)
+
+
+@main.route("/users//archive", methods=['GET', 'POST'])
+@login_required
+@user_is_platform_admin
+def archive_user(user_id):
+ if request.method == 'POST':
+ user_api_client.archive_user(user_id)
+ return redirect(url_for('.user_information', user_id=user_id))
+ else:
+ flash('There\'s no way to reverse this! Are you sure you want to archive this user?', 'delete')
+ return user_information(user_id)
diff --git a/app/navigation.py b/app/navigation.py
index 623d7c7e7..82d73b849 100644
--- a/app/navigation.py
+++ b/app/navigation.py
@@ -80,6 +80,7 @@ class HeaderNavigation(Navigation):
},
'platform-admin': {
'add_organisation',
+ 'archive_user',
'clear_cache',
'create_email_branding',
'create_letter_branding',
@@ -427,6 +428,7 @@ class MainNavigation(Navigation):
'add_service',
'agreement',
'archive_service',
+ 'archive_user',
'bat_phone',
'callbacks',
'cancel_invited_org_user',
@@ -619,6 +621,7 @@ class CaseworkNavigation(Navigation):
'api_integration',
'api_keys',
'archive_service',
+ 'archive_user',
'bat_phone',
'branding_request',
'callbacks',
@@ -902,6 +905,7 @@ class OrgNavigation(Navigation):
'api_integration',
'api_keys',
'archive_service',
+ 'archive_user',
'bat_phone',
'branding_request',
'callbacks',
diff --git a/app/notify_client/user_api_client.py b/app/notify_client/user_api_client.py
index f074e995f..091d8f1d5 100644
--- a/app/notify_client/user_api_client.py
+++ b/app/notify_client/user_api_client.py
@@ -65,6 +65,10 @@ class UserApiClient(NotifyAdminAPIClient):
user_data = self.post(url, data=data)
return user_data['data']
+ @cache.delete('user-{user_id}')
+ def archive_user(self, user_id):
+ return self.post('/user/{}/archive'.format(user_id), data=None)
+
@cache.delete('user-{user_id}')
def reset_failed_login_count(self, user_id):
url = "/user/{}/reset-failed-login-count".format(user_id)
diff --git a/app/templates/views/find-users/user-information.html b/app/templates/views/find-users/user-information.html
index 7cfa7b8fd..5149d23a8 100644
--- a/app/templates/views/find-users/user-information.html
+++ b/app/templates/views/find-users/user-information.html
@@ -38,6 +38,11 @@
{{ user.failed_login_count }} failed login attempts
{% endif %}
+
{% endblock %}
diff --git a/tests/app/main/views/test_find_users.py b/tests/app/main/views/test_find_users.py
index 5af41fc83..225c85258 100644
--- a/tests/app/main/views/test_find_users.py
+++ b/tests/app/main/views/test_find_users.py
@@ -1,3 +1,4 @@
+from bs4 import BeautifulSoup
from flask import url_for
from lxml import html
@@ -145,3 +146,33 @@ def test_user_information_page_displays_if_there_are_failed_login_attempts(
document = html.fromstring(response.get_data(as_text=True))
assert document.xpath("//p/text()[normalize-space()='2 failed login attempts']")
+
+
+def test_archive_user_prompts_for_confirmation(
+ logged_in_platform_admin_client,
+ api_user_active,
+ mock_get_organisations_and_services_for_user,
+):
+ response = logged_in_platform_admin_client.get(
+ url_for('main.archive_user', user_id=api_user_active.id)
+ )
+
+ assert response.status_code == 200
+ page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
+ assert 'Are you sure you want to archive this user?' in page.find('div', class_='banner-dangerous').text
+
+
+def test_archive_user_posts_to_user_client(
+ logged_in_platform_admin_client,
+ api_user_active,
+ mocker,
+):
+ mock_user_client = mocker.patch('app.user_api_client.post')
+
+ response = logged_in_platform_admin_client.post(
+ url_for('main.archive_user', user_id=api_user_active.id)
+ )
+
+ assert response.status_code == 302
+ assert response.location == url_for('main.user_information', user_id=api_user_active.id, _external=True)
+ mock_user_client.assert_called_once_with('/user/{}/archive'.format(api_user_active.id), data=None)
diff --git a/tests/app/notify_client/test_user_client.py b/tests/app/notify_client/test_user_client.py
index 5210a0a3e..1ab9389b0 100644
--- a/tests/app/notify_client/test_user_client.py
+++ b/tests/app/notify_client/test_user_client.py
@@ -194,6 +194,7 @@ def test_returns_value_from_cache(
(user_api_client, 'add_user_to_organisation', [sample_uuid(), user_id], {}),
(user_api_client, 'set_user_permissions', [user_id, SERVICE_ONE_ID, []], {}),
(user_api_client, 'activate_user', [api_user_pending(sample_uuid())['id']], {}),
+ (user_api_client, 'archive_user', [user_id], {}),
(service_api_client, 'remove_user_from_service', [SERVICE_ONE_ID, user_id], {}),
(service_api_client, 'create_service', ['', '', 0, False, user_id, sample_uuid()], {}),
(invite_api_client, 'accept_invite', [SERVICE_ONE_ID, user_id], {}),