From 64d6277056213bea38d230e03d8a56f032497f2a Mon Sep 17 00:00:00 2001 From: Nik Nyby Date: Sun, 8 Oct 2017 11:49:46 -0400 Subject: [PATCH 1/3] Fix SAML POST error in python 3 When using python 3, the saml assertion type needs to be converted to bytes in order to fix this error: TypeError at /accounts/caslogin/ POST data should be bytes or an iterable of bytes. It cannot be of type str. --- djangowind/auth.py | 27 ++++++++++--------- djangowind/tests/test_auth.py | 51 +++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/djangowind/auth.py b/djangowind/auth.py index cd64aef..5b5c5b1 100644 --- a/djangowind/auth.py +++ b/djangowind/auth.py @@ -3,6 +3,7 @@ from django.conf import settings from django.contrib.auth.models import User, Group from django.core.exceptions import ImproperlyConfigured +from django.utils.encoding import smart_bytes from warnings import warn from django_statsd.clients import statsd from xml.dom.minidom import parseString @@ -102,18 +103,18 @@ def validate_cas2_ticket(ticketid, url): def get_saml_assertion(ticket): - return ( - """""" - """""" - """""" + ticket - + """""" - """""") + return smart_bytes( + '' + '' + '' + ticket + + '' + '') SAML_1_0_NS = 'urn:oasis:names:tc:SAML:1.0:' @@ -141,7 +142,7 @@ def validate_saml_ticket(ticketid, url): 'connection': 'keep-alive', 'content-type': 'text/xml'} params = {'TARGET': url} - uri = cas_base + "cas/samlValidate" + '?' + urlencode(params) + uri = '{}cas/samlValidate?{}'.format(cas_base, urlencode(params)) request = Request(uri, '', headers) data = get_saml_assertion(ticketid) request.data = data diff --git a/djangowind/tests/test_auth.py b/djangowind/tests/test_auth.py index 1cfd9f6..aa573e0 100644 --- a/djangowind/tests/test_auth.py +++ b/djangowind/tests/test_auth.py @@ -1,5 +1,25 @@ from __future__ import unicode_literals +try: + from urllib.error import URLError +except ImportError: + from urllib2 import URLError + +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 http.client import HTTPResponse except ImportError: @@ -12,6 +32,7 @@ from django.test import TestCase from djangowind.auth import ( + get_saml_assertion, validate_cas2_ticket, BaseAuthBackend, CAS2AuthBackend, validate_saml_ticket, SAMLAuthBackend, AffilGroupMapper, StaffMapper, SuperuserMapper, @@ -312,6 +333,36 @@ def tr_affils(): return open_affils("tr_affils.txt") +class GetSAMLAssertionTest(TestCase): + def test_can_post_data(self): + cas_base = 'https://example.com' + url = 'https://example.com/abc' + headers = { + 'soapaction': 'http://www.oasis-open.org/committees/security', + 'cache-control': 'no-cache', + 'pragma': 'no-cache', + 'accept': 'text/xml', + 'connection': 'keep-alive', + 'content-type': 'text/xml' + } + params = {'TARGET': url} + uri = '{}cas/samlValidate?{}'.format(cas_base, urlencode(params)) + request = Request(uri, '', headers) + request.data = get_saml_assertion('ticket') + try: + urlopen(request) + except URLError: + # As long as this isn't a TypeError, and the url request + # was actuall made, then we can assert that + # get_saml_assertion() is good. This is to prevent an + # issue introduced since Python 3: + # + # POST data should be bytes or an iterable of bytes. It + # cannot be of type str. + # + pass + + @patch('djangowind.auth.urlopen') class ValidateSAMLTicketTest(TestCase): def setUp(self): From a6cc0530355fb4341297868b3c3d2f67795ccdb3 Mon Sep 17 00:00:00 2001 From: Nik Nyby Date: Sun, 8 Oct 2017 12:12:45 -0400 Subject: [PATCH 2/3] fix typo in test comment --- djangowind/tests/test_auth.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/djangowind/tests/test_auth.py b/djangowind/tests/test_auth.py index aa573e0..1d4c2bc 100644 --- a/djangowind/tests/test_auth.py +++ b/djangowind/tests/test_auth.py @@ -353,7 +353,7 @@ def test_can_post_data(self): urlopen(request) except URLError: # As long as this isn't a TypeError, and the url request - # was actuall made, then we can assert that + # was actually made, then we can assert that # get_saml_assertion() is good. This is to prevent an # issue introduced since Python 3: # From e3eaa3a48e70dfde0476dae61b5b6e9c8f247a7d Mon Sep 17 00:00:00 2001 From: Nik Nyby Date: Sun, 8 Oct 2017 12:16:34 -0400 Subject: [PATCH 3/3] update changelog --- CHANGES | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES b/CHANGES index 6b66945..4f5ba12 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +1.0.1 +================== + +* Fixed a CAS post error in python 3 + 1.0.0 (2017-04-07) ==================