mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-12 01:55:39 +00:00
[PUI] Session authentication (#6970)
* Adjust backend cookie settings * Allow CORS requests to /accounts/ * Refactor frontend code - Remove API token functions - Simplify cookie approach - Add isLoggedIn method * Adjust REST_AUTH settings * Cleanup auth functions in auth.tsx * Adjust CSRF_COOKIE_SAMESITE value * Fix login request * Prevent session auth on login view - Existing (invalid) session token causes 403 * Refactor ApiImage - Point to the right host - Simplify code - Now we use session cookies, so it *Just Works* * Fix download for attachment table - Now works with remote host * Cleanup settings.py * Refactor login / logout notifications * Update API version * Update src/frontend/src/components/items/AttachmentLink.tsx Co-authored-by: Lukas <76838159+wolflu05@users.noreply.github.com> * fix assert url * Remove comment * Add explicit page to logout user * Change tests to first logout * Prune dead code * Adjust tests * Cleanup * Direct to login view * Trying something * Update CUI test * Fix basic tests * Refactoring * Fix basic checks * Fix for PUI command tests * More test updates * Add speciifc test for quick login * More cleanup of playwright tests * Add some missing icons * Fix typo * Ignore coverage report for playwright test * Remove coveralls upload task --------- Co-authored-by: Lukas <76838159+wolflu05@users.noreply.github.com> Co-authored-by: Matthias Mair <code@mjmair.com>
This commit is contained in:
@ -1,12 +1,16 @@
|
||||
"""InvenTree API version information."""
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 187
|
||||
INVENTREE_API_VERSION = 188
|
||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||
|
||||
INVENTREE_API_TEXT = """
|
||||
|
||||
v187 - 2024-03-10 : https://github.com/inventree/InvenTree/pull/6985
|
||||
v188 - 2024-04-16 : https://github.com/inventree/InvenTree/pull/6970
|
||||
- Adds session authentication support for the API
|
||||
- Improvements for login / logout endpoints for better support of React web interface
|
||||
|
||||
v187 - 2024-04-10 : https://github.com/inventree/InvenTree/pull/6985
|
||||
- Allow Part list endpoint to be sorted by pricing_min and pricing_max values
|
||||
- Allow BomItem list endpoint to be sorted by pricing_min and pricing_max values
|
||||
- Allow InternalPrice and SalePrice endpoints to be sorted by quantity
|
||||
|
@ -492,10 +492,18 @@ if DEBUG:
|
||||
'rest_framework.renderers.BrowsableAPIRenderer'
|
||||
)
|
||||
|
||||
# dj-rest-auth
|
||||
# JWT switch
|
||||
USE_JWT = get_boolean_setting('INVENTREE_USE_JWT', 'use_jwt', False)
|
||||
REST_USE_JWT = USE_JWT
|
||||
|
||||
# dj-rest-auth
|
||||
REST_AUTH = {
|
||||
'SESSION_LOGIN': True,
|
||||
'TOKEN_MODEL': 'users.models.ApiToken',
|
||||
'TOKEN_CREATOR': 'users.models.default_create_token',
|
||||
'USE_JWT': USE_JWT,
|
||||
}
|
||||
|
||||
OLD_PASSWORD_FIELD_ENABLED = True
|
||||
REST_AUTH_REGISTER_SERIALIZERS = {
|
||||
'REGISTER_SERIALIZER': 'InvenTree.forms.CustomRegisterSerializer'
|
||||
@ -510,6 +518,7 @@ if USE_JWT:
|
||||
)
|
||||
INSTALLED_APPS.append('rest_framework_simplejwt')
|
||||
|
||||
|
||||
# WSGI default setting
|
||||
WSGI_APPLICATION = 'InvenTree.wsgi.application'
|
||||
|
||||
@ -1092,6 +1101,13 @@ if not TESTING and len(CSRF_TRUSTED_ORIGINS) == 0:
|
||||
)
|
||||
sys.exit(-1)
|
||||
|
||||
# Additional CSRF settings
|
||||
CSRF_HEADER_NAME = 'HTTP_X_CSRFTOKEN'
|
||||
CSRF_COOKIE_NAME = 'csrftoken'
|
||||
CSRF_COOKIE_SAMESITE = 'Lax'
|
||||
SESSION_COOKIE_SECURE = True
|
||||
SESSION_COOKIE_SAMESITE = 'Lax'
|
||||
|
||||
USE_X_FORWARDED_HOST = get_boolean_setting(
|
||||
'INVENTREE_USE_X_FORWARDED_HOST',
|
||||
config_key='use_x_forwarded_host',
|
||||
|
@ -160,6 +160,7 @@ apipatterns = [
|
||||
SocialAccountDisconnectView.as_view(),
|
||||
name='social_account_disconnect',
|
||||
),
|
||||
path('login/', users.api.Login.as_view(), name='api-login'),
|
||||
path('logout/', users.api.Logout.as_view(), name='api-logout'),
|
||||
path(
|
||||
'login-redirect/',
|
||||
|
@ -8,9 +8,11 @@ from django.contrib.auth.models import Group, User
|
||||
from django.urls import include, path, re_path
|
||||
from django.views.generic.base import RedirectView
|
||||
|
||||
from dj_rest_auth.views import LogoutView
|
||||
from dj_rest_auth.views import LoginView, LogoutView
|
||||
from drf_spectacular.utils import OpenApiResponse, extend_schema, extend_schema_view
|
||||
from rest_framework import exceptions, permissions
|
||||
from rest_framework.authentication import BasicAuthentication
|
||||
from rest_framework.decorators import authentication_classes
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
@ -205,6 +207,18 @@ class GroupList(ListCreateAPI):
|
||||
ordering_fields = ['name']
|
||||
|
||||
|
||||
@authentication_classes([BasicAuthentication])
|
||||
@extend_schema_view(
|
||||
post=extend_schema(
|
||||
responses={200: OpenApiResponse(description='User successfully logged in')}
|
||||
)
|
||||
)
|
||||
class Login(LoginView):
|
||||
"""API view for logging in via API."""
|
||||
|
||||
...
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
post=extend_schema(
|
||||
responses={200: OpenApiResponse(description='User successfully logged out')}
|
||||
|
@ -56,6 +56,17 @@ def default_token_expiry():
|
||||
return InvenTree.helpers.current_date() + datetime.timedelta(days=365)
|
||||
|
||||
|
||||
def default_create_token(token_model, user, serializer):
|
||||
"""Generate a default value for the token."""
|
||||
token = token_model.objects.filter(user=user, name='', revoked=False)
|
||||
|
||||
if token.exists():
|
||||
return token.first()
|
||||
|
||||
else:
|
||||
return token_model.objects.create(user=user, name='')
|
||||
|
||||
|
||||
class ApiToken(AuthToken, InvenTree.models.MetadataMixin):
|
||||
"""Extends the default token model provided by djangorestframework.authtoken.
|
||||
|
||||
|
Reference in New Issue
Block a user