Skip to content

Commit 7c85d31

Browse files
authored
Merge pull request #2 from anish5256/master
Add AuthToken Support and Device ID/Type to DRFPasswordless
2 parents 66bc2eb + 415ceb7 commit 7c85d31

File tree

9 files changed

+34
-14
lines changed

9 files changed

+34
-14
lines changed

drfpasswordless/authtoken/management/commands/drf_create_token.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from django.contrib.auth import get_user_model
22
from django.core.management.base import BaseCommand, CommandError
33

4-
from rest_framework.authtoken.models import Token
4+
from drfpasswordless.authtoken.models import Token
55

66
UserModel = get_user_model()
77

drfpasswordless/authtoken/migrations/0004_auto_20240927_1224.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Generated by Django 3.2.18 on 2024-09-27 06:54
1+
# Generated by Django 3.2.18 on 2024-10-04 06:21
22

33
from django.conf import settings
44
from django.db import migrations, models
@@ -28,4 +28,8 @@ class Migration(migrations.Migration):
2828
name='user',
2929
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='auth_token', to=settings.AUTH_USER_MODEL, verbose_name='User'),
3030
),
31+
migrations.AlterUniqueTogether(
32+
name='token',
33+
unique_together={('key', 'device_id')},
34+
),
3135
]

drfpasswordless/authtoken/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class Meta:
4242
abstract = 'drfpasswordless.authtoken' not in settings.INSTALLED_APPS
4343
verbose_name = _("Token")
4444
verbose_name_plural = _("Tokens")
45+
unique_together = (('key', 'device_id'),)
4546

4647
def save(self, *args, **kwargs):
4748
if not self.key:

drfpasswordless/authtoken/views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from rest_framework import parsers, renderers
2-
from rest_framework.authtoken.models import Token
2+
from drfpasswordless.authtoken.models import Token
33
from rest_framework.authtoken.serializers import AuthTokenSerializer
44
from rest_framework.compat import coreapi, coreschema
55
from rest_framework.response import Response

drfpasswordless/serializers.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from drfpasswordless.models import CallbackToken
99
from drfpasswordless.settings import api_settings
1010
from drfpasswordless.utils import verify_user_alias, validate_token_age
11-
11+
from drfpasswordless.authtoken.models import Token
1212
logger = logging.getLogger(__name__)
1313
User = get_user_model()
1414

@@ -200,6 +200,8 @@ def validate_alias(self, attrs):
200200

201201

202202
class CallbackTokenAuthSerializer(AbstractBaseCallbackTokenSerializer):
203+
device_id = serializers.CharField(required=False, max_length=64)
204+
device_type = serializers.ChoiceField(choices=Token.DEVICE_TYPES, required=False)
203205

204206
def validate(self, attrs):
205207
# Check Aliases

drfpasswordless/utils.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from django.core.mail import send_mail
66
from django.template import loader
77
from django.utils import timezone
8-
from rest_framework.authtoken.models import Token
8+
from drfpasswordless.authtoken.models import Token
99
from drfpasswordless.models import CallbackToken
1010
from drfpasswordless.settings import api_settings
1111

@@ -208,6 +208,7 @@ def send_sms_with_callback_token(user, mobile_token, **kwargs):
208208
return False
209209

210210

211-
def create_authentication_token(user):
212-
""" Default way to create an authentication token"""
213-
return Token.objects.get_or_create(user=user)
211+
def create_authentication_token(user, device_id="", device_type=""):
212+
return Token.objects.get_or_create(
213+
user=user, device_id=device_id, device_type=device_type
214+
)

drfpasswordless/views.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,19 @@ class AbstractBaseObtainAuthToken(APIView):
134134
This is a duplicate of rest_framework's own ObtainAuthToken method.
135135
Instead, this returns an Auth Token based on our 6 digit callback token and source.
136136
"""
137+
137138
serializer_class = None
138139

139140
def post(self, request, *args, **kwargs):
140141
serializer = self.serializer_class(data=request.data)
141142
if serializer.is_valid(raise_exception=True):
142-
user = serializer.validated_data['user']
143+
user = serializer.validated_data["user"]
143144
token_creator = import_string(api_settings.PASSWORDLESS_AUTH_TOKEN_CREATOR)
144-
(token, _) = token_creator(user)
145+
(token, _) = token_creator(
146+
user=user,
147+
device_id=serializer.validated_data.get("device_id", ""),
148+
device_type=serializer.validated_data.get("device_type", ""),
149+
)
145150

146151
if token:
147152
TokenSerializer = import_string(api_settings.PASSWORDLESS_AUTH_TOKEN_SERIALIZER)
@@ -150,8 +155,15 @@ def post(self, request, *args, **kwargs):
150155
# Return our key for consumption.
151156
return Response(token_serializer.data, status=status.HTTP_200_OK)
152157
else:
153-
logger.error("Couldn't log in unknown user. Errors on serializer: {}".format(serializer.error_messages))
154-
return Response({'detail': 'Couldn\'t log you in. Try again later.'}, status=status.HTTP_400_BAD_REQUEST)
158+
logger.error(
159+
"Couldn't log in unknown user. Errors on serializer: {}".format(
160+
serializer.error_messages
161+
)
162+
)
163+
return Response(
164+
{"detail": "Couldn't log you in. Try again later."},
165+
status=status.HTTP_400_BAD_REQUEST,
166+
)
155167

156168

157169
class ObtainAuthTokenFromCallbackToken(AbstractBaseObtainAuthToken):

tests/test_settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from rest_framework import status
2-
from rest_framework.authtoken.models import Token
2+
from drfpasswordless.authtoken.models import Token
33
from rest_framework.test import APITestCase
44

55
from django.contrib.auth import get_user_model

tests/test_verification.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from rest_framework import status
2-
from rest_framework.authtoken.models import Token
2+
from drfpasswordless.authtoken.models import Token
33
from django.utils.translation import gettext_lazy as _
44
from rest_framework.test import APITestCase
55
from django.contrib.auth import get_user_model

0 commit comments

Comments
 (0)