Skip to content

Commit 7b9239c

Browse files
authored
Merge pull request #56 from budlight/master
Demo Users
2 parents 7fe00df + c6d2ccb commit 7b9239c

File tree

7 files changed

+52
-21
lines changed

7 files changed

+52
-21
lines changed

README.md

+9
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,15 @@ DEFAULTS = {
309309
# exchanging a passwordless token for a real user auth token.
310310
'PASSWORDLESS_AUTH_TOKEN_SERIALIZER': 'drfpasswordless.serializers.TokenResponseSerializer'
311311
312+
# A dictionary of demo user's primary key mapped to their static pin
313+
'PASSWORDLESS_DEMO_USERS': {},
314+
315+
# configurable function for sending email
316+
'PASSWORDLESS_EMAIL_CALLBACK': 'drfpasswordless.utils.send_email_with_callback_token'
317+
# configurable function for sending sms
318+
'PASSWORDLESS_SMS_CALLBACK': 'drfpasswordless.utils.send_sms_with_callback_token'
319+
320+
312321
}
313322
```
314323

drfpasswordless/admin.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class CallbackInline(AbstractCallbackTokenInline):
2828

2929

3030
class AbstractCallbackTokenAdmin(UserLinkMixin, admin.ModelAdmin):
31-
readonly_fields = ('created_at', 'user', 'key', 'type',)
32-
list_display = ('created_at', UserLinkMixin.LINK_TO_USER_FIELD, 'key', 'type', 'is_active')
33-
fields = ('created_at', 'user', 'key', 'type', 'is_active')
31+
readonly_fields = ('created_at', 'user', 'key', 'type', 'to_alias_type')
32+
list_display = ('created_at', UserLinkMixin.LINK_TO_USER_FIELD, 'key', 'type', 'is_active', 'to_alias_type')
33+
fields = ('created_at', 'user', 'key', 'type', 'is_active', 'to_alias_type')
3434
extra = 0

drfpasswordless/serializers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ def validate(self, attrs):
235235
msg = _('Invalid alias parameters provided.')
236236
raise serializers.ValidationError(msg)
237237
except User.DoesNotExist:
238-
msg = _('Invalid alias parameters provided.')
238+
msg = _('Invalid user alias parameters provided.')
239239
raise serializers.ValidationError(msg)
240240
except ValidationError:
241241
msg = _('Invalid alias parameters provided.')

drfpasswordless/services.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
from django.utils.module_loading import import_string
2+
from drfpasswordless.settings import api_settings
13
from drfpasswordless.utils import (
24
create_callback_token_for_user,
3-
send_email_with_callback_token,
4-
send_sms_with_callback_token
55
)
66

77

@@ -10,10 +10,13 @@ class TokenService(object):
1010
def send_token(user, alias_type, token_type, **message_payload):
1111
token = create_callback_token_for_user(user, alias_type, token_type)
1212
send_action = None
13+
14+
if user.pk in api_settings.PASSWORDLESS_DEMO_USERS.keys():
15+
return True
1316
if alias_type == 'email':
14-
send_action = send_email_with_callback_token
17+
send_action = import_string(api_settings.PASSWORDLESS_EMAIL_CALLBACK)
1518
elif alias_type == 'mobile':
16-
send_action = send_sms_with_callback_token
19+
send_action = import_string(api_settings.PASSWORDLESS_SMS_CALLBACK)
1720
# Send to alias
1821
success = send_action(user, token, **message_payload)
1922
return success

drfpasswordless/settings.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,13 @@
8181

8282
# What function is called to construct a serializer for drf tokens when
8383
# exchanging a passwordless token for a real user auth token.
84-
'PASSWORDLESS_AUTH_TOKEN_SERIALIZER': 'drfpasswordless.serializers.TokenResponseSerializer'
84+
'PASSWORDLESS_AUTH_TOKEN_SERIALIZER': 'drfpasswordless.serializers.TokenResponseSerializer',
85+
86+
# A dictionary of demo user's primary key mapped to their static pin
87+
'PASSWORDLESS_DEMO_USERS': {},
88+
'PASSWORDLESS_EMAIL_CALLBACK': 'drfpasswordless.utils.send_email_with_callback_token',
89+
'PASSWORDLESS_SMS_CALLBACK': 'drfpasswordless.utils.send_sms_with_callback_token',
90+
8591
}
8692

8793
# List of settings that may be in string import notation.

drfpasswordless/signals.py

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ def invalidate_previous_tokens(sender, instance, created, **kwargs):
1515
"""
1616
Invalidates all previously issued tokens of that type when a new one is created, used, or anything like that.
1717
"""
18+
19+
if instance.user.pk in api_settings.PASSWORDLESS_DEMO_USERS.keys():
20+
return
21+
1822
if isinstance(instance, CallbackToken):
1923
CallbackToken.objects.active().filter(user=instance.user, type=instance.type).exclude(id=instance.id).update(is_active=False)
2024

drfpasswordless/utils.py

+21-12
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,28 @@ def authenticate_by_token(callback_token):
3636

3737

3838
def create_callback_token_for_user(user, alias_type, token_type):
39-
4039
token = None
4140
alias_type_u = alias_type.upper()
41+
to_alias_field = getattr(api_settings, f'PASSWORDLESS_USER_{alias_type_u}_FIELD_NAME')
42+
if user.pk in api_settings.PASSWORDLESS_DEMO_USERS.keys():
43+
token = CallbackToken.objects.filter(user=user).first()
44+
if token:
45+
return token
46+
else:
47+
return CallbackToken.objects.create(
48+
user=user,
49+
key=api_settings.PASSWORDLESS_DEMO_USERS[user.pk],
50+
to_alias_type=alias_type_u,
51+
to_alias=getattr(user, to_alias_field),
52+
type=token_type
53+
)
54+
55+
token = CallbackToken.objects.create(user=user,
56+
to_alias_type=alias_type_u,
57+
to_alias=getattr(user, to_alias_field),
58+
type=token_type)
4259

43-
if alias_type_u == 'EMAIL':
44-
token = CallbackToken.objects.create(user=user,
45-
to_alias_type=alias_type_u,
46-
to_alias=getattr(user, api_settings.PASSWORDLESS_USER_EMAIL_FIELD_NAME),
47-
type=token_type)
4860

49-
elif alias_type_u == 'MOBILE':
50-
token = CallbackToken.objects.create(user=user,
51-
to_alias_type=alias_type_u,
52-
to_alias=getattr(user, api_settings.PASSWORDLESS_USER_MOBILE_FIELD_NAME),
53-
type=token_type)
5461

5562
if token is not None:
5663
return token
@@ -62,11 +69,13 @@ def validate_token_age(callback_token):
6269
"""
6370
Returns True if a given token is within the age expiration limit.
6471
"""
72+
6573
try:
6674
token = CallbackToken.objects.get(key=callback_token, is_active=True)
6775
seconds = (timezone.now() - token.created_at).total_seconds()
6876
token_expiry_time = api_settings.PASSWORDLESS_TOKEN_EXPIRE_TIME
69-
77+
if token.user.pk in api_settings.PASSWORDLESS_DEMO_USERS.keys():
78+
return True
7079
if seconds <= token_expiry_time:
7180
return True
7281
else:

0 commit comments

Comments
 (0)