Merge pull request #9554 from PieterL75/issue_9536

Closes #9536: Last Used field on API tokens
This commit is contained in:
Jeremy Stretch 2022-06-23 11:53:58 -04:00 committed by GitHub
commit 4f33685ca7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 1 deletions

View File

@ -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
@ -40,6 +44,17 @@ class TokenAuthentication(authentication.TokenAuthentication):
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")

View File

@ -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 %}

View File

@ -58,7 +58,7 @@ class UserAdmin(UserAdmin_):
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):

View File

@ -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),
),
]

View File

@ -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,