Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 2024.07.1 #2196

Merged
merged 28 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
352bca9
chore(pre-commit): autoupdate hooks
pre-commit-ci[bot] Jun 17, 2024
3791eff
chore(deps): bump docker/build-push-action from 5 to 6
dependabot[bot] Jun 17, 2024
52c8e93
chore(deps): bump mkdocs-material from 9.5.26 to 9.5.27
dependabot[bot] Jun 17, 2024
20a7016
chore: Revert "Revert "Feat: enrollments can expire (#1989)" (#2052)"
angela-tran Jun 13, 2024
5057968
chore: update sample fixtures to show expiry example
angela-tran Jun 13, 2024
6088407
chore(deps-dev): bump cypress from 13.11.0 to 13.12.0 in /tests/cypress
dependabot[bot] Jun 19, 2024
bcb9b1e
Feat: enrollments can expire (#2165)
angela-tran Jun 20, 2024
fa8bd67
refactor(templates): consolidate login.gov media item into one template
angela-tran Jun 20, 2024
7a18294
chore(deps): bump treosh/lighthouse-ci-action from 11.4.0 to 12.1.0
dependabot[bot] Jun 21, 2024
53bc0c2
Refactor: consolidate Login.gov media item templates (#2180)
angela-tran Jun 24, 2024
de0eac2
chore(pre-commit): autoupdate hooks (#2170)
angela-tran Jun 24, 2024
d7727cf
chore(deps): bump docker/build-push-action from 5 to 6 (#2172)
angela-tran Jun 24, 2024
d2dc04f
chore(deps): bump mkdocs-material from 9.5.26 to 9.5.27 (#2173)
angela-tran Jun 24, 2024
690d497
chore(deps-dev): bump cypress from 13.11.0 to 13.12.0 in /tests/cypre…
angela-tran Jun 24, 2024
80a22c1
chore(deps): bump treosh/lighthouse-ci-action from 11.4.0 to 12.1.0 (…
angela-tran Jun 24, 2024
64e4248
fix(enrollment): fix changing languages on enrollment success
lalver1 Jun 20, 2024
d49aa6b
Fix: changing languages on the enrollment success page (#2179)
lalver1 Jun 24, 2024
3f1296c
fix(oauth): fix client not registered exception in logout
lalver1 Jun 25, 2024
71180b6
Fix: oauth client not registered exception in logout (#2185)
lalver1 Jul 2, 2024
0391d63
chore(deps): bump calitp-littlepay from 2024.6.1 to 2024.7.1
dependabot[bot] Jul 3, 2024
186cfb1
chore(deps): bump azure-identity from 1.16.1 to 1.17.1
dependabot[bot] Jun 24, 2024
d42ef2f
chore(deps): bump azure-identity from 1.16.1 to 1.17.1 (#2183)
angela-tran Jul 3, 2024
b72f8db
chore(deps): bump calitp-littlepay from 2024.6.1 to 2024.7.1 (#2192)
lalver1 Jul 3, 2024
8e6b928
chore(deps): bump sentry-sdk from 2.5.1 to 2.7.1
dependabot[bot] Jul 3, 2024
6120e60
chore(deps): bump sentry-sdk from 2.5.1 to 2.7.1 (#2187)
angela-tran Jul 3, 2024
7d193df
chore(pyproject): bump version
thekaveman Jul 3, 2024
4b52d3f
Chore: bump version for 2024.07.1 (#2193)
thekaveman Jul 3, 2024
b97aa48
Deploy 2024.07.1 to test (#2194)
lalver1 Jul 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
uses: docker/setup-buildx-action@v3

- name: Build, tag, and push image to GitHub Container Registry
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
builder: ${{ steps.buildx.outputs.name }}
build-args: GIT-SHA=${{ github.sha }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests-ui.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
docker compose up --detach client

- name: Run Lighthouse tests for a11y
uses: treosh/lighthouse-ci-action@11.4.0
uses: treosh/lighthouse-ci-action@12.1.0
with:
urls: |
http://localhost:8000
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ repos:
- python

- repo: https://github.com/PyCQA/flake8
rev: 7.0.0
rev: 7.1.0
hooks:
- id: flake8
types:
- python

- repo: https://github.com/pycqa/bandit
rev: 1.7.8
rev: 1.7.9
hooks:
- id: bandit
args: ["-ll"]
Expand Down
7 changes: 6 additions & 1 deletion benefits/core/migrations/local_fixtures.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,12 @@
"fields": {
"name": "calfresh",
"label": "CalFresh",
"group_id": "group123"
"group_id": "group123",
"supports_expiration": "True",
"expiration_days": 5,
"expiration_reenrollment_days": 3,
"reenrollment_error_template": "enrollment/reenrollment-error--calfresh.html",
"enrollment_success_template": "enrollment/success--mst.html"
}
},
{
Expand Down
1 change: 1 addition & 0 deletions benefits/core/templates/core/includes/lang-selector.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<form method="post" action="{% url "set_language" %}">
{% csrf_token %}
{% get_language_info for code as langinfo %}
<input name="next" type="hidden" value="{{ redirect_to }}" />
<input name="language" type="hidden" value="{{ code }}" />
<button class="btn btn-lg btn-outline-light" type="submit">{{ langinfo.name_local | capfirst }}</button>
</form>
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ <h1>{% translate "You selected a CalFresh Cardholder transit benefit." %}</h1>
{% endblock headline %}

{% block media-item %}
{% include "eligibility/includes/media-item--idcardcheck--start--calfresh.html" %}
{% include "eligibility/includes/media-item--idcardcheck--start--login-gov.html" %}
{% endblock media-item %}

{% block call-to-action %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ <h1>{% translate "You selected an Older Adult transit benefit." %}</h1>
{% endblock headline %}

{% block media-item %}
{% include "eligibility/includes/media-item--idcardcheck--start--senior.html" %}
{% include "eligibility/includes/media-item--idcardcheck--start--login-gov.html" %}
{% endblock media-item %}

{% block call-to-action %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ <h1>{% translate "You selected a Veteran transit benefit." %}</h1>
{% endblock headline %}

{% block media-item %}
{% include "eligibility/includes/media-item--idcardcheck--start--veteran.html" %}
{% include "eligibility/includes/media-item--idcardcheck--start--login-gov.html" %}
{% endblock media-item %}

{% block call-to-action %}
Expand Down
110 changes: 97 additions & 13 deletions benefits/enrollment/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
"""

import logging
from datetime import timedelta

from django.http import JsonResponse
from django.template.response import TemplateResponse
from django.urls import reverse
from django.utils import timezone
from django.utils.decorators import decorator_from_middleware
from littlepay.api.client import Client
from requests.exceptions import HTTPError
Expand Down Expand Up @@ -92,7 +94,6 @@ def index(request):
if not form.is_valid():
raise Exception("Invalid card token form")

logger.debug("Read tokenized card")
card_token = form.cleaned_data.get("card_token")

client = Client(
Expand All @@ -104,17 +105,69 @@ def index(request):
client.oauth.ensure_active_token(client.token)

funding_source = client.get_funding_source_by_token(card_token)
group_id = eligibility.group_id

try:
client.link_concession_group_funding_source(funding_source_id=funding_source.id, group_id=eligibility.group_id)
group_funding_source = _get_group_funding_source(
client=client, group_id=group_id, funding_source_id=funding_source.id
)

already_enrolled = group_funding_source is not None

if eligibility.supports_expiration:
# set expiry on session
if already_enrolled and group_funding_source.expiry_date is not None:
session.update(request, enrollment_expiry=group_funding_source.expiry_date)
else:
session.update(request, enrollment_expiry=_calculate_expiry(eligibility.expiration_days))

if not already_enrolled:
# enroll user with an expiration date, return success
client.link_concession_group_funding_source(
group_id=group_id, funding_source_id=funding_source.id, expiry=session.enrollment_expiry(request)
)
return success(request)
else: # already_enrolled
if group_funding_source.expiry_date is None:
# update expiration of existing enrollment, return success
client.update_concession_group_funding_source_expiry(
group_id=group_id,
funding_source_id=funding_source.id,
expiry=session.enrollment_expiry(request),
)
return success(request)
else:
is_expired = _is_expired(group_funding_source.expiry_date)
is_within_reenrollment_window = _is_within_reenrollment_window(
group_funding_source.expiry_date, session.enrollment_reenrollment(request)
)

if is_expired or is_within_reenrollment_window:
# update expiration of existing enrollment, return success
client.update_concession_group_funding_source_expiry(
group_id=group_id,
funding_source_id=funding_source.id,
expiry=session.enrollment_expiry(request),
)
return success(request)
else:
# re-enrollment error, return enrollment error with expiration and reenrollment_date
return reenrollment_error(request)
else: # eligibility does not support expiration
if not already_enrolled:
# enroll user with no expiration date, return success
client.link_concession_group_funding_source(group_id=group_id, funding_source_id=funding_source.id)
return success(request)
else: # already_enrolled
if group_funding_source.expiry_date is None:
# no action, return success
return success(request)
else:
# remove expiration date, return success
raise NotImplementedError("Removing expiration date is currently not supported")

except HTTPError as e:
# 409 means that customer already belongs to a concession group.
# the response JSON will look like:
# {"errors":[{"detail":"Conflict (409) - Customer already belongs to a concession group."}]}
if e.response.status_code == 409:
analytics.returned_success(request, eligibility.group_id)
return success(request)
elif e.response.status_code >= 500:
if e.response.status_code >= 500:
analytics.returned_error(request, str(e))
sentry_sdk.capture_exception(e)

Expand All @@ -125,9 +178,6 @@ def index(request):
except Exception as e:
analytics.returned_error(request, str(e))
raise e
else:
analytics.returned_success(request, eligibility.group_id)
return success(request)

# GET enrollment index
else:
Expand All @@ -154,6 +204,37 @@ def index(request):
return TemplateResponse(request, eligibility.enrollment_index_template, context)


def _get_group_funding_source(client: Client, group_id, funding_source_id):
group_funding_sources = client.get_concession_group_linked_funding_sources(group_id)
matching_group_funding_source = None
for group_funding_source in group_funding_sources:
if group_funding_source.id == funding_source_id:
matching_group_funding_source = group_funding_source
break

return matching_group_funding_source


def _is_expired(expiry_date):
"""Returns whether the passed in datetime is expired or not."""
return expiry_date <= timezone.now()


def _is_within_reenrollment_window(expiry_date, enrollment_reenrollment_date):
"""Returns if we are currently within the reenrollment window."""
return enrollment_reenrollment_date <= timezone.now() < expiry_date


def _calculate_expiry(expiration_days):
"""Returns the expiry datetime, which should be midnight in our configured timezone of the (N + 1)th day from now,
where N is expiration_days."""
default_time_zone = timezone.get_default_timezone()
expiry_date = timezone.localtime(timezone=default_time_zone) + timedelta(days=expiration_days + 1)
expiry_datetime = expiry_date.replace(hour=0, minute=0, second=0, microsecond=0)

return expiry_datetime


@decorator_from_middleware(EligibleSessionRequired)
def reenrollment_error(request):
"""View handler for a re-enrollment attempt that is not yet within the re-enrollment window."""
Expand Down Expand Up @@ -192,6 +273,7 @@ def system_error(request):


@pageview_decorator
@decorator_from_middleware(EligibleSessionRequired)
@decorator_from_middleware(VerifierSessionRequired)
def success(request):
"""View handler for the final success page."""
Expand All @@ -206,4 +288,6 @@ def success(request):
# if they click the logout button, they are taken to the new route
session.update(request, origin=reverse(ROUTE_LOGGED_OUT))

return TemplateResponse(request, eligibility.enrollment_success_template)
analytics.returned_success(request, eligibility.group_id)
context = {"redirect_to": request.path}
return TemplateResponse(request, eligibility.enrollment_success_template, context)
2 changes: 1 addition & 1 deletion benefits/oauth/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def cancel(request):
def logout(request):
"""View implementing OIDC and application sign out."""
verifier = session.verifier(request)
oauth_client = oauth.create_client(verifier.auth_provider.client_name)
oauth_client = create_client(oauth, verifier.auth_provider)

if not oauth_client:
raise Exception(f"oauth_client not registered: {verifier.auth_provider.client_name}")
Expand Down
6 changes: 5 additions & 1 deletion benefits/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,11 @@ def RUNTIME_ENVIRONMENT():

USE_I18N = True

TIME_ZONE = "UTC"
# See https://docs.djangoproject.com/en/5.0/ref/settings/#std-setting-TIME_ZONE
# > Note that this isn’t necessarily the time zone of the server.
# > When USE_TZ is True, this is the default time zone that Django will use to display datetimes in templates
# > and to interpret datetimes entered in forms.
TIME_ZONE = "America/Los_Angeles"
USE_TZ = True

# https://docs.djangoproject.com/en/5.0/topics/i18n/formatting/#creating-custom-format-files
Expand Down
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ mdx_truly_sane_lists
mkdocs==1.6.0
mkdocs-awesome-pages-plugin
mkdocs-macros-plugin
mkdocs-material==9.5.26
mkdocs-material==9.5.27
mkdocs-redirects
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "benefits"
version = "2024.06.1"
version = "2024.07.1"
description = "Cal-ITP Benefits is an application that enables automated eligibility verification and enrollment for transit benefits onto customers’ existing contactless bank (credit/debit) cards."
readme = "README.md"
license = { file = "LICENSE" }
Expand All @@ -9,15 +9,15 @@ requires-python = ">=3.9"
dependencies = [
"Authlib==1.3.1",
"azure-keyvault-secrets==4.8.0",
"azure-identity==1.16.1",
"azure-identity==1.17.1",
"Django==5.0.6",
"django-csp==3.8",
"django-admin-sortable2==2.2.1",
"django-google-sso==6.2.1",
"eligibility-api==2023.9.1",
"calitp-littlepay==2024.6.1",
"calitp-littlepay==2024.7.1",
"requests==2.32.3",
"sentry-sdk==2.5.1",
"sentry-sdk==2.7.1",
"six==1.16.0",
]

Expand Down
14 changes: 7 additions & 7 deletions tests/cypress/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading