come changed to oauth2_auth.py

This commit is contained in:
Massimo DiPierro
2012-03-09 13:49:46 -06:00
parent 42d797db1e
commit 8ac7656f2d
2 changed files with 51 additions and 45 deletions
+1 -1
View File
@@ -1 +1 @@
Version 1.99.7 (2012-03-09 01:59:43) dev Version 1.99.7 (2012-03-09 13:49:42) dev
+50 -44
View File
@@ -12,10 +12,10 @@ OAuth 2.0 Draft: http://tools.ietf.org/html/draft-ietf-oauth-v2-10
import time import time
import cgi import cgi
from urllib2 import urlopen
import urllib2 import urllib2
from urllib import urlencode from urllib import urlencode
from gluon import current, redirect, HTTP
class OAuthAccount(object): class OAuthAccount(object):
""" """
@@ -35,30 +35,27 @@ class OAuthAccount(object):
writable=False, readable=False)) writable=False, readable=False))
auth_table.username.requires = IS_NOT_IN_DB(db, auth_table.username) auth_table.username.requires = IS_NOT_IN_DB(db, auth_table.username)
.
.
.
auth.define_tables() auth.define_tables()
.
.
.
CLIENT_ID=\"<put your fb application id here>\" CLIENT_ID=\"<put your fb application id here>\"
CLIENT_SECRET=\"<put your fb application secret here>\" CLIENT_SECRET=\"<put your fb application secret here>\"
AUTH_URL="http://..." AUTH_URL="http://..."
TOKEN_URL="http://..." TOKEN_URL="http://..."
from gluon.contrib.login_methods.oauth20_account import OAuthAccount from gluon.contrib.login_methods.oauth20_account import OAuthAccount
auth.settings.login_form=OAuthAccount(globals(),CLIENT_ID,CLIENT_SECRET,AUTH_URL, TOKEN_URL, **args ) auth.settings.login_form=OAuthAccount(
None,CLIENT_ID,CLIENT_SECRET,AUTH_URL, TOKEN_URL, **args)
Any optional arg will be passed as is to remote server for requests. Any optional arg will be passed as is to remote server for requests.
It can be used for the optional "scope" parameters for Facebook. It can be used for the optional "scope" parameters for Facebook.
""" """
def __redirect_uri(self, next=None): def __redirect_uri(self, next=None):
"""Build the uri used by the authenticating server to redirect """
Build the uri used by the authenticating server to redirect
the client back to the page originating the auth request. the client back to the page originating the auth request.
Appends the _next action to the generated url so the flows continues. Appends the _next action to the generated url so the flows continues.
""" """
r = self.request r = current.request
http_host=r.env.http_x_forwarded_for http_host=r.env.http_x_forwarded_for
if not http_host: http_host=r.env.http_host if not http_host: http_host=r.env.http_host
@@ -74,8 +71,12 @@ class OAuthAccount(object):
def __build_url_opener(self, uri): def __build_url_opener(self, uri):
"""Build the url opener for managing HTTP Basic Athentication""" """
# Create an OpenerDirector with support for Basic HTTP Authentication... Build the url opener for managing HTTP Basic Athentication
"""
# Create an OpenerDirector with support
# for Basic HTTP Authentication...
auth_handler = urllib2.HTTPBasicAuthHandler() auth_handler = urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(None, auth_handler.add_password(None,
uri, uri,
@@ -86,22 +87,23 @@ class OAuthAccount(object):
def accessToken(self): def accessToken(self):
"""Return the access token generated by the authenticating server. """
Return the access token generated by the authenticating server.
If token is already in the session that one will be used. If token is already in the session that one will be used.
Otherwise the token is fetched from the auth server. Otherwise the token is fetched from the auth server.
""" """
if self.session.token and self.session.token.has_key('expires'): if current.session.token and current.session.token.has_key('expires'):
expires = self.session.token['expires'] expires = current.session.token['expires']
# reuse token until expiration # reuse token until expiration
if expires == 0 or expires > time.time(): if expires == 0 or expires > time.time():
return self.session.token['access_token'] return current.session.token['access_token']
if self.session.code: if current.session.code:
data = dict(client_id=self.client_id, data = dict(client_id=self.client_id,
client_secret=self.client_secret, client_secret=self.client_secret,
redirect_uri=self.session.redirect_uri, redirect_uri=current.session.redirect_uri,
response_type='token', code=self.session.code) response_type='token', code=current.session.code)
if self.args: if self.args:
@@ -113,33 +115,36 @@ class OAuthAccount(object):
except urllib2.HTTPError, e: except urllib2.HTTPError, e:
raise Exception(e.read()) raise Exception(e.read())
finally: finally:
del self.session.code # throw it away del current.session.code # throw it away
if open_url: if open_url:
try: try:
tokendata = cgi.parse_qs(open_url.read()) tokendata = cgi.parse_qs(open_url.read())
self.session.token = dict([(k,v[-1]) for k,v in tokendata.items()]) current.session.token = \
dict([(k,v[-1]) for k,v in tokendata.items()])
# set expiration absolute time try to avoid broken # set expiration absolute time try to avoid broken
# implementations where "expires_in" becomes "expires" # implementations where "expires_in" becomes "expires"
if self.session.token.has_key('expires_in'): if current.session.token.has_key('expires_in'):
exps = 'expires_in' exps = 'expires_in'
else: else:
exps = 'expires' exps = 'expires'
self.session.token['expires'] = int(self.session.token[exps]) + \ current.session.token['expires'] = \
int(current.session.token[exps]) + \
time.time() time.time()
finally: finally:
opener.close() opener.close()
return self.session.token['access_token'] return current.session.token['access_token']
self.session.token = None current.session.token = None
return None return None
def __init__(self, g, client_id, client_secret, auth_url, token_url, **args): def __init__(self, g,
self.globals = g client_id, client_secret, auth_url, token_url, **args):
"""
first argument is unused. Here only for legacy reasons.
"""
self.client_id = client_id self.client_id = client_id
self.client_secret = client_secret self.client_secret = client_secret
self.request = g['request']
self.session = g['session']
self.auth_url = auth_url self.auth_url = auth_url
self.token_url = token_url self.token_url = token_url
self.args = args self.args = args
@@ -149,12 +154,13 @@ class OAuthAccount(object):
return next return next
def logout_url(self, next="/"): def logout_url(self, next="/"):
del self.session.token del current.session.token
return next return next
def get_user(self): def get_user(self):
'''Returns the user using the Graph API. """
''' Returns the user using the Graph API.
"""
raise NotImplementedError, "Must override get_user()" raise NotImplementedError, "Must override get_user()"
if not self.accessToken(): if not self.accessToken():
return None return None
@@ -166,7 +172,7 @@ class OAuthAccount(object):
try: try:
user = self.graph.get_object("me") user = self.graph.get_object("me")
except GraphAPIError: except GraphAPIError:
self.session.token = None current.session.token = None
self.graph = None self.graph = None
if user: if user:
@@ -175,9 +181,9 @@ class OAuthAccount(object):
username = user['id']) username = user['id'])
def __oauth_login(self, next): def __oauth_login(self, next):
'''This method redirects the user to the authenticating form """
This method redirects the user to the authenticating form
on authentication server if the authentication code on authentication server if the authentication code
and the authentication token are not available to the and the authentication token are not available to the
application yet. application yet.
@@ -185,23 +191,23 @@ class OAuthAccount(object):
Once the authentication code has been received this method is Once the authentication code has been received this method is
called to set the access token into the session by calling called to set the access token into the session by calling
accessToken() accessToken()
''' """
if not self.accessToken(): if not self.accessToken():
if not self.request.vars.code: if not current.request.vars.code:
self.session.redirect_uri=self.__redirect_uri(next) current.session.redirect_uri=self.__redirect_uri(next)
data = dict(redirect_uri=self.session.redirect_uri, data = dict(redirect_uri=current.session.redirect_uri,
response_type='code', response_type='code',
client_id=self.client_id) client_id=self.client_id)
if self.args: if self.args:
data.update(self.args) data.update(self.args)
auth_request_url = self.auth_url + "?" +urlencode(data) auth_request_url = self.auth_url + "?" +urlencode(data)
HTTP = self.globals['HTTP']
raise HTTP(307, raise HTTP(307,
"You are not authenticated: you are being redirected to the <a href='" + auth_request_url + "'> authentication server</a>", "You are not authenticated: you are being redirected to the <a href='" + auth_request_url + "'> authentication server</a>",
Location=auth_request_url) Location=auth_request_url)
else: else:
self.session.code = self.request.vars.code current.session.code = current.request.vars.code
self.accessToken() self.accessToken()
return self.session.code return current.session.code
return None return None