Skip to content

Commit

Permalink
Merge pull request #9554 from PieterL75/issue_9536
Browse files Browse the repository at this point in the history
Closes #9536: Last Used field on API tokens
  • Loading branch information
jeremystretch authored Jun 23, 2022
2 parents f563ba7 + cfb9605 commit 4f33685
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 1 deletion.
15 changes: 15 additions & 0 deletions netbox/netbox/api/authentication.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import logging

from django.conf import settings
from django.utils import timezone
from rest_framework import authentication, exceptions
from rest_framework.permissions import BasePermission, DjangoObjectPermissions, SAFE_METHODS

from netbox.config import get_config
from users.models import Token
from utilities.request import get_client_ip

Expand Down Expand Up @@ -40,6 +44,17 @@ def authenticate_credentials(self, key):
except model.DoesNotExist:
raise exceptions.AuthenticationFailed("Invalid token")

# Update last used, but only once a minute. This reduces the write load on the db
if not token.last_used or (timezone.now() - token.last_used).total_seconds() > 60:
# If maintenance mode is enabled, assume the database is read-only, and disable updating the token's
# last_used time upon authentication.
if get_config().MAINTENANCE_MODE:
logger = logging.getLogger('netbox.auth.login')
logger.warning("Maintenance mode enabled: disabling update of token's last used timestamp")
else:
token.last_used = timezone.now()
token.save()

# Enforce the Token's expiration time, if one has been set.
if token.is_expired:
raise exceptions.AuthenticationFailed("Token expired")
Expand Down
8 changes: 8 additions & 0 deletions netbox/templates/users/api_tokens.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@
<span>Never</span>
{% endif %}
</div>
<div class="col col-md-3">
<small class="text-muted">Last Used</small><br />
{% if token.last_used %}
{{ token.last_used|annotated_date }}
{% else %}
<span>Never</span>
{% endif %}
</div>
<div class="col col-md-3">
<small class="text-muted">Create/Edit/Delete Operations</small><br />
{% if token.write_enabled %}
Expand Down
2 changes: 1 addition & 1 deletion netbox/users/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def get_inlines(self, request, obj):
class TokenAdmin(admin.ModelAdmin):
form = forms.TokenAdminForm
list_display = [
'key', 'user', 'created', 'expires', 'write_enabled', 'description', 'list_allowed_ips'
'key', 'user', 'created', 'expires', 'last_used', 'write_enabled', 'description', 'list_allowed_ips'
]

def list_allowed_ips(self, obj):
Expand Down
18 changes: 18 additions & 0 deletions netbox/users/migrations/0003_token_last_used.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.0.4 on 2022-06-16 15:26

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('users', '0002_standardize_id_fields'),
]

operations = [
migrations.AddField(
model_name='token',
name='last_used',
field=models.DateTimeField(blank=True, null=True),
),
]
4 changes: 4 additions & 0 deletions netbox/users/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ class Token(models.Model):
blank=True,
null=True
)
last_used = models.DateTimeField(
blank=True,
null=True
)
key = models.CharField(
max_length=40,
unique=True,
Expand Down

0 comments on commit 4f33685

Please sign in to comment.