Skip to content

Commit 3e1bfb5

Browse files
authored
[HIDP-194] Add last_usage field to OpenIdConnection model (#336)
2 parents 20ccc58 + ec177d3 commit 3e1bfb5

File tree

6 files changed

+50
-1
lines changed

6 files changed

+50
-1
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Generated by Django 5.2 on 2025-05-08 09:11
2+
3+
import django.utils.timezone
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('hidp_federated', '0001_initial'),
11+
]
12+
13+
operations = [
14+
migrations.AddField(
15+
model_name='openidconnection',
16+
name='last_usage',
17+
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='last usage of this connection'),
18+
),
19+
]

packages/hidp/hidp/federated/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from django.conf import settings
22
from django.db import models
3+
from django.utils import timezone
34
from django.utils.text import format_lazy
45
from django.utils.translation import gettext_lazy as _
56

@@ -53,6 +54,10 @@ class OpenIdConnection(models.Model):
5354
# Unique identifier for the user at the identity provider (i.e. the "sub" claim)
5455
# Guaranteed to be unique together with the issuer_claim.
5556
subject_claim = models.CharField(max_length=255)
57+
# The last time the user used this OpenID connection.
58+
last_usage = models.DateTimeField(
59+
_("last usage of this connection"), default=timezone.now
60+
)
5661

5762
# Manager
5863
objects = OpenIdConnectionQuerySet.as_manager()

packages/hidp/hidp/federated/views.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
HttpResponseRedirect,
1212
)
1313
from django.urls import reverse, reverse_lazy
14+
from django.utils import timezone
1415
from django.utils.decorators import method_decorator
1516
from django.utils.http import url_has_allowed_host_and_scheme
1617
from django.utils.text import format_lazy
@@ -180,6 +181,10 @@ def get_next_url( # noqa: PLR6301 (no-self-use)
180181
user_info=user_info,
181182
)
182183
view_name = "hidp_oidc_client:login"
184+
185+
# Update the last used date of the connection.
186+
connection.last_usage = timezone.now()
187+
connection.save()
183188
elif request.user.is_authenticated:
184189
# `sub` claim does not match an existing user:
185190
# Display a form allowing the user to link the OIDC account.

packages/hidp/hidp/locale/django.pot

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,10 @@ msgstr ""
191191
msgid "Unknown provider: {provider_key}"
192192
msgstr ""
193193

194+
#: hidp/federated/models.py
195+
msgid "last usage of this connection"
196+
msgstr ""
197+
194198
#: hidp/federated/views.py
195199
msgid "An unexpected error occurred during authentication. Please try again."
196200
msgstr ""

packages/hidp/hidp/locale/nl/LC_MESSAGES/django.po

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,10 @@ msgstr "OpenID-koppelingen"
192192
msgid "Unknown provider: {provider_key}"
193193
msgstr "Onbekende dienst: {provider_key}"
194194

195+
#: hidp/federated/models.py
196+
msgid "last usage of this connection"
197+
msgstr "laatste gebruik van deze koppeling"
198+
195199
#: hidp/federated/views.py
196200
msgid "An unexpected error occurred during authentication. Please try again."
197201
msgstr "Onverwachte fout tijdens authenticatie. Probeer het opnieuw."

packages/hidp/tests/smoke_tests/test_federated/test_views.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,12 +271,16 @@ def test_redirect_to_register(self, mock_handle_authentication_callback):
271271
)
272272
def test_redirect_to_login(self, mock_handle_authentication_callback):
273273
user = user_factories.VerifiedUserFactory()
274-
models.OpenIdConnection.objects.create(
274+
connection = models.OpenIdConnection.objects.create(
275275
user=user,
276276
provider_key="example",
277277
issuer_claim="example",
278278
subject_claim="test_subject",
279279
)
280+
281+
# Save original timestamp for comparison
282+
original_last_usage = connection.last_usage
283+
280284
response = self.client.get(
281285
reverse("hidp_oidc_client:callback", kwargs={"provider_key": "example"}),
282286
secure=True,
@@ -289,6 +293,14 @@ def test_redirect_to_login(self, mock_handle_authentication_callback):
289293
token = query["token"][0]
290294
self.assertIn(token, self.client.session)
291295

296+
# Refresh from DB and assert last_usage was updated
297+
connection.refresh_from_db()
298+
self.assertIsNotNone(connection.last_usage)
299+
self.assertGreater(
300+
connection.last_usage,
301+
original_last_usage,
302+
)
303+
292304
@mock.patch(
293305
"hidp.federated.views.authorization_code_flow.handle_authentication_callback",
294306
return_value=(*_VALID_AUTH_CALLBACK, None),

0 commit comments

Comments
 (0)