From 10cdc9f147e55a22a0d7b623ef559090da37c4b3 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 9 Jul 2024 11:10:52 +0200 Subject: [PATCH] Adds deviceId to the user + login and logout services update --- api/urls.py | 1 + api/views.py | 24 ++++++++++++------- .../migrations/0074_customuser_device_id.py | 18 ++++++++++++++ tournaments/models/custom_user.py | 4 +++- 4 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 tournaments/migrations/0074_customuser_device_id.py diff --git a/api/urls.py b/api/urls.py index eab1768..b4f15d6 100644 --- a/api/urls.py +++ b/api/urls.py @@ -29,6 +29,7 @@ urlpatterns = [ path("change-password/", views.ChangePasswordView.as_view(), name="change_password"), path('token-auth/', views.CustomAuthToken.as_view()), + path('api-token-logout/', views.Logout.as_view()), # forgotten password path('dj-rest-auth/', include('dj_rest_auth.urls')), diff --git a/api/views.py b/api/views.py index 13b44da..bc4a09d 100644 --- a/api/views.py +++ b/api/views.py @@ -23,20 +23,28 @@ class CustomAuthToken(APIView): def post(self, request, *args, **kwargs): username = request.data.get('username') password = request.data.get('password') + device_id = request.data.get('device_id') user = authenticate(username=username, password=password) - print('a') if user is not None: - print('b') - # Delete old token - count, details = Token.objects.filter(user=user).delete() - # Create new token - token, created = Token.objects.get_or_create(user=user) - return Response({'token': token.key, 'deleted': (count > 0) }) + + if user.device_id is None or user.device_id == device_id: + token, created = Token.objects.get_or_create(user=user) + return Response({'token': token.key}) + else: + return Response({'error': 'Cannot log on another device'}, status=status.HTTP_403_FORBIDDEN) else: - print('c') return Response({'error': 'Invalid Credentials'}, status=status.HTTP_401_UNAUTHORIZED) +class Logout(APIView): + permission_classes = (IsAuthenticated,) + + def post(self, request, *args, **kwargs): + request.user.auth_token.delete() + request.user.device_id = None + request.user.save() + return Response(status=status.HTTP_200_OK) + @api_view(['GET']) def user_by_token(request): serializer = UserSerializer(request.user) diff --git a/tournaments/migrations/0074_customuser_device_id.py b/tournaments/migrations/0074_customuser_device_id.py new file mode 100644 index 0000000..d03d09c --- /dev/null +++ b/tournaments/migrations/0074_customuser_device_id.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.11 on 2024-07-09 09:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tournaments', '0073_log'), + ] + + operations = [ + migrations.AddField( + model_name='customuser', + name='device_id', + field=models.CharField(blank=True, max_length=50, null=True), + ), + ] diff --git a/tournaments/models/custom_user.py b/tournaments/models/custom_user.py index 8f8f888..743110c 100644 --- a/tournaments/models/custom_user.py +++ b/tournaments/models/custom_user.py @@ -29,6 +29,8 @@ class CustomUser(AbstractUser): group_stage_match_format_preference = models.IntegerField(default=enums.FederalMatchCategory.NINE_GAMES, choices=enums.FederalMatchCategory.choices, null=True, blank=True) loser_bracket_match_format_preference = models.IntegerField(default=enums.FederalMatchCategory.NINE_GAMES, choices=enums.FederalMatchCategory.choices, null=True, blank=True) + device_id = models.CharField(max_length=50, null=True, blank=True) + ### ### ### ### ### ### ### ### ### ### ### WARNING ### ### ### ### ### ### ### ### ### ### ### WARNING : Any added field MUST be inserted in the method below: fields_for_update() ### ### ### ### ### ### ### ### ### ### ### ### WARNING ### ### ### ### ### ### ### ### ### ### @@ -40,7 +42,7 @@ class CustomUser(AbstractUser): 'summons_message_body', 'summons_message_signature', 'summons_available_payment_methods', 'summons_display_format', 'summons_display_entry_fee', 'summons_use_full_custom_message', 'match_formats_default_duration', 'bracket_match_format_preference', - 'group_stage_match_format_preference', 'loser_bracket_match_format_preference'] + 'group_stage_match_format_preference', 'loser_bracket_match_format_preference', 'device_id'] def __str__(self): return self.username