2023-08-29 11:08:35 +00:00
|
|
|
import logging
|
|
|
|
|
from django.test import TestCase, Client
|
|
|
|
|
from django.contrib.auth import get_user_model
|
|
|
|
|
from django.contrib.messages.storage.fallback import FallbackStorage
|
|
|
|
|
from django.contrib.messages import get_messages
|
|
|
|
|
from django.test.client import RequestFactory
|
|
|
|
|
from django.urls import reverse
|
|
|
|
|
from django.core import mail
|
|
|
|
|
from django.utils import translation
|
|
|
|
|
from .utils import create_one_time_login, one_time_login, send_one_time_login_mail
|
2023-08-27 20:47:19 +00:00
|
|
|
|
2023-08-29 11:08:35 +00:00
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class OneTimeLoginModelTestCase(TestCase):
|
|
|
|
|
"""
|
|
|
|
|
Tests all logic contained in the OneTimeLogin model.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
|
user = get_user_model().objects.create_user(
|
|
|
|
|
"john",
|
|
|
|
|
"lennon@thebeatles.com",
|
|
|
|
|
"johnpassword")
|
|
|
|
|
user.save()
|
|
|
|
|
|
|
|
|
|
def test_get_absolute_url(self):
|
|
|
|
|
user = get_user_model().objects.get(username='john')
|
|
|
|
|
url = "/test/url"
|
|
|
|
|
|
|
|
|
|
otl = create_one_time_login(user, url)
|
|
|
|
|
|
|
|
|
|
abs_url = otl.get_absolute_url()
|
|
|
|
|
|
|
|
|
|
logger.debug('test_get_absolute_url: url %s', abs_url)
|
|
|
|
|
|
|
|
|
|
assert otl.secret in abs_url, 'secret is part of URL'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UtilsTestCase(TestCase):
|
|
|
|
|
"""
|
|
|
|
|
Tests all logic contained in the util functions.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
|
# prepare request factory
|
|
|
|
|
self.factory = RequestFactory()
|
|
|
|
|
|
|
|
|
|
# prepare test user
|
|
|
|
|
user = get_user_model().objects.create_user(
|
|
|
|
|
"john",
|
|
|
|
|
"lennon@thebeatles.com",
|
|
|
|
|
"johnpassword")
|
|
|
|
|
user.save()
|
|
|
|
|
|
|
|
|
|
# use english translations
|
|
|
|
|
translation.activate('en')
|
|
|
|
|
|
|
|
|
|
def test_create_one_time_login(self):
|
|
|
|
|
user = get_user_model().objects.get(username='john')
|
|
|
|
|
url = "/test/url"
|
|
|
|
|
|
|
|
|
|
otl = create_one_time_login(user, url)
|
|
|
|
|
|
|
|
|
|
assert len(otl.secret) > 10, 'length of secret'
|
|
|
|
|
assert otl.user is user
|
|
|
|
|
assert otl.url is url
|
|
|
|
|
|
|
|
|
|
def test_one_time_login_ok(self):
|
|
|
|
|
user = get_user_model().objects.get(username='john')
|
|
|
|
|
url = "/test/url"
|
|
|
|
|
|
|
|
|
|
otl = create_one_time_login(user, url)
|
|
|
|
|
request = self.factory.get(otl.get_absolute_url())
|
|
|
|
|
|
|
|
|
|
(otl_user, otl_url) = one_time_login(request, otl.secret)
|
|
|
|
|
|
|
|
|
|
logger.debug('test_one_time_login_ok: user %s, url %s',
|
|
|
|
|
otl_user, otl_url)
|
|
|
|
|
|
|
|
|
|
assert otl_user is not None, 'user was found'
|
|
|
|
|
assert otl_user == user, 'user is the right one'
|
|
|
|
|
assert otl_url == url, 'URL is the right one'
|
|
|
|
|
|
|
|
|
|
def test_one_time_login_wrong(self):
|
|
|
|
|
secret = "a_wrong_secret"
|
|
|
|
|
|
|
|
|
|
url = reverse('one_time_login:login', args=[secret])
|
|
|
|
|
|
|
|
|
|
request = self.factory.get(url)
|
|
|
|
|
|
|
|
|
|
(otl_user, otl_url) = one_time_login(request, secret)
|
|
|
|
|
|
|
|
|
|
logger.debug('test_one_time_login_wrong: user %s, url %s',
|
|
|
|
|
otl_user, otl_url)
|
|
|
|
|
|
|
|
|
|
assert otl_user is None, 'user was not found'
|
|
|
|
|
assert otl_url is None, 'no redirect URL'
|
|
|
|
|
|
|
|
|
|
def test_one_time_login_used(self):
|
|
|
|
|
user = get_user_model().objects.get(username='john')
|
|
|
|
|
url = "/test/url"
|
|
|
|
|
|
|
|
|
|
otl = create_one_time_login(user, url)
|
|
|
|
|
request = self.factory.get(otl.get_absolute_url())
|
|
|
|
|
# Add support django messaging framework
|
|
|
|
|
setattr(request, 'session', 'session')
|
|
|
|
|
messages = FallbackStorage(request)
|
|
|
|
|
setattr(request, '_messages', messages)
|
|
|
|
|
|
|
|
|
|
(otl_user, otl_url) = one_time_login(request, otl.secret)
|
|
|
|
|
|
|
|
|
|
logger.debug('test_one_time_login_used: first try: user %s, url %s',
|
|
|
|
|
otl_user, otl_url)
|
|
|
|
|
|
|
|
|
|
assert otl_user is not None, 'user was found'
|
|
|
|
|
assert otl_user == user, 'user is the right one'
|
|
|
|
|
assert otl_url == url, 'URL is the right one'
|
|
|
|
|
|
|
|
|
|
(otl_user, otl_url) = one_time_login(request, otl.secret)
|
|
|
|
|
|
|
|
|
|
logger.debug('test_one_time_login_used: second try: user %s, url %s',
|
|
|
|
|
otl_user, otl_url)
|
|
|
|
|
|
|
|
|
|
assert otl_user is None, 'user was not found'
|
|
|
|
|
assert otl_url is None, 'no redirect URL'
|
|
|
|
|
|
|
|
|
|
messages = [m.message for m in get_messages(request)]
|
|
|
|
|
|
|
|
|
|
logger.debug('test_one_time_login_used: messages %r', messages)
|
|
|
|
|
|
|
|
|
|
assert len(messages) == 2, 'there are two message'
|
|
|
|
|
assert 'used already' in str(messages[0]), 'already used message'
|
|
|
|
|
assert 'new login link' in str(messages[1]), 'new login sent'
|
|
|
|
|
|
|
|
|
|
def test_send_one_time_login_mail(self):
|
|
|
|
|
user = get_user_model().objects.get(username='john')
|
|
|
|
|
url = "/test/url"
|
|
|
|
|
|
|
|
|
|
otl = create_one_time_login(user, url)
|
|
|
|
|
request = self.factory.get(otl.get_absolute_url())
|
|
|
|
|
# Add support django messaging framework
|
|
|
|
|
setattr(request, 'session', 'session')
|
|
|
|
|
setattr(request, '_messages', FallbackStorage(request))
|
|
|
|
|
|
|
|
|
|
send_one_time_login_mail(otl.secret, user.email, request)
|
|
|
|
|
|
|
|
|
|
messages = [m.message for m in get_messages(request)]
|
|
|
|
|
|
|
|
|
|
logger.debug('test_send_one_time_login_mail: messages %r', messages)
|
|
|
|
|
|
|
|
|
|
assert len(messages) == 1, 'there are two message'
|
|
|
|
|
assert 'new login link' in str(messages[0]), 'new login sent'
|
|
|
|
|
|
|
|
|
|
logger.debug('test_send_one_time_login_mail: outbox %r',
|
|
|
|
|
mail.outbox)
|
|
|
|
|
|
|
|
|
|
sent_mail = mail.outbox[0]
|
|
|
|
|
|
|
|
|
|
logger.debug('test_send_one_time_login_mail: to %r',
|
|
|
|
|
sent_mail.to)
|
|
|
|
|
logger.debug('test_send_one_time_login_mail: content %r',
|
|
|
|
|
sent_mail.body)
|
|
|
|
|
|
|
|
|
|
assert otl.user.email in sent_mail.to, 'receiver address'
|
|
|
|
|
assert otl.get_absolute_url() in sent_mail.body, 'mail content'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ViewsTestCase(TestCase):
|
|
|
|
|
"""
|
|
|
|
|
Test one time login views.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
|
# prepare test user
|
|
|
|
|
user = get_user_model().objects.create_user(
|
|
|
|
|
"john",
|
|
|
|
|
"lennon@thebeatles.com",
|
|
|
|
|
"johnpassword")
|
|
|
|
|
user.save()
|
|
|
|
|
|
|
|
|
|
# use english translations
|
|
|
|
|
translation.activate('en')
|
|
|
|
|
|
|
|
|
|
def test_one_time_login_ok(self):
|
|
|
|
|
user = get_user_model().objects.get(username='john')
|
|
|
|
|
url = reverse('one_time_login:protected')
|
|
|
|
|
|
|
|
|
|
otl = create_one_time_login(user, url)
|
|
|
|
|
|
|
|
|
|
client = Client()
|
|
|
|
|
|
|
|
|
|
response = client.get(otl.get_absolute_url())
|
|
|
|
|
|
|
|
|
|
logger.debug('test_one_time_login: response %r', response)
|
|
|
|
|
|
|
|
|
|
assert response.status_code == 302, 'response is redirect'
|
|
|
|
|
assert response.url == reverse(
|
|
|
|
|
'one_time_login:protected'), 'redirect URL'
|
|
|
|
|
|
|
|
|
|
def test_one_time_login_wrong(self):
|
|
|
|
|
client = Client()
|
|
|
|
|
|
|
|
|
|
response = client.get(
|
|
|
|
|
reverse('one_time_login:login', args=['1234567']))
|
|
|
|
|
|
|
|
|
|
logger.debug('test_one_time_login: response %r', response)
|
|
|
|
|
|
|
|
|
|
assert response.status_code == 302, 'response is redirect'
|
|
|
|
|
assert response.url == '/', 'redirect URL'
|