From 6999d72f76e2581c7023208f39326720cf381f14 Mon Sep 17 00:00:00 2001
From: Andrew Shumway
Date: Wed, 7 Feb 2024 09:38:18 -0700
Subject: [PATCH 01/17] Fix dashboard bug/usage page
---
app/main/views/dashboard.py | 46 ++++++-----------
app/utils/time.py | 2 +-
.../views/organizations/test_organizations.py | 10 ++--
tests/app/main/views/test_dashboard.py | 49 ++++++++++++-------
tests/app/utils/test_time.py | 8 +--
5 files changed, 55 insertions(+), 60 deletions(-)
diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py
index a88203ae7..f5f38087a 100644
--- a/app/main/views/dashboard.py
+++ b/app/main/views/dashboard.py
@@ -123,11 +123,17 @@ def template_usage(service_id):
months=months,
stats=stats,
most_used_template_count=max(
- max(
- (template["requested_count"] for template in month["templates_used"]),
- default=0,
- )
- for month in months
+ (
+ max(
+ (
+ template["requested_count"]
+ for template in month["templates_used"]
+ ),
+ default=0,
+ )
+ for month in months
+ ),
+ default=0,
),
years=get_tuples_of_financial_years(
partial(url_for, ".template_usage", service_id=service_id),
@@ -144,31 +150,16 @@ def usage(service_id):
year, current_financial_year = requested_and_current_financial_year(request)
free_sms_allowance = billing_api_client.get_free_sms_fragment_limit_for_year(
- service_id, year
+ service_id
)
+
units = billing_api_client.get_monthly_usage_for_service(service_id, year)
+
yearly_usage = billing_api_client.get_annual_usage_for_service(service_id, year)
more_stats = format_monthly_stats_to_list(
service_api_client.get_monthly_notification_stats(service_id, year)["data"]
)
- if year == current_financial_year:
- # This includes Oct, Nov, Dec
- # but we don't need next year's data yet
- more_stats = [
- month
- for month in more_stats
- if month["name"] in ["October", "November", "December"]
- ]
- elif year == (current_financial_year + 1):
- # This is all the other months
- # and we need last year's data
- more_stats = [
- month
- for month in more_stats
- if month["name"] not in ["October", "November", "December"]
- ]
-
return render_template(
"views/usage.html",
months=list(get_monthly_usage_breakdown(year, units, more_stats)),
@@ -330,7 +321,6 @@ def get_dashboard_partials(service_id):
dashboard_totals = (get_dashboard_totals(stats),)
free_sms_allowance = billing_api_client.get_free_sms_fragment_limit_for_year(
current_service.id,
- get_current_financial_year(),
)
yearly_usage = billing_api_client.get_annual_usage_for_service(
service_id,
@@ -422,13 +412,7 @@ def aggregate_status_types(counts_dict):
def get_months_for_financial_year(year, time_format="%B"):
- return [
- month.strftime(time_format)
- for month in (
- get_months_for_year(10, 13, year) + get_months_for_year(1, 10, year + 1)
- )
- if month < datetime.now()
- ]
+ return [month.strftime(time_format) for month in (get_months_for_year(1, 13, year))]
def get_months_for_year(start, end, year):
diff --git a/app/utils/time.py b/app/utils/time.py
index 9ae24b1bd..e2f4a8e36 100644
--- a/app/utils/time.py
+++ b/app/utils/time.py
@@ -11,7 +11,7 @@ def get_current_financial_year():
now = datetime.now(preferred_tz)
current_month = int(now.strftime("%-m"))
current_year = int(now.strftime("%Y"))
- return current_year if current_month > 9 else current_year - 1
+ return current_year if current_month < 10 else current_year + 1
def is_less_than_days_ago(date_from_db, number_of_days):
diff --git a/tests/app/main/views/organizations/test_organizations.py b/tests/app/main/views/organizations/test_organizations.py
index 7679e1429..27663ad22 100644
--- a/tests/app/main/views/organizations/test_organizations.py
+++ b/tests/app/main/views/organizations/test_organizations.py
@@ -388,7 +388,7 @@ def test_organization_services_shows_live_services_and_usage(
client_request.login(active_user_with_permissions)
page = client_request.get(".organization_dashboard", org_id=ORGANISATION_ID)
- mock.assert_called_once_with(ORGANISATION_ID, 2019)
+ mock.assert_called_once_with(ORGANISATION_ID, 2020)
services = page.select("main h3")
usage_rows = page.select("main .grid-col-6")
@@ -459,9 +459,9 @@ def test_organization_services_shows_live_services_and_usage_with_count_of_1(
@pytest.mark.parametrize(
("financial_year", "expected_selected"),
[
- (2017, "2017 to 2018 fiscal year"),
(2018, "2018 to 2019 fiscal year"),
(2019, "2019 to 2020 fiscal year"),
+ (2020, "2020 to 2021 fiscal year"),
],
)
def test_organization_services_filters_by_financial_year(
@@ -483,9 +483,9 @@ def test_organization_services_filters_by_financial_year(
)
mock.assert_called_once_with(ORGANISATION_ID, financial_year)
assert normalize_spaces(page.select_one(".pill").text) == (
+ "2020 to 2021 fiscal year "
"2019 to 2020 fiscal year "
- "2018 to 2019 fiscal year "
- "2017 to 2018 fiscal year"
+ "2018 to 2019 fiscal year"
)
assert normalize_spaces(page.select_one(".pill-item--selected").text) == (
expected_selected
@@ -610,7 +610,7 @@ def test_organization_services_links_to_downloadable_report(
assert link_to_report.attrs["href"] == url_for(
".download_organization_usage_report",
org_id=ORGANISATION_ID,
- selected_year=2021,
+ selected_year=2022,
)
diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py
index 8e9ecb531..9703a2de5 100644
--- a/tests/app/main/views/test_dashboard.py
+++ b/tests/app/main/views/test_dashboard.py
@@ -666,12 +666,12 @@ def test_should_show_redirect_from_template_history(
)
-@freeze_time("2017-01-01 12:00") # 4 months into 2016 financial year
+@freeze_time("2017-1-1 12:00") # Switching to calendar year
@pytest.mark.parametrize(
"extra_args",
[
{},
- {"year": "2016"},
+ {"year": "2017"},
],
)
def test_should_show_monthly_breakdown_of_template_usage(
@@ -683,7 +683,7 @@ def test_should_show_monthly_breakdown_of_template_usage(
"main.template_usage", service_id=SERVICE_ONE_ID, **extra_args
)
- mock_get_monthly_template_usage.assert_called_once_with(SERVICE_ONE_ID, 2016)
+ mock_get_monthly_template_usage.assert_called_once_with(SERVICE_ONE_ID, 2017)
table_rows = page.select("tbody tr")
@@ -691,9 +691,21 @@ def test_should_show_monthly_breakdown_of_template_usage(
"My first template " "Text message template " "2"
)
- assert len(table_rows) == len(["October"])
+ assert len(table_rows) == len(["January"])
assert len(page.select(".table-no-data")) == len(
- ["November", "December", "January"]
+ [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ ]
)
@@ -736,9 +748,9 @@ def test_stats_pages_show_last_3_years(
)
assert normalize_spaces(page.select_one(".pill").text) == (
+ "2015 to 2016 fiscal year "
"2014 to 2015 fiscal year "
- "2013 to 2014 fiscal year "
- "2012 to 2013 fiscal year"
+ "2013 to 2014 fiscal year"
)
@@ -953,18 +965,18 @@ def test_usage_page(
service_id=SERVICE_ONE_ID,
)
- mock_get_monthly_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2011)
- mock_get_annual_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2011)
- mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID, 2011)
+ mock_get_monthly_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2012)
+ mock_get_annual_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2012)
+ mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID)
nav = page.find("ul", {"class": "pill"})
unselected_nav_links = nav.select("a:not(.pill-item--selected)")
assert (
normalize_spaces(nav.find("a", {"aria-current": "page"}).text)
- == "2011 to 2012 fiscal year"
+ == "2012 to 2013 fiscal year"
)
- assert normalize_spaces(unselected_nav_links[0].text) == "2010 to 2011 fiscal year"
- assert normalize_spaces(unselected_nav_links[1].text) == "2009 to 2010 fiscal year"
+ assert normalize_spaces(unselected_nav_links[0].text) == "2011 to 2012 fiscal year"
+ assert normalize_spaces(unselected_nav_links[1].text) == "2010 to 2011 fiscal year"
annual_usage = page.find_all("div", {"class": "keyline-block"})
@@ -1031,8 +1043,7 @@ def test_usage_page_monthly_breakdown(
page = client_request.get("main.usage", service_id=SERVICE_ONE_ID)
monthly_breakdown = normalize_spaces(page.find("table").text)
- assert "October" in monthly_breakdown
- assert "249,860 free text messages" in monthly_breakdown
+ assert "January" in monthly_breakdown
assert "February" in monthly_breakdown
assert "$16.40" in monthly_breakdown
@@ -1048,8 +1059,8 @@ def test_usage_page_monthly_breakdown(
@pytest.mark.parametrize(
("now", "expected_number_of_months"),
[
- (freeze_time("2017-03-31 11:09:00.061258"), 6),
- (freeze_time("2017-01-01 11:09:00.061258"), 4),
+ (freeze_time("2017-03-31 11:09:00.061258"), 12),
+ (freeze_time("2017-01-01 11:09:00.061258"), 12),
],
)
def test_usage_page_monthly_breakdown_shows_months_so_far(
@@ -1109,7 +1120,7 @@ def test_usage_page_with_year_argument(
)
mock_get_monthly_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2000)
mock_get_annual_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2000)
- mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID, 2000)
+ mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID)
mock_get_monthly_notification_stats.assert_called_with(SERVICE_ONE_ID, 2000)
@@ -1144,7 +1155,7 @@ def test_future_usage_page(
mock_get_annual_usage_for_service_in_future.assert_called_once_with(
SERVICE_ONE_ID, 2014
)
- mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID, 2014)
+ mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID)
mock_get_monthly_notification_stats.assert_called_with(SERVICE_ONE_ID, 2014)
diff --git a/tests/app/utils/test_time.py b/tests/app/utils/test_time.py
index 931fdb816..ae51edb97 100644
--- a/tests/app/utils/test_time.py
+++ b/tests/app/utils/test_time.py
@@ -20,10 +20,10 @@ def test_is_less_than_days_ago(date_from_db, expected_result):
@pytest.mark.parametrize(
("datetime_string", "financial_year"),
[
- ("2021-01-01T00:00:00+00:00", 2020), # Start of 2021
- ("2021-04-01T03:59:59+00:00", 2020), # One minute before midnight (BST)
- ("2021-10-01T04:05:00+00:00", 2021), # Midnight (BST)
- ("2021-12-12T12:12:12+01:00", 2021), # Later in the year
+ ("2021-01-01T00:00:00+00:00", 2021), # Start of 2021
+ ("2021-04-01T03:59:59+00:00", 2021), # One minute before midnight (BST)
+ ("2021-10-01T04:05:00+00:00", 2022), # Midnight (BST)
+ ("2021-12-12T12:12:12+01:00", 2022), # Later in the year
],
)
def test_get_financial_year(datetime_string, financial_year):
From 5a440863afa1592acf51b0927fc364989ab0d326 Mon Sep 17 00:00:00 2001
From: Andrew Shumway
Date: Wed, 7 Feb 2024 14:43:39 -0700
Subject: [PATCH 02/17] Fix trial mode allowance bug
---
app/main/views/dashboard.py | 8 ++++++++
tests/app/main/views/test_dashboard.py | 2 ++
tests/conftest.py | 2 ++
3 files changed, 12 insertions(+)
diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py
index f5f38087a..87a013547 100644
--- a/app/main/views/dashboard.py
+++ b/app/main/views/dashboard.py
@@ -322,6 +322,14 @@ def get_dashboard_partials(service_id):
free_sms_allowance = billing_api_client.get_free_sms_fragment_limit_for_year(
current_service.id,
)
+ # These 2 calls will update the dashboard sms allowance count while in trial mode.
+ billing_api_client.get_monthly_usage_for_service(
+ service_id, get_current_financial_year()
+ )
+ billing_api_client.create_or_update_free_sms_fragment_limit(
+ service_id, free_sms_fragment_limit=free_sms_allowance
+ )
+
yearly_usage = billing_api_client.get_annual_usage_for_service(
service_id,
get_current_financial_year(),
diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py
index 9703a2de5..10d686a98 100644
--- a/tests/app/main/views/test_dashboard.py
+++ b/tests/app/main/views/test_dashboard.py
@@ -1386,7 +1386,9 @@ def test_route_for_service_permissions(
mock_has_no_jobs,
mock_get_template_statistics,
mock_get_service_statistics,
+ mock_get_monthly_usage_for_service,
mock_get_annual_usage_for_service,
+ mock_create_or_update_free_sms_fragment_limit,
mock_get_free_sms_fragment_limit,
mock_get_inbound_sms_summary,
):
diff --git a/tests/conftest.py b/tests/conftest.py
index ec4ff8ad1..1724f0234 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -2327,6 +2327,8 @@ def client_request(logged_in_client, mocker, service_one): # noqa (C901 too com
"app.billing_api_client.create_or_update_free_sms_fragment_limit", autospec=True
)
+ mocker.patch("app.billing_api_client.get_monthly_usage_for_service", autospec=True)
+
class ClientRequest:
@staticmethod
@contextmanager
From c9c8882dc9d465b2f66306a146b153218e39cfa9 Mon Sep 17 00:00:00 2001
From: Andrew Shumway
Date: Wed, 27 Mar 2024 10:10:56 -0600
Subject: [PATCH 03/17] Fix test
---
tests/app/main/views/test_dashboard.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py
index cd543d903..9679f2bce 100644
--- a/tests/app/main/views/test_dashboard.py
+++ b/tests/app/main/views/test_dashboard.py
@@ -679,7 +679,7 @@ def test_should_show_redirect_from_template_history(
)
-@freeze_time("2017-1-1 12:00") # Switching to calendar year
+@freeze_time("2017-01-01 12:00")
@pytest.mark.parametrize(
"extra_args",
[
@@ -705,6 +705,7 @@ def test_should_show_monthly_breakdown_of_template_usage(
)
assert len(table_rows) == len(["January"])
+ # October is the only month with data, thus it's not in the list.
assert len(page.select(".table-no-data")) == len(
[
"January",
@@ -716,8 +717,8 @@ def test_should_show_monthly_breakdown_of_template_usage(
"July",
"August",
"September",
- "October",
"November",
+ "December",
]
)
From f46f9661f1ef5e0f04ab4ef5cdf0f6e11dc819f6 Mon Sep 17 00:00:00 2001
From: Jonathan Bobel
Date: Mon, 8 Apr 2024 11:32:09 -0400
Subject: [PATCH 04/17] 1269 - Content updates for Service Settings after
login.gov integration
---
app/main/views/service_settings.py | 1 +
app/templates/views/service-settings/set-auth-type.html | 7 ++++++-
poetry.lock | 7 ++++++-
3 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py
index 628ac59e5..7d301426f 100644
--- a/app/main/views/service_settings.py
+++ b/app/main/views/service_settings.py
@@ -650,6 +650,7 @@ def service_set_channel(service_id, channel):
def service_set_auth_type(service_id):
return render_template(
"views/service-settings/set-auth-type.html",
+ login_gov_enabled=False,
)
diff --git a/app/templates/views/service-settings/set-auth-type.html b/app/templates/views/service-settings/set-auth-type.html
index 263740222..2fa545a4c 100644
--- a/app/templates/views/service-settings/set-auth-type.html
+++ b/app/templates/views/service-settings/set-auth-type.html
@@ -16,7 +16,12 @@
{{ page_header('Sign-in method') }}
- {% if 'email_auth' in current_service.permissions %}
+
+ {% if login_gov_enabled %}
+
Your username, password, and multi-factor authentication options are handled by Login.gov.
+
To make changes, head to Login.gov and sign-in with your credentials.
+
Any changes made to your Login.gov account will automatically be synced with Notify.gov.
+ {% elif 'email_auth' in current_service.permissions and not login_gov_enabled %}
Email link or text message code
diff --git a/poetry.lock b/poetry.lock
index 930c20232..2a90e8113 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1210,6 +1210,7 @@ description = "Powerful and Pythonic XML processing library combining libxml2/li
optional = false
python-versions = ">=3.6"
files = [
+ {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:704f5572ff473a5f897745abebc6df40f22d4133c1e0a1f124e4f2bd3330ff7e"},
{file = "lxml-5.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d3c0f8567ffe7502d969c2c1b809892dc793b5d0665f602aad19895f8d508da"},
{file = "lxml-5.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5fcfbebdb0c5d8d18b84118842f31965d59ee3e66996ac842e21f957eb76138c"},
{file = "lxml-5.1.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f37c6d7106a9d6f0708d4e164b707037b7380fcd0b04c5bd9cae1fb46a856fb"},
@@ -1219,6 +1220,7 @@ files = [
{file = "lxml-5.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82bddf0e72cb2af3cbba7cec1d2fd11fda0de6be8f4492223d4a268713ef2147"},
{file = "lxml-5.1.0-cp310-cp310-win32.whl", hash = "sha256:b66aa6357b265670bb574f050ffceefb98549c721cf28351b748be1ef9577d93"},
{file = "lxml-5.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:4946e7f59b7b6a9e27bef34422f645e9a368cb2be11bf1ef3cafc39a1f6ba68d"},
+ {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:14deca1460b4b0f6b01f1ddc9557704e8b365f55c63070463f6c18619ebf964f"},
{file = "lxml-5.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed8c3d2cd329bf779b7ed38db176738f3f8be637bb395ce9629fc76f78afe3d4"},
{file = "lxml-5.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:436a943c2900bb98123b06437cdd30580a61340fbdb7b28aaf345a459c19046a"},
{file = "lxml-5.1.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:acb6b2f96f60f70e7f34efe0c3ea34ca63f19ca63ce90019c6cbca6b676e81fa"},
@@ -1228,6 +1230,7 @@ files = [
{file = "lxml-5.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4c9bda132ad108b387c33fabfea47866af87f4ea6ffb79418004f0521e63204"},
{file = "lxml-5.1.0-cp311-cp311-win32.whl", hash = "sha256:bc64d1b1dab08f679fb89c368f4c05693f58a9faf744c4d390d7ed1d8223869b"},
{file = "lxml-5.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5ab722ae5a873d8dcee1f5f45ddd93c34210aed44ff2dc643b5025981908cda"},
+ {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9aa543980ab1fbf1720969af1d99095a548ea42e00361e727c58a40832439114"},
{file = "lxml-5.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6f11b77ec0979f7e4dc5ae081325a2946f1fe424148d3945f943ceaede98adb8"},
{file = "lxml-5.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a36c506e5f8aeb40680491d39ed94670487ce6614b9d27cabe45d94cd5d63e1e"},
{file = "lxml-5.1.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f643ffd2669ffd4b5a3e9b41c909b72b2a1d5e4915da90a77e119b8d48ce867a"},
@@ -1253,8 +1256,8 @@ files = [
{file = "lxml-5.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8f52fe6859b9db71ee609b0c0a70fea5f1e71c3462ecf144ca800d3f434f0764"},
{file = "lxml-5.1.0-cp37-cp37m-win32.whl", hash = "sha256:d42e3a3fc18acc88b838efded0e6ec3edf3e328a58c68fbd36a7263a874906c8"},
{file = "lxml-5.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:eac68f96539b32fce2c9b47eb7c25bb2582bdaf1bbb360d25f564ee9e04c542b"},
+ {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae15347a88cf8af0949a9872b57a320d2605ae069bcdf047677318bc0bba45b1"},
{file = "lxml-5.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c26aab6ea9c54d3bed716b8851c8bfc40cb249b8e9880e250d1eddde9f709bf5"},
- {file = "lxml-5.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cfbac9f6149174f76df7e08c2e28b19d74aed90cad60383ad8671d3af7d0502f"},
{file = "lxml-5.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:342e95bddec3a698ac24378d61996b3ee5ba9acfeb253986002ac53c9a5f6f84"},
{file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:725e171e0b99a66ec8605ac77fa12239dbe061482ac854d25720e2294652eeaa"},
{file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d184e0d5c918cff04cdde9dbdf9600e960161d773666958c9d7b565ccc60c45"},
@@ -1262,6 +1265,7 @@ files = [
{file = "lxml-5.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d48fc57e7c1e3df57be5ae8614bab6d4e7b60f65c5457915c26892c41afc59e"},
{file = "lxml-5.1.0-cp38-cp38-win32.whl", hash = "sha256:7ec465e6549ed97e9f1e5ed51c657c9ede767bc1c11552f7f4d022c4df4a977a"},
{file = "lxml-5.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:b21b4031b53d25b0858d4e124f2f9131ffc1530431c6d1321805c90da78388d1"},
+ {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:52427a7eadc98f9e62cb1368a5079ae826f94f05755d2d567d93ee1bc3ceb354"},
{file = "lxml-5.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a2a2c724d97c1eb8cf966b16ca2915566a4904b9aad2ed9a09c748ffe14f969"},
{file = "lxml-5.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:843b9c835580d52828d8f69ea4302537337a21e6b4f1ec711a52241ba4a824f3"},
{file = "lxml-5.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b99f564659cfa704a2dd82d0684207b1aadf7d02d33e54845f9fc78e06b7581"},
@@ -2378,6 +2382,7 @@ files = [
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
+ {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
From 6784cf9f3cd7b96b8073c20e892cb68f05eca7f0 Mon Sep 17 00:00:00 2001
From: Jonathan Bobel
Date: Mon, 15 Apr 2024 15:50:42 -0400
Subject: [PATCH 05/17] 1423 - Few final updates to switch over to login.gov
---
app/main/views/sign_in.py | 1 -
app/templates/views/signin.html | 33 ++++------------------
poetry.lock | 2 +-
tests/app/main/views/test_accept_invite.py | 9 ++----
tests/app/main/views/test_sign_in.py | 31 ++++----------------
5 files changed, 15 insertions(+), 61 deletions(-)
diff --git a/app/main/views/sign_in.py b/app/main/views/sign_in.py
index 6de46b023..f5870c2e1 100644
--- a/app/main/views/sign_in.py
+++ b/app/main/views/sign_in.py
@@ -197,7 +197,6 @@ def sign_in():
form=form,
again=bool(redirect_url),
other_device=other_device,
- login_gov_enabled=True,
password_reset_url=password_reset_url,
initial_signin_url=url,
)
diff --git a/app/templates/views/signin.html b/app/templates/views/signin.html
index 6d6f578ee..5532eb7c1 100644
--- a/app/templates/views/signin.html
+++ b/app/templates/views/signin.html
@@ -12,18 +12,6 @@
{% block maincolumn_content %}
-{% if login_gov_enabled %}
-
-
-
-
Login.gov is required by April 16, 2024
-
- You have left to use Login.gov to sign in
-
-
-
-
-{% endif %}
{% if again %}
@@ -39,22 +27,12 @@
{% endif %}
{% else %}
Sign in
- {% if login_gov_enabled %}
-
You can access your account by signing in with one of the options below:
-
Sign in with Login.gov
-
Or:
- {% endif %}
+
Access your Notify.gov account by signing in with Login.gov:
+
Sign in with Login.gov
{% endif %}
-
- {% call form_wrapper(autocomplete=True) %}
- {{ form.email_address(param_extensions={"autocomplete": "email"}) }}
- {{ form.password(param_extensions={"autocomplete": "current-password"}) }}
- {{ page_footer("Continue", secondary_link=password_reset_url, secondary_link_text="Forgot your password?") }}
- {% endcall %}
- {% if login_gov_enabled %}
-
Notify.gov is changing the sign-in experience to Login.gov effective
April 16, 2024
+
Effective April 16, 2024 Notify.gov requires you sign-in through Login.gov
Why are we doing this?
- Enhanced security: Login.gov is really secure and trustworthy
@@ -64,12 +42,11 @@
What do I need to do?
- If you have a Login.gov account, start using it to sign in to Notify today.
- - If you don’t have a Login.gov account, you must create one by April 16, 2024 to continue to access Notify.
+ - If you don’t have a Login.gov account, you must create one to continue to access Notify.
- Create Login.gov account
+ Create Login.gov account
-{% endif %}
{% endblock %}
diff --git a/poetry.lock b/poetry.lock
index 21064bf51..e46765a4f 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1516,7 +1516,6 @@ files = [
{file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"},
{file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"},
{file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"},
- {file = "msgpack-1.0.8-py3-none-any.whl", hash = "sha256:24f727df1e20b9876fa6e95f840a2a2651e34c0ad147676356f4bf5fbb0206ca"},
{file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"},
]
@@ -2383,6 +2382,7 @@ files = [
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
+ {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
diff --git a/tests/app/main/views/test_accept_invite.py b/tests/app/main/views/test_accept_invite.py
index c677eeec2..d1eadc28f 100644
--- a/tests/app/main/views/test_accept_invite.py
+++ b/tests/app/main/views/test_accept_invite.py
@@ -222,8 +222,7 @@ def test_if_existing_user_accepts_twice_they_redirect_to_sign_in(
) == (
"You need to sign in again",
# TODO: Improve this given Login.gov configuration.
- # "We signed you out because you have not used Notify for a while.",
- "You have left to use Login.gov to sign in",
+ "We signed you out because you have not used Notify for a while.",
)
# We don’t let people update `email_access_validated_at` using an
# already-accepted invite
@@ -338,8 +337,7 @@ def test_existing_user_of_service_get_redirected_to_signin(
) == (
"You need to sign in again",
# TODO: Improve this given Login.gov configuration.
- # "We signed you out because you have not used Notify for a while.",
- "You have left to use Login.gov to sign in",
+ "We signed you out because you have not used Notify for a while.",
)
assert mock_accept_invite.call_count == 1
@@ -429,8 +427,7 @@ def test_existing_signed_out_user_accept_invite_redirects_to_sign_in(
) == (
"You need to sign in again",
# TODO: Improve this given Login.gov configuration.
- # "We signed you out because you have not used Notify for a while.",
- "You have left to use Login.gov to sign in",
+ "We signed you out because you have not used Notify for a while.",
)
diff --git a/tests/app/main/views/test_sign_in.py b/tests/app/main/views/test_sign_in.py
index ddb7a8b08..e89cb6e7b 100644
--- a/tests/app/main/views/test_sign_in.py
+++ b/tests/app/main/views/test_sign_in.py
@@ -12,40 +12,21 @@ def test_render_sign_in_template_for_new_user(client_request):
client_request.logout()
page = client_request.get("main.sign_in")
assert normalize_spaces(page.select_one("h1").text) == "Sign in"
- assert normalize_spaces(page.select("label")[0].text) == "Email address"
- assert page.select_one("#email_address").get("value") is None
- assert page.select_one("#email_address")["autocomplete"] == "email"
- assert normalize_spaces(page.select("label")[1].text) == "Password"
- assert page.select_one("#password").get("value") is None
- assert page.select_one("#password")["autocomplete"] == "current-password"
- # Removing for the pilot
- # assert page.select('main a')[0].text == 'create one now'
- # assert page.select('main a')[0]['href'] == url_for('main.register')
+ assert (
+ page.select("main p")[0].text
+ == "Access your Notify.gov account by signing in with Login.gov:"
+ )
# TODO: Fix this test to be less brittle! If the Login.gov link is enabled,
# then these indices need to be 1 instead of 0.
# Currently it's not enabled for the test or production environments.
- assert page.select("main a")[1].text == "Forgot your password?"
- assert page.select("main a")[1]["href"] == url_for("main.forgot_password")
+ assert page.select("main a")[0].text == "Sign in with Login.gov"
+ assert page.select("main a")[1].text == "Create Login.gov account"
# TODO: We'll have to adjust this depending on whether Login.gov is
# enabled or not; fix this in the future.
assert "Sign in again" not in normalize_spaces(page.text)
-def test_render_sign_in_template_with_next_link_for_password_reset(client_request):
- client_request.logout()
- page = client_request.get(
- "main.sign_in",
- _optional_args=f"?next=/services/{SERVICE_ONE_ID}/templates",
- _test_page_title=False,
- )
- forgot_password_link = page.find("a", class_="usa-link")
- assert forgot_password_link.text == "Forgot your password?"
- assert forgot_password_link["href"] == url_for(
- "main.forgot_password", next=f"/services/{SERVICE_ONE_ID}/templates"
- )
-
-
def test_reformat_keystring():
orig = "-----BEGIN PRIVATE KEY----- blah blah blah -----END PRIVATE KEY-----"
expected = """-----BEGIN PRIVATE KEY-----
From b83019fdb722467d6f936f3ee1e9455b04c37565 Mon Sep 17 00:00:00 2001
From: Jonathan Bobel
Date: Tue, 16 Apr 2024 10:57:16 -0400
Subject: [PATCH 06/17] Fixing pa11y scan
---
app/templates/error/500.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/templates/error/500.html b/app/templates/error/500.html
index af86388d7..aca8332df 100644
--- a/app/templates/error/500.html
+++ b/app/templates/error/500.html
@@ -7,7 +7,7 @@
Sorry, we can't deliver what you asked for right now.
- Please try again later or email us for more information.
+ Please try again later or email us for more information.
From 96293598f883cec509c6cc45612f673d465d6609 Mon Sep 17 00:00:00 2001
From: Jonathan Bobel
Date: Tue, 16 Apr 2024 10:57:47 -0400
Subject: [PATCH 07/17] Fixing pa11y scan
---
app/templates/error/500.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/templates/error/500.html b/app/templates/error/500.html
index af86388d7..aca8332df 100644
--- a/app/templates/error/500.html
+++ b/app/templates/error/500.html
@@ -7,7 +7,7 @@
Sorry, we can't deliver what you asked for right now.
- Please try again later or email us for more information.
+ Please try again later or email us for more information.
From 0044beaeeda071d6e7c0b406ecb3230ade4e33cd Mon Sep 17 00:00:00 2001
From: Carlo Costino
Date: Tue, 16 Apr 2024 11:46:57 -0400
Subject: [PATCH 08/17] Updated dependencies and ignore gunicorn audit flag
This changeset updates a couple of dependencies, including our Python dependency audit check, and specifically ignores a gunicorn audit flag that appeared on 4/16/2024.
As soon as there is an update available for gunicorn that addresses the issue we will remove the flag to ignore the vulnerability report and update the dependency.
Signed-off-by: Carlo Costino
---
.github/workflows/checks.yml | 4 ++-
poetry.lock | 53 ++++++++++++++++--------------------
2 files changed, 27 insertions(+), 30 deletions(-)
diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml
index be0a6cc66..ab6778272 100644
--- a/.github/workflows/checks.yml
+++ b/.github/workflows/checks.yml
@@ -157,9 +157,11 @@ jobs:
- uses: ./.github/actions/setup-project
- name: Create requirements.txt
run: poetry export --without-hashes --format=requirements.txt > requirements.txt
- - uses: pypa/gh-action-pip-audit@v1.0.6
+ - uses: pypa/gh-action-pip-audit@v1.0.8
with:
inputs: requirements.txt
+ ignore-vulns: |
+ GHSA-w3h3-4rj7-4ph4
- name: Run npm audit
run: make npm-audit
diff --git a/poetry.lock b/poetry.lock
index 21064bf51..13cfa6cfb 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -87,33 +87,33 @@ lxml = ["lxml"]
[[package]]
name = "black"
-version = "24.3.0"
+version = "24.4.0"
description = "The uncompromising code formatter."
optional = false
python-versions = ">=3.8"
files = [
- {file = "black-24.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395"},
- {file = "black-24.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995"},
- {file = "black-24.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7"},
- {file = "black-24.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0"},
- {file = "black-24.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9"},
- {file = "black-24.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597"},
- {file = "black-24.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d"},
- {file = "black-24.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5"},
- {file = "black-24.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f"},
- {file = "black-24.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11"},
- {file = "black-24.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4"},
- {file = "black-24.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5"},
- {file = "black-24.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837"},
- {file = "black-24.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd"},
- {file = "black-24.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213"},
- {file = "black-24.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959"},
- {file = "black-24.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb"},
- {file = "black-24.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7"},
- {file = "black-24.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7"},
- {file = "black-24.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f"},
- {file = "black-24.3.0-py3-none-any.whl", hash = "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93"},
- {file = "black-24.3.0.tar.gz", hash = "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f"},
+ {file = "black-24.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6ad001a9ddd9b8dfd1b434d566be39b1cd502802c8d38bbb1ba612afda2ef436"},
+ {file = "black-24.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3a3a092b8b756c643fe45f4624dbd5a389f770a4ac294cf4d0fce6af86addaf"},
+ {file = "black-24.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dae79397f367ac8d7adb6c779813328f6d690943f64b32983e896bcccd18cbad"},
+ {file = "black-24.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:71d998b73c957444fb7c52096c3843875f4b6b47a54972598741fe9a7f737fcb"},
+ {file = "black-24.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8e5537f456a22cf5cfcb2707803431d2feeb82ab3748ade280d6ccd0b40ed2e8"},
+ {file = "black-24.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64e60a7edd71fd542a10a9643bf369bfd2644de95ec71e86790b063aa02ff745"},
+ {file = "black-24.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cd5b4f76056cecce3e69b0d4c228326d2595f506797f40b9233424e2524c070"},
+ {file = "black-24.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:64578cf99b6b46a6301bc28bdb89f9d6f9b592b1c5837818a177c98525dbe397"},
+ {file = "black-24.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f95cece33329dc4aa3b0e1a771c41075812e46cf3d6e3f1dfe3d91ff09826ed2"},
+ {file = "black-24.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4396ca365a4310beef84d446ca5016f671b10f07abdba3e4e4304218d2c71d33"},
+ {file = "black-24.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44d99dfdf37a2a00a6f7a8dcbd19edf361d056ee51093b2445de7ca09adac965"},
+ {file = "black-24.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:21f9407063ec71c5580b8ad975653c66508d6a9f57bd008bb8691d273705adcd"},
+ {file = "black-24.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:652e55bb722ca026299eb74e53880ee2315b181dfdd44dca98e43448620ddec1"},
+ {file = "black-24.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7f2966b9b2b3b7104fca9d75b2ee856fe3fdd7ed9e47c753a4bb1a675f2caab8"},
+ {file = "black-24.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bb9ca06e556a09f7f7177bc7cb604e5ed2d2df1e9119e4f7d2f1f7071c32e5d"},
+ {file = "black-24.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:d4e71cdebdc8efeb6deaf5f2deb28325f8614d48426bed118ecc2dcaefb9ebf3"},
+ {file = "black-24.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6644f97a7ef6f401a150cca551a1ff97e03c25d8519ee0bbc9b0058772882665"},
+ {file = "black-24.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:75a2d0b4f5eb81f7eebc31f788f9830a6ce10a68c91fbe0fade34fff7a2836e6"},
+ {file = "black-24.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb949f56a63c5e134dfdca12091e98ffb5fd446293ebae123d10fc1abad00b9e"},
+ {file = "black-24.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:7852b05d02b5b9a8c893ab95863ef8986e4dda29af80bbbda94d7aee1abf8702"},
+ {file = "black-24.4.0-py3-none-any.whl", hash = "sha256:74eb9b5420e26b42c00a3ff470dc0cd144b80a766128b1771d07643165e08d0e"},
+ {file = "black-24.4.0.tar.gz", hash = "sha256:f07b69fda20578367eaebbd670ff8fc653ab181e1ff95d84497f9fa20e7d0641"},
]
[package.dependencies]
@@ -1210,7 +1210,6 @@ description = "Powerful and Pythonic XML processing library combining libxml2/li
optional = false
python-versions = ">=3.6"
files = [
- {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:704f5572ff473a5f897745abebc6df40f22d4133c1e0a1f124e4f2bd3330ff7e"},
{file = "lxml-5.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d3c0f8567ffe7502d969c2c1b809892dc793b5d0665f602aad19895f8d508da"},
{file = "lxml-5.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5fcfbebdb0c5d8d18b84118842f31965d59ee3e66996ac842e21f957eb76138c"},
{file = "lxml-5.1.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f37c6d7106a9d6f0708d4e164b707037b7380fcd0b04c5bd9cae1fb46a856fb"},
@@ -1220,7 +1219,6 @@ files = [
{file = "lxml-5.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82bddf0e72cb2af3cbba7cec1d2fd11fda0de6be8f4492223d4a268713ef2147"},
{file = "lxml-5.1.0-cp310-cp310-win32.whl", hash = "sha256:b66aa6357b265670bb574f050ffceefb98549c721cf28351b748be1ef9577d93"},
{file = "lxml-5.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:4946e7f59b7b6a9e27bef34422f645e9a368cb2be11bf1ef3cafc39a1f6ba68d"},
- {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:14deca1460b4b0f6b01f1ddc9557704e8b365f55c63070463f6c18619ebf964f"},
{file = "lxml-5.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed8c3d2cd329bf779b7ed38db176738f3f8be637bb395ce9629fc76f78afe3d4"},
{file = "lxml-5.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:436a943c2900bb98123b06437cdd30580a61340fbdb7b28aaf345a459c19046a"},
{file = "lxml-5.1.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:acb6b2f96f60f70e7f34efe0c3ea34ca63f19ca63ce90019c6cbca6b676e81fa"},
@@ -1230,7 +1228,6 @@ files = [
{file = "lxml-5.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4c9bda132ad108b387c33fabfea47866af87f4ea6ffb79418004f0521e63204"},
{file = "lxml-5.1.0-cp311-cp311-win32.whl", hash = "sha256:bc64d1b1dab08f679fb89c368f4c05693f58a9faf744c4d390d7ed1d8223869b"},
{file = "lxml-5.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5ab722ae5a873d8dcee1f5f45ddd93c34210aed44ff2dc643b5025981908cda"},
- {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9aa543980ab1fbf1720969af1d99095a548ea42e00361e727c58a40832439114"},
{file = "lxml-5.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6f11b77ec0979f7e4dc5ae081325a2946f1fe424148d3945f943ceaede98adb8"},
{file = "lxml-5.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a36c506e5f8aeb40680491d39ed94670487ce6614b9d27cabe45d94cd5d63e1e"},
{file = "lxml-5.1.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f643ffd2669ffd4b5a3e9b41c909b72b2a1d5e4915da90a77e119b8d48ce867a"},
@@ -1256,8 +1253,8 @@ files = [
{file = "lxml-5.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8f52fe6859b9db71ee609b0c0a70fea5f1e71c3462ecf144ca800d3f434f0764"},
{file = "lxml-5.1.0-cp37-cp37m-win32.whl", hash = "sha256:d42e3a3fc18acc88b838efded0e6ec3edf3e328a58c68fbd36a7263a874906c8"},
{file = "lxml-5.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:eac68f96539b32fce2c9b47eb7c25bb2582bdaf1bbb360d25f564ee9e04c542b"},
- {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae15347a88cf8af0949a9872b57a320d2605ae069bcdf047677318bc0bba45b1"},
{file = "lxml-5.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c26aab6ea9c54d3bed716b8851c8bfc40cb249b8e9880e250d1eddde9f709bf5"},
+ {file = "lxml-5.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cfbac9f6149174f76df7e08c2e28b19d74aed90cad60383ad8671d3af7d0502f"},
{file = "lxml-5.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:342e95bddec3a698ac24378d61996b3ee5ba9acfeb253986002ac53c9a5f6f84"},
{file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:725e171e0b99a66ec8605ac77fa12239dbe061482ac854d25720e2294652eeaa"},
{file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d184e0d5c918cff04cdde9dbdf9600e960161d773666958c9d7b565ccc60c45"},
@@ -1265,7 +1262,6 @@ files = [
{file = "lxml-5.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d48fc57e7c1e3df57be5ae8614bab6d4e7b60f65c5457915c26892c41afc59e"},
{file = "lxml-5.1.0-cp38-cp38-win32.whl", hash = "sha256:7ec465e6549ed97e9f1e5ed51c657c9ede767bc1c11552f7f4d022c4df4a977a"},
{file = "lxml-5.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:b21b4031b53d25b0858d4e124f2f9131ffc1530431c6d1321805c90da78388d1"},
- {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:52427a7eadc98f9e62cb1368a5079ae826f94f05755d2d567d93ee1bc3ceb354"},
{file = "lxml-5.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a2a2c724d97c1eb8cf966b16ca2915566a4904b9aad2ed9a09c748ffe14f969"},
{file = "lxml-5.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:843b9c835580d52828d8f69ea4302537337a21e6b4f1ec711a52241ba4a824f3"},
{file = "lxml-5.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b99f564659cfa704a2dd82d0684207b1aadf7d02d33e54845f9fc78e06b7581"},
@@ -1516,7 +1512,6 @@ files = [
{file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"},
{file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"},
{file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"},
- {file = "msgpack-1.0.8-py3-none-any.whl", hash = "sha256:24f727df1e20b9876fa6e95f840a2a2651e34c0ad147676356f4bf5fbb0206ca"},
{file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"},
]
From f30899d762a369aac2b822e83e4eedf0365e16f7 Mon Sep 17 00:00:00 2001
From: Kenneth Kehl <@kkehl@flexion.us>
Date: Tue, 16 Apr 2024 12:06:33 -0700
Subject: [PATCH 09/17] fix 90 day email validation
---
app/main/views/sign_in.py | 35 ++++++++++++++++++++++++++++++++---
1 file changed, 32 insertions(+), 3 deletions(-)
diff --git a/app/main/views/sign_in.py b/app/main/views/sign_in.py
index 6de46b023..88360dca3 100644
--- a/app/main/views/sign_in.py
+++ b/app/main/views/sign_in.py
@@ -6,6 +6,7 @@ import jwt
import requests
from flask import (
Markup,
+ Response,
abort,
current_app,
flash,
@@ -26,6 +27,7 @@ from app.main.views.verify import activate_user
from app.models.user import InvitedUser, User
from app.utils import hide_from_search_engines
from app.utils.login import is_safe_redirect_url
+from app.utils.time import is_less_than_days_ago
def _reformat_keystring(orig):
@@ -100,20 +102,47 @@ def _do_login_dot_gov():
user_email, user_uuid = _get_user_email_and_uuid(access_token)
redirect_url = request.args.get("next")
user = user_api_client.get_user_by_uuid_or_email(user_uuid, user_email)
- activate_user(user["id"])
+
+ # Check if the email needs to be revalidated
+ is_fresh_email = is_less_than_days_ago(
+ user["email_access_validated_at"], 90
+ )
+ if not is_fresh_email:
+ return verify_email(user, redirect_url)
+
+ usr = User.from_email_address(user["email_address"])
+ activate_user(usr.id)
except BaseException as be: # noqa B036
current_app.logger.error(be)
error(401)
-
return redirect(url_for("main.show_accounts_or_dashboard", next=redirect_url))
# end login.gov
+def verify_email(user, redirect_url):
+ user_api_client.send_verify_code(user["id"], "email", None, redirect_url)
+ title = "Email resent" if request.args.get("email_resent") else "Check your email"
+ redirect_url = request.args.get("next")
+ return render_template(
+ "views/re-validate-email-sent.html", title=title, redirect_url=redirect_url
+ )
+
+
@main.route("/sign-in", methods=(["GET", "POST"]))
@hide_from_search_engines
def sign_in():
- _do_login_dot_gov()
+ # If we have to revalidated the email, send the message
+ # via email and redirect to the "verify your email page"
+ # and don't proceed further with login
+ email_verify_template = _do_login_dot_gov()
+ if (
+ email_verify_template
+ and not isinstance(email_verify_template, Response)
+ and "Check your email" in email_verify_template
+ ):
+ return email_verify_template
+
redirect_url = request.args.get("next")
if os.getenv("NOTIFY_E2E_TEST_EMAIL"):
From e14fc8b6542ca8f3a078a9bb415095ab4f107423 Mon Sep 17 00:00:00 2001
From: Jonathan Bobel
Date: Wed, 17 Apr 2024 11:03:45 -0400
Subject: [PATCH 10/17] Changed the flag to true
---
app/main/views/service_settings.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py
index 7d301426f..a006845a8 100644
--- a/app/main/views/service_settings.py
+++ b/app/main/views/service_settings.py
@@ -650,7 +650,7 @@ def service_set_channel(service_id, channel):
def service_set_auth_type(service_id):
return render_template(
"views/service-settings/set-auth-type.html",
- login_gov_enabled=False,
+ login_gov_enabled=True,
)
From 8596a9cdb33b59cada29f03c8170817ab36ef63d Mon Sep 17 00:00:00 2001
From: Jonathan Bobel
Date: Wed, 17 Apr 2024 11:26:14 -0400
Subject: [PATCH 11/17] Removing the email and password fields in the settings
area because login.gov will take care of this
---
app/templates/views/user-profile.html | 25 -------------------------
1 file changed, 25 deletions(-)
diff --git a/app/templates/views/user-profile.html b/app/templates/views/user-profile.html
index d3e6ff7c8..88f2f1668 100644
--- a/app/templates/views/user-profile.html
+++ b/app/templates/views/user-profile.html
@@ -27,21 +27,6 @@
}}
{% endcall %}
- {% call row() %}
- {{ text_field('Email address') }}
- {{ text_field(current_user.email_address) }}
- {% if can_see_edit %}
- {{ edit_field(
- 'Change',
- url_for('.user_profile_email'),
- suffix='email address'
- )
- }}
- {% else %}
- {{ text_field('') }}
- {% endif %}
- {% endcall %}
-
{% call row() %}
{{ text_field('Mobile number') }}
{{ optional_text_field(current_user.mobile_number) }}
@@ -53,16 +38,6 @@
}}
{% endcall %}
- {% call row() %}
- {{ text_field('Password') }}
- {{ text_field('Last changed ' + current_user.password_changed_at|format_delta) }}
- {{ edit_field(
- 'Change',
- url_for('.user_profile_password'),
- suffix='password'
- )
- }}
- {% endcall %}
{% call row() %}
{{ text_field('Preferred Timezone') }}
{{ optional_text_field(current_user.preferred_timezone) }}
From 7755e02ad88a816a9cfbc03be1b24490ad5d7733 Mon Sep 17 00:00:00 2001
From: Jonathan Bobel
Date: Wed, 17 Apr 2024 11:49:47 -0400
Subject: [PATCH 12/17] Removing instances of the login_gov_enabled flag as it
will be live with this push to production
---
app/main/views/service_settings.py | 1 -
.../views/service-settings/set-auth-type.html | 30 ++-----------------
2 files changed, 3 insertions(+), 28 deletions(-)
diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py
index a006845a8..628ac59e5 100644
--- a/app/main/views/service_settings.py
+++ b/app/main/views/service_settings.py
@@ -650,7 +650,6 @@ def service_set_channel(service_id, channel):
def service_set_auth_type(service_id):
return render_template(
"views/service-settings/set-auth-type.html",
- login_gov_enabled=True,
)
diff --git a/app/templates/views/service-settings/set-auth-type.html b/app/templates/views/service-settings/set-auth-type.html
index 2fa545a4c..2fd5259f8 100644
--- a/app/templates/views/service-settings/set-auth-type.html
+++ b/app/templates/views/service-settings/set-auth-type.html
@@ -16,33 +16,9 @@
{{ page_header('Sign-in method') }}
-
- {% if login_gov_enabled %}
-
Your username, password, and multi-factor authentication options are handled by Login.gov.
-
To make changes, head to Login.gov and sign-in with your credentials.
-
Any changes made to your Login.gov account will automatically be synced with Notify.gov.
- {% elif 'email_auth' in current_service.permissions and not login_gov_enabled %}
-
- Email link or text message code
-
-
- Your team members can sign in with either a text message code
- or an email link.
-
-
- You can set the sign-in method for individual team members.
-
- {% else %}
-
- Text message code
-
-
- Your team members sign in with a text message code.
-
-
- Contact us if signing in with a text message is a problem for your team.
-
- {% endif %}
+
Your username, password, and multi-factor authentication options are handled by Login.gov.
+
To make changes, head to Login.gov and sign-in with your credentials.
+
Any changes made to your Login.gov account will automatically be synced with Notify.gov.
From 78c08e69f78eaa109519dfdbf12739d41d3f180b Mon Sep 17 00:00:00 2001
From: Jonathan Bobel
Date: Wed, 17 Apr 2024 12:01:37 -0400
Subject: [PATCH 13/17] Fixed failing test
---
.../views/service_settings/test_service_settings.py | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
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 b87ef12d5..462910406 100644
--- a/tests/app/main/views/service_settings/test_service_settings.py
+++ b/tests/app/main/views/service_settings/test_service_settings.py
@@ -2545,11 +2545,19 @@ def test_send_files_by_email_contact_details_does_not_update_invalid_contact_det
@pytest.mark.parametrize(
("endpoint", "permissions", "expected_p"),
[
- ("main.service_set_auth_type", [], ("Text message code")),
+ (
+ "main.service_set_auth_type",
+ [],
+ (
+ "Your username, password, and multi-factor authentication options are handled by Login.gov."
+ ),
+ ),
(
"main.service_set_auth_type",
["email_auth"],
- ("Email link or text message code"),
+ (
+ "Your username, password, and multi-factor authentication options are handled by Login.gov."
+ ),
),
],
)
From 7bd9c748e5735e48674719b4b29e1aa35f692733 Mon Sep 17 00:00:00 2001
From: Jonathan Bobel
Date: Wed, 17 Apr 2024 12:39:10 -0400
Subject: [PATCH 14/17] 1436 - small content change for mobile number hint
---
app/templates/views/set-up-your-profile.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/templates/views/set-up-your-profile.html b/app/templates/views/set-up-your-profile.html
index 8f37d3617..e774a921f 100644
--- a/app/templates/views/set-up-your-profile.html
+++ b/app/templates/views/set-up-your-profile.html
@@ -16,7 +16,7 @@ Set up your profile
{{ form.name(param_extensions={}) }}