195 lines
6.6 KiB
Python
195 lines
6.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
import json
|
|
import unittest
|
|
|
|
import mock
|
|
from django import test
|
|
from django.conf import settings
|
|
from django.contrib.auth import get_user_model
|
|
from django.core import serializers
|
|
from django.urls import reverse
|
|
from django.http import Http404, QueryDict
|
|
from django.views.generic import FormView
|
|
|
|
from ..models import SQRLIdentity, SQRLNut
|
|
from ..views import (
|
|
SQRL_IDENTITY_SESSION_KEY,
|
|
SQRLCompleteRegistrationView,
|
|
SQRLStatusView,
|
|
)
|
|
|
|
|
|
TESTING_MODULE = 'sqrl.views'
|
|
|
|
|
|
class TestSQRLStatusView(test.TestCase):
|
|
def setUp(self):
|
|
super(TestSQRLStatusView, self).setUp()
|
|
self.view = SQRLStatusView()
|
|
self.view.request = mock.MagicMock(GET={})
|
|
self.view.request.is_ajax.return_value = True
|
|
self.view.kwargs = {
|
|
'transaction': '123',
|
|
}
|
|
|
|
self.nut = SQRLNut.objects.create(
|
|
nonce='hello',
|
|
transaction_nonce='123',
|
|
ip_address='127.0.0.1',
|
|
is_transaction_complete=True,
|
|
)
|
|
|
|
def tearDown(self):
|
|
self.nut and self.nut.delete()
|
|
super(TestSQRLStatusView, self).tearDown()
|
|
|
|
def test_get_success_url(self):
|
|
self.assertEqual(
|
|
self.view.get_success_url(),
|
|
settings.LOGIN_REDIRECT_URL
|
|
)
|
|
|
|
def test_get_success_url_from_querystring(self):
|
|
self.view.request.GET['url'] = '?next={}'.format(reverse('sqrl:login'))
|
|
|
|
self.assertEqual(
|
|
self.view.get_success_url(),
|
|
reverse('sqrl:login'),
|
|
)
|
|
|
|
def test_get_success_url_complete_registration(self):
|
|
self.view.request.GET['url'] = '?next={}'.format(reverse('sqrl:login'))
|
|
self.view.request.user.is_authenticated.return_value = False
|
|
self.view.request.session = {SQRL_IDENTITY_SESSION_KEY: ''}
|
|
|
|
self.assertEqual(
|
|
self.view.get_success_url(),
|
|
reverse('sqrl:complete-registration') + '?next={}'.format(reverse('sqrl:login')),
|
|
)
|
|
|
|
def test_get_object_404(self):
|
|
self.nut.delete()
|
|
self.nut = None
|
|
|
|
with self.assertRaises(Http404):
|
|
self.view.get_object()
|
|
|
|
def test_get_object(self):
|
|
actual = self.view.get_object()
|
|
|
|
self.assertIsInstance(actual, SQRLNut)
|
|
self.assertEqual(actual.nonce, self.nut.nonce)
|
|
self.assertEqual(actual.transaction_nonce, self.nut.transaction_nonce)
|
|
|
|
def test_post(self):
|
|
response = self.view.post(self.view.request, self.nut.transaction_nonce)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertEqual(response['content-type'], 'application/json')
|
|
self.assertEqual(json.loads(response.content.decode('utf-8')), {
|
|
'transaction_complete': True,
|
|
'redirect_to': settings.LOGIN_REDIRECT_URL,
|
|
})
|
|
|
|
def test_post_not_ajax(self):
|
|
self.view.request.is_ajax.return_value = False
|
|
|
|
response = self.view.post(self.view.request, self.nut.transaction_nonce)
|
|
|
|
self.assertEqual(response.status_code, 405)
|
|
|
|
|
|
class TestSQRLAuthView(test.TestCase):
|
|
pass
|
|
|
|
|
|
class TestCompleteRegistrationView(test.TestCase):
|
|
def setUp(self):
|
|
super(TestCompleteRegistrationView, self).setUp()
|
|
self.view = SQRLCompleteRegistrationView()
|
|
self.username = 'foobartest'
|
|
self.view.request = mock.MagicMock(
|
|
method='POST',
|
|
POST={
|
|
'username': self.username,
|
|
},
|
|
)
|
|
self.identity = SQRLIdentity(
|
|
public_key='a' * 43,
|
|
verify_unlock_key='b' * 43,
|
|
server_unlock_key='c' * 43,
|
|
is_enabled=True,
|
|
is_only_sqrl=False,
|
|
)
|
|
self.view.request.session = {
|
|
SQRL_IDENTITY_SESSION_KEY: serializers.serialize('json', [self.identity]),
|
|
}
|
|
|
|
def tearDown(self):
|
|
SQRLIdentity.objects.filter(public_key=self.identity.public_key).delete()
|
|
get_user_model().objects.filter(username=self.username).delete()
|
|
super(TestCompleteRegistrationView, self).tearDown()
|
|
|
|
def test_check_session_for_sqrl_identity_or_404(self):
|
|
self.assertIsNone(self.view.check_session_for_sqrl_identity_or_404())
|
|
|
|
def test_check_session_for_sqrl_identity_or_404_raises(self):
|
|
self.view.request.session = {}
|
|
|
|
with self.assertRaises(Http404):
|
|
self.view.check_session_for_sqrl_identity_or_404()
|
|
|
|
@mock.patch.object(SQRLCompleteRegistrationView, 'check_session_for_sqrl_identity_or_404')
|
|
@mock.patch.object(FormView, 'get')
|
|
def test_get(self, mock_super_get, mock_check_session_for_sqrl_identity_or_404):
|
|
response = self.view.get(self.view.request)
|
|
|
|
self.assertEqual(response, mock_super_get.return_value)
|
|
mock_check_session_for_sqrl_identity_or_404.assert_called_once_with()
|
|
|
|
@mock.patch.object(SQRLCompleteRegistrationView, 'check_session_for_sqrl_identity_or_404')
|
|
@mock.patch.object(FormView, 'post')
|
|
def test_post(self, mock_super_post, mock_check_session_for_sqrl_identity_or_404):
|
|
response = self.view.post(self.view.request)
|
|
|
|
self.assertEqual(response, mock_super_post.return_value)
|
|
mock_check_session_for_sqrl_identity_or_404.assert_called_once_with()
|
|
|
|
def test_get_success_url(self):
|
|
self.assertEqual(
|
|
self.view.get_success_url(),
|
|
settings.LOGIN_REDIRECT_URL
|
|
)
|
|
|
|
def test_get_success_url_from_querystring(self):
|
|
self.view.request.GET = {'next': reverse('sqrl:manage')}
|
|
|
|
self.assertEqual(
|
|
self.view.get_success_url(),
|
|
reverse('sqrl:manage'),
|
|
)
|
|
|
|
@mock.patch(TESTING_MODULE + '.login')
|
|
def test_form_valid(self, mock_login):
|
|
form = self.view.get_form(self.view.get_form_class())
|
|
form.is_valid()
|
|
|
|
# sanity checks
|
|
self.assertFalse(get_user_model().objects.filter(username=self.username).count())
|
|
self.assertFalse(SQRLIdentity.objects.filter(public_key=self.identity.public_key).count())
|
|
|
|
response = self.view.form_valid(form)
|
|
user = get_user_model().objects.filter(username=self.username).first()
|
|
|
|
self.assertIsNotNone(user)
|
|
self.assertEqual(user.username, self.username)
|
|
self.assertIsInstance(user.sqrl_identity, SQRLIdentity)
|
|
self.assertEqual(user.sqrl_identity.public_key, self.identity.public_key)
|
|
self.assertEqual(response.status_code, 302)
|
|
|
|
def test_form_valid_could_not_decode_identity(self):
|
|
self.view.request.session[SQRL_IDENTITY_SESSION_KEY] = ''
|
|
response = self.view.form_valid(self.view.get_form(self.view.get_form_class()))
|
|
|
|
self.assertEqual(response.status_code, 500)
|