diff --git a/backend/report_submission/test_views.py b/backend/report_submission/test_views.py
index d7b1c6d3ee..46f8d3fb25 100644
--- a/backend/report_submission/test_views.py
+++ b/backend/report_submission/test_views.py
@@ -385,8 +385,7 @@ def test_step_three_accessandsubmission_submission_fail(self):
data = {}
response = self.client.post(url, data=data)
- self.assertEqual(response.status_code, 302)
- self.assertEqual(response.url, "/report_submission/accessandsubmission/")
+ self.assertEqual(response.status_code, 400)
def test_reportsubmissionredirectview_get_redirects(self):
url = reverse("report_submission:report_submission")
@@ -777,7 +776,7 @@ def test_post_gsa_migration_error(self):
self.assertIn("errors", response.context)
self.assertIn(
- "GSA_MIGRATION not permitted outside of migrations",
+ "Enter a valid email address.",
response.context["errors"],
)
diff --git a/backend/report_submission/views.py b/backend/report_submission/views.py
index 9cb23569d4..fcb2f53859 100644
--- a/backend/report_submission/views.py
+++ b/backend/report_submission/views.py
@@ -114,20 +114,17 @@ def get(self, request):
args["step"] = 3
return render(request, "report_submission/step-3.html", args)
- # render access-submission form
-
- # gather/save step 3 info, redirect to step ...4?
- def post(self, post_request):
- result = api.views.access_and_submission_check(
- post_request.user, post_request.POST
- )
+ def post(self, request):
+ result = api.views.access_and_submission_check(request.user, request.POST)
report_id = result.get("report_id")
if report_id:
return redirect(f"/report_submission/general-information/{report_id}")
else:
- return redirect(reverse("report_submission:accessandsubmission"))
+ return render(
+ request, "report_submission/step-3.html", context=result, status=400
+ )
class GeneralInformationFormView(LoginRequiredMixin, View):
diff --git a/backend/support/api/admin_api_v1_1_0/create_functions.sql b/backend/support/api/admin_api_v1_1_0/create_functions.sql
index 336b2e2ccf..b89b001186 100644
--- a/backend/support/api/admin_api_v1_1_0/create_functions.sql
+++ b/backend/support/api/admin_api_v1_1_0/create_functions.sql
@@ -126,7 +126,7 @@ BEGIN
-- Are they already in the table?
SELECT count(up.email)
FROM public.users_userpermission as up
- WHERE email = params->>'email' INTO already_exists;
+ WHERE LOWER(email) = LOWER(params->>'email') INTO already_exists;
-- If they are, we're going to exit.
IF already_exists <> 0
@@ -146,11 +146,11 @@ BEGIN
-- Can we make the 1 not magic... do a select into.
INSERT INTO public.users_userpermission
(email, permission_id, user_id)
- VALUES (params->>'email', read_tribal_id, null);
+ VALUES (LOWER(params->>'email'), read_tribal_id, null);
- RAISE INFO 'ADMIN_API add_tribal_access_email OK %', params->>'email';
+ RAISE INFO 'ADMIN_API add_tribal_access_email OK %', LOWER(params->>'email');
RETURN admin_api_v1_1_0_functions.log_admin_api_event('tribal-access-email-added',
- json_build_object('email', params->>'email'));
+ json_build_object('email', LOWER(params->>'email')));
END IF;
ELSE
RETURN 0;
@@ -222,7 +222,7 @@ BEGIN
THEN
-- Delete rows where the email address matches
DELETE FROM public.users_userpermission as up
- WHERE up.email = params->>'email';
+ WHERE LOWER(up.email) = LOWER(params->>'email');
-- This is the Postgres way to find out how many rows
-- were affected by a DELETE.
GET DIAGNOSTICS affected_rows = ROW_COUNT;
@@ -230,7 +230,7 @@ BEGIN
IF affected_rows > 0
THEN
RETURN admin_api_v1_1_0_functions.log_admin_api_event('tribal-access-email-removed',
- json_build_object('email', params->>'email'));
+ json_build_object('email', LOWER(params->>'email')));
ELSE
RETURN 0;
END IF;
@@ -297,14 +297,14 @@ BEGIN
SELECT EXISTS (
SELECT 1
FROM public.dissemination_TribalApiAccessKeyIds
- WHERE email = params->>'email'
+ WHERE LOWER(email) = LOWER(params->>'email')
)
INTO user_exists;
-- If the user already exists, it means they have access.
-- For purposes of this function, lets call that "succses", and return true.
IF user_exists THEN
- RAISE INFO 'ADMIN_API add_tribal_api_key_access ALREADY_EXISTS %', params->>'email';
+ RAISE INFO 'ADMIN_API add_tribal_api_key_access ALREADY_EXISTS %', LOWER(params->>'email');
RETURN json_build_object(
'result', 'success',
'message', 'User with this key already exists')::JSON;
@@ -313,8 +313,8 @@ BEGIN
-- If the user does not exist, add a new record
INSERT INTO public.dissemination_TribalApiAccessKeyIds (email, key_id, date_added)
- VALUES (params->>'email', params->>'key_id', CURRENT_TIMESTAMP);
- RAISE INFO 'ADMIN_API add_tribal_api_key_access ACCESS_GRANTED % %', params->>'email', params->>'key_id';
+ VALUES (LOWER(params->>'email'), params->>'key_id', CURRENT_TIMESTAMP);
+ RAISE INFO 'ADMIN_API add_tribal_api_key_access ACCESS_GRANTED % %', LOWER(params->>'email'), params->>'key_id';
RETURN json_build_object(
'result', 'success',
'message', 'User access granted')::JSON;
@@ -328,7 +328,7 @@ BEGIN
END IF;
-- Return false by default.
- RAISE INFO 'ADMIN_API add_tribal_api_key_access WAT %', params->>'email';
+ RAISE INFO 'ADMIN_API add_tribal_api_key_access WAT %', LOWER(params->>'email');
RETURN json_build_object(
'result', 'failure',
'message', 'Unknown error in access addition')::JSON;
@@ -352,20 +352,20 @@ BEGIN
SELECT EXISTS (
SELECT 1
FROM public.dissemination_TribalApiAccessKeyIds
- WHERE email = params->>'email'
+ WHERE LOWER(email) = LOWER(params->>'email')
)
INTO user_exists;
-- If the user exists, remove the record
IF user_exists THEN
DELETE FROM public.dissemination_TribalApiAccessKeyIds
- WHERE email = params->>'email';
- RAISE INFO 'ADMIN_API remove_tribal_api_key_access ACCESS_REMOVED %', params->>'email';
+ WHERE LOWER(email) = LOWER(params->>'email');
+ RAISE INFO 'ADMIN_API remove_tribal_api_key_access ACCESS_REMOVED %', LOWER(params->>'email');
RETURN json_build_object(
'result', 'success',
'message', 'Removed record')::JSON;
ELSE
- RAISE INFO 'ADMIN_API remove_tribal_api_key_access DID_NOT_EXIST %', params->>'email';
+ RAISE INFO 'ADMIN_API remove_tribal_api_key_access DID_NOT_EXIST %', LOWER(params->>'email');
RETURN json_build_object(
'result', 'failure',
'message', 'User did not exist in table')::JSON;
@@ -376,7 +376,7 @@ BEGIN
'result', 'failure',
'message', 'Admin user lacks DELETE permissions')::JSON; -- Return false if the API user doesn't have read permissions
END IF;
- RAISE INFO 'ADMIN_API add_tribal_api_key_access WAT %', params->>'email';
+ RAISE INFO 'ADMIN_API add_tribal_api_key_access WAT %', LOWER(params->>'email');
RETURN json_build_object(
'result', 'failure',
'message', 'Uknown error in access removal')::JSON;
diff --git a/docs/testing.md b/docs/testing.md
index d480e1dd3f..43f56f3391 100644
--- a/docs/testing.md
+++ b/docs/testing.md
@@ -17,6 +17,7 @@ We use [Django's test execution framework](https://docs.djangoproject.com/en/4.0
- [Linting](#linting)
- [End-to-end testing](#end-to-end-testing)
- [Testing behind Login.gov](#testing-behind-logingov)
+- [Admin API testing](#admin-api-testing)
## Packages
- [model_bakery](https://model-bakery.readthedocs.io/en/latest/), to help create data and instances within our tests
@@ -184,3 +185,30 @@ in files in [backend/cypress/e2e/](/backend/cypress/e2e). To run these tests:
Github repository. To use them in a Github Actions workflow, use the [Github
Actions secrets
store](https://docs.github.com/en/actions/security-guides/encrypted-secrets)
+
+# Admin API Testing
+For interfacing the admin API locally, we will need to account for a few things.
+
+## Resources
+
+For communicating with the Postgrest API, you could use one of the following extensions if you are using Visual Studio Code:
+- [REST Client](https://marketplace.visualstudio.com/items?itemName=humao.rest-client)
+- [Postman](https://marketplace.visualstudio.com/items?itemName=Postman.postman-for-vscode)
+
+Though keep in mind you should be able to use whatever API service you prefer to run.
+
+## Checklist
+
+1. When running `docker compose up`, make sure the `web-1` service completes the startup procedures.
+ - E.G., `STARTUP STARTUP_CHECK seed_cog_baseline PASS` should be one of the last startup logs. If this passes, then the API tables are up.
+2. Make sure you prepare your request headers with the following:
+ - `Authorization: Bearer {JWT}` is important for authenticating your requests.
+ - `x-api-user-id: {uuid}` should be populated with a user ID from the `support_administrative_key_uuids` table. You can create your own row in this table for local testing purposes.
+ - `x-api-key: {key}`
+ - `content-profile: {api-version}` is required for POST requests.
+ - `accept-profile: {api-version}` is required for GET requests.
+ - `Prefer: params=single-object` is needed for the API to read your payload. In most if not all cases, it is set to `params=single-object`.
+
+## "Cheat-sheet" for testing
+
+We have a `.rest` file in `/backend/support/api/admin_api_vX_X_X` that contains many of the admin API endpoints, as well the headers/parameters/payload that are needed to run it successfully.