diff options
-rw-r--r-- | askbot/conf/login_providers.py | 5 | ||||
-rw-r--r-- | askbot/deps/django_authopenid/backends.py | 16 | ||||
-rw-r--r-- | askbot/deps/django_authopenid/forms.py | 6 | ||||
-rw-r--r-- | askbot/deps/django_authopenid/util.py | 27 | ||||
-rw-r--r-- | askbot/deps/django_authopenid/views.py | 16 | ||||
-rw-r--r-- | askbot/doc/source/changelog.rst | 1 | ||||
-rw-r--r-- | askbot/media/jquery-openid/images/mozilla-persona.gif | bin | 0 -> 2197 bytes | |||
-rw-r--r-- | askbot/media/jquery-openid/jquery.openid.js | 34 | ||||
-rw-r--r-- | askbot/templates/authopenid/providers_javascript.html | 3 | ||||
-rw-r--r-- | askbot/templates/authopenid/signin.html | 1 | ||||
-rw-r--r-- | askbot/templates/meta/html_head_javascript.html | 2 |
11 files changed, 107 insertions, 4 deletions
diff --git a/askbot/conf/login_providers.py b/askbot/conf/login_providers.py index faa6ae8c..3c30bffa 100644 --- a/askbot/conf/login_providers.py +++ b/askbot/conf/login_providers.py @@ -123,6 +123,7 @@ providers = ( 'Facebook', 'Flickr', 'Google', + 'Mozilla Persona', 'Twitter', 'LinkedIn', 'LiveJournal', @@ -134,7 +135,7 @@ providers = ( 'Verisign', 'Yahoo', 'identi.ca', - 'LaunchPad' + 'LaunchPad', ) DISABLED_BY_DEFAULT = ('LaunchPad',) @@ -158,7 +159,7 @@ for provider in providers: 'in the "External keys" section' ) % {'provider': provider} - setting_name = 'SIGNIN_%s_ENABLED' % provider.upper() + setting_name = 'SIGNIN_%s_ENABLED' % provider.upper().replace(' ', '_') settings.register( livesettings.BooleanValue( LOGIN_PROVIDERS, diff --git a/askbot/deps/django_authopenid/backends.py b/askbot/deps/django_authopenid/backends.py index f719e811..6d01a3a0 100644 --- a/askbot/deps/django_authopenid/backends.py +++ b/askbot/deps/django_authopenid/backends.py @@ -37,6 +37,7 @@ class AuthBackend(object): provider_name = None,#required with all except email_key openid_url = None, email_key = None, + email = None, # used with mozilla-persona method oauth_user_id = None,#used with oauth facebook_user_id = None,#user with facebook wordpress_url = None, # required for self hosted wordpress @@ -129,7 +130,20 @@ class AuthBackend(object): 'duplicate openid url in the database!!! %s' % openid_url ) return None - + + elif method == 'mozilla-persona': + try: + assoc = UserAssociation.objects.get( + openid_url=email, + provider_name='mozilla-persona' + ) + return assoc.user + except UserAssociation.DoesNotExist: + return None + except UserAssociation.MultipleObjectsReturned: + logging.critical( + 'duplicate user with mozilla persona %s!!!' % email + ) elif method == 'email': #with this method we do no use user association diff --git a/askbot/deps/django_authopenid/forms.py b/askbot/deps/django_authopenid/forms.py index 1ada641e..5f64ccd5 100644 --- a/askbot/deps/django_authopenid/forms.py +++ b/askbot/deps/django_authopenid/forms.py @@ -126,6 +126,10 @@ class LoginForm(forms.Form): """ next = NextUrlField() login_provider_name = LoginProviderField() + persona_assertion = forms.CharField( + required=False, + widget=forms.widgets.HiddenInput() + ) openid_login_token = forms.CharField( max_length=256, required = False, @@ -221,6 +225,8 @@ class LoginForm(forms.Form): #self.do_clean_oauth_fields() elif provider_type == 'wordpress_site': self.cleaned_data['login_type'] = 'wordpress_site' + elif provider_type == 'mozilla-persona': + self.cleaned_data['login_type'] = 'mozilla-persona' return self.cleaned_data diff --git a/askbot/deps/django_authopenid/util.py b/askbot/deps/django_authopenid/util.py index deb9ad27..880dbf9d 100644 --- a/askbot/deps/django_authopenid/util.py +++ b/askbot/deps/django_authopenid/util.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- import cgi +import httplib import urllib import urlparse import functools @@ -182,7 +183,8 @@ def filter_enabled_providers(data): delete_list = list() for provider_key, provider_settings in data.items(): name = provider_settings['name'] - is_enabled = getattr(askbot_settings, 'SIGNIN_' + name.upper() + '_ENABLED') + name_key = name.upper().replace('-', '_') + is_enabled = getattr(askbot_settings, 'SIGNIN_' + name_key + '_ENABLED') if is_enabled == False: delete_list.append(provider_key) @@ -500,6 +502,12 @@ def get_enabled_major_login_providers(): 'icon_media_path': '/jquery-openid/images/google.gif', 'openid_endpoint': 'https://www.google.com/accounts/o8/id', } + data['mozilla-persona'] = { + 'name': 'mozilla-persona', + 'display_name': 'Mozilla Persona', + 'type': 'mozilla-persona', + 'icon_media_path': '/jquery-openid/images/mozilla-persona.gif', + } data['yahoo'] = { 'name': 'yahoo', 'display_name': 'Yahoo', @@ -860,3 +868,20 @@ def ldap_check_password(username, password): except ldap.LDAPError, e: logging.critical(unicode(e)) return False + + +def mozilla_persona_get_email_from_assertion(assertion): + conn = httplib.HTTPSConnection('verifier.login.persona.org') + parsed_url = urlparse.urlparse(askbot_settings.APP_URL) + params = urllib.urlencode({ + 'assertion': assertion, + 'audience': parsed_url.scheme + '://' + parsed_url.netloc + }) + headers = {'Content-type': 'application/x-www-form-urlencoded', 'Accept': 'text/plain'} + conn.request('POST', '/verify', params, headers) + response = conn.getresponse() + if response.status == 200: + data = simplejson.loads(response.read()) + return data.get('email') + #todo: nead more feedback to help debug fail cases + return None diff --git a/askbot/deps/django_authopenid/views.py b/askbot/deps/django_authopenid/views.py index 1f629791..09cba6fc 100644 --- a/askbot/deps/django_authopenid/views.py +++ b/askbot/deps/django_authopenid/views.py @@ -537,6 +537,22 @@ def signin(request, template_name='authopenid/signin.html'): ) raise Http404 + elif login_form.cleaned_data['login_type'] == 'mozilla-persona': + assertion = login_form.cleaned_data['persona_assertion'] + email = util.mozilla_persona_get_email_from_assertion(assertion) + if email: + user = authenticate(email=email, method='mozilla-persona') + if user: + login(request, user) + return HttpResponseRedirect(next_url) + else: + return finalize_generic_signin( + request, + login_provider_name = 'mozilla-persona', + user_identifier = email, + redirect_url = next_url + ) + elif login_form.cleaned_data['login_type'] == 'openid': #initiate communication process logging.debug('processing signin with openid submission') diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst index 28ad0a3d..57a7b252 100644 --- a/askbot/doc/source/changelog.rst +++ b/askbot/doc/source/changelog.rst @@ -3,6 +3,7 @@ Changes in Askbot Development master branch (only on github) ------------------------------------------ +* Implemented Mozilla Persona authentication * Allowed custom providers of gravatar service (michas2) * Allowed configurable custom OpenID login button * Allowed custom list of feedback recipients (Keto) diff --git a/askbot/media/jquery-openid/images/mozilla-persona.gif b/askbot/media/jquery-openid/images/mozilla-persona.gif Binary files differnew file mode 100644 index 00000000..e4a8a2d4 --- /dev/null +++ b/askbot/media/jquery-openid/images/mozilla-persona.gif diff --git a/askbot/media/jquery-openid/jquery.openid.js b/askbot/media/jquery-openid/jquery.openid.js index 20807065..520f031c 100644 --- a/askbot/media/jquery-openid/jquery.openid.js +++ b/askbot/media/jquery-openid/jquery.openid.js @@ -381,12 +381,35 @@ $.fn.authenticator = function() { $('#id_email').focus(); }; + var start_mozilla_persona_login = function() { + navigator.id.request(); + return false; + }; + var clear_password_fields = function(){ $('#id_password').val(''); $('#id_new_password').val(''); $('#id_new_password_retyped').val(''); }; + var setupMozillaPersonaListeners = function() { + navigator.id.watch({ + loggedInUser: askbot['data']['userEmail'], + onlogin: function(assertion) { + var assertionElement = signin_form.find('input[name=persona_assertion]'); + assertionElement.val(assertion); + provider_name_input.val('mozilla-persona'); + signin_form.submit(); + return false; + }, + onlogout: function() { + if (askbot['data']['userIsAuthenticated']) { + window.location.href = askbot['urls']['signOut']; + } + } + }); + }; + var setup_default_handlers = function(){ setup_event_handlers( signin_page.find('input.openid-direct'), @@ -403,6 +426,17 @@ $.fn.authenticator = function() { start_login_with_extra_openid_token ); + var mozillaPersonaBtn = signin_page.find('input.mozilla-persona'); + + if (mozillaPersonaBtn.length) { + setupMozillaPersonaListeners(); + setup_event_handlers( + signin_page.find('input.mozilla-persona'), + start_mozilla_persona_login + ); + } + + setup_event_handlers( signin_page.find('input.oauth,input.oauth2'), start_simple_login diff --git a/askbot/templates/authopenid/providers_javascript.html b/askbot/templates/authopenid/providers_javascript.html index 86f1004f..668fb1e9 100644 --- a/askbot/templates/authopenid/providers_javascript.html +++ b/askbot/templates/authopenid/providers_javascript.html @@ -1,4 +1,7 @@ <script type='text/javascript' src='{{ "/js/jquery.validate.min.js"|media }}'></script> +{% if settings.SIGNIN_MOZILLA_PERSONA_ENABLED %} +<script type="text/javascript" src="https://login.persona.org/include.js"></script> +{% endif %} <script type="text/javascript" src="{{ "/jquery-openid/jquery.openid.js"|media }}"></script> <script type="text/javascript"> askbot['urls']['changePassword'] = '{% url change_password %}'; diff --git a/askbot/templates/authopenid/signin.html b/askbot/templates/authopenid/signin.html index daf5a45a..c2717023 100644 --- a/askbot/templates/authopenid/signin.html +++ b/askbot/templates/authopenid/signin.html @@ -44,6 +44,7 @@ {% endif %}
{{ login_form.login_provider_name }}
{{ login_form.next }}
+ {{ login_form.persona_assertion }}
{{
login_macros.provider_buttons(
login_form = login_form,
diff --git a/askbot/templates/meta/html_head_javascript.html b/askbot/templates/meta/html_head_javascript.html index 062a435f..da9c7f74 100644 --- a/askbot/templates/meta/html_head_javascript.html +++ b/askbot/templates/meta/html_head_javascript.html @@ -7,12 +7,14 @@ {% if request.user.is_authenticated() %} askbot['data']['userId'] = {{ request.user.id }}; askbot['data']['userName'] = '{{ request.user.username|escape }}'; + askbot['data']['userEmail'] = '{{ request.user.email|escape }}'; askbot['data']['userIsAdminOrMod'] = {{ request.user.is_administrator_or_moderator()|as_js_bool }}; askbot['data']['userIsAdmin'] = {{ request.user.is_administrator()|as_js_bool }}; askbot['data']['userReputation'] = {{ request.user.reputation }}; askbot['data']['userIsReadOnly'] = {{ request.user.is_read_only()|as_js_bool }}; {% else %} askbot['data']['userReputation'] = 0; + askbot['data']['userEmail'] = null; askbot['data']['userIsReadOnly'] = false;//in principle we allow anon users to start posting {% endif %} askbot['urls'] = {}; |