From 6edaec3876fa1b02ce5778c5eb8d60c661969456 Mon Sep 17 00:00:00 2001 From: Matthew Scragg Date: Thu, 12 Nov 2015 17:19:26 -0600 Subject: [PATCH] get oauth data from providers --- realms/config/__init__.py | 2 +- realms/modules/auth/oauth/models.py | 40 +++++++++++++++++++++++------ realms/modules/auth/oauth/views.py | 11 ++++---- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/realms/config/__init__.py b/realms/config/__init__.py index ffe8050..72e4a4d 100644 --- a/realms/config/__init__.py +++ b/realms/config/__init__.py @@ -84,7 +84,7 @@ DB_URI = 'sqlite:////tmp/wiki.db' # DB_URI = 'crate://' LDAP = { - 'URI': 'ldap://localhost:8389', + 'URI': '', # This BIND_DN/BIND_PASSWORD default to '', this is shown here for demonstrative purposes # The values '' perform an anonymous bind so we may use search/bind method diff --git a/realms/modules/auth/oauth/models.py b/realms/modules/auth/oauth/models.py index 46a07ba..b1e6288 100644 --- a/realms/modules/auth/oauth/models.py +++ b/realms/modules/auth/oauth/models.py @@ -17,10 +17,12 @@ providers = { authorize_url='https://api.twitter.com/oauth/authenticate', access_token_method='GET'), 'button': ' Twitter', + 'profile': None, 'field_map': { 'id': 'user_id', 'username': 'screen_name' - } + }, + 'token_name': 'oauth_token' }, 'github': { 'oauth': dict( @@ -31,11 +33,13 @@ providers = { access_token_url='https://github.com/login/oauth/access_token', authorize_url='https://github.com/login/oauth/authorize'), 'button': ' Github', + 'profile': 'user', 'field_map': { 'id': ['user', 'id'], 'username': ['user', 'login'], 'email': ['user', 'email'] - } + }, + 'token_name': 'access_token' }, 'facebook': { 'oauth': dict( @@ -47,11 +51,13 @@ providers = { authorize_url='https://www.facebook.com/dialog/oauth' ), 'button': ' Facebook', + 'profile': '/me', 'field_map': { 'id': 'id', 'username': 'name', 'email': 'email' - } + }, + 'token_name': 'access_name' }, 'google': { 'oauth': dict( @@ -64,7 +70,14 @@ providers = { access_token_url='https://accounts.google.com/o/oauth2/token', authorize_url='https://accounts.google.com/o/oauth2/auth', ), - 'button': ' Google' + 'button': ' Google', + 'profile': 'userinfo', + 'field_map': { + 'id': 'id', + 'username': 'name', + 'email': 'email' + }, + 'token_name': 'access_token' } } @@ -73,9 +86,10 @@ class User(BaseUser): type = 'oauth' provider = None - def __init__(self, provider, user_id, username, token): + def __init__(self, provider, user_id, username=None, token=None, email=None): self.provider = provider self.username = username + self.email = email self.id = user_id self.token = token self.auth_id = "%s-%s" % (provider, username) @@ -93,7 +107,8 @@ class User(BaseUser): return users.get(user_id) @staticmethod - def auth(provider, resp): + def auth(provider, data, resp): + oauth_token = resp.get(User.get_provider_value(provider, 'token_name')) field_map = providers.get(provider).get('field_map') if not field_map: raise NotImplementedError @@ -111,9 +126,10 @@ class User(BaseUser): fields = {} for k, v in field_map.items(): - fields[k] = get_value(resp, v) + fields[k] = get_value(data, v) - user = User(provider, fields['id'], fields['username'], User.hash_password(resp['oauth_token'])) + user = User(provider, fields['id'], username=fields.get('username'), email=fields.get('email'), + token=User.hash_password(oauth_token)) users[user.auth_id] = user if user: @@ -133,6 +149,14 @@ class User(BaseUser): 'secret'), **providers[provider]['oauth']) + @classmethod + def get_provider_value(cls, provider, key): + return providers.get(provider, {}).get(key) + + @classmethod + def get_token(cls, provider, resp): + return resp.get(cls.get_provider_value(provider, 'token_name')) + def get_id(self): return unicode("%s/%s" % (self.type, self.auth_id)) diff --git a/realms/modules/auth/oauth/views.py b/realms/modules/auth/oauth/views.py index 31fd281..b80f00e 100644 --- a/realms/modules/auth/oauth/views.py +++ b/realms/modules/auth/oauth/views.py @@ -18,7 +18,8 @@ def login(provider): def callback(provider): next_url = request.args.get('next') or url_for(current_app.config['ROOT_ENDPOINT']) try: - resp = User.get_app(provider).authorized_response() + remote_app = User.get_app(provider) + resp = remote_app.authorized_response() if resp is None: flash('You denied the request to sign in.', 'error') flash('Reason: ' + request.args['error_reason'] + @@ -28,11 +29,9 @@ def callback(provider): flash('Access denied: %s' % e.message) return redirect(next_url) - session[provider + '_token'] = ( - resp['oauth_token'], - resp['oauth_token_secret'] - ) + profile = User.get_provider_value(provider, 'profile') + data = remote_app.get(profile) if profile else resp - User.auth(provider, resp) + User.auth(provider, data, resp) return redirect(next_url)