diff --git a/.travis.yml b/.travis.yml
index 165b098..6862435 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,6 +2,7 @@ language: python
sudo: false
python:
- "2.7"
+ - "3.5"
env:
- DJANGO="Django>=1.8.0,<1.9.0"
- DJANGO="Django>=1.9.0,<1.10.0"
diff --git a/djangowind/auth.py b/djangowind/auth.py
index a89753c..254db90 100644
--- a/djangowind/auth.py
+++ b/djangowind/auth.py
@@ -1,7 +1,28 @@
+from __future__ import unicode_literals
+
from django.conf import settings
from django.contrib.auth.models import User, Group
-import urllib
-import urllib2
+
+try:
+ from urllib.request import Request
+except ImportError:
+ from urllib2 import Request
+
+try:
+ from urllib.request import urlopen
+except ImportError:
+ from urllib2 import urlopen
+
+try:
+ from urllib.parse import urlencode
+except ImportError:
+ from urllib import urlencode
+
+try:
+ from urllib.parse import quote
+except ImportError:
+ from urllib2 import quote
+
from django.core.exceptions import ImproperlyConfigured
from warnings import warn
from django_statsd.clients import statsd
@@ -22,7 +43,7 @@ def validate_wind_ticket(ticketid):
if hasattr(settings, 'WIND_BASE'):
wind_base = getattr(settings, 'WIND_BASE')
uri = wind_base + "validate?ticketid=%s" % ticketid
- response = urllib.urlopen(uri).read()
+ response = urlopen(uri).read()
lines = response.split("\n")
if lines[0] == "yes":
statsd.incr('djangowind.validate_wind_ticket.success')
@@ -51,8 +72,8 @@ def validate_cas2_ticket(ticketid, url):
cas_base = getattr(settings, 'CAS_BASE')
uri = cas_base + "cas/serviceValidate?ticket=%s&service=%s" % (
ticketid,
- urllib2.quote(url))
- response = urllib.urlopen(uri).read()
+ quote(url))
+ response = urlopen(uri).read()
try:
dom = parseString(response)
if dom.documentElement.nodeName != 'cas:serviceResponse':
@@ -138,12 +159,12 @@ def validate_saml_ticket(ticketid, url):
'connection': 'keep-alive',
'content-type': 'text/xml'}
params = {'TARGET': url}
- uri = cas_base + "cas/samlValidate" + '?' + urllib.urlencode(params)
- url = urllib2.Request(uri, '', headers)
+ uri = cas_base + "cas/samlValidate" + '?' + urlencode(params)
+ request = Request(uri, '', headers)
data = get_saml_assertion(ticketid)
- url.add_data(data)
+ request.data = data
- page = urllib2.urlopen(url)
+ page = urlopen(request)
response = page.read()
try:
user = None
@@ -240,10 +261,10 @@ def load_handler(self, path):
module, attr = path[:i], path[i + 1:]
try:
mod = __import__(module, {}, {}, [attr])
- except ImportError, e:
+ except ImportError as e:
raise ImproperlyConfigured(
'Error importing wind handler %s: "%s"' % (module, e))
- except ValueError, e:
+ except ValueError as e:
raise ImproperlyConfigured('Error importing wind handler.')
try:
cls = getattr(mod, attr)
diff --git a/djangowind/context.py b/djangowind/context.py
index e66aa79..22e8845 100644
--- a/djangowind/context.py
+++ b/djangowind/context.py
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
from django.conf import settings
from django.contrib.auth.forms import AuthenticationForm
diff --git a/djangowind/tests/test_auth.py b/djangowind/tests/test_auth.py
index 8c356c3..2fc0ff4 100644
--- a/djangowind/tests/test_auth.py
+++ b/djangowind/tests/test_auth.py
@@ -1,5 +1,16 @@
+from __future__ import unicode_literals
+
+try:
+ from http.client import HTTPResponse
+except ImportError:
+ from httplib import HTTPResponse
+
+try:
+ from unittest.mock import Mock, patch
+except ImportError:
+ from mock import Mock, patch
+
from django.test import TestCase
-from httpretty import HTTPretty, httprettified
from djangowind.auth import validate_wind_ticket, WindAuthBackend
from djangowind.auth import validate_cas2_ticket, CAS2AuthBackend
from djangowind.auth import validate_saml_ticket, SAMLAuthBackend
@@ -9,79 +20,78 @@
import os.path
+@patch('djangowind.auth.urlopen')
class ValidateWindTicketTest(TestCase):
- def test_no_ticket(self):
+ def setUp(self):
+ self.response = Mock(spec=HTTPResponse)
+
+ def test_no_ticket(self, mock_urlopen):
self.assertEqual(
validate_wind_ticket(""),
(False, 'no ticketid', ''))
- @httprettified
- def test_validate_ticket_success(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- "https://wind.columbia.edu/validate?ticket=foo",
- body="yes\nanders"
- )
+ def test_validate_ticket_success(self, mock_urlopen):
+ self.response.read.return_value = 'yes\nanders'
+ mock_urlopen.return_value = self.response
+
self.assertEqual(
validate_wind_ticket("foo"),
(True, 'anders', ['anders']))
+ mock_urlopen.assert_called_with(
+ 'https://wind.columbia.edu/validate?ticketid=foo')
+
+ def test_validate_ticket_success_with_groups(self, mock_urlopen):
+ self.response.read.return_value = "yes\nanders\ngroup1\ngroup2"
+ mock_urlopen.return_value = self.response
- @httprettified
- def test_validate_ticket_success_with_groups(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- "https://wind.columbia.edu/validate?ticket=foo",
- body="yes\nanders\ngroup1\ngroup2"
- )
self.assertEqual(
validate_wind_ticket("foo"),
(True, 'anders', ['anders', 'group1', 'group2']))
+ mock_urlopen.assert_called_with(
+ 'https://wind.columbia.edu/validate?ticketid=foo')
+
+ def test_validate_ticket_fail(self, mock_urlopen):
+ self.response.read.return_value = 'no\nanders'
+ mock_urlopen.return_value = self.response
- @httprettified
- def test_validate_ticket_fail(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- "https://wind.columbia.edu/validate?ticket=foo",
- body="no\nanders"
- )
self.assertEqual(
validate_wind_ticket("foo"),
(False, "The ticket was already used or was invalid.", []))
+ mock_urlopen.assert_called_with(
+ 'https://wind.columbia.edu/validate?ticketid=foo')
+
+ def test_validate_ticket_invalid_response(self, mock_urlopen):
+ self.response.read.return_value = \
+ "holy crap! I'm not a valid WIND response!"
+ mock_urlopen.return_value = self.response
- @httprettified
- def test_validate_ticket_invalid_response(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- "https://wind.columbia.edu/validate?ticket=foo",
- body="holy crap! I'm not a valid WIND response!"
- )
self.assertEqual(
validate_wind_ticket("foo"),
(False, "WIND did not return a valid response.", []))
+ mock_urlopen.assert_called_with(
+ 'https://wind.columbia.edu/validate?ticketid=foo')
+
+ def test_validate_ticket_alternate_wind_base(self, mock_urlopen):
+ self.response.read.return_value = 'yes\nanders'
+ mock_urlopen.return_value = self.response
- @httprettified
- def test_validate_ticket_alternate_wind_base(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- "https://foo.example.com/validate?ticket=foo",
- body="yes\nanders"
- )
with self.settings(WIND_BASE="https://foo.example.com/"):
self.assertEqual(
validate_wind_ticket("foo"),
(True, 'anders', ['anders']))
+ mock_urlopen.assert_called_with(
+ 'https://foo.example.com/validate?ticketid=foo')
+@patch('djangowind.auth.urlopen')
class ValidateTRCasTicketTest(TestCase):
- @httprettified
- def test_validate_ticket_success(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- ("https://cas.example.com/cas/serviceValidate?"
- "ticket=foo&service=https%3A//"
- "slank.ccnmtl.columbia.edu/accounts/caslogin/%3Fnext%3D/"),
- body=tr_affils()
- )
+ def setUp(self):
+ self.response = Mock(spec=HTTPResponse)
+
+ def test_validate_ticket_success(self, mock_urlopen):
+ self.response.read.return_value = tr_affils()
+ mock_urlopen.return_value = self.response
+
with self.settings(CAS_BASE="https://cas.example.com/"):
self.assertEqual(
validate_cas2_ticket(
@@ -90,118 +100,117 @@ def test_validate_ticket_success(self):
"accounts/caslogin/?next=/")),
(True, "test_claim",
["test_claim", "crs-3", "crs-1"]))
+ mock_urlopen.assert_called_with(
+ "https://cas.example.com/cas/serviceValidate?"
+ "ticket=foo&service=https%3A//"
+ "slank.ccnmtl.columbia.edu/accounts/caslogin/%3Fnext%3D/")
+@patch('djangowind.auth.urlopen')
class ValidateCas2TicketTest(TestCase):
- def test_no_ticket(self):
+ def setUp(self):
+ self.response = Mock(spec=HTTPResponse)
+
+ def test_no_ticket(self, mock_urlopen):
self.assertEqual(
validate_cas2_ticket("", ""),
(False, 'no ticketid', ''))
- @httprettified
- def test_validate_ticket_success(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- ("https://cas.columbia.edu/cas/serviceValidate?ticket=foo"
- "&https%3A//slank.ccnmtl.columbia.edu/accounts/"
- "caslogin/?next=/"),
- body=(
- "\n\n\n\n\t\n"
- "\t\tanp8\n"
- "\n"
- "\n"
- "\t\n"
- "\n")
- )
+ def test_validate_ticket_success(self, mock_urlopen):
+ self.response.read.return_value = (
+ "\n\n\n\n\t\n"
+ "\t\tanp8\n"
+ "\n"
+ "\n"
+ "\t\n"
+ "\n")
+ mock_urlopen.return_value = self.response
+
self.assertEqual(
validate_cas2_ticket(
"foo",
"https://slank.ccnmtl.columbia.edu/accounts/caslogin/?next=/"),
(True, 'anp8', ['anp8']))
-
- @httprettified
- def test_validate_ticket_success_with_groups(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- ("https://cas.columbia.edu/cas/serviceValidate?ticket=foo"
- "&https%3A//slank.ccnmtl.columbia.edu/accounts/"
- "caslogin/?next=/"),
- body=(
- "\n\n\n\n\t\n"
- "\t\tanp8\n"
- "\t\t\n"
- "\t\t\tgroup1\n"
- "\t\t\tgroup2\n"
- "\t\t\n"
- "\n"
- "\n"
- "\t\n"
- "\n")
- )
+ mock_urlopen.assert_called_with(
+ "https://cas.columbia.edu/cas/serviceValidate?ticket=foo"
+ "&service=https%3A//slank.ccnmtl.columbia.edu/accounts/"
+ "caslogin/%3Fnext%3D/")
+
+ def test_validate_ticket_success_with_groups(self, mock_urlopen):
+ self.response.read.return_value = (
+ "\n\n\n\n\t\n"
+ "\t\tanp8\n"
+ "\t\t\n"
+ "\t\t\tgroup1\n"
+ "\t\t\tgroup2\n"
+ "\t\t\n"
+ "\n"
+ "\n"
+ "\t\n"
+ "\n")
+ mock_urlopen.return_value = self.response
self.assertEqual(
validate_cas2_ticket(
"foo",
"https://slank.ccnmtl.columbia.edu/accounts/caslogin/?next=/"),
(True, 'anp8', ['anp8', 'group1', 'group2']))
+ mock_urlopen.assert_called_with(
+ "https://cas.columbia.edu/cas/serviceValidate?ticket=foo"
+ "&service=https%3A//slank.ccnmtl.columbia.edu/accounts/"
+ "caslogin/%3Fnext%3D/")
+
+ def test_validate_ticket_fail(self, mock_urlopen):
+ self.response.read.return_value = (
+ "\n\n\n\n\t\n\t\tticket 'ST-181952-OK0"
+ "qr5suLueHccqPfgIT-idmcasprod2' does not match supp"
+ "lied service. The original service was 'https://"
+ "slank.ccnmtl.columbia.edu/accounts/caslogin/?next=/'"
+ "and the supplied service was 'https://slank.ccnmtl."
+ "columbia.edu/accounts/caslogin/'.\n\t\n")
+ mock_urlopen.return_value = self.response
- @httprettified
- def test_validate_ticket_fail(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- ("https://cas.columbia.edu/cas/serviceValidate?"
- "ticket=foo&https%3A//slank.ccnmtl.columbia.edu/"
- "accounts/caslogin/?next=/"),
- body=(
- "\n\n\n\n\t\n\t\tticket 'ST-181952-OK0"
- "qr5suLueHccqPfgIT-idmcasprod2' does not match supp"
- "lied service. The original service was 'https://"
- "slank.ccnmtl.columbia.edu/accounts/caslogin/?next=/'"
- "and the supplied service was 'https://slank.ccnmtl."
- "columbia.edu/accounts/caslogin/'.\n\t\n")
- )
self.assertEqual(
validate_cas2_ticket(
"foo",
"https://slank.ccnmtl.columbia.edu/accounts/caslogin/?next=/"),
(False, "The ticket was already used or was invalid.", []))
+ mock_urlopen.assert_called_with(
+ "https://cas.columbia.edu/cas/serviceValidate?ticket=foo"
+ "&service=https%3A//slank.ccnmtl.columbia.edu/accounts/"
+ "caslogin/%3Fnext%3D/")
+
+ def test_validate_ticket_invalid_response(self, mock_urlopen):
+ self.response.read.return_value = \
+ "holy crap! I'm not a valid CAS response!"
+ mock_urlopen.return_value = self.response
- @httprettified
- def test_validate_ticket_invalid_response(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- ("https://cas.columbia.edu/cas/serviceValidate?"
- "ticket=foo&https%3A//slank.ccnmtl.columbia.edu/"
- "accounts/caslogin/?next=/"),
- body="holy crap! I'm not a valid CAS response!"
- )
self.assertEqual(
validate_cas2_ticket(
"foo",
"https://slank.ccnmtl.columbia.edu/accounts/caslogin/?next=/"),
(False, "CAS did not return a valid response.", []))
+ mock_urlopen.assert_called_with(
+ "https://cas.columbia.edu/cas/serviceValidate?ticket=foo"
+ "&service=https%3A//slank.ccnmtl.columbia.edu/accounts/"
+ "caslogin/%3Fnext%3D/")
+
+ def test_validate_ticket_alternate_case_base(self, mock_urlopen):
+ self.response.read.return_value = (
+ "\n\n\n\n\t\n"
+ "\t\tanp8\n"
+ "\n"
+ "\n"
+ "\t\n"
+ "\n")
+ mock_urlopen.return_value = self.response
- @httprettified
- def test_validate_ticket_alternate_case_base(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- ("https://cas.example.com/cas/serviceValidate?ticket=foo"
- "&https%3A//slank.ccnmtl.columbia.edu/accounts/"
- "caslogin/?next=/"),
- body=(
- "\n\n\n\n\t\n"
- "\t\tanp8\n"
- "\n"
- "\n"
- "\t\n"
- "\n")
- )
with self.settings(CAS_BASE="https://cas.example.com/"):
self.assertEqual(
validate_cas2_ticket(
@@ -209,25 +218,28 @@ def test_validate_ticket_alternate_case_base(self):
("https://slank.ccnmtl.columbia.edu/accounts/"
"caslogin/?next=/")),
(True, 'anp8', ['anp8']))
+ mock_urlopen.assert_called_with(
+ "https://cas.example.com/cas/serviceValidate?ticket=foo"
+ "&service=https%3A//slank.ccnmtl.columbia.edu/accounts/"
+ "caslogin/%3Fnext%3D/")
- @httprettified
- def test_validate_tr_success(self):
+ def test_validate_tr_success(self, mock_urlopen):
""" for teachrecovery, we authenticate against a drupal
CAS server. The documented response looks like this:
https://gist.github.com/cravecode/6679b68d14a7250c8fe9
"""
- HTTPretty.register_uri(
- HTTPretty.GET,
- ("https://cas.columbia.edu/cas/serviceValidate?ticket=foo"
- "&https%3A//slank.ccnmtl.columbia.edu/accounts/"
- "caslogin/?next=/"),
- body=TR_SUCCESS,
- )
+ self.response.read.return_value = TR_SUCCESS
+ mock_urlopen.return_value = self.response
+
self.assertEqual(
validate_cas2_ticket(
"foo",
"https://slank.ccnmtl.columbia.edu/accounts/caslogin/?next=/"),
(True, 'test_claim', ['test_claim', u'crs-3', u'crs-1']))
+ mock_urlopen.assert_called_with(
+ "https://cas.columbia.edu/cas/serviceValidate?ticket=foo"
+ "&service=https%3A//slank.ccnmtl.columbia.edu/accounts/"
+ "caslogin/%3Fnext%3D/")
TR_SUCCESS = """
@@ -360,35 +372,29 @@ def tr_affils():
return open_affils("tr_affils.txt")
+@patch('djangowind.auth.urlopen')
class ValidateSAMLTicketTest(TestCase):
- def test_no_ticket(self):
+ def setUp(self):
+ self.response = Mock(spec=HTTPResponse)
+
+ def test_no_ticket(self, mock_urlopen):
self.assertEqual(
validate_saml_ticket("", ""),
(False, 'no ticketid', ''))
- @httprettified
- def test_validate_ticket_success(self):
- HTTPretty.register_uri(
- HTTPretty.POST,
- ("https://cas.columbia.edu/cas/samlValidate?"
- "TARGET=https%3A%2F%2Fslank.ccnmtl.columbia.edu"
- "%2Faccounts%2Fcaslogin%2F%3Fnext%3D%2F"),
- body=saml_success_no_affils())
+ def test_validate_ticket_success(self, mock_urlopen):
+ self.response.read.return_value = saml_success_no_affils()
+ mock_urlopen.return_value = self.response
+
self.assertEqual(
validate_saml_ticket(
"foo",
"https://slank.ccnmtl.columbia.edu/accounts/caslogin/?next=/"),
(True, 'anp8', ['anp8']))
- @httprettified
- def test_validate_ticket_success_with_groups(self):
- HTTPretty.register_uri(
- HTTPretty.POST,
- ("https://cas.columbia.edu/cas/samlValidate?"
- "TARGET=https%3A%2F%2Fslank.ccnmtl.columbia.edu"
- "%2Faccounts%2Fcaslogin%2F%3Fnext%3D%2F"),
- body=saml_success_affils()
- )
+ def test_validate_ticket_success_with_groups(self, mock_urlopen):
+ self.response.read.return_value = saml_success_affils()
+ mock_urlopen.return_value = self.response
self.assertEqual(
validate_saml_ticket(
@@ -403,43 +409,31 @@ def test_validate_ticket_success_with_groups(self):
'tlc-pt.cunix.local:columbia.edu',
'tlcxml.cunix.local:columbia.edu']))
- @httprettified
- def test_validate_ticket_fail(self):
- HTTPretty.register_uri(
- HTTPretty.POST,
- ("https://cas.columbia.edu/cas/samlValidate?"
- "TARGET=https%3A%2F%2Fslank.ccnmtl.columbia.edu"
- "%2Faccounts%2Fcaslogin%2F%3Fnext%3D%2F"),
- body=SAML_FAIL)
+ def test_validate_ticket_fail(self, mock_urlopen):
+ self.response.read.return_value = SAML_FAIL
+ mock_urlopen.return_value = self.response
+
self.assertEqual(
validate_saml_ticket(
"foo",
"https://slank.ccnmtl.columbia.edu/accounts/caslogin/?next=/"),
(False, "CAS/SAML Validation Failed", []))
- @httprettified
- def test_validate_ticket_invalid_response(self):
- HTTPretty.register_uri(
- HTTPretty.POST,
- ("https://cas.columbia.edu/cas/samlValidate?"
- "TARGET=https%3A%2F%2Fslank.ccnmtl.columbia.edu"
- "%2Faccounts%2Fcaslogin%2F%3Fnext%3D%2F"),
- body="holy crap! I'm not a valid CAS response!"
- )
+ def test_validate_ticket_invalid_response(self, mock_urlopen):
+ self.response.read.return_value = \
+ "holy crap! I'm not a valid CAS response!"
+ mock_urlopen.return_value = self.response
+
self.assertEqual(
validate_saml_ticket(
"foo",
"https://slank.ccnmtl.columbia.edu/accounts/caslogin/?next=/"),
(False, "CAS did not return a valid response.", []))
- @httprettified
- def test_validate_ticket_alternate_cas_base(self):
- HTTPretty.register_uri(
- HTTPretty.POST,
- ("https://cas.example.com/cas/samlValidate?"
- "TARGET=https%3A%2F%2Fslank.ccnmtl.columbia.edu"
- "%2Faccounts%2Fcaslogin%2F%3Fnext%3D%2F"),
- body=saml_success_no_affils())
+ def test_validate_ticket_alternate_cas_base(self, mock_urlopen):
+ self.response.read.return_value = saml_success_no_affils()
+ mock_urlopen.return_value = self.response
+
with self.settings(CAS_BASE="https://cas.example.com/"):
self.assertEqual(
validate_saml_ticket(
@@ -448,15 +442,10 @@ def test_validate_ticket_alternate_cas_base(self):
"caslogin/?next=/")),
(True, 'anp8', ['anp8']))
- @httprettified
- def test_validate_ticket_with_jonah_affils(self):
- HTTPretty.register_uri(
- HTTPretty.POST,
- ("https://cas.columbia.edu/cas/samlValidate?"
- "TARGET=https%3A%2F%2Fslank.ccnmtl.columbia.edu"
- "%2Faccounts%2Fcaslogin%2F%3Fnext%3D%2F"),
- body=jonah_affils()
- )
+ def test_validate_ticket_with_jonah_affils(self, mock_urlopen):
+ self.response.read.return_value = jonah_affils()
+ mock_urlopen.return_value = self.response
+
self.assertEqual(
validate_saml_ticket(
"foo",
@@ -500,18 +489,18 @@ def test_validate_ticket_with_jonah_affils(self):
't3.y2009.s001.cg8200.soci.st.course:columbia.edu']))
+@patch('djangowind.auth.urlopen')
class WindAuthBackendTest(TestCase):
- def test_authenticate_no_ticket(self):
+ def setUp(self):
+ self.response = Mock(spec=HTTPResponse)
+
+ def test_authenticate_no_ticket(self, mock_urlopen):
w = WindAuthBackend()
self.assertEqual(w.authenticate(None), None)
- @httprettified
- def test_authenticate_success(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- "https://wind.columbia.edu/validate?ticket=foo",
- body="yes\nanders"
- )
+ def test_authenticate_success(self, mock_urlopen):
+ self.response.read.return_value = 'yes\nanders'
+ mock_urlopen.return_value = self.response
w = WindAuthBackend()
r = w.authenticate("foo")
self.assertEqual(r.username, "anders")
@@ -523,14 +512,13 @@ def test_authenticate_success(self):
r = w.authenticate("foo")
self.assertEqual(r.username, "anders")
self.assertFalse(r.has_usable_password())
+ mock_urlopen.assert_called_with(
+ 'https://wind.columbia.edu/validate?ticketid=foo')
+
+ def test_authenticate_success_existing_user(self, mock_urlopen):
+ self.response.read.return_value = 'yes\nanders'
+ mock_urlopen.return_value = self.response
- @httprettified
- def test_authenticate_success_existing_user(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- "https://wind.columbia.edu/validate?ticket=foo",
- body="yes\nanders"
- )
u = User.objects.create(username="anders")
u.set_password("something other than unusable")
u.save()
@@ -538,33 +526,33 @@ def test_authenticate_success_existing_user(self):
r = w.authenticate("foo")
self.assertEqual(r.username, "anders")
self.assertNotEqual(r.password, "!")
+ mock_urlopen.assert_called_with(
+ 'https://wind.columbia.edu/validate?ticketid=foo')
+
+ def test_authenticate_failure(self, mock_urlopen):
+ self.response.read.return_value = 'no\nanders'
+ mock_urlopen.return_value = self.response
- @httprettified
- def test_authenticate_failure(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- "https://wind.columbia.edu/validate?ticket=foo",
- body="no\nanders"
- )
w = WindAuthBackend()
r = w.authenticate("foo")
self.assertEqual(r, None)
+ mock_urlopen.assert_called_with(
+ 'https://wind.columbia.edu/validate?ticketid=foo')
+
+ def test_authenticate_success_with_mappers(self, mock_urlopen):
+ self.response.read.return_value = 'yes\nanders'
+ mock_urlopen.return_value = self.response
- @httprettified
- def test_authenticate_success_with_mappers(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- "https://wind.columbia.edu/validate?ticket=foo",
- body="yes\nanders"
- )
with self.settings(
WIND_AFFIL_HANDLERS=['djangowind.auth.AffilGroupMapper']):
w = WindAuthBackend()
r = w.authenticate("foo")
self.assertEqual(r.username, "anders")
self.assertFalse(r.has_usable_password())
+ mock_urlopen.assert_called_with(
+ 'https://wind.columbia.edu/validate?ticketid=foo')
- def test_get_user(self):
+ def test_get_user(self, mock_urlopen):
w = WindAuthBackend()
# no pre-existing user
r = w.get_user(1)
@@ -575,27 +563,25 @@ def test_get_user(self):
self.assertEqual(r, u)
+@patch('djangowind.auth.urlopen')
class CAS2AuthBackendTest(TestCase):
- def test_authenticate_no_ticket(self):
+ def setUp(self):
+ self.response = Mock(spec=HTTPResponse)
+
+ def test_authenticate_no_ticket(self, mock_urlopen):
w = CAS2AuthBackend()
self.assertEqual(w.authenticate(None), None)
- @httprettified
- def test_authenticate_success(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- ("https://cas.columbia.edu/cas/serviceValidate?ticket=foo"
- "&https%3A//slank.ccnmtl.columbia.edu/accounts/"
- "caslogin/?next=/"),
- body=(
- "\n\n\n\n\t\n"
- "\t\tanp8\n"
- "\n"
- "\n"
- "\t\n"
- "\n")
- )
+ def test_authenticate_success(self, mock_urlopen):
+ self.response.read.return_value = (
+ "\n\n\n\n\t\n"
+ "\t\tanp8\n"
+ "\n"
+ "\n"
+ "\t\n"
+ "\n")
+ mock_urlopen.return_value = self.response
w = CAS2AuthBackend()
r = w.authenticate(
@@ -604,6 +590,10 @@ def test_authenticate_success(self):
"caslogin/?next=/"))
self.assertEqual(r.username, "anp8")
self.assertFalse(r.has_usable_password())
+ mock_urlopen.assert_called_with(
+ 'https://cas.columbia.edu/cas/serviceValidate?ticket=foo'
+ '&service=https%3A//slank.ccnmtl.columbia.edu/'
+ 'accounts/caslogin/%3Fnext%3D/')
with self.settings(
WIND_PROFILE_HANDLERS=['djangowind.auth.DummyProfileHandler']):
@@ -615,22 +605,16 @@ def test_authenticate_success(self):
self.assertEqual(r.username, "anp8")
self.assertFalse(r.has_usable_password())
- @httprettified
- def test_authenticate_success_existing_user(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- ("https://cas.columbia.edu/cas/serviceValidate?ticket=foo"
- "&https%3A//slank.ccnmtl.columbia.edu/accounts/"
- "caslogin/?next=/"),
- body=(
- "\n\n\n\n\t\n"
- "\t\tanp8\n"
- "\n"
- "\n"
- "\t\n"
- "\n")
- )
+ def test_authenticate_success_existing_user(self, mock_urlopen):
+ self.response.read.return_value = (
+ "\n\n\n\n\t\n"
+ "\t\tanp8\n"
+ "\n"
+ "\n"
+ "\t\n"
+ "\n")
+ mock_urlopen.return_value = self.response
u = User.objects.create(username="anp8")
u.set_password("something other than unusable")
@@ -642,25 +626,23 @@ def test_authenticate_success_existing_user(self):
"caslogin/?next=/"))
self.assertEqual(r.username, "anp8")
self.assertNotEqual(r.password, "!")
-
- @httprettified
- def test_authenticate_failure(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- ("https://cas.columbia.edu/cas/serviceValidate?"
- "ticket=foo&https%3A//slank.ccnmtl.columbia.edu/"
- "accounts/caslogin/?next=/"),
- body=(
- "\n\n\n\n\t\n\t\tticket 'ST-181952-OK0"
- "qr5suLueHccqPfgIT-idmcasprod2' does not match supp"
- "lied service. The original service was 'https://"
- "slank.ccnmtl.columbia.edu/accounts/caslogin/?next=/'"
- "and the supplied service was 'https://slank.ccnmtl."
- "columbia.edu/accounts/caslogin/'.\n\t\n")
- )
+ mock_urlopen.assert_called_with(
+ 'https://cas.columbia.edu/cas/serviceValidate?ticket=foo'
+ '&service=https%3A//slank.ccnmtl.columbia.edu/'
+ 'accounts/caslogin/%3Fnext%3D/')
+
+ def test_authenticate_failure(self, mock_urlopen):
+ self.response.read.return_value = (
+ "\n\n\n\n\t\n\t\tticket 'ST-181952-OK0"
+ "qr5suLueHccqPfgIT-idmcasprod2' does not match supp"
+ "lied service. The original service was 'https://"
+ "slank.ccnmtl.columbia.edu/accounts/caslogin/?next=/'"
+ "and the supplied service was 'https://slank.ccnmtl."
+ "columbia.edu/accounts/caslogin/'.\n\t\n")
+ mock_urlopen.return_value = self.response
w = CAS2AuthBackend()
r = w.authenticate(
@@ -668,23 +650,21 @@ def test_authenticate_failure(self):
url=("https://slank.ccnmtl.columbia.edu/accounts/"
"caslogin/?next=/"))
self.assertEqual(r, None)
-
- @httprettified
- def test_authenticate_success_with_mappers(self):
- HTTPretty.register_uri(
- HTTPretty.GET,
- ("https://cas.columbia.edu/cas/serviceValidate?ticket=foo"
- "&https%3A//slank.ccnmtl.columbia.edu/accounts/"
- "caslogin/?next=/"),
- body=(
- "\n\n\n\n\t\n"
- "\t\tanp8\n"
- "\n"
- "\n"
- "\t\n"
- "\n")
- )
+ mock_urlopen.assert_called_with(
+ 'https://cas.columbia.edu/cas/serviceValidate?ticket=foo'
+ '&service=https%3A//slank.ccnmtl.columbia.edu/'
+ 'accounts/caslogin/%3Fnext%3D/')
+
+ def test_authenticate_success_with_mappers(self, mock_urlopen):
+ self.response.read.return_value = (
+ "\n\n\n\n\t\n"
+ "\t\tanp8\n"
+ "\n"
+ "\n"
+ "\t\n"
+ "\n")
+ mock_urlopen.return_value = self.response
with self.settings(
WIND_AFFIL_HANDLERS=['djangowind.auth.AffilGroupMapper']):
@@ -695,22 +675,24 @@ def test_authenticate_success_with_mappers(self):
"caslogin/?next=/"))
self.assertEqual(r.username, "anp8")
self.assertFalse(r.has_usable_password())
+ mock_urlopen.assert_called_with(
+ 'https://cas.columbia.edu/cas/serviceValidate?ticket=foo'
+ '&service=https%3A//slank.ccnmtl.columbia.edu/'
+ 'accounts/caslogin/%3Fnext%3D/')
+@patch('djangowind.auth.urlopen')
class SAMLAuthBackendTest(TestCase):
- def test_authenticate_no_ticket(self):
+ def setUp(self):
+ self.response = Mock(spec=HTTPResponse)
+
+ def test_authenticate_no_ticket(self, mock_urlopen):
w = SAMLAuthBackend()
self.assertEqual(w.authenticate(None), None)
- @httprettified
- def test_authenticate_success(self):
- HTTPretty.register_uri(
- HTTPretty.POST,
- ("https://cas.columbia.edu/cas/samlValidate?"
- "TARGET=https%3A%2F%2Fslank.ccnmtl.columbia.edu"
- "%2Faccounts%2Fcaslogin%2F%3Fnext%3D%2F"),
- body=saml_success_affils()
- )
+ def test_authenticate_success(self, mock_urlopen):
+ self.response.read.return_value = saml_success_affils()
+ mock_urlopen.return_value = self.response
w = SAMLAuthBackend()
r = w.authenticate(
@@ -730,15 +712,9 @@ def test_authenticate_success(self):
self.assertEqual(r.username, "anp8")
self.assertFalse(r.has_usable_password())
- @httprettified
- def test_authenticate_success_existing_user(self):
- HTTPretty.register_uri(
- HTTPretty.POST,
- ("https://cas.columbia.edu/cas/samlValidate?"
- "TARGET=https%3A%2F%2Fslank.ccnmtl.columbia.edu"
- "%2Faccounts%2Fcaslogin%2F%3Fnext%3D%2F"),
- body=saml_success_affils()
- )
+ def test_authenticate_success_existing_user(self, mock_urlopen):
+ self.response.read.return_value = saml_success_affils()
+ mock_urlopen.return_value = self.response
u = User.objects.create(username="anp8")
u.set_password("something other than unusable")
@@ -751,14 +727,9 @@ def test_authenticate_success_existing_user(self):
self.assertEqual(r.username, "anp8")
self.assertNotEqual(r.password, "!")
- @httprettified
- def test_authenticate_failure(self):
- HTTPretty.register_uri(
- HTTPretty.POST,
- ("https://cas.columbia.edu/cas/samlValidate?"
- "TARGET=https%3A%2F%2Fslank.ccnmtl.columbia.edu"
- "%2Faccounts%2Fcaslogin%2F%3Fnext%3D%2F"),
- body=SAML_FAIL)
+ def test_authenticate_failure(self, mock_urlopen):
+ self.response.read.return_value = SAML_FAIL
+ mock_urlopen.return_value = self.response
w = SAMLAuthBackend()
r = w.authenticate(
@@ -767,15 +738,9 @@ def test_authenticate_failure(self):
"caslogin/?next=/"))
self.assertEqual(r, None)
- @httprettified
- def test_authenticate_success_with_mappers(self):
- HTTPretty.register_uri(
- HTTPretty.POST,
- ("https://cas.columbia.edu/cas/samlValidate?"
- "TARGET=https%3A%2F%2Fslank.ccnmtl.columbia.edu"
- "%2Faccounts%2Fcaslogin%2F%3Fnext%3D%2F"),
- body=saml_success_affils()
- )
+ def test_authenticate_success_with_mappers(self, mock_urlopen):
+ self.response.read.return_value = saml_success_affils()
+ mock_urlopen.return_value = self.response
with self.settings(
WIND_AFFIL_HANDLERS=['djangowind.auth.AffilGroupMapper']):
diff --git a/djangowind/tests/test_views.py b/djangowind/tests/test_views.py
index f0b4026..5fc9936 100644
--- a/djangowind/tests/test_views.py
+++ b/djangowind/tests/test_views.py
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
from django.test import TestCase
diff --git a/djangowind/urls.py b/djangowind/urls.py
index 8bae916..671a634 100644
--- a/djangowind/urls.py
+++ b/djangowind/urls.py
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
from django.conf.urls import patterns
urlpatterns = patterns('',
diff --git a/djangowind/views.py b/djangowind/views.py
index 87045ab..57be579 100644
--- a/djangowind/views.py
+++ b/djangowind/views.py
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
from django.http import HttpResponseRedirect, HttpResponseForbidden
from django.shortcuts import render_to_response
diff --git a/runtests.py b/runtests.py
index 77d3e09..4177803 100644
--- a/runtests.py
+++ b/runtests.py
@@ -61,7 +61,7 @@ def main():
pass
# Fire off the tests
- call_command('jenkins', '--enable-coverage')
+ call_command('jenkins')
if __name__ == '__main__':
main()
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..2a9acf1
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,2 @@
+[bdist_wheel]
+universal = 1
diff --git a/test_reqs.txt b/test_reqs.txt
index 79b9813..1aa6a92 100644
--- a/test_reqs.txt
+++ b/test_reqs.txt
@@ -1,8 +1,9 @@
coverage==4.0.3
+mock==2.0.0
flake8==2.5.4
-httpretty==0.8.14
django-jenkins==0.18.1
pep8==1.5.7
pyflakes==1.1.0
statsd==3.2.1
django-statsd-mozilla==0.3.16
+ipdb==0.9.3