Skip to content

Conversation

@pheus
Copy link
Contributor

@pheus pheus commented Nov 21, 2025

Fixes: #20823

This PR adds model-level validation to prevent creating API tokens with an expiration date in the past, while still allowing updates to existing tokens (including already-expired ones).

Changes:

  • Updates Token.clean() to raise a ValidationError when creating a new token (pk is None) whose expires timestamp is already in the past.
  • Leaves updates to existing tokens unchanged so that expired tokens can still be modified as needed.
  • Adds tests in users/tests/test_models.py covering:
    • the Token.is_expired property for None, future, and past expiration times
    • creation of tokens with a past expiration date
    • updates to existing expired tokens

No database or API schema changes are introduced by this PR.

Add model-level validation to prevent creating tokens with a past
expiration date. Updates to existing tokens are still allowed, ensuring
flexibility for expired token modifications.
Includes test cases to verify this behavior.

Fixes netbox-community#20823
@jeremystretch jeremystretch requested review from a team and jnovinger and removed request for a team November 21, 2025 14:29
# Prevent creating a token with a past expiration date
# while allowing updates to existing tokens.
if self.pk is None and self.is_expired:
raise ValidationError({'expires': _('Expiration time must be in the future.')})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should consider giving the user some feedback here on what the current date, time, and timezone the server expects are. NetBox's settings.py defaults to UTC if an installation's config does not set a custom TIME_ZONE setting, which actually tripped me up when I was testing this locally as I didn't have it set and so was confused why this wasn't working for something just 15 mins ahead of the current time (I'm UTC-6:00 at the moment).

I'm not arguing that we should include it by default in the UI, but perhaps just when this validation error is raised. You can look at netbox.tables.columns.DateTimeColumn to see how we've accessed the TIME_ZONE setting and displayed it in table columns, although you may need to format it a little differently here. I would also review Django's docs on internationalization to find the best way to include a dynamic element like that in a translatable string.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detailed review and for pointing out the timezone behavior! That context about the default UTC setting and DateTimeColumn is really helpful.

I’ll look into surfacing the server’s current date/time and timezone when this validation error is raised and make sure it’s done in a way that plays nicely with Django’s i18n and translations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prevent Creation Of API Token With Expiration In Past

2 participants