[manual] Implement backend support for authenticating a user via Google.

This code adds a dependency on python-django-auth-openid, installable as
django-openid-auth from PyPI.

On prod, one needs to run a syncdb in order to create the required
tables. A database *migration* is not required, as these are new tables
only.

(imported from commit c902a0df8d589d93743b27e480154a04402b2c41)
This commit is contained in:
Luke Faraone 2013-02-20 16:26:06 -05:00
parent 801723b45c
commit 0fe0cf0ffb
6 changed files with 62 additions and 3 deletions

View File

@ -1,5 +1,8 @@
from django.contrib.auth.models import User
from django.conf import settings
from openid.consumer.consumer import SUCCESS
from zephyr.lib.cache import cache_with_key
@cache_with_key(lambda user_id: 'tornado_user:%d' % (user_id,))
@ -39,6 +42,31 @@ class EmailAuthBackend(object):
# any mutable fields from Tornado (just the id)
return get_tornado_user(user_id)
try:
return User.objects.get(pk=user_id)
return User.objects.get(id=user_id)
except User.DoesNotExist:
return None
# Adapted from http://djangosnippets.org/snippets/2183/ by user Hangya (September 1, 2010)
class GoogleBackend:
def authenticate(self, openid_response):
if openid_response is None:
return None
if openid_response.status != SUCCESS:
return None
google_email = openid_response.getSigned('http://openid.net/srv/ax/1.0', 'value.email')
try:
user = User.objects.get(email__iexact=google_email)
except User.DoesNotExist:
# create a new user, or send a message to admins, etc.
return None
return user
def get_user(self, user_id):
try:
return User.objects.get(id=user_id)
except User.DoesNotExist:
return None

View File

@ -2,6 +2,8 @@
import os
import platform
from zephyr.openid import openid_failure_handler
DEPLOYED = (('humbughq.com' in platform.node())
or os.path.exists('/etc/humbug-server'))
STAGING_DEPLOYED = (platform.node() == 'staging.humbughq.com')
@ -157,7 +159,8 @@ MIDDLEWARE_CLASSES = (
'django.contrib.auth.middleware.AuthenticationMiddleware',
)
AUTHENTICATION_BACKENDS = ('humbug.backends.EmailAuthBackend',)
AUTHENTICATION_BACKENDS = ('humbug.backends.EmailAuthBackend',
'humbug.backends.GoogleBackend')
TEST_RUNNER = 'zephyr.tests.Runner'
@ -174,6 +177,7 @@ INSTALLED_APPS = (
'django.contrib.sites',
'django.contrib.staticfiles',
'south',
'django_openid_auth',
'jstemplate',
'confirmation',
'pipeline',
@ -372,6 +376,9 @@ EMAIL_PORT = 587
DEFAULT_FROM_EMAIL = "Humbug <humbug@humbughq.com>"
LOGIN_REDIRECT_URL='/'
OPENID_SSO_SERVER_URL = 'https://www.google.com/accounts/o8/id'
OPENID_CREATE_USERS = True
OPENID_RENDER_FAILURE = openid_failure_handler
EVENT_LOG_DIR = 'event_log'

View File

@ -5,6 +5,8 @@ import zephyr.forms
urlpatterns = patterns('',
url(r'^$', 'zephyr.views.home'),
url(r'^accounts/login/openid/$', 'django_openid_auth.views.login_begin', name='openid-login'),
url(r'^accounts/login/openid/done/$', 'django_openid_auth.views.login_complete', name='openid-complete'),
# We have two entries for accounts/login to allow reverses on the Django
# view we're wrapping to continue to function.
url(r'^accounts/login/', 'zephyr.views.login_page', {'template_name': 'zephyr/login.html'}),

View File

@ -4,7 +4,7 @@ class humbug::app_frontend {
$web_packages = [ "nginx", "memcached", "python-pylibmc", "python-tornado", "python-django",
"python-pygments", "python-flup", "ipython", "python-psycopg2",
"yui-compressor", ]
"yui-compressor", "python-django-auth-openid"]
package { $web_packages: ensure => "installed" }
file { "/etc/nginx/nginx.conf":

View File

@ -0,0 +1,14 @@
{% extends "zephyr/portico.html" %}
{% block for_you %} isn't feeling too good. {% endblock %}
{% block portico_content %}
<br/>
<p class="lead">We couldn't validate your Google account<p>
<p>You might want to <a href="{% url django_openid_auth.views.login_begin %}">try logging in via Google again</a> or <a href="{%url django.contrib.auth.views.login %}">log in with a username or password.</a></p>
<p>If you'd like, you can also <a href="mailto:support@humbughq.com?Subject=Error%20logging%20in%20with%20Google%20Apps&Body=Hi%20there%2C%0A%0AI%20encountered%20an%20error%20when%20attempting%20to%20log%20in%20with%20Google%20Apps%20on%20Humbug%20using%20my%20email%20address%20youremailgoeshere@yourdomain.example.com%0A%0AError%20message%3A%20%20{{ message|escape }}%0A%0ASincerely%2C%20%0A%0AYour%20name%20here">drop us a line</a> to let us know what happened.</p>
{% endblock %}

8
zephyr/openid.py Normal file
View File

@ -0,0 +1,8 @@
# Defer importing until later to avoid circular imports
def openid_failure_handler(request, message, status=403, template_name=None, exception=None):
# We ignore template_name in this function
from django_openid_auth.views import default_render_failure
return default_render_failure(request, message, status=403, template_name="openid_error.html", exception=None)