Skip to content

Commit c5ffb95

Browse files
authored
Fix for returning expired token during authentication (#10228) (#10233)
1 parent cfd741c commit c5ffb95

File tree

2 files changed

+26
-26
lines changed

2 files changed

+26
-26
lines changed

src/backend/InvenTree/users/api.py

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""DRF API definition for the 'users' app."""
22

3-
import datetime
43
import logging
54

65
from django.contrib.auth import authenticate, get_user, login, logout
@@ -326,24 +325,7 @@ def get(self, request, *args, **kwargs):
326325
user = request.user
327326
name = request.query_params.get('name', '')
328327

329-
name = ApiToken.sanitize_name(name)
330-
331-
today = datetime.date.today()
332-
333-
# Find existing token, which has not expired
334-
token = ApiToken.objects.filter(
335-
user=user, name=name, revoked=False, expiry__gte=today
336-
).first()
337-
338-
if not token:
339-
# User is authenticated, and requesting a token against the provided name.
340-
token = ApiToken.objects.create(user=request.user, name=name)
341-
342-
logger.info(
343-
"Created new API token for user '%s' (name='%s')",
344-
user.username,
345-
name,
346-
)
328+
token = ApiToken.get_or_create(user=user, token_name=name)
347329

348330
# Add some metadata about the request
349331
token.set_metadata('user_agent', request.headers.get('user-agent', ''))

src/backend/InvenTree/users/models.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,9 @@ def default_token_expiry():
5858

5959
def default_create_token(token_model, user, serializer):
6060
"""Generate a default value for the token."""
61-
token = token_model.objects.filter(user=user, name='', revoked=False)
62-
63-
if token.exists():
64-
return token.first()
65-
66-
else:
67-
return token_model.objects.create(user=user, name='')
61+
# this implementation only works for inventree API tokens
62+
assert token_model is ApiToken
63+
return ApiToken.get_or_create(user=user, token_name='')
6864

6965

7066
class ApiToken(AuthToken, InvenTree.models.MetadataMixin):
@@ -94,6 +90,28 @@ def generate_key(cls, prefix='inv-'):
9490

9591
return prefix + str(AuthToken.generate_key()) + suffix
9692

93+
@classmethod
94+
def get_or_create(cls, user, token_name: str):
95+
"""Gets or creates a valid API token for the given user. Only call from authenticated context."""
96+
token_name = cls.sanitize_name(token_name)
97+
today = datetime.date.today()
98+
99+
# Find existing token, which has not expired
100+
token = cls.objects.filter(
101+
user=user, name=token_name, revoked=False, expiry__gte=today
102+
).first()
103+
104+
# create new token if no matching one exists.
105+
if not token:
106+
token = cls.objects.create(user=user, name=token_name)
107+
logger.info(
108+
"Created new API token for user '%s' (name='%s')",
109+
user.username,
110+
token_name,
111+
)
112+
113+
return token
114+
97115
# Override the 'key' field - force it to be unique
98116
key = models.CharField(
99117
default=default_token,

0 commit comments

Comments
 (0)