From 3cbcd5e5abc9765cd329b09de514f2b5c47b7723 Mon Sep 17 00:00:00 2001 From: Alex Kamedov Date: Sun, 24 Apr 2011 13:59:56 +0600 Subject: [PATCH] add tests, fix LOGIN_REDIRECT_URL settings support --- cas_provider/fixtures/cas_users.json | 130 +++++++++++++++++++++++++++ cas_provider/forms.py | 5 +- cas_provider/models.py | 2 +- cas_provider/tests.py | 91 +++++++++++++++++++ cas_provider/utils.py | 4 +- cas_provider/views.py | 2 +- 6 files changed, 228 insertions(+), 6 deletions(-) create mode 100644 cas_provider/fixtures/cas_users.json create mode 100644 cas_provider/tests.py diff --git a/cas_provider/fixtures/cas_users.json b/cas_provider/fixtures/cas_users.json new file mode 100644 index 0000000..f31d5cb --- /dev/null +++ b/cas_provider/fixtures/cas_users.json @@ -0,0 +1,130 @@ +[ + { + "pk": 1, + "model": "auth.group", + "fields": { + "name": "editor", + "permissions": [] + } + }, + { + "pk": 2, + "model": "auth.group", + "fields": { + "name": "author", + "permissions": [] + } + }, + { + "pk": 1, + "model": "auth.user", + "fields": { + "username": "root", + "first_name": "", + "last_name": "", + "is_active": true, + "is_superuser": true, + "is_staff": true, + "last_login": "2011-04-24 11:29:11", + "groups": [], + "user_permissions": [], + "password": "sha1$602c5$ba8608296f6bfcb352e978084b337a90d586ecc3", + "email": "root@example.com", + "date_joined": "2010-07-04 13:33:14" + } + }, + { + "pk": 26, + "model": "auth.user", + "fields": { + "username": "active", + "first_name": "", + "last_name": "", + "is_active": true, + "is_superuser": false, + "is_staff": false, + "last_login": "2011-04-01 12:42:53", + "groups": [], + "user_permissions": [], + "password": "sha1$7dfb4$d19f8340a01b597089dfde6dc17bc5288c1f863e", + "email": "active@example.com", + "date_joined": "2011-04-01 11:12:45" + } + }, + { + "pk": 30, + "model": "auth.user", + "fields": { + "username": "author", + "first_name": "", + "last_name": "", + "is_active": true, + "is_superuser": false, + "is_staff": true, + "last_login": "2011-04-24 11:32:16", + "groups": [ + 2 + ], + "user_permissions": [], + "password": "sha1$6c580$01509bea19e3ade9f1bcf303205a7cb10ce6762d", + "email": "", + "date_joined": "2011-04-24 11:32:16" + } + }, + { + "pk": 29, + "model": "auth.user", + "fields": { + "username": "editor", + "first_name": "", + "last_name": "", + "is_active": true, + "is_superuser": false, + "is_staff": true, + "last_login": "2011-04-24 11:31:50", + "groups": [ + 1 + ], + "user_permissions": [], + "password": "sha1$3be01$b6aa05c61fc52edae3055c55e160d4cfd4756d91", + "email": "editor@exapmle.com", + "date_joined": "2011-04-24 11:31:50" + } + }, + { + "pk": 27, + "model": "auth.user", + "fields": { + "username": "nonactive", + "first_name": "", + "last_name": "", + "is_active": false, + "is_superuser": false, + "is_staff": false, + "last_login": "2011-04-24 11:31:00", + "groups": [], + "user_permissions": [], + "password": "sha1$0bf10$d60f146d15e4fe3cb0de5a607a17902d0f63a95c", + "email": "", + "date_joined": "2011-04-24 11:31:00" + } + }, + { + "pk": 28, + "model": "auth.user", + "fields": { + "username": "staff", + "first_name": "", + "last_name": "", + "is_active": true, + "is_superuser": false, + "is_staff": true, + "last_login": "2011-04-24 11:31:26", + "groups": [], + "user_permissions": [], + "password": "sha1$5df85$bb4c1894a866fb86465d28831000af20316233d5", + "email": "staff@example.com", + "date_joined": "2011-04-24 11:31:26" + } + } +] \ No newline at end of file diff --git a/cas_provider/forms.py b/cas_provider/forms.py index 80b8913..912f184 100644 --- a/cas_provider/forms.py +++ b/cas_provider/forms.py @@ -1,15 +1,16 @@ from django import forms from django.utils.translation import ugettext_lazy as _ - from utils import create_login_ticket + class LoginForm(forms.Form): username = forms.CharField(max_length=30, label=_('username')) password = forms.CharField(widget=forms.PasswordInput, label=_('password')) #warn = forms.BooleanField(required=False) # TODO: Implement lt = forms.CharField(widget=forms.HiddenInput, initial=create_login_ticket) + def __init__(self, service=None, renew=None, gateway=None, request=None, *args, **kwargs): super(LoginForm, self).__init__(*args, **kwargs) self.request = request if service is not None: - self.fields['service'] = forms.CharField(widget=forms.HiddenInput, initial=service) \ No newline at end of file + self.fields['service'] = forms.CharField(widget=forms.HiddenInput, initial=service) diff --git a/cas_provider/models.py b/cas_provider/models.py index 6eecc3e..516992d 100644 --- a/cas_provider/models.py +++ b/cas_provider/models.py @@ -1,5 +1,5 @@ -from django.db import models from django.contrib.auth.models import User +from django.db import models from django.utils.translation import ugettext_lazy as _ __all__ = ['ServiceTicket', 'LoginTicket'] diff --git a/cas_provider/tests.py b/cas_provider/tests.py new file mode 100644 index 0000000..2ad95f7 --- /dev/null +++ b/cas_provider/tests.py @@ -0,0 +1,91 @@ +from django.core.urlresolvers import reverse +from django.test import TestCase +from urlparse import urlparse + + +class UserTest(TestCase): + + fixtures = ['cas_users.json', ] + + def setUp(self): + self.service = 'http://example.com/' + + + def test_succeessful_login(self): + response = self._login_user('root', '123') + self._validate_cas1(response, True) + + response = self.client.get(reverse('cas_login'), {'service': self.service}, follow=False) + self.assertEqual(response.status_code, 302) + self.assertTrue(response['location'].startswith('%s?ticket=' % self.service)) + + response = self.client.get(reverse('cas_login'), follow=False) + self.assertEqual(response.status_code, 302) + self.assertTrue(response['location'].startswith('http://testserver/')) + + response = self.client.get(response['location'], follow=False) + self.assertIn(response.status_code, [302, 200]) + + + def test_logout(self): + response = self._login_user('root', '123') + self._validate_cas1(response, True) + + response = self.client.get(reverse('cas_logout'), follow=False) + self.assertEqual(response.status_code, 200) + + response = self.client.get(reverse('cas_login'), follow=False) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context['user'].is_anonymous(), True) + + + def test_broken_pwd(self): + self._fail_login('root', '321') + + def test_broken_username(self): + self._fail_login('notroot', '123') + + def test_nonactive_user_login(self): + self._fail_login('nonactive', '123') + + + def _fail_login(self, username, password): + response = self._login_user(username, password) + self._validate_cas1(response, False) + + response = self.client.get(reverse('cas_login'), {'service': self.service}, follow=False) + self.assertEqual(response.status_code, 200) + response = self.client.get(reverse('cas_login'), follow=False) + self.assertEqual(response.status_code, 200) + + + + def _login_user(self, username, password): + self.username = username + response = self.client.get(reverse('cas_login'), {'service': self.service}) + self.assertEqual(response.status_code, 200) + form = response.context['form'] + service = form['service'].value() + return self.client.post(reverse('cas_login'), { + 'username': username, + 'password': password, + 'lt': form['lt'].value(), + 'service': service + }, follow=False) + + + def _validate_cas1(self, response, is_correct=True): + if is_correct: + self.assertEqual(response.status_code, 302) + self.assertTrue(response.has_header('location')) + location = urlparse(response['location']) + ticket = location.query.split('=')[1] + + response = self.client.get(reverse('cas_validate'), {'ticket': ticket, 'service': self.service}, follow=False) + self.assertEqual(response.status_code, 200) + self.assertEqual(unicode(response.content), u'yes\r\n%s\r\n' % self.username if is_correct else u'no\r\n') + else: + self.assertEqual(response.status_code, 200) + self.assertGreater(len(response.context['errors']), 0) + self.assertEqual(len(response.context['form'].errors), 0) + diff --git a/cas_provider/utils.py b/cas_provider/utils.py index 04a5c12..fcff8a6 100644 --- a/cas_provider/utils.py +++ b/cas_provider/utils.py @@ -1,7 +1,7 @@ +from models import ServiceTicket, LoginTicket from random import Random import string -from models import ServiceTicket, LoginTicket def _generate_string(length=8, chars=string.ascii_letters + string.digits): """ Generates a random string of the requested length. Used for creation of tickets. """ @@ -21,4 +21,4 @@ def create_login_ticket(): ticket_string = 'LT-' + _generate_string(29) ticket = LoginTicket(ticket=ticket_string) ticket.save() - return ticket_string \ No newline at end of file + return ticket_string diff --git a/cas_provider/views.py b/cas_provider/views.py index 7f63cd4..3686d74 100644 --- a/cas_provider/views.py +++ b/cas_provider/views.py @@ -13,7 +13,7 @@ from utils import create_service_ticket __all__ = ['login', 'validate', 'logout', 'service_validate'] -def login(request, template_name='cas/login.html', success_redirect='/accounts/'): +def login(request, template_name='cas/login.html', success_redirect=getattr(settings, 'LOGIN_REDIRECT_URL', '/accounts/')): service = request.GET.get('service', None) if request.user.is_authenticated(): if service is not None: -- 2.20.1