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:
@ -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
|
||||
|
||||
|
@ -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/',
|
||||
|
@ -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',
|
||||
]
|
||||
|
Reference in New Issue
Block a user