add tests, fix LOGIN_REDIRECT_URL settings support
authorAlex Kamedov <alex@kamedov.ru>
Sun, 24 Apr 2011 07:59:56 +0000 (13:59 +0600)
committerAlex Kamedov <alex@kamedov.ru>
Sun, 24 Apr 2011 07:59:56 +0000 (13:59 +0600)
cas_provider/fixtures/cas_users.json [new file with mode: 0644]
cas_provider/forms.py
cas_provider/models.py
cas_provider/tests.py [new file with mode: 0644]
cas_provider/utils.py
cas_provider/views.py

diff --git a/cas_provider/fixtures/cas_users.json b/cas_provider/fixtures/cas_users.json
new file mode 100644 (file)
index 0000000..f31d5cb
--- /dev/null
@@ -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
index 80b8913..912f184 100644 (file)
@@ -1,15 +1,16 @@
 from django import forms
 from django.utils.translation import ugettext_lazy as _
 from django import forms
 from django.utils.translation import ugettext_lazy as _
-
 from utils import create_login_ticket
 
 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)
 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:
     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)
index 6eecc3e..516992d 100644 (file)
@@ -1,5 +1,5 @@
-from django.db import models
 from django.contrib.auth.models import User
 from django.contrib.auth.models import User
+from django.db import models
 from django.utils.translation import ugettext_lazy as _
 
 __all__ = ['ServiceTicket', 'LoginTicket']
 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 (file)
index 0000000..2ad95f7
--- /dev/null
@@ -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)
+
index 04a5c12..fcff8a6 100644 (file)
@@ -1,7 +1,7 @@
+from models import ServiceTicket, LoginTicket
 from random import Random
 import string
 
 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. """
 
 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()
     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
index 7f63cd4..3686d74 100644 (file)
@@ -13,7 +13,7 @@ from utils import create_service_ticket
 __all__ = ['login', 'validate', 'logout', 'service_validate']
 
 
 __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:
     service = request.GET.get('service', None)
     if request.user.is_authenticated():
         if service is not None: