Python 3.4 compatibility & fixed some of the tests.
authorRadek Czajka <rczajka@rczajka.pl>
Fri, 19 Sep 2014 23:42:43 +0000 (01:42 +0200)
committerRadek Czajka <rczajka@rczajka.pl>
Fri, 19 Sep 2014 23:42:43 +0000 (01:42 +0200)
12 files changed:
README.rst
cas_provider/__init__.py
cas_provider/admin.py
cas_provider/attribute_formatters.py
cas_provider/management/commands/cleanuptickets.py
cas_provider/models.py
cas_provider/templates/cas/warn.html
cas_provider/tests.py
cas_provider/views.py
cas_provider_examples/simple/manage.py [deleted file]
cas_provider_examples/simple/settings.py
cas_provider_examples/simple/urls.py

index 258d685..d7bed27 100644 (file)
@@ -19,29 +19,6 @@ Or, put `cas_provider` somewhere on your Python path.
 
 If you want use CAS v.2 protocol or above, you must install `lxml` package to correct work.
 
-UPDATING FROM PREVIOUS VERSION
-===============================
-
-I introduced south for DB schema migration. The schema from any previous version without south is 0001_initial.
-You will get an error:
-
-    ``Running migrations for cas_provider:``
-
-    ``- Migrating forwards to 0001_initial.``
-
-    ``> cas_provider:0001_initial``
-
-    ``Traceback (most recent call last):``
-
-    ``...``
-
-    ``django.db.utils.DatabaseError: relation "cas_provider_serviceticket" already exists``
-
-to circumvent that problem you will need to fake the initial migration:
-
- python manage.py migrate cas_provider 0001_initial --fake
-
-
 USAGE
 ======
 
index 1dd6c7a..22cedc3 100644 (file)
@@ -8,7 +8,7 @@ _DEFAULTS = {
     'CAS_AUTO_REDIRECT_AFTER_LOGOUT': False,
 }
 
-for key, value in _DEFAULTS.iteritems():
+for key, value in _DEFAULTS.items():
     try:
         getattr(settings, key)
     except AttributeError:
index 499fa43..90182e2 100644 (file)
@@ -1,5 +1,5 @@
 from django.contrib import admin
-from models import *
+from .models import *
 
 
 class ServiceTicketAdmin(admin.ModelAdmin):
index 55eb4dd..b06cd84 100644 (file)
@@ -6,11 +6,17 @@ NSMAP = {'cas': CAS_URI}
 CAS = '{%s}' % CAS_URI
 
 
+try:
+    basestring
+except NameError:
+    basestring = (str, bytes)
+
+
 def jasig(auth_success, attrs):
     attributes = etree.SubElement(auth_success, CAS + 'attributes')
     style = etree.SubElement(attributes, CAS + 'attraStyle')
     style.text = u'Jasig'
-    for name, value in attrs.items():
+    for name, value in sorted(attrs.items()):
         if isinstance(value, collections.Iterable) and not isinstance(value, basestring):
             for e in value:
                 element = etree.SubElement(attributes, CAS + name)
@@ -23,7 +29,7 @@ def jasig(auth_success, attrs):
 def ruby_cas(auth_success, attrs):
     style = etree.SubElement(auth_success, CAS + 'attraStyle')
     style.text = u'RubyCAS'
-    for name, value in attrs.items():
+    for name, value in sorted(attrs.items()):
         if isinstance(value, collections.Iterable) and not isinstance(value, basestring):
             for e in value:
                 element = etree.SubElement(auth_success, CAS + name)
@@ -35,7 +41,7 @@ def ruby_cas(auth_success, attrs):
 
 def name_value(auth_success, attrs):
     etree.SubElement(auth_success, CAS + 'attribute', name=u'attraStyle', value=u'Name-Value')
-    for name, value in attrs.items():
+    for name, value in sorted(attrs.items()):
         if isinstance(value, collections.Iterable) and not isinstance(value, basestring):
             for e in value:
                 etree.SubElement(auth_success, CAS + 'attribute', name=name, value=e)
index 401bec1..c951993 100644 (file)
@@ -6,6 +6,7 @@ Calls ``ServiceTickets.objects.delete_expired_users()``, which
 contains the actual logic for determining which accounts are deleted.
 
 """
+from __future__ import print_function
 
 from django.core.management.base import NoArgsCommand
 from django.conf import settings
@@ -18,21 +19,21 @@ class Command(NoArgsCommand):
     help = "Delete expired service tickets from the database"
 
     def handle_noargs(self, **options):
-        print "Service tickets:"
+        print("Service tickets:")
         tickets = ServiceTicket.objects.all()
         for ticket in tickets:
             expiration = datetime.timedelta(minutes=settings.CAS_TICKET_EXPIRATION)
             if datetime.datetime.now() > ticket.created + expiration:
-                print "Deleting %s..." % ticket.ticket
+                print("Deleting %s..." % ticket.ticket)
                 ticket.delete()
             else:
-                print "%s not expired..." % ticket.ticket
+                print("%s not expired..." % ticket.ticket)
         tickets = LoginTicket.objects.all()
-        print "Login tickets:"
+        print("Login tickets:")
         for ticket in tickets:
             expiration = datetime.timedelta(minutes=settings.CAS_TICKET_EXPIRATION)
             if datetime.datetime.now() > ticket.created + expiration:
-                print "Deleting %s..." % ticket.ticket
+                print("Deleting %s..." % ticket.ticket)
                 ticket.delete()
             else:
-                print "%s not expired..." % ticket.ticket
\ No newline at end of file
+                print("%s not expired..." % ticket.ticket)
index 4b75fca..43463d5 100644 (file)
@@ -3,14 +3,15 @@ from django.db import models
 from django.utils.translation import ugettext_lazy as _
 from random import Random
 import string
-import urllib
-import urlparse
-
-if hasattr(urlparse, 'parse_qs'):
-    parse_qs = urlparse.parse_qs
-else:
-    # Python <2.6 compatibility
-    from cgi import parse_qs
+try:
+    from urllib.parse import urlencode, urlparse, parse_qs, ParseResult
+except ImportError:
+    from urllib import urlencode
+    from urlparse import urlparse, ParseResult
+    try:
+        from urlparse import parse_qs
+    except: # Python <2.6 compatibility
+        from cgi import parse_qs
 
 __all__ = ['ServiceTicket', 'LoginTicket', 'ProxyGrantingTicket', 'ProxyTicket', 'ProxyGrantingTicketIOU']
 
@@ -45,13 +46,13 @@ class ServiceTicket(BaseTicket):
         verbose_name_plural = _('Service Tickets')
 
     def get_redirect_url(self):
-        parsed = urlparse.urlparse(self.service)
+        parsed = urlparse(self.service)
         query = parse_qs(parsed.query)
         query['ticket'] = [self.ticket]
-        query = [((k, v) if len(v) > 1 else (k, v[0])) for k, v in query.iteritems()]
-        parsed = urlparse.ParseResult(parsed.scheme, parsed.netloc,
+        query = [((k, v) if len(v) > 1 else (k, v[0])) for k, v in query.items()]
+        parsed = ParseResult(parsed.scheme, parsed.netloc,
                                       parsed.path, parsed.params,
-                                      urllib.urlencode(query), parsed.fragment)
+                                      urlencode(query), parsed.fragment)
         return parsed.geturl()
 
 
index ca9e561..9c74eee 100644 (file)
@@ -5,7 +5,7 @@ Warning
 {% endblock %}
 
 {% block content %}
-  <form action='{% url cas_login %}' method='get'>
+  <form action='{% url 'cas_login' %}' method='get'>
     <fieldset>
       <legend>Confirm to log in to {{ service }}</legend>
          <input type="hidden" name="service" value="{{ service }}">
index 46ba3ca..dbb1be1 100644 (file)
@@ -1,17 +1,24 @@
-import StringIO
-import urllib2
+from __future__ import unicode_literals
+from io import StringIO
 from xml import etree
 from xml.etree import ElementTree
 import cas_provider
 from cas_provider.attribute_formatters import CAS, NSMAP
 from cas_provider.models import ServiceTicket
+from cas_provider.signals import cas_collect_custom_attributes
 from cas_provider.views import _cas2_sucess_response, INVALID_TICKET, _cas2_error_response, generate_proxy_granting_ticket
 from django.contrib.auth.models import User, UserManager
 from django.core.urlresolvers import reverse
 from django.test import TestCase
-from urlparse import urlparse, parse_qsl, parse_qs
 from django.conf import settings
 
+try:
+    from urllib.parse import urlparse, parse_qsl, parse_qs
+    from urllib import request
+except:
+    from urlparse import urlparse, parse_qsl, parse_qs
+    import urllib2 as request
+
 
 
 
@@ -33,7 +40,7 @@ class ViewsTest(TestCase):
 
 
     def test_successful_login_with_proxy(self):
-        urllib2.urlopen = dummy_urlopen # monkey patching urllib2.urlopen so that the testcase doesnt really opens a url
+        request.urlopen = dummy_urlopen # monkey patching request.urlopen so that the testcase doesnt really opens a url
         proxyTarget = "http://my.sweet.service"
 
         response = self._login_user('root', '123')
@@ -41,7 +48,7 @@ class ViewsTest(TestCase):
 
         # Test: I'm acting as the service that will call another service
         # Step 1: Get the proxy granting ticket
-        responseXml = ElementTree.parse(StringIO.StringIO(response.content))
+        responseXml = ElementTree.parse(StringIO(response.content.decode('utf-8')))
         auth_success = responseXml.find(CAS + 'authenticationSuccess', namespaces=NSMAP)
         pgt = auth_success.find(CAS + "proxyGrantingTicket", namespaces=NSMAP)
         user = auth_success.find(CAS + "user", namespaces=NSMAP)
@@ -53,14 +60,14 @@ class ViewsTest(TestCase):
 
         #Step 2: Get the actual proxy ticket
         proxyTicketResponse = self.client.get(reverse('proxy'), {'targetService': proxyTarget, 'pgt': pgtId}, follow=False)
-        proxyTicketResponseXml = ElementTree.parse(StringIO.StringIO(proxyTicketResponse.content))
+        proxyTicketResponseXml = ElementTree.parse(StringIO(proxyTicketResponse.content))
         self.assertIsNotNone(proxyTicketResponseXml.find(CAS + "proxySuccess", namespaces=NSMAP))
         self.assertIsNotNone(proxyTicketResponseXml.find(CAS + "proxySuccess/cas:proxyTicket", namespaces=NSMAP))
         proxyTicket = proxyTicketResponseXml.find(CAS + "proxySuccess/cas:proxyTicket", namespaces=NSMAP);
 
         #Step 3: I have the proxy ticket I can talk to some other backend service as the currently logged in user!
         proxyValidateResponse = self.client.get(reverse('cas_proxy_validate'), {'ticket': proxyTicket.text, 'service': proxyTarget})
-        proxyValidateResponseXml = ElementTree.parse(StringIO.StringIO(proxyValidateResponse.content))
+        proxyValidateResponseXml = ElementTree.parse(StringIO(proxyValidateResponse.content))
 
         auth_success_2 = proxyValidateResponseXml.find(CAS + 'authenticationSuccess', namespaces=NSMAP)
         user_2 = auth_success.find(CAS + "user", namespaces=NSMAP)
@@ -71,7 +78,7 @@ class ViewsTest(TestCase):
 
 
     def test_successful_proxy_chaining(self):
-        urllib2.urlopen = dummy_urlopen # monkey patching urllib2.urlopen so that the testcase doesnt really opens a url
+        request.urlopen = dummy_urlopen # monkey patching request.urlopen so that the testcase doesnt really opens a url
         proxyTarget_1 = "http://my.sweet.service_1"
         proxyTarget_2 = "http://my.sweet.service_2"
 
@@ -80,7 +87,7 @@ class ViewsTest(TestCase):
 
         # Test: I'm acting as the service that will call another service
         # Step 1: Get the proxy granting ticket
-        responseXml = ElementTree.parse(StringIO.StringIO(response.content))
+        responseXml = ElementTree.parse(StringIO(response.content.decode('utf-8')))
         auth_success_1 = responseXml.find(CAS + 'authenticationSuccess', namespaces=NSMAP)
         pgt_1 = auth_success_1.find(CAS + "proxyGrantingTicket", namespaces=NSMAP)
         user_1 = auth_success_1.find(CAS + "user", namespaces=NSMAP)
@@ -92,7 +99,7 @@ class ViewsTest(TestCase):
 
         #Step 2: Get the actual proxy ticket
         proxyTicketResponse_1 = self.client.get(reverse('proxy'), {'targetService': proxyTarget_1, 'pgt': pgtId_1}, follow=False)
-        proxyTicketResponseXml_1 = ElementTree.parse(StringIO.StringIO(proxyTicketResponse_1.content))
+        proxyTicketResponseXml_1 = ElementTree.parse(StringIO(proxyTicketResponse_1.content))
         self.assertIsNotNone(proxyTicketResponseXml_1.find(CAS + "proxySuccess", namespaces=NSMAP))
         self.assertIsNotNone(proxyTicketResponseXml_1.find(CAS + "proxySuccess/cas:proxyTicket", namespaces=NSMAP))
         proxyTicket_1 = proxyTicketResponseXml_1.find(CAS + "proxySuccess/cas:proxyTicket", namespaces=NSMAP);
@@ -100,7 +107,7 @@ class ViewsTest(TestCase):
         #Step 3: I'm backend service 1 - I have the proxy ticket - I want to talk to back service 2
         #
         proxyValidateResponse_1 = self.client.get(reverse('cas_proxy_validate'), {'ticket': proxyTicket_1.text, 'service': proxyTarget_1, 'pgtUrl': proxyTarget_2})
-        proxyValidateResponseXml_1 = ElementTree.parse(StringIO.StringIO(proxyValidateResponse_1.content))
+        proxyValidateResponseXml_1 = ElementTree.parse(StringIO(proxyValidateResponse_1.content))
 
         auth_success_2 = proxyValidateResponseXml_1.find(CAS + 'authenticationSuccess', namespaces=NSMAP)
         user_2 = auth_success_2.find(CAS + "user", namespaces=NSMAP)
@@ -120,13 +127,13 @@ class ViewsTest(TestCase):
 
         #Step 4: Get the second proxy ticket
         proxyTicketResponse_2 = self.client.get(reverse('proxy'), {'targetService': proxyTarget_2, 'pgt': pgtId_2})
-        proxyTicketResponseXml_2 = ElementTree.parse(StringIO.StringIO(proxyTicketResponse_2.content))
+        proxyTicketResponseXml_2 = ElementTree.parse(StringIO(proxyTicketResponse_2.content))
         self.assertIsNotNone(proxyTicketResponseXml_2.find(CAS + "proxySuccess", namespaces=NSMAP))
         self.assertIsNotNone(proxyTicketResponseXml_2.find(CAS + "proxySuccess/cas:proxyTicket", namespaces=NSMAP))
         proxyTicket_2 = proxyTicketResponseXml_2.find(CAS + "proxySuccess/cas:proxyTicket", namespaces=NSMAP)
 
         proxyValidateResponse_3 = self.client.get(reverse('cas_proxy_validate'), {'ticket': proxyTicket_2.text, 'service': proxyTarget_2, 'pgtUrl': None})
-        proxyValidateResponseXml_3 = ElementTree.parse(StringIO.StringIO(proxyValidateResponse_3.content))
+        proxyValidateResponseXml_3 = ElementTree.parse(StringIO(proxyValidateResponse_3.content))
 
         auth_success_3 = proxyValidateResponseXml_3.find(CAS + 'authenticationSuccess', namespaces=NSMAP)
         user_3 = auth_success_3.find(CAS + "user", namespaces=NSMAP)
@@ -194,19 +201,21 @@ class ViewsTest(TestCase):
         self.assertEqual(response.content, _cas2_sucess_response(user).content)
 
     def test_cas2_custom_attrs(self):
-        settings.CAS_CUSTOM_ATTRIBUTES_CALLBACK = cas_mapping
+        cas_collect_custom_attributes.connect(cas_mapping)
         response = self._login_user('editor', '123')
+        self.maxDiff=None
 
         response = self._validate_cas2(response, True)
-        self.assertEqual(response.content, '''<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">'''
+        self.assertEqual(response.content.decode('utf-8'),
+                                           '''<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">'''
                                            '''<cas:authenticationSuccess>'''
                                            '''<cas:user>editor</cas:user>'''
                                            '''<cas:attributes>'''
                                            '''<cas:attraStyle>Jasig</cas:attraStyle>'''
+                                           '''<cas:email>editor@exapmle.com</cas:email>'''
                                            '''<cas:group>editor</cas:group>'''
-                                           '''<cas:is_staff>True</cas:is_staff>'''
                                            '''<cas:is_active>True</cas:is_active>'''
-                                           '''<cas:email>editor@exapmle.com</cas:email>'''
+                                           '''<cas:is_staff>True</cas:is_staff>'''
                                            '''</cas:attributes>'''
                                            '''</cas:authenticationSuccess>'''
                                            '''</cas:serviceResponse>''')
@@ -215,14 +224,15 @@ class ViewsTest(TestCase):
         response = self._login_user('editor', '123')
         settings.CAS_CUSTOM_ATTRIBUTES_FORMATER = 'cas_provider.attribute_formatters.ruby_cas'
         response = self._validate_cas2(response, True)
-        self.assertEqual(response.content, '''<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">'''
+        self.assertEqual(response.content.decode('utf-8'),
+                                           '''<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">'''
                                            '''<cas:authenticationSuccess>'''
                                            '''<cas:user>editor</cas:user>'''
                                            '''<cas:attraStyle>RubyCAS</cas:attraStyle>'''
+                                           '''<cas:email>editor@exapmle.com</cas:email>'''
                                            '''<cas:group>editor</cas:group>'''
-                                           '''<cas:is_staff>True</cas:is_staff>'''
                                            '''<cas:is_active>True</cas:is_active>'''
-                                           '''<cas:email>editor@exapmle.com</cas:email>'''
+                                           '''<cas:is_staff>True</cas:is_staff>'''
                                            '''</cas:authenticationSuccess>'''
                                            '''</cas:serviceResponse>''')
 
@@ -230,14 +240,15 @@ class ViewsTest(TestCase):
         response = self._login_user('editor', '123')
         settings.CAS_CUSTOM_ATTRIBUTES_FORMATER = 'cas_provider.attribute_formatters.name_value'
         response = self._validate_cas2(response, True)
-        self.assertEqual(response.content, '''<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">'''
+        self.assertEqual(response.content.decode('utf-8'),
+                                           '''<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">'''
                                            '''<cas:authenticationSuccess>'''
                                            '''<cas:user>editor</cas:user>'''
                                            '''<cas:attribute name="attraStyle" value="Name-Value"/>'''
+                                           '''<cas:attribute name="email" value="editor@exapmle.com"/>'''
                                            '''<cas:attribute name="group" value="editor"/>'''
-                                           '''<cas:attribute name="is_staff" value="True"/>'''
                                            '''<cas:attribute name="is_active" value="True"/>'''
-                                           '''<cas:attribute name="email" value="editor@exapmle.com"/>'''
+                                           '''<cas:attribute name="is_staff" value="True"/>'''
                                            '''</cas:authenticationSuccess>'''
                                            '''</cas:serviceResponse>''')
 
@@ -249,7 +260,7 @@ class ViewsTest(TestCase):
 
 
     def test_generate_proxy_granting_ticket(self):
-        urllib2.urlopen = dummy_urlopen # monkey patching urllib2.urlopen so that the testcase doesnt really opens a url
+        request.urlopen = dummy_urlopen # monkey patching request.urlopen so that the testcase doesnt really opens a url
         url = 'http://my.call.back/callhere'
 
         user = User.objects.get(username = 'root')
@@ -286,7 +297,6 @@ class ViewsTest(TestCase):
         return self.client.post(reverse('cas_login'), {
             'username': username,
             'password': password,
-            'lt': form['lt'].value(),
             'service': service
         }, follow=False)
 
@@ -300,14 +310,14 @@ class ViewsTest(TestCase):
 
             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\n%s\n' % self.username)
+            self.assertEqual(response.content.decode('utf-8'), 'yes\n%s\n' % self.username)
         else:
             self.assertEqual(response.status_code, 200)
-            self.assertEqual(len(response.context['form'].errors), 1)
+            self.assertEqual(len(response.context['errors']), 1)
 
             response = self.client.get(reverse('cas_validate'), {'ticket': 'ST-12312312312312312312312', 'service': self.service}, follow=False)
             self.assertEqual(response.status_code, 200)
-            self.assertEqual(response.content, u'no\n\n')
+            self.assertEqual(response.content.decode('utf-8'), 'no\n\n')
 
 
     def _validate_cas2(self, response, is_correct=True, pgtUrl = None):
@@ -323,7 +333,7 @@ class ViewsTest(TestCase):
             self.assertEqual(response.status_code, 200)
         else:
             self.assertEqual(response.status_code, 200)
-            self.assertEqual(len(response.context['form'].errors), 1)
+            self.assertEqual(len(response.context['errors']), 1)
 
             response = self.client.get(reverse('cas_service_validate'), {'ticket': 'ST-12312312312312312312312', 'service': self.service}, follow=False)
             self.assertEqual(response.status_code, 200)
@@ -342,10 +352,10 @@ class ModelsTestCase(TestCase):
         self.assertEqual(ticket.get_redirect_url(), '%(service)s?ticket=%(ticket)s' % ticket.__dict__)
 
 
-def cas_mapping(user):
+def cas_mapping(sender, user, **kwargs):
     return {
-        'is_staff': unicode(user.is_staff),
-        'is_active': unicode(user.is_active),
+        'is_staff': str(user.is_staff),
+        'is_active': str(user.is_active),
         'email': user.email,
         'group': [g.name for g in user.groups.all()]
     }
index 976c271..8ae10fa 100644 (file)
@@ -1,10 +1,14 @@
 import logging
 logger = logging.getLogger('cas_provider.views')
-import urllib
 
-from urllib import urlencode
-import urllib2
-import urlparse
+try:
+    from urllib.error import HTTPError, URLError
+    from urllib.parse import parse_qsl, urlencode, urlparse, urlsplit, urlunsplit
+    from urllib.request import urlopen
+except ImportError:
+    from urllib import urlencode
+    from urllib2 import HTTPError, URLError, urlopen
+    from urlparse import parse_qsl, urlparse, urlsplit, urlunsplit
 from functools import wraps
 
 from django.utils.decorators import available_attrs
@@ -118,7 +122,7 @@ def login(request, template_name='cas/login.html',
                         )
                     if service is not None:
                         args['service'] = service
-                    args = urllib.urlencode(args)
+                    args = urlencode(args)
 
                     url = '%s?%s' % (base_url, args)
                     logging.debug('Redirecting to %s', url)
@@ -255,8 +259,8 @@ def ticket_validate(service, ticket_string, pgtUrl):
     except ServiceTicket.DoesNotExist:
         return _cas2_error_response(INVALID_TICKET)
 
-    ticketUrl = urlparse.urlparse(ticket.service)
-    serviceUrl = urlparse.urlparse(service)
+    ticketUrl = urlparse(ticket.service)
+    serviceUrl = urlparse(service)
 
     if not(ticketUrl.hostname == serviceUrl.hostname and ticketUrl.path == serviceUrl.path and ticketUrl.port == serviceUrl.port):
         return _cas2_error_response(INVALID_SERVICE)
@@ -307,7 +311,7 @@ def proxy_validate(request):
 
 def generate_proxy_granting_ticket(pgt_url, ticket):
     proxy_callback_good_status = (200, 202, 301, 302, 304)
-    uri = list(urlparse.urlsplit(pgt_url))
+    uri = list(urlsplit(pgt_url))
 
     pgt = ProxyGrantingTicket()
     pgt.serviceTicket = ticket
@@ -319,18 +323,18 @@ def generate_proxy_granting_ticket(pgt_url, ticket):
 
     params = {'pgtId': pgt.ticket, 'pgtIou': pgt.pgtiou}
 
-    query = dict(urlparse.parse_qsl(uri[4]))
+    query = dict(parse_qsl(uri[4]))
     query.update(params)
 
     uri[3] = urlencode(query)
 
     try:
-        urllib2.urlopen(urlparse.urlunsplit(uri))
-    except urllib2.HTTPError as e:
+        urlopen(urlunsplit(uri))
+    except HTTPError as e:
         if not e.code in proxy_callback_good_status:
             logger.debug('Checking Proxy Callback URL {} returned {}. Not issuing PGT.'.format(uri, e.code))
             return
-    except urllib2.URLError as e:
+    except URLError as e:
         logger.debug('Checking Proxy Callback URL {} raised URLError. Not issuing PGT.'.format(uri))
         return
 
@@ -362,7 +366,7 @@ def proxy_success(pt):
     proxySuccess = etree.SubElement(response, CAS + 'proxySuccess')
     proxyTicket = etree.SubElement(proxySuccess, CAS + 'proxyTicket')
     proxyTicket.text = pt
-    return unicode(etree.tostring(response, encoding='utf-8'), 'utf-8')
+    return etree.tostring(response, encoding='unicode')
 
 
 def auth_success_response(user, pgt, proxies):
@@ -397,4 +401,4 @@ def auth_success_response(user, pgt, proxies):
             proxyElement = etree.SubElement(proxiesElement, CAS + "proxy")
             proxyElement.text = proxy
 
-    return unicode(etree.tostring(response, encoding='utf-8'), 'utf-8')
+    return etree.tostring(response, encoding='unicode')
diff --git a/cas_provider_examples/simple/manage.py b/cas_provider_examples/simple/manage.py
deleted file mode 100644 (file)
index 3e4eedc..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env python
-from django.core.management import execute_manager
-import imp
-try:
-    imp.find_module('settings') # Assumed to be in the same directory.
-except ImportError:
-    import sys
-    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n" % __file__)
-    sys.exit(1)
-
-import settings
-
-if __name__ == "__main__":
-    execute_manager(settings)
index 209927c..1896e81 100644 (file)
@@ -104,10 +104,11 @@ import os
 PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))
 
 TEMPLATE_DIRS = (
-     os.path.join(PROJECT_PATH, 'templates')
+     os.path.join(PROJECT_PATH, 'templates'),
 )
 
 INSTALLED_APPS = (
+    'django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.sessions',
@@ -115,7 +116,6 @@ INSTALLED_APPS = (
     'django.contrib.messages',
     'django.contrib.staticfiles',
     'cas_provider',
-    'south',
 )
 
 # A sample logging configuration. The only tangible logging
index c717237..1d8eafa 100644 (file)
@@ -1,10 +1,10 @@
-from django.conf.urls.defaults import patterns, include, url
-
-import cas_provider
-from django.views.generic.simple import redirect_to, direct_to_template
+from django.conf.urls import patterns, include, url
+from django.contrib import admin
+from django.views.generic import TemplateView
 
 urlpatterns = patterns('',
+    url(r'^admin/', include(admin.site.urls)),
                        url(r'^', include('cas_provider.urls')),
-                       url(r'^accounts/profile', direct_to_template, {'template': 'login-success-redirect-target.html'}),
+                       url(r'^accounts/profile', TemplateView.as_view(template_name='login-success-redirect-target.html')),
 
                        )