From 2b4c0b355d70bc62b9d39c7c446e2bbba2cb9c1c Mon Sep 17 00:00:00 2001
From: Ben Adida <ben@adida.net>
Date: Sat, 30 Aug 2014 22:18:54 +0000
Subject: [PATCH] changed google auth to use openid2.0, fixes #68

---
 helios_auth/auth_systems/google.py | 52 ++++++++++++++++++------------
 requirements.txt                   |  1 +
 settings.py                        |  4 +++
 3 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/helios_auth/auth_systems/google.py b/helios_auth/auth_systems/google.py
index 4a50f44..e13a9f4 100644
--- a/helios_auth/auth_systems/google.py
+++ b/helios_auth/auth_systems/google.py
@@ -7,42 +7,54 @@ from django.http import *
 from django.core.mail import send_mail
 from django.conf import settings
 
+import httplib2,json
+
 import sys, os, cgi, urllib, urllib2, re
-from xml.etree import ElementTree
 
-from openid import view_helpers
+from oauth2client.client import OAuth2WebServerFlow
 
 # some parameters to indicate that status updating is not possible
 STATUS_UPDATES = False
 
 # display tweaks
 LOGIN_MESSAGE = "Log in with my Google Account"
-OPENID_ENDPOINT = 'https://www.google.com/accounts/o8/id'
 
-# FIXME!
-# TRUST_ROOT = 'http://localhost:8000'
-# RETURN_TO = 'http://localhost:8000/auth/after'
+def get_flow(redirect_url=None):
+  return OAuth2WebServerFlow(client_id=settings.GOOGLE_CLIENT_ID,
+            client_secret=settings.GOOGLE_CLIENT_SECRET,
+            scope='profile email',
+            redirect_uri=redirect_url)
 
 def get_auth_url(request, redirect_url):
-  # FIXME?? TRUST_ROOT should be diff than return_url?
-  request.session['google_redirect_url'] = redirect_url
-  url = view_helpers.start_openid(request.session, OPENID_ENDPOINT, redirect_url, redirect_url)
-  return url
+  flow = get_flow(redirect_url)
+
+  request.session['google-flow'] = flow
+  return flow.step1_get_authorize_url()
 
 def get_user_info_after_auth(request):
-  data = view_helpers.finish_openid(request.session, request.GET, request.session['google_redirect_url'])
+  flow = request.session['google-flow']
+  code = request.GET['code']
+  credentials = flow.step2_exchange(code)
 
-  if not data.has_key('ax'):
-    return None
+  # the email address is in the credentials, that's how we make sure it's verified
+  id_token = credentials.id_token
+  if not id_token['email_verified']:
+    raise Exception("email address with Google not verified")
+   
+  email = id_token['email']
 
-  email = data['ax']['email'][0]
+  # get the nice name
+  http = httplib2.Http(".cache")
+  http = credentials.authorize(http)
+  (resp_headers, content) = http.request("https://www.googleapis.com/plus/v1/people/me", "GET")
 
-  # do we have a firstname/lastname?
-  if data['ax'].has_key('firstname') and data['ax'].has_key('lastname'):
-    name = "%s %s" % (data['ax']['firstname'][0], data['ax']['lastname'][0])
-  else:
-    name = email
+  response = json.loads(content)
 
+  name = response['displayName']
+  
+  # watch out, response also contains email addresses, but not sure whether thsoe are verified or not
+  # so for email address we will only look at the id_token
+  
   return {'type' : 'google', 'user_id': email, 'name': name , 'info': {'email': email}, 'token':{}}
     
 def do_logout(user):
@@ -67,4 +79,4 @@ def check_constraint(constraint, user_info):
   """
   for eligibility
   """
-  pass
+  pass
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 0ee4a32..2b31034 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -23,3 +23,4 @@ bleach==1.4
 boto==2.27.0
 django-ses==0.6.0
 validate_email==1.2
+oauth2client==1.2
\ No newline at end of file
diff --git a/settings.py b/settings.py
index f3ad0fe..eab44a0 100644
--- a/settings.py
+++ b/settings.py
@@ -200,6 +200,10 @@ HELIOS_PRIVATE_DEFAULT = False
 AUTH_ENABLED_AUTH_SYSTEMS = get_from_env('AUTH_ENABLED_AUTH_SYSTEMS', 'google').split(",")
 AUTH_DEFAULT_AUTH_SYSTEM = get_from_env('AUTH_DEFAULT_AUTH_SYSTEM', None)
 
+# google
+GOOGLE_CLIENT_ID = get_from_env('GOOGLE_CLIENT_ID', '')
+GOOGLE_CLIENT_SECRET = get_from_env('GOOGLE_CLIENT_SECRET', '')
+
 # facebook
 FACEBOOK_APP_ID = get_from_env('FACEBOOK_APP_ID','')
 FACEBOOK_API_KEY = get_from_env('FACEBOOK_API_KEY','')
-- 
GitLab