Merge pull request #201 from quinox/basicauth

Verify username/password with BasicAuth plugin
This commit is contained in:
Solly 2015-10-06 22:39:27 -04:00
commit 223e9608d7
2 changed files with 39 additions and 4 deletions

View File

@ -0,0 +1,28 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
""" Unit tests for Authentication plugins"""
from websockify.auth_plugins import BasicHTTPAuth, AuthenticationError
import unittest
class BasicHTTPAuthTestCase(unittest.TestCase):
def setUp(self):
self.plugin = BasicHTTPAuth('Aladdin:open sesame')
def test_no_auth(self):
headers = {}
self.assertRaises(AuthenticationError, self.plugin.authenticate, headers, 'localhost', '1234')
def test_invalid_password(self):
headers = {'Authorization': 'Basic QWxhZGRpbjpzZXNhbWUgc3RyZWV0'}
self.assertRaises(AuthenticationError, self.plugin.authenticate, headers, 'localhost', '1234')
def test_valid_password(self):
headers = {'Authorization': 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='}
self.plugin.authenticate(headers, 'localhost', '1234')
def test_garbage_auth(self):
headers = {'Authorization': 'Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxx'}
self.assertRaises(AuthenticationError, self.plugin.authenticate, headers, 'localhost', '1234')

View File

@ -30,12 +30,13 @@ class InvalidOriginError(AuthenticationError):
class BasicHTTPAuth(object):
"""Verifies Basic Auth headers. Specify src as username:password"""
def __init__(self, src=None):
self.src = src
def authenticate(self, headers, target_host, target_port):
import base64
auth_header = headers.get('Authorization')
if auth_header:
if not auth_header.startswith('Basic '):
@ -46,18 +47,24 @@ class BasicHTTPAuth(object):
except TypeError:
raise AuthenticationError(response_code=403)
user_pass = user_pass_raw.split(':', 1)
try:
# http://stackoverflow.com/questions/7242316/what-encoding-should-i-use-for-http-basic-authentication
user_pass_as_text = user_pass_raw.decode('ISO-8859-1')
except UnicodeDecodeError:
raise AuthenticationError(response_code=403)
user_pass = user_pass_as_text.split(':', 1)
if len(user_pass) != 2:
raise AuthenticationError(response_code=403)
if not self.validate_creds:
if not self.validate_creds(*user_pass):
raise AuthenticationError(response_code=403)
else:
raise AuthenticationError(response_code=401,
response_headers={'WWW-Authenticate': 'Basic realm="Websockify"'})
def validate_creds(username, password):
def validate_creds(self, username, password):
if '%s:%s' % (username, password) == self.src:
return True
else: