Adam Lowry avatar Adam Lowry committed 6668423

Return 401 when given an invalid basic auth header instead of a 500.

Comments (0)

Files changed (2)

piston/authentication.py

+import binascii
+
 import oauth
 from django.http import HttpResponse, HttpResponseRedirect
 from django.contrib.auth.models import User, AnonymousUser
         if not auth_string:
             return False
             
-        (authmeth, auth) = auth_string.split(" ", 1)
-        
-        if not authmeth.lower() == 'basic':
+        try:
+            (authmeth, auth) = auth_string.split(" ", 1)
+
+            if not authmeth.lower() == 'basic':
+                return False
+
+            auth = auth.strip().decode('base64')
+            (username, password) = auth.split(':', 1)
+        except (ValueError, binascii.Error):
             return False
-            
-        auth = auth.strip().decode('base64')
-        (username, password) = auth.split(':', 1)
         
         request.user = self.auth_func(username=username, password=password) \
             or AnonymousUser()

tests/test_project/apps/testapp/tests.py

         atoken = Token.objects.get(key=oa_atoken.key, token_type=Token.ACCESS)
         self.assertEqual(atoken.secret, oa_atoken.secret)
 
- 
+
+class BasicAuthTest(MainTests):
+
+    def test_invalid_auth_header(self):
+        response = self.client.get('/api/entries/')
+        self.assertEquals(response.status_code, 401)
+
+        # no space
+        bad_auth_string = 'Basic%s' % base64.encodestring('admin:admin').rstrip()
+        response = self.client.get('/api/entries/',
+            HTTP_AUTHORIZATION=bad_auth_string)
+        self.assertEquals(response.status_code, 401)
+
+        # no colon
+        bad_auth_string = 'Basic %s' % base64.encodestring('adminadmin').rstrip()
+        response = self.client.get('/api/entries/',
+            HTTP_AUTHORIZATION=bad_auth_string)
+        self.assertEquals(response.status_code, 401)
+
+        # non base64 data
+        bad_auth_string = 'Basic FOOBARQ!'
+        response = self.client.get('/api/entries/',
+            HTTP_AUTHORIZATION=bad_auth_string)
+        self.assertEquals(response.status_code, 401)
+
 class MultiXMLTests(MainTests):
     def init_delegate(self):
         self.t1_data = TestModel()
         resp = self.client.get('/api/popo')
         self.assertEquals(resp.status_code, 200)
         self.assertEquals({'type': 'plain', 'field': 'a field'}, simplejson.loads(resp.content))
-        
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.