From e91eac0c667c74062672a1a2cdb7da2a910f8cf7 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 23 Jun 2019 22:44:57 +1000 Subject: [PATCH 1/6] Include PK in user serializer --- InvenTree/users/serializers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/InvenTree/users/serializers.py b/InvenTree/users/serializers.py index 01ce8f44b3..13aadb24b1 100644 --- a/InvenTree/users/serializers.py +++ b/InvenTree/users/serializers.py @@ -8,7 +8,8 @@ class UserSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = User - fields = ('username', + fields = ('pk', + 'username', 'first_name', 'last_name', 'email',) From 881adb94873ad932e1f2652991403c0287b3c6d7 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 23 Jun 2019 23:47:06 +1000 Subject: [PATCH 2/6] Add API endpoint for user to request auth token --- InvenTree/InvenTree/middleware.py | 5 ++--- InvenTree/InvenTree/settings.py | 22 ++++++++++++++-------- InvenTree/users/urls.py | 2 ++ InvenTree/users/views.py | 24 ++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/InvenTree/InvenTree/middleware.py b/InvenTree/InvenTree/middleware.py index 9abf3643e3..d6d40e85b6 100644 --- a/InvenTree/InvenTree/middleware.py +++ b/InvenTree/InvenTree/middleware.py @@ -20,10 +20,9 @@ class AuthRequiredMiddleware(object): response = self.get_response(request) + # Redirect any unauthorized HTTP requests to the login page if not request.user.is_authenticated: - print(request.path_info) - - if not request.path_info == reverse_lazy('login'): + if not request.path_info == reverse_lazy('login') and not request.path_info.startswith('/api/'): return HttpResponseRedirect(reverse_lazy('login')) # Code to be executed for each request/response after diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index d5ff5749ba..6bff46c4c5 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -65,14 +65,15 @@ INSTALLED_APPS = [ 'order.apps.OrderConfig', # Third part add-ons - 'django_filters', # Extended filter functionality - 'dbbackup', # Database backup / restore - 'rest_framework', # DRF (Django Rest Framework) - 'corsheaders', # Cross-origin Resource Sharing for DRF - 'crispy_forms', # Improved form rendering - 'import_export', # Import / export tables to file - 'django_cleanup', # Automatically delete orphaned MEDIA files - 'qr_code', # Generate QR codes + 'django_filters', # Extended filter functionality + 'dbbackup', # Database backup / restore + 'rest_framework', # DRF (Django Rest Framework) + 'rest_framework.authtoken', # Token authentication for API + 'corsheaders', # Cross-origin Resource Sharing for DRF + 'crispy_forms', # Improved form rendering + 'import_export', # Import / export tables to file + 'django_cleanup', # Automatically delete orphaned MEDIA files + 'qr_code', # Generate QR codes ] LOGGING = { @@ -131,6 +132,11 @@ TEMPLATES = [ REST_FRAMEWORK = { 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler', 'DATETIME_FORMAT': '%Y-%m-%d %H:%M', + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'rest_framework.authentication.BasicAuthentication', + 'rest_framework.authentication.SessionAuthentication', + 'rest_framework.authentication.TokenAuthentication', + ) # 'EXCEPTION_HANDLER': 'InvenTree.utils.api_exception_handler', # 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', # 'PAGE_SIZE': 50, diff --git a/InvenTree/users/urls.py b/InvenTree/users/urls.py index 046cab9428..6082ef14df 100644 --- a/InvenTree/users/urls.py +++ b/InvenTree/users/urls.py @@ -5,5 +5,7 @@ from . import views user_urls = [ url(r'^(?P[0-9]+)/?$', views.UserDetail.as_view(), name='user-detail'), + url(r'token', views.GetAuthToken.as_view()), + url(r'^$', views.UserList.as_view()), ] diff --git a/InvenTree/users/views.py b/InvenTree/users/views.py index 20fee70caa..0314c65ced 100644 --- a/InvenTree/users/views.py +++ b/InvenTree/users/views.py @@ -2,8 +2,13 @@ from rest_framework import generics, permissions from django.contrib.auth.models import User from .serializers import UserSerializer +from rest_framework.authtoken.views import ObtainAuthToken +from rest_framework.authtoken.models import Token +from rest_framework.response import Response + class UserDetail(generics.RetrieveAPIView): + """ Detail endpoint for a single user """ queryset = User.objects.all() serializer_class = UserSerializer @@ -11,7 +16,26 @@ class UserDetail(generics.RetrieveAPIView): class UserList(generics.ListAPIView): + """ List endpoint for detail on all users """ queryset = User.objects.all() serializer_class = UserSerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + + +class GetAuthToken(ObtainAuthToken): + """ Return authentication token for an authenticated user. """ + + def post(self, request, *args, **kwargs): + serializer = self.serializer_class(data=request.data, + context={'request': request}) + serializer.is_valid(raise_exception=True) + user = serializer.validated_data['user'] + token, created = Token.objects.get_or_create(user=user) + print("YAAAAAAAAH") + return Response({ + 'token': token.key, + 'pk': user.pk, + 'username': user.username, + 'email': user.email + }) From faf2fd408fcb585541b9e7277d172902ed187f30 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 24 Jun 2019 00:01:34 +1000 Subject: [PATCH 3/6] PEP fix --- InvenTree/part/api.py | 4 ++-- setup.cfg | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index fbb73c1a12..4b1e449c08 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -336,7 +336,7 @@ part_api_urls = [ url(r'^category/', include(cat_api_urls)), url(r'^star/', include(part_star_api_urls)), - url(r'^(?P\d+)/', PartDetail.as_view(), name='api-part-detail'), + url(r'^(?P\d+)/?', PartDetail.as_view(), name='api-part-detail'), url(r'^.*$', PartList.as_view(), name='api-part-list'), ] @@ -344,7 +344,7 @@ part_api_urls = [ bom_api_urls = [ # BOM Item Detail - url('^(?P\d+)/', BomDetail.as_view(), name='api-bom-detail'), + url(r'^(?P\d+)/?', BomDetail.as_view(), name='api-bom-detail'), # Catch-all url(r'^.*$', BomList.as_view(), name='api-bom-list'), diff --git a/setup.cfg b/setup.cfg index d6e7ca056a..8f2e7d6410 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,7 +3,7 @@ ignore = # - W293 - blank lines contain whitespace W293, # - E501 - line too long (82 characters) - E501, + E501, E722 # - C901 - function is too complex C901, exclude = .git,__pycache__,*/migrations/* From 5567339e7ad71cbdac3790bf36f21e4b283931a9 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 24 Jun 2019 00:06:41 +1000 Subject: [PATCH 4/6] no message --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 8f2e7d6410..61a1b69c6f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,7 +3,7 @@ ignore = # - W293 - blank lines contain whitespace W293, # - E501 - line too long (82 characters) - E501, E722 + E501, E722, # - C901 - function is too complex C901, exclude = .git,__pycache__,*/migrations/* From 071695bfe1f116c2357808a23da0a13a91b20eb8 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 24 Jun 2019 00:12:31 +1000 Subject: [PATCH 5/6] Moar tabs plz --- InvenTree/InvenTree/settings.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 6bff46c4c5..bb50ed04f4 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -65,15 +65,15 @@ INSTALLED_APPS = [ 'order.apps.OrderConfig', # Third part add-ons - 'django_filters', # Extended filter functionality - 'dbbackup', # Database backup / restore - 'rest_framework', # DRF (Django Rest Framework) - 'rest_framework.authtoken', # Token authentication for API - 'corsheaders', # Cross-origin Resource Sharing for DRF - 'crispy_forms', # Improved form rendering - 'import_export', # Import / export tables to file - 'django_cleanup', # Automatically delete orphaned MEDIA files - 'qr_code', # Generate QR codes + 'django_filters', # Extended filter functionality + 'dbbackup', # Database backup / restore + 'rest_framework', # DRF (Django Rest Framework) + 'rest_framework.authtoken', # Token authentication for API + 'corsheaders', # Cross-origin Resource Sharing for DRF + 'crispy_forms', # Improved form rendering + 'import_export', # Import / export tables to file + 'django_cleanup', # Automatically delete orphaned MEDIA files + 'qr_code', # Generate QR codes ] LOGGING = { From d70140e256c4fd42d1a96950c8eecdfe66b8ed30 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 24 Jun 2019 00:20:22 +1000 Subject: [PATCH 6/6] Remove a debug message --- InvenTree/users/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/users/views.py b/InvenTree/users/views.py index 0314c65ced..e10fe2c615 100644 --- a/InvenTree/users/views.py +++ b/InvenTree/users/views.py @@ -32,7 +32,7 @@ class GetAuthToken(ObtainAuthToken): serializer.is_valid(raise_exception=True) user = serializer.validated_data['user'] token, created = Token.objects.get_or_create(user=user) - print("YAAAAAAAAH") + return Response({ 'token': token.key, 'pk': user.pk,