Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Revert "upgrade to django-browserid==0.7.1"

This reverts commit a78e698.
  • Loading branch information...
commit 0b784afa0a984cb632b89e5623089980d79e2501 1 parent 5f367d6
Peter Bengtsson authored December 17, 2012

Showing 86 changed files with 609 additions and 15,120 deletions. Show diff stats Hide diff stats

  1. 6  lib/python/django_browserid/__init__.py
  2. 44  lib/python/django_browserid/auth.py
  3. 59  lib/python/django_browserid/base.py
  4. 2  lib/python/django_browserid/forms.py
  5. 70  lib/python/django_browserid/static/browserid/browserid.js
  6. 2  lib/python/django_browserid/tests/__init__.py
  7. 23  lib/python/django_browserid/tests/models.py
  8. 3  lib/python/django_browserid/tests/settings.py
  9. 104  lib/python/django_browserid/tests/test_auth.py
  10. 46  lib/python/django_browserid/tests/test_verification.py
  11. 42  lib/python/django_browserid/tests/test_views.py
  12. 14  lib/python/django_browserid/views.py
  13. 35  lib/python/requests/__init__.py
  14. 23  lib/python/requests/_oauth.py
  15. 58  lib/python/requests/adapters.py
  16. 17  lib/python/requests/api.py
  17. 361  lib/python/requests/auth.py
  18. 3,338  lib/python/requests/cacert.pem
  19. 27  lib/python/requests/certs.py
  20. 24  lib/python/requests/compat.py
  21. 44  lib/python/requests/cookies.py
  22. 11  lib/python/requests/defaults.py
  23. 10  lib/python/requests/exceptions.py
  24. 9  lib/python/requests/hooks.py
  25. 229  lib/python/requests/models.py
  26. 26  lib/python/requests/packages/chardet/__init__.py
  27. 923  lib/python/requests/packages/chardet/big5freq.py
  28. 41  lib/python/requests/packages/chardet/big5prober.py
  29. 200  lib/python/requests/packages/chardet/chardistribution.py
  30. 96  lib/python/requests/packages/chardet/charsetgroupprober.py
  31. 60  lib/python/requests/packages/chardet/charsetprober.py
  32. 56  lib/python/requests/packages/chardet/codingstatemachine.py
  33. 47  lib/python/requests/packages/chardet/constants.py
  34. 79  lib/python/requests/packages/chardet/escprober.py
  35. 240  lib/python/requests/packages/chardet/escsm.py
  36. 85  lib/python/requests/packages/chardet/eucjpprober.py
  37. 594  lib/python/requests/packages/chardet/euckrfreq.py
  38. 41  lib/python/requests/packages/chardet/euckrprober.py
  39. 426  lib/python/requests/packages/chardet/euctwfreq.py
  40. 41  lib/python/requests/packages/chardet/euctwprober.py
  41. 471  lib/python/requests/packages/chardet/gb2312freq.py
  42. 41  lib/python/requests/packages/chardet/gb2312prober.py
  43. 269  lib/python/requests/packages/chardet/hebrewprober.py
  44. 567  lib/python/requests/packages/chardet/jisfreq.py
  45. 210  lib/python/requests/packages/chardet/jpcntx.py
  46. 228  lib/python/requests/packages/chardet/langbulgarianmodel.py
  47. 329  lib/python/requests/packages/chardet/langcyrillicmodel.py
  48. 225  lib/python/requests/packages/chardet/langgreekmodel.py
  49. 201  lib/python/requests/packages/chardet/langhebrewmodel.py
  50. 225  lib/python/requests/packages/chardet/langhungarianmodel.py
  51. 200  lib/python/requests/packages/chardet/langthaimodel.py
  52. 136  lib/python/requests/packages/chardet/latin1prober.py
  53. 82  lib/python/requests/packages/chardet/mbcharsetprober.py
  54. 50  lib/python/requests/packages/chardet/mbcsgroupprober.py
  55. 514  lib/python/requests/packages/chardet/mbcssm.py
  56. 106  lib/python/requests/packages/chardet/sbcharsetprober.py
  57. 64  lib/python/requests/packages/chardet/sbcsgroupprober.py
  58. 85  lib/python/requests/packages/chardet/sjisprober.py
  59. 154  lib/python/requests/packages/chardet/universaldetector.py
  60. 76  lib/python/requests/packages/chardet/utf8prober.py
  61. 229  lib/python/requests/packages/oauthlib/common.py
  62. 13  lib/python/requests/packages/oauthlib/oauth1/__init__.py
  63. 889  lib/python/requests/packages/oauthlib/oauth1/rfc5849/__init__.py
  64. 134  lib/python/requests/packages/oauthlib/oauth1/rfc5849/parameters.py
  65. 551  lib/python/requests/packages/oauthlib/oauth1/rfc5849/signature.py
  66. 99  lib/python/requests/packages/oauthlib/oauth1/rfc5849/utils.py
  67. 13  lib/python/requests/packages/oauthlib/oauth2/__init__.py
  68. 497  lib/python/requests/packages/oauthlib/oauth2/draft25/__init__.py
  69. 256  lib/python/requests/packages/oauthlib/oauth2/draft25/parameters.py
  70. 132  lib/python/requests/packages/oauthlib/oauth2/draft25/tokens.py
  71. 39  lib/python/requests/packages/oauthlib/oauth2/draft25/utils.py
  72. 20  lib/python/requests/packages/urllib3/__init__.py
  73. 169  lib/python/requests/packages/urllib3/_collections.py
  74. 92  lib/python/requests/packages/urllib3/connectionpool.py
  75. 10  lib/python/requests/packages/urllib3/exceptions.py
  76. 13  lib/python/requests/packages/urllib3/filepost.py
  77. 260  lib/python/requests/packages/urllib3/packages/ordered_dict.py
  78. 64  lib/python/requests/packages/urllib3/poolmanager.py
  79. 8  lib/python/requests/packages/urllib3/response.py
  80. 194  lib/python/requests/packages/urllib3/util.py
  81. 12  lib/python/requests/safe_mode.py
  82. 60  lib/python/requests/sessions.py
  83. 2  lib/python/requests/status_codes.py
  84. 1  lib/python/requests/structures.py
  85. 183  lib/python/requests/utils.py
  86. 0  python/requests/packages/oauthlib/__init__.py b/lib/python/requests/packages/oauthlib/__init__.py
6  lib/python/django_browserid/__init__.py
@@ -5,7 +5,5 @@
5 5
 License, v. 2.0. If a copy of the MPL was not distributed with this
6 6
 file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 7
 """
8  
-__version__ = '0.7.1'
9  
-
10  
-from django_browserid.auth import BrowserIDBackend  # NOQA
11  
-from django_browserid.base import get_audience, verify  # NOQA
  8
+from django_browserid.auth import BrowserIDBackend
  9
+from django_browserid.base import get_audience, verify
44  lib/python/django_browserid/auth.py
@@ -6,24 +6,24 @@
6 6
 import base64
7 7
 import hashlib
8 8
 import logging
  9
+from warnings import warn
9 10
 
10 11
 from django.conf import settings
  12
+from django.contrib.auth.models import User
11 13
 from django.core.exceptions import ImproperlyConfigured
12 14
 from django.utils.importlib import import_module
13 15
 
14  
-from django_browserid.base import verify
  16
+from django_browserid.base import get_audience as base_get_audience, verify
15 17
 from django_browserid.signals import user_created
16 18
 
17  
-try:
18  
-    from django.contrib.auth import get_user_model
19  
-except ImportError:
20  
-    from django.contrib.auth.models import User
21 19
 
22  
-    def get_user_model(*args, **kwargs):
23  
-        return User
  20
+log = logging.getLogger(__name__)
24 21
 
25 22
 
26  
-log = logging.getLogger(__name__)
  23
+def get_audience(*args):
  24
+    warn('Deprecated, please use the standalone function '
  25
+         'django_browserid.get_audience instead.', DeprecationWarning)
  26
+    return base_get_audience(*args)
27 27
 
28 28
 
29 29
 def default_username_algo(email):
@@ -40,17 +40,14 @@ class BrowserIDBackend(object):
40 40
     supports_inactive_user = True
41 41
     supports_object_permissions = False
42 42
 
43  
-    def __init__(self):
44  
-        """
45  
-        Store the current user model on creation to avoid issues if
46  
-        settings.AUTH_USER_MODEL changes, which usually only happens during
47  
-        tests.
48  
-        """
49  
-        self.User = get_user_model()
  43
+    def verify(self, *args):
  44
+        warn('Deprecated, please use the standalone function '
  45
+             'django_browserid.verify instead.', DeprecationWarning)
  46
+        return verify(*args)
50 47
 
51 48
     def filter_users_by_email(self, email):
52 49
         """Return all users matching the specified email."""
53  
-        return self.User.objects.filter(email=email)
  50
+        return User.objects.filter(email=email)
54 51
 
55 52
     def create_user(self, email):
56 53
         """Return object for a newly created user account."""
@@ -60,7 +57,7 @@ def create_user(self, email):
60 57
         else:
61 58
             username = default_username_algo(email)
62 59
 
63  
-        return self.User.objects.create_user(username, email)
  60
+        return User.objects.create_user(username, email)
64 61
 
65 62
     def authenticate(self, assertion=None, audience=None):
66 63
         """``django.contrib.auth`` compatible authentication method.
@@ -84,8 +81,7 @@ def authenticate(self, assertion=None, audience=None):
84 81
         # log and bail. randomly selecting one seems really wrong.
85 82
         users = self.filter_users_by_email(email=email)
86 83
         if len(users) > 1:
87  
-            log.warn('{0} users with email address {1}.'.format(len(users),
88  
-                                                                email))
  84
+            log.warn('%d users with email address %s.' % (len(users), email))
89 85
             return None
90 86
         if len(users) == 1:
91 87
             return users[0]
@@ -94,7 +90,7 @@ def authenticate(self, assertion=None, audience=None):
94 90
         if not create_user:
95 91
             return None
96 92
         else:
97  
-            if create_user is True:
  93
+            if create_user == True:
98 94
                 create_function = self.create_user
99 95
             else:
100 96
                 # Find the function to call.
@@ -106,8 +102,8 @@ def authenticate(self, assertion=None, audience=None):
106 102
 
107 103
     def get_user(self, user_id):
108 104
         try:
109  
-            return self.User.objects.get(pk=user_id)
110  
-        except self.User.DoesNotExist:
  105
+            return User.objects.get(pk=user_id)
  106
+        except User.DoesNotExist:
111 107
             return None
112 108
 
113 109
     def _load_module(self, path):
@@ -129,6 +125,6 @@ def _load_module(self, path):
129 125
         try:
130 126
             create_user = getattr(mod, attr)
131 127
         except AttributeError:
132  
-            raise ImproperlyConfigured('Module {0} does not define a {1} '
133  
-                                       'function.'.format(module, attr))
  128
+            raise ImproperlyConfigured('Module "%s" does not define a "%s" '
  129
+                                       'function.' % (module, attr))
134 130
         return create_user
59  lib/python/django_browserid/base.py
@@ -9,7 +9,7 @@
9 9
 try:
10 10
     import json
11 11
 except ImportError:
12  
-    import simplejson as json  # NOQA
  12
+    import simplejson as json
13 13
 
14 14
 
15 15
 from django.conf import settings
@@ -21,7 +21,7 @@
21 21
 
22 22
 
23 23
 DEFAULT_HTTP_TIMEOUT = 5
24  
-DEFAULT_VERIFICATION_URL = 'https://verifier.login.persona.org/verify'
  24
+DEFAULT_VERIFICATION_URL = 'https://browserid.org/verify'
25 25
 OKAY_RESPONSE = 'okay'
26 26
 
27 27
 
@@ -36,6 +36,17 @@ def get_audience(request):
36 36
         SITE_URL = 'https://example.com'
37 37
         SITE_URL = 'http://example.com'
38 38
 
  39
+    If you don't have a SITE_URL you can also use these varables:
  40
+    PROTOCOL, DOMAIN, and (optionally) PORT.
  41
+    Example 1:
  42
+        PROTOCOL = 'https://'
  43
+        DOMAIN = 'example.com'
  44
+
  45
+    Example 2:
  46
+        PROTOCOL = 'http://'
  47
+        DOMAIN = '127.0.0.1'
  48
+        PORT = '8001'
  49
+
39 50
     If none are set, we trust the request to populate the audience.
40 51
     This is *not secure*!
41 52
     """
@@ -48,11 +59,32 @@ def get_audience(request):
48 59
         req_proto = 'http://'
49 60
     req_domain = request.get_host()
50 61
 
  62
+    # If we don't define it explicitly
  63
+    if not site_url:
  64
+        warn('Using DOMAIN and PROTOCOL to specify your BrowserID audience is '
  65
+             'deprecated. Please use the SITE_URL setting instead.',
  66
+             DeprecationWarning)
  67
+
  68
+        # DOMAIN is example.com req_domain is example.com:8001
  69
+        domain = getattr(settings, 'DOMAIN', req_domain.split(':')[0])
  70
+        protocol = getattr(settings, 'PROTOCOL', req_proto)
  71
+
  72
+        standards = {'https://': 443, 'http://': 80}
  73
+        if ':' in req_domain:
  74
+            req_port = req_domain.split(':')[1]
  75
+        else:
  76
+            req_port = None
  77
+        port = getattr(settings, 'PORT', req_port or standards[protocol])
  78
+        if port == standards[protocol]:
  79
+            site_url = ''.join(map(str, (protocol, domain)))
  80
+        else:
  81
+            site_url = ''.join(map(str, (protocol, domain, ':', port)))
  82
+
51 83
     req_url = "%s%s" % (req_proto, req_domain)
52 84
     if site_url != "%s%s" % (req_proto, req_domain):
53  
-        log.warning('Misconfigured SITE_URL? settings has {0}, but '
54  
-                    'actual request was {1} BrowserID may fail on '
55  
-                    'audience'.format(site_url, req_url))
  85
+        log.warning('Misconfigured SITE_URL? settings has [%s], but '
  86
+                    'actual request was [%s] BrowserID may fail on '
  87
+                    'audience' % (site_url, req_url))
56 88
     return site_url
57 89
 
58 90
 
@@ -62,8 +94,10 @@ def _verify_http_request(url, qs):
62 94
         'proxies': getattr(settings, 'BROWSERID_PROXY_INFO', None),
63 95
         'verify': not getattr(settings, 'BROWSERID_DISABLE_CERT_CHECK', False),
64 96
         'headers': {'Content-type': 'application/x-www-form-urlencoded'},
65  
-        'timeout': getattr(settings, 'BROWSERID_HTTP_TIMEOUT',
66  
-                           DEFAULT_HTTP_TIMEOUT),
  97
+        'params': {
  98
+            'timeout': getattr(settings, 'BROWSERID_HTTP_TIMEOUT',
  99
+                               DEFAULT_HTTP_TIMEOUT)
  100
+        }
67 101
     }
68 102
 
69 103
     if parameters['verify']:
@@ -74,7 +108,8 @@ def _verify_http_request(url, qs):
74 108
     try:
75 109
         rv = json.loads(r.content)
76 110
     except ValueError:
77  
-        log.debug('Failed to decode JSON. Resp: {0}, Content: {1}'.format(r.status_code, r.content))
  111
+        log.debug('Failed to decode JSON. Resp: %s, Content: %s' %
  112
+                  (r.status_code, r.content))
78 113
         return dict(status='failure')
79 114
 
80 115
     return rv
@@ -85,7 +120,7 @@ def verify(assertion, audience):
85 120
     verify_url = getattr(settings, 'BROWSERID_VERIFICATION_URL',
86 121
                          DEFAULT_VERIFICATION_URL)
87 122
 
88  
-    log.info("Verification URL: {0}".format(verify_url))
  123
+    log.info("Verification URL: %s" % verify_url)
89 124
 
90 125
     result = _verify_http_request(verify_url, urllib.urlencode({
91 126
         'assertion': assertion,
@@ -95,7 +130,7 @@ def verify(assertion, audience):
95 130
     if result['status'] == OKAY_RESPONSE:
96 131
         return result
97 132
 
98  
-    log.error('BrowserID verification failure. Response: {0} '
99  
-              'Audience: {1}'.format(result, audience))
100  
-    log.error("BID assert: {0}".format(assertion))
  133
+    log.error('BrowserID verification failure. Response: %r '
  134
+              'Audience: %r' % (result, audience))
  135
+    log.error("BID assert: %r" % assertion)
101 136
     return False
2  lib/python/django_browserid/forms.py
@@ -10,4 +10,4 @@ class BrowserIDForm(forms.Form):
10 10
     assertion = forms.CharField(widget=forms.HiddenInput())
11 11
 
12 12
     class Media:
13  
-        js = ('browserid/browserid.js', 'https://login.persona.org/include.js')
  13
+        js = ('browserid/browserid.js', 'https://browserid.org/include.js')
70  lib/python/django_browserid/static/browserid/browserid.js
... ...
@@ -1,67 +1,15 @@
1 1
 /* This Source Code Form is subject to the terms of the Mozilla Public
2 2
  * License, v. 2.0. If a copy of the MPL was not distributed with this
3 3
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4  
-
5  
-(function($) {
6  
-    'use strict';
7  
-
8  
-    $(function() {
9  
-        // State? Ewwwwww.
10  
-        var logoutButton = null;
11  
-        var requestOptions = [
12  
-            'siteName',
13  
-            'siteLogo',
14  
-            'oncancel',
15  
-            'privacyPolicy',
16  
-            'returnTo',
17  
-            'termsOfService'
18  
-        ];
19  
-
20  
-        $(document).delegate('.browserid-login, #browserid', 'click', function(e) {
21  
-            e.preventDefault();
22  
-
23  
-            // Arguments to navigator.id.request can be specified by data-attributes
24  
-            // on the BrowserID link: <a href="#" data-site-name="Site Name">
25  
-            var options = {};
26  
-            var $link = $(e.target);
27  
-            for (var k = 0; k < requestOptions.length; k++) {
28  
-                var name = requestOptions[k];
29  
-                var value = $link.data(name);
30  
-                if (value !== undefined) {
31  
-                    options[name] = value;
32  
-                }
33  
-            }
34  
-
35  
-            navigator.id.request(options); // Triggers BrowserID login dialog.
36  
-        });
37  
-
38  
-        $('.browserid-logout').bind('click', function(e) {
39  
-            e.preventDefault();
40  
-            logoutButton = e.target;
41  
-            navigator.id.logout(); // Clears User Agent BrowserID state.
42  
-        });
43  
-
44  
-        navigator.id.watch({
45  
-            onlogin: function(assertion) {
46  
-                // Don't bother if login just failed.
47  
-                if (location.search.indexOf('bid_login_failed=1') !== -1) {
48  
-                    navigator.id.logout();
49  
-                } else if (assertion) {
50  
-                    var $e = $('#id_assertion');
51  
-                    $e.val(assertion.toString());
52  
-                    $e.parent().submit();
53  
-                }
54  
-            },
55  
-
56  
-            onlogout: function() {
57  
-                var currentButton = logoutButton;
58  
-                if (currentButton !== null) {
59  
-                    logoutButton = null;
60  
-                    if (currentButton.href) {
61  
-                        window.location = currentButton.href;
62  
-                    }
63  
-                }
  4
+ $(document).ready(function() {
  5
+    $('#browserid').bind('click', function(e) {
  6
+        e.preventDefault();
  7
+        navigator.id.getVerifiedEmail(function(assertion) {
  8
+            if (assertion) {
  9
+                var $e = $('#id_assertion');
  10
+                $e.val(assertion.toString());
  11
+                $e.parent().submit();
64 12
             }
65 13
         });
66 14
     });
67  
-})(jQuery);
  15
+});
2  lib/python/django_browserid/tests/__init__.py
@@ -31,7 +31,7 @@ def __init__(self, email=None, audience=None):
31 31
         self.return_value = {
32 32
             u'audience': audience,
33 33
             u'email': email,
34  
-            u'issuer': u'login.persona.org:443',
  34
+            u'issuer': u'browserid.org:443',
35 35
             u'status': u'okay' if email is not None else u'failure',
36 36
             u'valid-until': 1311377222765
37 37
         }
23  lib/python/django_browserid/tests/models.py
... ...
@@ -1,23 +0,0 @@
1  
-"""
2  
-This Source Code Form is subject to the terms of the Mozilla Public
3  
-License, v. 2.0. If a copy of the MPL was not distributed with this
4  
-file, You can obtain one at http://mozilla.org/MPL/2.0/.
5  
-"""
6  
-from django.db import models
7  
-
8  
-try:
9  
-    from django.contrib.auth.models import AbstractBaseUser
10  
-except ImportError:
11  
-    AbstractBaseUser = object
12  
-
13  
-
14  
-class CustomUser(AbstractBaseUser):
15  
-    USERNAME_FIELD = 'email'
16  
-
17  
-    email = models.EmailField(unique=True, db_index=True)
18  
-
19  
-    def get_full_name(self):
20  
-        return self.email
21  
-
22  
-    def get_short_name(self):
23  
-        return self.email
3  lib/python/django_browserid/tests/settings.py
@@ -5,8 +5,6 @@
5 5
 """
6 6
 TEST_RUNNER = 'django_nose.runner.NoseTestSuiteRunner'
7 7
 
8  
-SECRET_KEY = 'asdf'
9  
-
10 8
 DATABASES = {
11 9
     'default': {
12 10
         'NAME': 'test.db',
@@ -17,7 +15,6 @@
17 15
 INSTALLED_APPS = (
18 16
     'django_nose',
19 17
     'django_browserid',
20  
-    'django_browserid.tests',
21 18
 
22 19
     'django.contrib.auth',
23 20
     'django.contrib.contenttypes',
104  lib/python/django_browserid/tests/test_auth.py
@@ -7,23 +7,11 @@
7 7
 from django.contrib.auth.models import User
8 8
 from django.test import TestCase
9 9
 
10  
-from mock import ANY, patch
  10
+from mock import patch
11 11
 
12 12
 from django_browserid.auth import BrowserIDBackend, default_username_algo
13 13
 from django_browserid.tests import mock_browserid
14 14
 
15  
-# Support Python 2.6 by using unittest2
16  
-try:
17  
-    from unittest import skipIf
18  
-except ImportError:
19  
-    from unittest2 import skipIf
20  
-
21  
-try:
22  
-    from django.contrib.auth import get_user_model
23  
-    from django_browserid.tests.models import CustomUser
24  
-except ImportError:
25  
-    get_user_model = False
26  
-
27 15
 
28 16
 def new_user(email, username=None):
29 17
         """Creates a user with the specified email for testing."""
@@ -37,98 +25,72 @@ def auth(self, verified_email=None):
37 25
         """
38 26
         Attempt to authenticate a user with BrowserIDBackend.
39 27
 
40  
-        If verified_email is None, verification will fail, otherwise it will
41  
-        pass and return the specified email.
  28
+        If verified_email is None, verification will fail, otherwise it will pass
  29
+        and return the specified email.
42 30
         """
43 31
         with mock_browserid(verified_email):
44 32
             backend = BrowserIDBackend()
45 33
             return backend.authenticate(assertion='asdf', audience='asdf')
46 34
 
47 35
     def test_failed_verification(self):
48  
-        # If verification fails, return None.
49  
-        self.assertTrue(self.auth(None) is None)
  36
+        """If verification fails, return None."""
  37
+        assert self.auth(None) is None
50 38
 
51 39
     def test_duplicate_emails(self):
52  
-        # If there are two users with the same email address, return None.
  40
+        """If there are two users with the same email address, return None."""
53 41
         new_user('a@example.com', 'test1')
54 42
         new_user('a@example.com', 'test2')
55  
-        self.assertTrue(self.auth('a@example.com') is None)
  43
+        assert self.auth('a@example.com') is None
56 44
 
57 45
     def test_auth_success(self):
58  
-        # If a single user is found with the verified email, return an instance
59  
-        # of their user object.
  46
+        """
  47
+        If a single user is found with the verified email, return an instance of
  48
+        their user object.
  49
+        """
60 50
         user = new_user('a@example.com')
61  
-        self.assertEqual(self.auth('a@example.com'), user)
  51
+        assert self.auth('a@example.com') == user
62 52
 
63 53
     @patch.object(settings, 'BROWSERID_CREATE_USER', False)
64 54
     def test_no_create_user(self):
65  
-        # If user creation is disabled and no user is found, return None.
66  
-        self.assertTrue(self.auth('a@example.com') is None)
  55
+        """If user creation is disabled and no user is found, return None."""
  56
+        assert self.auth('a@example.com') is None
67 57
 
68 58
     @patch.object(settings, 'BROWSERID_CREATE_USER', True)
69 59
     def test_create_user(self):
70  
-        # If user creation is enabled and no user is found, return a new
71  
-        # User.
  60
+        """
  61
+        If user creation is enabled and no user is found, return a new
  62
+        User.
  63
+        """
72 64
         user = self.auth('a@example.com')
73  
-        self.assertTrue(user is not None)
74  
-        self.assertTrue(isinstance(user, User))
75  
-        self.assertEqual(user.email, 'a@example.com')
  65
+        assert user is not None
  66
+        assert isinstance(user, User)
  67
+        assert user.email == 'a@example.com'
76 68
 
77 69
     @patch.object(settings, 'BROWSERID_CREATE_USER',
78 70
                   'django_browserid.tests.test_auth.new_user')
79 71
     @patch('django_browserid.tests.test_auth.new_user')
80 72
     def test_custom_create_user(self, create_user):
81  
-        # If user creation is enabled with a custom create function and no user
82  
-        # is found, return the new user created with the custom function.
  73
+        """
  74
+        If user creation is enabled with a custom create function and no user
  75
+        is found, return the new user created with the custom function.
  76
+        """
83 77
         create_user.return_value = 'test'
84  
-        self.assertEqual(self.auth('a@example.com'), 'test')
85  
-        create_user.assert_called_with('a@example.com')
  78
+        assert self.auth('a@example.com') == 'test'
  79
+        assert create_user.called_with('a@example.com')
86 80
 
87 81
     @patch.object(settings, 'BROWSERID_USERNAME_ALGO')
88 82
     @patch.object(settings, 'BROWSERID_CREATE_USER', True)
89 83
     def test_custom_username_algorithm(self, username_algo):
90  
-        # If a custom username algorithm is specified, use it!
  84
+        """If a custom username algorithm is specified, use it!"""
91 85
         username_algo.return_value = 'test'
92 86
         user = self.auth('a@b.com')
93  
-        self.assertEqual(user.username, 'test')
  87
+        assert user.username == 'test'
94 88
 
95  
-    @patch('django_browserid.auth.user_created')
  89
+    @patch('django_browserid.signals.user_created')
96 90
     @patch.object(settings, 'BROWSERID_CREATE_USER', True)
97 91
     def test_user_created_signal(self, user_created):
98  
-        # Test that the user_created signal is called when a new user is
99  
-        # created.
100  
-        user = self.auth('a@b.com')
101  
-        user_created.send.assert_called_with(ANY, user=user)
102  
-
103  
-
104  
-# Only run custom user model tests if we're using a version of Django that
105  
-# supports it.
106  
-@patch.object(settings, 'AUTH_USER_MODEL', 'tests.CustomUser')
107  
-@skipIf(not get_user_model, 'Not supported in Django < 1.5')
108  
-class CustomUserModelTests(TestCase):
109  
-    def _auth(self, backend=None, verified_email=None):
110  
-        if backend is None:
111  
-            backend = BrowserIDBackend()
112  
-
113  
-        with mock_browserid(verified_email):
114  
-            return backend.authenticate(assertion='asdf', audience='asdf')
115  
-
116  
-    def test_existing_user(self):
117  
-        """If a custom user exists with the given email, return them."""
118  
-        user = CustomUser.objects.create(email='a@test.com')
119  
-        authed_user = self._auth(verified_email='a@test.com')
120  
-        self.assertEqual(user, authed_user)
121  
-
122  
-    @patch.object(settings, 'BROWSERID_CREATE_USER', True)
123  
-    def test_create_new_user(self):
124 92
         """
125  
-        If a custom user does not exist with the given email, create a new
126  
-        user and return them.
  93
+        Test that the user_created signal is called when a new user is created.
127 94
         """
128  
-        class CustomUserBrowserIDBackend(BrowserIDBackend):
129  
-            def create_user(self, email):
130  
-                return CustomUser.objects.create(email=email)
131  
-        user = self._auth(backend=CustomUserBrowserIDBackend(),
132  
-                          verified_email='b@test.com')
133  
-        self.assertTrue(isinstance(user, CustomUser))
134  
-        self.assertEqual(user.email, 'b@test.com')
  95
+        user = self.auth('a@b.com')
  96
+        assert user_created.call.called_with(user=user)
46  lib/python/django_browserid/tests/test_verification.py
@@ -9,7 +9,7 @@
9 9
 from django.contrib import auth
10 10
 from django.contrib.auth.models import User
11 11
 
12  
-from mock import ANY, patch
  12
+from mock import patch
13 13
 
14 14
 from django_browserid.base import verify
15 15
 from django_browserid.tests import mock_browserid
@@ -38,7 +38,7 @@ def negative_assertion(fake_http_request, **kwargs):
38 38
 
39 39
 @patch('django_browserid.auth.BrowserIDBackend.authenticate')
40 40
 def test_backend_authenticate(fake):
41  
-    # Test that the authentication backend is set up correctly.
  41
+    """Test that the authentication backend is set up correctly."""
42 42
     fake.return_value = None
43 43
     auth.authenticate(**authenticate_kwargs)
44 44
     fake.assert_called_with(**authenticate_kwargs)
@@ -46,7 +46,7 @@ def test_backend_authenticate(fake):
46 46
 
47 47
 @patch('django_browserid.auth.verify')
48 48
 def test_backend_verify(fake):
49  
-    # Test that authenticate() calls verify().
  49
+    """Test that authenticate() calls verify()."""
50 50
     fake.return_value = False
51 51
     auth.authenticate(**authenticate_kwargs)
52 52
     fake.assert_called_with(assertion, audience)
@@ -54,21 +54,19 @@ def test_backend_verify(fake):
54 54
 
55 55
 @mock_browserid(None)
56 56
 def test_backend_verify_invalid_assertion():
57  
-    # Test that authenticate() returns None when credentials are bad.
  57
+    """Test that authenticate() returns None when credentials are bad."""
58 58
     user = auth.authenticate(**authenticate_kwargs)
59 59
     assert user is None
60 60
 
61  
-
62 61
 @patch('django_browserid.auth.verify')
63 62
 def test_auth_copes_with_false(verify):
64  
-    # Test that authenticate copes with False.
  63
+    """Test that authenticate copes with False."""
65 64
     verify.return_value = False
66 65
     assert BrowserIDBackend().authenticate(**authenticate_kwargs) is None
67 66
 
68  
-
69 67
 @mock_browserid('myemail@example.com')
70 68
 def test_verify_correct_credentials():
71  
-    # Test that verify() returns assertion details when assertion is valid.
  69
+    """Test that verify() returns assertion details when assertion is valid."""
72 70
     verification = verify(assertion, audience)
73 71
     assert verification['status'] == 'okay'
74 72
     assert verification['email'] == 'myemail@example.com'
@@ -78,14 +76,11 @@ def test_verify_correct_credentials():
78 76
 @patch.object(settings, 'BROWSERID_USERNAME_ALGO', None, create=True)
79 77
 @mock_browserid('bid_create@example.com')
80 78
 def test_authenticate_create_user():
81  
-    # Test that automatic user creation works when enabled.
  79
+    """Test that automatic user creation works when enabled."""
82 80
     User.objects.filter(email='bid_create@example.com').delete()
83  
-    ob = User.objects.filter(email='bid_create@example.com')
84  
-    assert ob.exists() is False
  81
+    assert User.objects.filter(email='bid_create@example.com').exists() == False
85 82
     auth.authenticate(**authenticate_kwargs)
86  
-
87  
-    ob = User.objects.filter(email='bid_create@example.com')
88  
-    assert ob.exists() is True
  83
+    assert User.objects.filter(email='bid_create@example.com').exists() == True
89 84
 
90 85
 
91 86
 def username_algo(email):
@@ -96,8 +91,8 @@ def username_algo(email):
96 91
 @patch.object(settings, 'BROWSERID_USERNAME_ALGO', username_algo, create=True)
97 92
 @mock_browserid('bid_alt_username@example.com')
98 93
 def test_authenticate_create_user_with_alternate_username_algo():
99  
-    # Test that automatic user creation with an alternate username algo
100  
-    # works.
  94
+    """Test that automatic user creation with an alternate username algo
  95
+    works."""
101 96
     user = auth.authenticate(**authenticate_kwargs)
102 97
     assert user.username == 'bid_alt_username'
103 98
 
@@ -107,7 +102,7 @@ def test_authenticate_create_user_with_alternate_username_algo():
107 102
 @patch('django_browserid.tests.fake_create_user')
108 103
 @mock_browserid('does.not.exist@example.org')
109 104
 def test_authenticate_create_user_with_callable(fake):
110  
-    # Test that automatic user creation with a callable function name works
  105
+    """Test that automatic user creation with a callable function name works"""
111 106
     fake.return_value = None
112 107
     auth.authenticate(**authenticate_kwargs)
113 108
     fake.assert_called_with('does.not.exist@example.org')
@@ -116,21 +111,6 @@ def test_authenticate_create_user_with_callable(fake):
116 111
 @patch.object(settings, 'BROWSERID_CREATE_USER', False, create=True)
117 112
 @mock_browserid('someotheremail@example.com')
118 113
 def test_authenticate_missing_user():
119  
-     # Test that authenticate() returns None when user creation disabled.
  114
+    """Test that authenticate() returns None when user creation disabled."""
120 115
     user = auth.authenticate(**authenticate_kwargs)
121 116
     assert user is None
122  
-
123  
-
124  
-@patch.object(settings, 'BROWSERID_HTTP_TIMEOUT', 1, create=True)
125  
-@patch.object(settings, 'BROWSERID_VERIFICATION_URL',
126  
-              'https://custom.org/verify', create=True)
127  
-@patch('django_browserid.base.requests.post')
128  
-def test_verify_post_uses_custom_settings(post):
129  
-    post.return_value.content = '{"status": "okay"}'
130  
-    verify(assertion, audience)
131  
-    post.assert_called_with('https://custom.org/verify',
132  
-                            verify=True,
133  
-                            proxies=ANY,
134  
-                            data=ANY,
135  
-                            timeout=1,
136  
-                            headers=ANY)
42  lib/python/django_browserid/tests/test_views.py
@@ -59,48 +59,30 @@ def verify(request_type, redirect_field_name=None, success_url=None,
59 59
 
60 60
 
61 61
 def test_get_redirect_failure():
62  
-    # Issuing a GET to the verify view redirects to the failure URL.
  62
+    """Issuing a GET to the verify view redirects to the failure URL."""
63 63
     response = verify('get', failure_url='/fail')
64 64
     assert response.status_code == 302
65  
-    assert response['Location'].endswith('/fail?bid_login_failed=1')
  65
+    assert response['Location'].endswith('/fail')
66 66
 
67 67
 
68 68
 def test_invalid_redirect_failure():
69  
-    # Invalid form arguments redirect to the failure URL.
  69
+    """Invalid form arguments redirect to the failure URL."""
70 70
     response = verify('post', failure_url='/fail', blah='asdf')
71 71
     assert response.status_code == 302
72  
-    assert response['Location'].endswith('/fail?bid_login_failed=1')
  72
+    assert response['Location'].endswith('/fail')
73 73
 
74 74
 
75 75
 @mock_browserid(None)
76 76
 def test_auth_fail_redirect_failure():
77  
-    # If authentication fails, redirect to the failure URL.
  77
+    """If authentication fails, redirect to the failure URL."""
78 78
     response = verify('post', failure_url='/fail', assertion='asdf')
79 79
     assert response.status_code == 302
80  
-    assert response['Location'].endswith('/fail?bid_login_failed=1')
81  
-
82  
-
83  
-@mock_browserid(None)
84  
-def test_auth_fail_url_parameters():
85  
-    # Ensure that bid_login_failed=1 is appended to the failure url.
86  
-    response = verify('post', failure_url='/fail?', assertion='asdf')
87  
-    assert response['Location'].endswith('/fail?bid_login_failed=1')
88  
-
89  
-    response = verify('post', failure_url='/fail?asdf', assertion='asdf')
90  
-    assert response['Location'].endswith('/fail?asdf&bid_login_failed=1')
91  
-
92  
-    response = verify('post', failure_url='/fail?asdf=4', assertion='asdf')
93  
-    assert response['Location'].endswith('/fail?asdf=4&bid_login_failed=1')
94  
-
95  
-    response = verify('post', failure_url='/fail?asdf=4&bid_login_failed=1',
96  
-                      assertion='asdf')
97  
-    assert response['Location'].endswith('/fail?asdf=4&bid_login_failed=1'
98  
-                                         '&bid_login_failed=1')
  80
+    assert response['Location'].endswith('/fail')
99 81
 
100 82
 
101 83
 @mock_browserid('test@example.com')
102 84
 def test_auth_success_redirect_success():
103  
-    # If authentication succeeds, redirect to the success URL.
  85
+    """If authentication succeeds, redirect to the success URL."""
104 86
     response = verify('post', success_url='/success', assertion='asdf')
105 87
     assert response.status_code == 302
106 88
     assert response['Location'].endswith('/success')
@@ -108,8 +90,9 @@ def test_auth_success_redirect_success():
108 90
 
109 91
 @mock_browserid('test@example.com')
110 92
 def test_default_redirect_field():
111  
-    # If a redirect is passed as an argument to the request, redirect to that
112  
-    # instead of the success URL.
  93
+    """If a redirect is passed as an argument to the request, redirect to that
  94
+    instead of the success URL.
  95
+    """
113 96
     kwargs = {auth.REDIRECT_FIELD_NAME: '/field_success', 'assertion': 'asdf'}
114 97
     response = verify('post', success_url='/success', **kwargs)
115 98
     assert response.status_code == 302
@@ -118,8 +101,9 @@ def test_default_redirect_field():
118 101
 
119 102
 @mock_browserid('test@example.com')
120 103
 def test_redirect_field_name():
121  
-    # If a redirect field name is specified, use the request argument matching
122  
-    # that name as the path to redirect to.
  104
+    """If a redirect field name is specified, use the request argument matching
  105
+    that name as the path to redirect to.
  106
+    """
123 107
     kwargs = {'my_redirect': '/field_success', 'assertion': 'asdf'}
124 108
     response = verify('post', success_url='/success',
125 109
                       redirect_field_name='my_redirect', **kwargs)
14  lib/python/django_browserid/views.py
@@ -36,20 +36,12 @@ def login_failure(self):
36 36
         """Handle a failed login. Use this to perform complex redirects
37 37
         post-login.
38 38
         """
39  
-        # Append "?bid_login_failed=1" to the URL to notify the JavaScript that
40  
-        # login failed.
41  
-        failure_url = self.get_failure_url()
42  
-
43  
-        if not failure_url.endswith('?'):
44  
-            failure_url += '?' if not '?' in failure_url else '&'
45  
-        failure_url += 'bid_login_failed=1'
46  
-
47  
-        return redirect(failure_url)
  39
+        return redirect(self.get_failure_url())
48 40
 
49 41
     def form_valid(self, form):
50 42
         """Handles the return post request from the browserID form and puts
51 43
         interesting variables into the class. If everything checks out, then
52  
-        we call login_success to decide how to handle a valid user
  44
+        we call handle_user to decide how to handle a valid user
53 45
         """
54 46
         self.assertion = form.cleaned_data['assertion']
55 47
         self.audience = get_audience(self.request)
@@ -66,7 +58,7 @@ def form_invalid(self, *args, **kwargs):
66 58
         return self.login_failure()
67 59
 
68 60
     def get(self, *args, **kwargs):
69  
-        return self.login_failure()
  61
+        return redirect(self.get_failure_url())
70 62
 
71 63
     def get_failure_url(self):
72 64
         """
35  lib/python/requests/__init__.py
@@ -6,35 +6,8 @@
6 6
 #          /
7 7
 
8 8
 """
9  
-requests HTTP library
10  
-~~~~~~~~~~~~~~~~~~~~~
11  
-
12  
-Requests is an HTTP library, written in Python, for human beings. Basic GET
13  
-usage:
14  
-
15  
-   >>> import requests
16  
-   >>> r = requests.get('http://python.org')
17  
-   >>> r.status_code
18  
-   200
19  
-   >>> 'Python is a programming language' in r.content
20  
-   True
21  
-
22  
-... or POST:
23  
-
24  
-   >>> payload = dict(key1='value1', key2='value2')
25  
-   >>> r = requests.post("http://httpbin.org/post", data=payload)
26  
-   >>> print r.text
27  
-   {
28  
-     ...
29  
-     "form": {
30  
-       "key2": "value2",
31  
-       "key1": "value1"
32  
-     },
33  
-     ...
34  
-   }
35  
-
36  
-The other HTTP methods are supported - see `requests.api`. Full documentation
37  
-is at <http://python-requests.org>.
  9
+requests
  10
+~~~~~~~~
38 11
 
39 12
 :copyright: (c) 2012 by Kenneth Reitz.
40 13
 :license: ISC, see LICENSE for more details.
@@ -42,8 +15,8 @@
42 15
 """
43 16
 
44 17
 __title__ = 'requests'
45  
-__version__ = '0.14.2'
46  
-__build__ = 0x001402
  18
+__version__ = '0.13.0'
  19
+__build__ = 0x001300
47 20
 __author__ = 'Kenneth Reitz'
48 21
 __license__ = 'ISC'
49 22
 __copyright__ = 'Copyright 2012 Kenneth Reitz'
23  lib/python/requests/_oauth.py
... ...
@@ -1,23 +0,0 @@
1  
-# -*- coding: utf-8 -*-
2  
-
3  
-"""
4  
-requests._oauth
5  
-~~~~~~~~~~~~~~~
6  
-
7  
-This module contains the path hack necessary for oauthlib to be vendored into
8  
-requests while allowing upstream changes.
9  
-"""
10  
-
11  
-import os
12  
-import sys
13  
-
14  
-try:
15  
-    from oauthlib.oauth1 import rfc5849
16  
-    from oauthlib.common import extract_params
17  
-    from oauthlib.oauth1.rfc5849 import (Client, SIGNATURE_HMAC, SIGNATURE_TYPE_AUTH_HEADER)
18  
-except ImportError:
19  
-    from .packages import oauthlib
20  
-    sys.modules['oauthlib'] = oauthlib
21  
-    from oauthlib.oauth1 import rfc5849
22  
-    from oauthlib.common import extract_params
23  
-    from oauthlib.oauth1.rfc5849 import (Client, SIGNATURE_HMAC, SIGNATURE_TYPE_AUTH_HEADER)
58  lib/python/requests/adapters.py
... ...
@@ -1,58 +0,0 @@
1  
-# -*- coding: utf-8 -*-
2  
-
3  
-"""
4  
-requests.adapters
5  
-~~~~~~~~~~~~~~~~~
6  
-
7  
-This module contains the transport adapters that Requests uses to define
8  
-and maintain connections.
9  
-"""
10  
-
11  
-from .packages.urllib3.poolmanager import PoolManager
12  
-
13  
-class BaseAdapter(object):
14  
-    """The Base Transport Adapter"""
15  
-
16  
-    def __init__(self, config=None):
17  
-        super(BaseAdapter, self).__init__()
18  
-        self.config = config or {}
19  
-        self.session = None
20  
-
21  
-    @property
22  
-    def configure(self, config):
23  
-        self.config.update(config)
24  
-
25  
-    def send(self):
26  
-        raise NotImplementedError
27  
-
28  
-    def close(self):
29  
-        raise NotImplementedError
30  
-
31  
-
32  
-class HTTPAdapter(BaseAdapter):
33  
-    """Built-In HTTP Adapter for Urllib3."""
34  
-    def __init__(self):
35  
-        super(HTTPAdapter, self).__init__()
36  
-
37  
-        self.init_poolmanager()
38  
-
39  
-    def init_poolmanager(self):
40  
-        self.poolmanager = PoolManager(
41  
-            num_pools=self.config.get('pool_connections'),
42  
-            maxsize=self.config.get('pool_maxsize')
43  
-        )
44  
-
45  
-    def close(self):
46  
-        """Dispose of any internal state.
47  
-
48  
-        Currently, this just closes the PoolManager, which closes pooled
49  
-        connections.
50  
-        """
51  
-        self.poolmanager.clear()
52  
-
53  
-    def send(self, request):
54  
-        """Sends request object. Returns Response object."""
55  
-        pass
56  
-
57  
-
58  
-
17  lib/python/requests/api.py
@@ -14,7 +14,6 @@
14 14
 from . import sessions
15 15
 from .safe_mode import catch_exceptions_if_in_safe_mode
16 16
 
17  
-
18 17
 @catch_exceptions_if_in_safe_mode
19 18
 def request(method, url, **kwargs):
20 19
     """Constructs and sends a :class:`Request <Request>`.
@@ -39,19 +38,9 @@ def request(method, url, **kwargs):
39 38
     :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
40 39
     """
41 40
 
42  
-    # if this session was passed in, leave it open (and retain pooled connections);
43  
-    # if we're making it just for this call, then close it when we're done.
44  
-    adhoc_session = False
45  
-    session = kwargs.pop('session', None)
46  
-    if session is None:
47  
-        session = sessions.session()
48  
-        adhoc_session = True
49  
-
50  
-    try:
51  
-        return session.request(method=method, url=url, **kwargs)
52  
-    finally:
53  
-        if adhoc_session:
54  
-            session.close()
  41
+    s = kwargs.pop('session') if 'session' in kwargs else sessions.session()
  42
+    return s.request(method=method, url=url, **kwargs)
  43
+
55 44
 
56 45
 
57 46
 def get(url, **kwargs):
361  lib/python/requests/auth.py
@@ -8,10 +8,8 @@
8 8
 """
9 9
 
10 10
 import os
11  
-import re
12 11
 import time
13 12
 import hashlib
14  
-import logging
15 13
 
16 14
 from base64 import b64encode
17 15
 
@@ -19,22 +17,15 @@
19 17
 from .utils import parse_dict_header
20 18
 
21 19
 try:
22  
-    from ._oauth import (Client, SIGNATURE_HMAC, SIGNATURE_TYPE_AUTH_HEADER, extract_params)
23  
-
  20
+    from oauthlib.oauth1.rfc5849 import (Client, SIGNATURE_HMAC, SIGNATURE_TYPE_AUTH_HEADER)
  21
+    from oauthlib.common import extract_params
  22
+    # hush pyflakes:
  23
+    SIGNATURE_HMAC; SIGNATURE_TYPE_AUTH_HEADER
24 24
 except (ImportError, SyntaxError):
25 25
     SIGNATURE_HMAC = None
26 26
     SIGNATURE_TYPE_AUTH_HEADER = None
27 27
 
28  
-try:
29  
-    import kerberos as k
30  
-except ImportError as exc:
31  
-    k = None
32  
-
33  
-log = logging.getLogger(__name__)
34  
-
35 28
 CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded'
36  
-CONTENT_TYPE_MULTI_PART = 'multipart/form-data'
37  
-
38 29
 
39 30
 def _basic_auth_str(username, password):
40 31
     """Returns a Basic Auth string."""
@@ -75,37 +66,29 @@ def __call__(self, r):
75 66
         Parameters may be included from the body if the content-type is
76 67
         urlencoded, if no content type is set an educated guess is made.
77 68
         """
78  
-        # split(";") because Content-Type may be "multipart/form-data; boundary=xxxxx"
79  
-        contenttype = r.headers.get('Content-Type', '').split(";")[0].lower()
  69
+        contenttype = r.headers.get('Content-Type', None)
80 70
         # extract_params will not give params unless the body is a properly
81 71
         # formatted string, a dictionary or a list of 2-tuples.
82  
-        decoded_body = extract_params(r.data)
83  
-
84  
-        # extract_params can only check the present r.data and does not know
85  
-        # of r.files, thus an extra check is performed. We know that
86  
-        # if files are present the request will not have
87  
-        # Content-type: x-www-form-urlencoded. We guess it will have
88  
-        # a mimetype of multipart/form-data and if this is not the case
89  
-        # we assume the correct header will be set later.
90  
-        _oauth_signed = True
91  
-        if r.files and contenttype == CONTENT_TYPE_MULTI_PART:
92  
-            # Omit body data in the signing and since it will always
93  
-            # be empty (cant add paras to body if multipart) and we wish
94  
-            # to preserve body.
95  
-            r.url, r.headers, _ = self.client.sign(
96  
-                unicode(r.full_url), unicode(r.method), None, r.headers)
97  
-        elif decoded_body is not None and contenttype in (CONTENT_TYPE_FORM_URLENCODED, ''):
98  
-            # Normal signing
99  
-            if not contenttype:
100  
-                r.headers['Content-Type'] = CONTENT_TYPE_FORM_URLENCODED
101  
-            r.url, r.headers, r.data = self.client.sign(
102  
-                unicode(r.full_url), unicode(r.method), r.data, r.headers)
103  
-        else:
104  
-            _oauth_signed = False
105  
-        if _oauth_signed:
106  
-            # Both flows add params to the URL by using r.full_url,
107  
-            # so this prevents adding it again later
108  
-            r.params = {}
  72
+        decoded_body = extract_params(r.data)     
  73
+        if contenttype == None and decoded_body != None:
  74
+            # extract_params can only check the present r.data and does not know
  75
+            # of r.files, thus an extra check is performed. We know that 
  76
+            # if files are present the request will not have 
  77
+            # Content-type: x-www-form-urlencoded. We guess it will have
  78
+            # a mimetype of multipart/form-encoded and if this is not the case
  79
+            # we assume the correct header will be set later.
  80
+            if r.files:
  81
+                # Omit body data in the signing and since it will always
  82
+                # be empty (cant add paras to body if multipart) and we wish
  83
+                # to preserve body. 
  84
+                r.headers['Content-Type'] = 'multipart/form-encoded'
  85
+                r.url, r.headers, _ = self.client.sign(
  86
+                    unicode(r.url), unicode(r.method), None, r.headers)
  87
+            else:
  88
+                # Normal signing
  89
+                r.headers['Content-Type'] = 'application/x-www-form-urlencoded'
  90
+                r.url, r.headers, r.data = self.client.sign(
  91
+                    unicode(r.url), unicode(r.method), r.data, r.headers)
109 92
 
110 93
             # Having the authorization header, key or value, in unicode will
111 94
             # result in UnicodeDecodeErrors when the request is concatenated
@@ -117,12 +100,12 @@ def __call__(self, r):
117 100
             # >>> d
118 101
             # { u'a' : 'foo' }
119 102
             u_header = unicode('Authorization')
120  
-            if u_header in r.headers:
  103
+            if u_header in r.headers:               
121 104
                 auth_header = r.headers[u_header].encode('utf-8')
122 105
                 del r.headers[u_header]
123 106
                 r.headers['Authorization'] = auth_header
124 107
 
125  
-        return r
  108
+            return r
126 109
 
127 110
 
128 111
 class HTTPBasicAuth(AuthBase):
@@ -148,101 +131,91 @@ class HTTPDigestAuth(AuthBase):
148 131
     def __init__(self, username, password):
149 132
         self.username = username
150 133
         self.password = password
151  
-        self.last_nonce = ''
152  
-        self.nonce_count = 0
153  
-        self.chal = {}
154  
-
155  
-    def build_digest_header(self, method, url):
156  
-
157  
-        realm = self.chal['realm']
158  
-        nonce = self.chal['nonce']
159  
-        qop = self.chal.get('qop')