2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-17 04:25:42 +00:00

[FR] Add Tokens to PUI (#7693)

* [FR] Add Tokens to PUI
Fixes #6500

* fix name / call pattern

* cleanup

* add "revoke" action

* Lock currently used token

* Update serializers.py

* bump api version
This commit is contained in:
Matthias Mair
2024-07-22 12:25:45 +02:00
committed by GitHub
parent 69298c365a
commit d46ed4af6f
5 changed files with 158 additions and 5 deletions

View File

@ -1,12 +1,15 @@
"""InvenTree API version information."""
# InvenTree API version
INVENTREE_API_VERSION = 226
INVENTREE_API_VERSION = 227
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
INVENTREE_API_TEXT = """
v227 - 2024-07-19 : https://github.com/inventree/InvenTree/pull/7693/
- Adds endpoints to list and revoke the tokens issued to the current user
v226 - 2024-07-15 : https://github.com/inventree/InvenTree/pull/7648
- Adds barcode generation API endpoint

View File

@ -18,6 +18,8 @@ from drf_spectacular.utils import OpenApiResponse, extend_schema, extend_schema_
from rest_framework import exceptions, permissions
from rest_framework.authentication import BasicAuthentication
from rest_framework.decorators import authentication_classes
from rest_framework.generics import DestroyAPIView
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
@ -34,7 +36,12 @@ from InvenTree.mixins import (
from InvenTree.serializers import ExendedUserSerializer, UserCreateSerializer
from InvenTree.settings import FRONTEND_URL_BASE
from users.models import ApiToken, Owner
from users.serializers import GroupSerializer, OwnerSerializer, RoleSerializer
from users.serializers import (
ApiTokenSerializer,
GroupSerializer,
OwnerSerializer,
RoleSerializer,
)
logger = logging.getLogger('inventree')
@ -342,6 +349,22 @@ class GetAuthToken(APIView):
raise exceptions.NotAuthenticated()
class TokenListView(DestroyAPIView, ListAPI):
"""List of registered tokens for current users."""
permission_classes = (IsAuthenticated,)
serializer_class = ApiTokenSerializer
def get_queryset(self):
"""Only return data for current user."""
return ApiToken.objects.filter(user=self.request.user)
def perform_destroy(self, instance):
"""Revoke token."""
instance.revoked = True
instance.save()
class LoginRedirect(RedirectView):
"""Redirect to the correct starting page after backend login."""
@ -356,6 +379,13 @@ class LoginRedirect(RedirectView):
user_urls = [
path('roles/', RoleDetails.as_view(), name='api-user-roles'),
path('token/', GetAuthToken.as_view(), name='api-token'),
path(
'tokens/',
include([
path('<int:pk>/', TokenListView.as_view(), name='api-token-detail'),
path('', TokenListView.as_view(), name='api-token-list'),
]),
),
path('me/', MeUserDetail.as_view(), name='api-user-me'),
path(
'owner/',

View File

@ -8,7 +8,7 @@ from rest_framework import serializers
from InvenTree.serializers import InvenTreeModelSerializer
from .models import Owner, RuleSet, check_user_role
from .models import ApiToken, Owner, RuleSet, check_user_role
class OwnerSerializer(InvenTreeModelSerializer):
@ -116,5 +116,35 @@ def generate_permission_dict(permissions):
perms[model] = []
perms[model].append(perm)
return perms
class ApiTokenSerializer(InvenTreeModelSerializer):
"""Serializer for the ApiToken model."""
in_use = serializers.SerializerMethodField(read_only=True)
def get_in_use(self, token: ApiToken) -> bool:
"""Return True if the token is currently used to call the endpoint."""
from InvenTree.middleware import get_token_from_request
request = self.context.get('request')
rq_token = get_token_from_request(request)
return token.key == rq_token
class Meta:
"""Meta options for ApiTokenSerializer."""
model = ApiToken
fields = [
'created',
'expiry',
'id',
'last_seen',
'name',
'token',
'active',
'revoked',
'user',
'in_use',
]