Skip to content

Commit

Permalink
Fix deshaw#2 (Py3k compat), missing import, logging
Browse files Browse the repository at this point in the history
  • Loading branch information
twosigmajab committed Dec 2, 2018
1 parent def3402 commit fc40e6e
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 19 deletions.
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Topic :: Internet :: WWW/HTTP',
'Topic :: Internet :: WWW/HTTP :: WSGI',
'Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware',
Expand Down
23 changes: 13 additions & 10 deletions test_wsgi_kerberos.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from wsgi_kerberos import KerberosAuthMiddleware
from wsgi_kerberos import KerberosAuthMiddleware, ensure_bytestring
from webtest import TestApp
import kerberos
import mock
import unittest


def index(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
return ['Hello %s' % environ.get('REMOTE_USER', 'ANONYMOUS')]
response_body = 'Hello %s' % environ.get('REMOTE_USER', 'ANONYMOUS')
return [ensure_bytestring(response_body)]


class BasicAppTestCase(unittest.TestCase):
Expand All @@ -28,7 +30,7 @@ def test_authentication_not_required(self, clean, name, response, step, init):
r = app.get('/', expect_errors=False)
self.assertEqual(r.status, '200 OK')
self.assertEqual(r.status_int, 200)
self.assertEqual(r.body, 'Hello ANONYMOUS')
self.assertEqual(r.body, b'Hello ANONYMOUS')
self.assertEqual(r.headers.get('WWW-Authenticate'), None)
self.assertEqual(r.headers['content-type'], 'text/plain')

Expand All @@ -51,7 +53,7 @@ def test_unauthorized(self):

self.assertEqual(r.status, '401 Unauthorized')
self.assertEqual(r.status_int, 401)
self.assertEqual(r.body, 'Unauthorized')
self.assertEqual(r.body, b'Unauthorized')
self.assertEqual(r.headers['www-authenticate'], 'Negotiate')
self.assertEqual(r.headers['content-type'], 'text/plain')

Expand All @@ -71,7 +73,7 @@ def test_unauthorized_custom(self):

self.assertEqual(r.status, '401 Unauthorized')
self.assertEqual(r.status_int, 401)
self.assertEqual(r.body, 'CUSTOM')
self.assertEqual(r.body, b'CUSTOM')
self.assertEqual(r.headers['www-authenticate'], 'Negotiate')
self.assertEqual(r.headers['content-type'], 'text/plain')

Expand All @@ -92,7 +94,7 @@ def test_unauthorized_custom_content_type(self):

self.assertEqual(r.status, '401 Unauthorized')
self.assertEqual(r.status_int, 401)
self.assertEqual(r.body, 'CUSTOM')
self.assertEqual(r.body, b'CUSTOM')
self.assertEqual(r.headers['www-authenticate'], 'Negotiate')
self.assertEqual(r.headers['content-type'], 'text/html')

Expand All @@ -118,7 +120,7 @@ def test_authorized(self, clean, name, response, step, init):

self.assertEqual(r.status, '200 OK')
self.assertEqual(r.status_int, 200)
self.assertEqual(r.body, 'Hello user@EXAMPLE.ORG')
self.assertEqual(r.body, b'Hello user@EXAMPLE.ORG')
self.assertEqual(r.headers['WWW-Authenticate'], 'negotiate STOKEN')
self.assertEqual(r.headers['content-type'], 'text/plain')

Expand Down Expand Up @@ -149,7 +151,7 @@ def test_forbidden(self, clean, name, response, step, init):

self.assertEqual(r.status, '403 Forbidden')
self.assertEqual(r.status_int, 403)
self.assertEqual(r.body, 'Forbidden')
self.assertEqual(r.body, b'Forbidden')
self.assertEqual(r.headers['content-type'], 'text/plain')

self.assertEqual(init.mock_calls, [mock.call('HTTP@example.org')])
Expand Down Expand Up @@ -182,7 +184,7 @@ def test_forbidden_custom(self, clean, name, response, step, init):

self.assertEqual(r.status, '403 Forbidden')
self.assertEqual(r.status_int, 403)
self.assertEqual(r.body, 'CUSTOM')
self.assertEqual(r.body, b'CUSTOM')
self.assertEqual(r.headers['content-type'], 'text/plain')

self.assertEqual(init.mock_calls, [mock.call('HTTP@example.org')])
Expand Down Expand Up @@ -216,7 +218,7 @@ def test_forbidden_custom_content_type(self, clean, name, response, step, init):

self.assertEqual(r.status, '403 Forbidden')
self.assertEqual(r.status_int, 403)
self.assertEqual(r.body, 'CUSTOM')
self.assertEqual(r.body, b'CUSTOM')
self.assertEqual(r.headers['content-type'], 'text/html')

self.assertEqual(init.mock_calls, [mock.call('HTTP@example.org')])
Expand All @@ -225,5 +227,6 @@ def test_forbidden_custom_content_type(self, clean, name, response, step, init):
self.assertEqual(response.mock_calls, [])
self.assertEqual(clean.mock_calls, [mock.call(state)])


if __name__ == '__main__':
unittest.main()
29 changes: 20 additions & 9 deletions wsgi_kerberos.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,25 @@
Add Kerberos/GSSAPI Negotiate Authentication support to any WSGI Application
'''
import errno
import kerberos
import logging
import os
import socket
import sys

LOG = logging.getLogger(__name__)
LOG.addHandler(logging.NullHandler())

PY3 = sys.version_info > (3,)
if PY3:
basestring = (bytes, str)
unicode = str


def ensure_bytestring(s):
return s.encode('utf-8') if isinstance(s, unicode) else s


def _consume_request(environ):
'''
Expand Down Expand Up @@ -73,14 +84,16 @@ def __init__(self, app, hostname=None, unauthorized=None, forbidden=None,
hostname = socket.gethostname()

if unauthorized is None:
unauthorized = ('Unauthorized', 'text/plain')
unauthorized = (b'Unauthorized', 'text/plain')
elif isinstance(unauthorized, basestring):
unauthorized = (unauthorized, 'text/plain')
unauthorized = (ensure_bytestring(unauthorized[0]), unauthorized[1])

if forbidden is None:
forbidden = ('Forbidden', 'text/plain')
forbidden = (b'Forbidden', 'text/plain')
elif isinstance(forbidden, basestring):
forbidden = (forbidden, 'text/plain')
forbidden = (ensure_bytestring(forbidden[0]), forbidden[1])

if auth_required_callback is None:
auth_required_callback = lambda x: True
Expand All @@ -96,13 +109,11 @@ def __init__(self, app, hostname=None, unauthorized=None, forbidden=None,
principal = kerberos.getServerPrincipalDetails('HTTP',
hostname)
except kerberos.KrbError as exc:
LOG.warn('KerberosAuthMiddleware: %s' % exc.message[0])
LOG.warning('KerberosAuthMiddleware: %s', exc)
else:
LOG.debug('KerberosAuthMiddleware is identifying as %s' %
principal)
LOG.debug('KerberosAuthMiddleware is identifying as %s', principal)
else:
LOG.warn('KerberosAuthMiddleware: set KRB5_KTNAME to your keytab '
'file')
LOG.warning('KerberosAuthMiddleware: set KRB5_KTNAME to your keytab file')

def _unauthorized(self, environ, start_response, token=None):
'''
Expand All @@ -112,7 +123,7 @@ def _unauthorized(self, environ, start_response, token=None):
if token:
headers.append(('WWW-Authenticate', token))
else:
headers.append( ('WWW-Authenticate', 'Negotiate'))
headers.append(('WWW-Authenticate', 'Negotiate'))
_consume_request(environ)
start_response('401 Unauthorized', headers)
return [self.unauthorized[0]]
Expand Down Expand Up @@ -152,7 +163,6 @@ def _authenticate(self, client_token):
kerberos.authGSSServerClean(state)
return server_token, user


def __call__(self, environ, start_response):
'''
Authenticate the client, and on success invoke the WSGI application.
Expand Down Expand Up @@ -181,6 +191,7 @@ def __call__(self, environ, start_response):
# call the application, add the token to the response, and return
# it
environ['REMOTE_USER'] = user

def custom_start_response(status, headers, exc_info=None):
headers.append(('WWW-Authenticate', ' '.join(['negotiate',
server_token])))
Expand Down

0 comments on commit fc40e6e

Please sign in to comment.