summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2014-04-30 08:56:01 -0300
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2014-04-30 08:56:01 -0300
commit98e5abb0ad52bfa6467d47d24f7798d9c1d175a7 (patch)
tree5044eda31663e63b262325a230a5dfcb703684e9
parent2a0668d9537e1ee0b09808999d9e0ffb96fdd008 (diff)
downloadaskbot-98e5abb0ad52bfa6467d47d24f7798d9c1d175a7.tar.gz
askbot-98e5abb0ad52bfa6467d47d24f7798d9c1d175a7.tar.bz2
askbot-98e5abb0ad52bfa6467d47d24f7798d9c1d175a7.zip
first pass on mozilla persona protocol
-rw-r--r--askbot/conf/login_providers.py5
-rw-r--r--askbot/deps/django_authopenid/backends.py16
-rw-r--r--askbot/deps/django_authopenid/forms.py6
-rw-r--r--askbot/deps/django_authopenid/util.py27
-rw-r--r--askbot/deps/django_authopenid/views.py16
-rw-r--r--askbot/doc/source/changelog.rst1
-rw-r--r--askbot/media/jquery-openid/images/mozilla-persona.gifbin0 -> 2197 bytes
-rw-r--r--askbot/media/jquery-openid/jquery.openid.js34
-rw-r--r--askbot/templates/authopenid/providers_javascript.html3
-rw-r--r--askbot/templates/authopenid/signin.html1
-rw-r--r--askbot/templates/meta/html_head_javascript.html2
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
new file mode 100644
index 00000000..e4a8a2d4
--- /dev/null
+++ b/askbot/media/jquery-openid/images/mozilla-persona.gif
Binary files differ
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'] = {};