Skip to content
This repository has been archived by the owner on Jan 8, 2019. It is now read-only.

Commit

Permalink
upgrade to django-browserid==0.7.1
Browse files Browse the repository at this point in the history
  • Loading branch information
peterbe committed Dec 13, 2012
1 parent 8508fd6 commit a78e698
Show file tree
Hide file tree
Showing 86 changed files with 15,120 additions and 609 deletions.
6 changes: 4 additions & 2 deletions lib/python/django_browserid/__init__.py
Expand Up @@ -5,5 +5,7 @@
License, v. 2.0. If a copy of the MPL was not distributed with this License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/. file, You can obtain one at http://mozilla.org/MPL/2.0/.
""" """
from django_browserid.auth import BrowserIDBackend __version__ = '0.7.1'
from django_browserid.base import get_audience, verify
from django_browserid.auth import BrowserIDBackend # NOQA
from django_browserid.base import get_audience, verify # NOQA
44 changes: 24 additions & 20 deletions lib/python/django_browserid/auth.py
Expand Up @@ -6,24 +6,24 @@
import base64 import base64
import hashlib import hashlib
import logging import logging
from warnings import warn


from django.conf import settings from django.conf import settings
from django.contrib.auth.models import User
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.utils.importlib import import_module from django.utils.importlib import import_module


from django_browserid.base import get_audience as base_get_audience, verify from django_browserid.base import verify
from django_browserid.signals import user_created from django_browserid.signals import user_created


try:
from django.contrib.auth import get_user_model
except ImportError:
from django.contrib.auth.models import User


log = logging.getLogger(__name__) def get_user_model(*args, **kwargs):
return User




def get_audience(*args): log = logging.getLogger(__name__)
warn('Deprecated, please use the standalone function '
'django_browserid.get_audience instead.', DeprecationWarning)
return base_get_audience(*args)




def default_username_algo(email): def default_username_algo(email):
Expand All @@ -40,14 +40,17 @@ class BrowserIDBackend(object):
supports_inactive_user = True supports_inactive_user = True
supports_object_permissions = False supports_object_permissions = False


def verify(self, *args): def __init__(self):
warn('Deprecated, please use the standalone function ' """
'django_browserid.verify instead.', DeprecationWarning) Store the current user model on creation to avoid issues if
return verify(*args) settings.AUTH_USER_MODEL changes, which usually only happens during
tests.
"""
self.User = get_user_model()


def filter_users_by_email(self, email): def filter_users_by_email(self, email):
"""Return all users matching the specified email.""" """Return all users matching the specified email."""
return User.objects.filter(email=email) return self.User.objects.filter(email=email)


def create_user(self, email): def create_user(self, email):
"""Return object for a newly created user account.""" """Return object for a newly created user account."""
Expand All @@ -57,7 +60,7 @@ def create_user(self, email):
else: else:
username = default_username_algo(email) username = default_username_algo(email)


return User.objects.create_user(username, email) return self.User.objects.create_user(username, email)


def authenticate(self, assertion=None, audience=None): def authenticate(self, assertion=None, audience=None):
"""``django.contrib.auth`` compatible authentication method. """``django.contrib.auth`` compatible authentication method.
Expand All @@ -81,7 +84,8 @@ def authenticate(self, assertion=None, audience=None):
# log and bail. randomly selecting one seems really wrong. # log and bail. randomly selecting one seems really wrong.
users = self.filter_users_by_email(email=email) users = self.filter_users_by_email(email=email)
if len(users) > 1: if len(users) > 1:
log.warn('%d users with email address %s.' % (len(users), email)) log.warn('{0} users with email address {1}.'.format(len(users),
email))
return None return None
if len(users) == 1: if len(users) == 1:
return users[0] return users[0]
Expand All @@ -90,7 +94,7 @@ def authenticate(self, assertion=None, audience=None):
if not create_user: if not create_user:
return None return None
else: else:
if create_user == True: if create_user is True:
create_function = self.create_user create_function = self.create_user
else: else:
# Find the function to call. # Find the function to call.
Expand All @@ -102,8 +106,8 @@ def authenticate(self, assertion=None, audience=None):


def get_user(self, user_id): def get_user(self, user_id):
try: try:
return User.objects.get(pk=user_id) return self.User.objects.get(pk=user_id)
except User.DoesNotExist: except self.User.DoesNotExist:
return None return None


def _load_module(self, path): def _load_module(self, path):
Expand All @@ -125,6 +129,6 @@ def _load_module(self, path):
try: try:
create_user = getattr(mod, attr) create_user = getattr(mod, attr)
except AttributeError: except AttributeError:
raise ImproperlyConfigured('Module "%s" does not define a "%s" ' raise ImproperlyConfigured('Module {0} does not define a {1} '
'function.' % (module, attr)) 'function.'.format(module, attr))
return create_user return create_user
59 changes: 12 additions & 47 deletions lib/python/django_browserid/base.py
Expand Up @@ -9,7 +9,7 @@
try: try:
import json import json
except ImportError: except ImportError:
import simplejson as json import simplejson as json # NOQA




from django.conf import settings from django.conf import settings
Expand All @@ -21,7 +21,7 @@




DEFAULT_HTTP_TIMEOUT = 5 DEFAULT_HTTP_TIMEOUT = 5
DEFAULT_VERIFICATION_URL = 'https://browserid.org/verify' DEFAULT_VERIFICATION_URL = 'https://verifier.login.persona.org/verify'
OKAY_RESPONSE = 'okay' OKAY_RESPONSE = 'okay'




Expand All @@ -36,17 +36,6 @@ def get_audience(request):
SITE_URL = 'https://example.com' SITE_URL = 'https://example.com'
SITE_URL = 'http://example.com' SITE_URL = 'http://example.com'
If you don't have a SITE_URL you can also use these varables:
PROTOCOL, DOMAIN, and (optionally) PORT.
Example 1:
PROTOCOL = 'https://'
DOMAIN = 'example.com'
Example 2:
PROTOCOL = 'http://'
DOMAIN = '127.0.0.1'
PORT = '8001'
If none are set, we trust the request to populate the audience. If none are set, we trust the request to populate the audience.
This is *not secure*! This is *not secure*!
""" """
Expand All @@ -59,32 +48,11 @@ def get_audience(request):
req_proto = 'http://' req_proto = 'http://'
req_domain = request.get_host() req_domain = request.get_host()


# If we don't define it explicitly
if not site_url:
warn('Using DOMAIN and PROTOCOL to specify your BrowserID audience is '
'deprecated. Please use the SITE_URL setting instead.',
DeprecationWarning)

# DOMAIN is example.com req_domain is example.com:8001
domain = getattr(settings, 'DOMAIN', req_domain.split(':')[0])
protocol = getattr(settings, 'PROTOCOL', req_proto)

standards = {'https://': 443, 'http://': 80}
if ':' in req_domain:
req_port = req_domain.split(':')[1]
else:
req_port = None
port = getattr(settings, 'PORT', req_port or standards[protocol])
if port == standards[protocol]:
site_url = ''.join(map(str, (protocol, domain)))
else:
site_url = ''.join(map(str, (protocol, domain, ':', port)))

req_url = "%s%s" % (req_proto, req_domain) req_url = "%s%s" % (req_proto, req_domain)
if site_url != "%s%s" % (req_proto, req_domain): if site_url != "%s%s" % (req_proto, req_domain):
log.warning('Misconfigured SITE_URL? settings has [%s], but ' log.warning('Misconfigured SITE_URL? settings has {0}, but '
'actual request was [%s] BrowserID may fail on ' 'actual request was {1} BrowserID may fail on '
'audience' % (site_url, req_url)) 'audience'.format(site_url, req_url))
return site_url return site_url




Expand All @@ -94,10 +62,8 @@ def _verify_http_request(url, qs):
'proxies': getattr(settings, 'BROWSERID_PROXY_INFO', None), 'proxies': getattr(settings, 'BROWSERID_PROXY_INFO', None),
'verify': not getattr(settings, 'BROWSERID_DISABLE_CERT_CHECK', False), 'verify': not getattr(settings, 'BROWSERID_DISABLE_CERT_CHECK', False),
'headers': {'Content-type': 'application/x-www-form-urlencoded'}, 'headers': {'Content-type': 'application/x-www-form-urlencoded'},
'params': { 'timeout': getattr(settings, 'BROWSERID_HTTP_TIMEOUT',
'timeout': getattr(settings, 'BROWSERID_HTTP_TIMEOUT', DEFAULT_HTTP_TIMEOUT),
DEFAULT_HTTP_TIMEOUT)
}
} }


if parameters['verify']: if parameters['verify']:
Expand All @@ -108,8 +74,7 @@ def _verify_http_request(url, qs):
try: try:
rv = json.loads(r.content) rv = json.loads(r.content)
except ValueError: except ValueError:
log.debug('Failed to decode JSON. Resp: %s, Content: %s' % log.debug('Failed to decode JSON. Resp: {0}, Content: {1}'.format(r.status_code, r.content))
(r.status_code, r.content))
return dict(status='failure') return dict(status='failure')


return rv return rv
Expand All @@ -120,7 +85,7 @@ def verify(assertion, audience):
verify_url = getattr(settings, 'BROWSERID_VERIFICATION_URL', verify_url = getattr(settings, 'BROWSERID_VERIFICATION_URL',
DEFAULT_VERIFICATION_URL) DEFAULT_VERIFICATION_URL)


log.info("Verification URL: %s" % verify_url) log.info("Verification URL: {0}".format(verify_url))


result = _verify_http_request(verify_url, urllib.urlencode({ result = _verify_http_request(verify_url, urllib.urlencode({
'assertion': assertion, 'assertion': assertion,
Expand All @@ -130,7 +95,7 @@ def verify(assertion, audience):
if result['status'] == OKAY_RESPONSE: if result['status'] == OKAY_RESPONSE:
return result return result


log.error('BrowserID verification failure. Response: %r ' log.error('BrowserID verification failure. Response: {0} '
'Audience: %r' % (result, audience)) 'Audience: {1}'.format(result, audience))
log.error("BID assert: %r" % assertion) log.error("BID assert: {0}".format(assertion))
return False return False
2 changes: 1 addition & 1 deletion lib/python/django_browserid/forms.py
Expand Up @@ -10,4 +10,4 @@ class BrowserIDForm(forms.Form):
assertion = forms.CharField(widget=forms.HiddenInput()) assertion = forms.CharField(widget=forms.HiddenInput())


class Media: class Media:
js = ('browserid/browserid.js', 'https://browserid.org/include.js') js = ('browserid/browserid.js', 'https://login.persona.org/include.js')
70 changes: 61 additions & 9 deletions lib/python/django_browserid/static/browserid/browserid.js
@@ -1,15 +1,67 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
$(document).ready(function() {
$('#browserid').bind('click', function(e) { (function($) {
e.preventDefault(); 'use strict';
navigator.id.getVerifiedEmail(function(assertion) {
if (assertion) { $(function() {
var $e = $('#id_assertion'); // State? Ewwwwww.
$e.val(assertion.toString()); var logoutButton = null;
$e.parent().submit(); var requestOptions = [
'siteName',
'siteLogo',
'oncancel',
'privacyPolicy',
'returnTo',
'termsOfService'
];

$(document).delegate('.browserid-login, #browserid', 'click', function(e) {
e.preventDefault();

// Arguments to navigator.id.request can be specified by data-attributes
// on the BrowserID link: <a href="#" data-site-name="Site Name">
var options = {};
var $link = $(e.target);
for (var k = 0; k < requestOptions.length; k++) {
var name = requestOptions[k];
var value = $link.data(name);
if (value !== undefined) {
options[name] = value;
}
}

navigator.id.request(options); // Triggers BrowserID login dialog.
});

$('.browserid-logout').bind('click', function(e) {
e.preventDefault();
logoutButton = e.target;
navigator.id.logout(); // Clears User Agent BrowserID state.
});

navigator.id.watch({
onlogin: function(assertion) {
// Don't bother if login just failed.
if (location.search.indexOf('bid_login_failed=1') !== -1) {
navigator.id.logout();
} else if (assertion) {
var $e = $('#id_assertion');
$e.val(assertion.toString());
$e.parent().submit();
}
},

onlogout: function() {
var currentButton = logoutButton;
if (currentButton !== null) {
logoutButton = null;
if (currentButton.href) {
window.location = currentButton.href;
}
}
} }
}); });
}); });
}); })(jQuery);
2 changes: 1 addition & 1 deletion lib/python/django_browserid/tests/__init__.py
Expand Up @@ -31,7 +31,7 @@ def __init__(self, email=None, audience=None):
self.return_value = { self.return_value = {
u'audience': audience, u'audience': audience,
u'email': email, u'email': email,
u'issuer': u'browserid.org:443', u'issuer': u'login.persona.org:443',
u'status': u'okay' if email is not None else u'failure', u'status': u'okay' if email is not None else u'failure',
u'valid-until': 1311377222765 u'valid-until': 1311377222765
} }
Expand Down
23 changes: 23 additions & 0 deletions lib/python/django_browserid/tests/models.py
@@ -0,0 +1,23 @@
"""
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
from django.db import models

try:
from django.contrib.auth.models import AbstractBaseUser
except ImportError:
AbstractBaseUser = object


class CustomUser(AbstractBaseUser):
USERNAME_FIELD = 'email'

email = models.EmailField(unique=True, db_index=True)

def get_full_name(self):
return self.email

def get_short_name(self):
return self.email
3 changes: 3 additions & 0 deletions lib/python/django_browserid/tests/settings.py
Expand Up @@ -5,6 +5,8 @@
""" """
TEST_RUNNER = 'django_nose.runner.NoseTestSuiteRunner' TEST_RUNNER = 'django_nose.runner.NoseTestSuiteRunner'


SECRET_KEY = 'asdf'

DATABASES = { DATABASES = {
'default': { 'default': {
'NAME': 'test.db', 'NAME': 'test.db',
Expand All @@ -15,6 +17,7 @@
INSTALLED_APPS = ( INSTALLED_APPS = (
'django_nose', 'django_nose',
'django_browserid', 'django_browserid',
'django_browserid.tests',


'django.contrib.auth', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.contenttypes',
Expand Down

0 comments on commit a78e698

Please sign in to comment.