Remove Flask-OAuthlib and oauth_blender_id from Pillar
We switch completely to a rauth-based approach, allowing multiple providers for authentication.
This commit is contained in:
parent
6e9a539d61
commit
6b3e523036
@ -115,7 +115,6 @@ class PillarServer(Eve):
|
||||
|
||||
# Configure authentication
|
||||
self.login_manager = auth.config_login_manager(self)
|
||||
self.oauth_blender_id = auth.config_oauth_login(self)
|
||||
|
||||
self._config_caching()
|
||||
|
||||
|
@ -9,7 +9,8 @@ import logging
|
||||
|
||||
import requests
|
||||
from bson import tz_util
|
||||
from flask import Blueprint, request, current_app, jsonify
|
||||
from rauth import OAuth2Session
|
||||
from flask import Blueprint, request, current_app, jsonify, session
|
||||
from requests.adapters import HTTPAdapter
|
||||
|
||||
from pillar.api.utils import authentication
|
||||
@ -175,23 +176,26 @@ def fetch_blenderid_user() -> dict:
|
||||
|
||||
bid_url = '%s/api/user' % blender_id_endpoint()
|
||||
log.debug('Fetching user info from %s', bid_url)
|
||||
|
||||
try:
|
||||
bid_resp = current_app.oauth_blender_id.get(bid_url)
|
||||
client_id = current_app.config['OAUTH_CREDENTIALS']['blender-id']['id']
|
||||
client_secret = current_app.config['OAUTH_CREDENTIALS']['blender-id']['secret']
|
||||
oauth_session = OAuth2Session(
|
||||
client_id, client_secret, access_token=session['blender_id_oauth_token'])
|
||||
bid_resp = oauth_session.get(bid_url)
|
||||
except httplib2.HttpLib2Error:
|
||||
log.exception('Error getting %s from BlenderID', bid_url)
|
||||
return {}
|
||||
|
||||
if bid_resp.status != 200:
|
||||
log.warning('Error %i from BlenderID %s: %s', bid_resp.status, bid_url, bid_resp.data)
|
||||
if bid_resp.status_code != 200:
|
||||
log.warning('Error %i from BlenderID %s: %s', bid_resp.status_code, bid_url, bid_resp.data)
|
||||
return {}
|
||||
|
||||
if not bid_resp.data:
|
||||
if not bid_resp.json():
|
||||
log.warning('Empty data returned from BlenderID %s', bid_url)
|
||||
return {}
|
||||
|
||||
log.debug('BlenderID returned %s', bid_resp.data)
|
||||
return bid_resp.data
|
||||
log.debug('BlenderID returned %s', bid_resp.json())
|
||||
return bid_resp.json()
|
||||
|
||||
|
||||
def setup_app(app, url_prefix):
|
||||
|
@ -6,7 +6,6 @@ import typing
|
||||
|
||||
from flask import session, g
|
||||
import flask_login
|
||||
import flask_oauthlib.client
|
||||
from werkzeug.local import LocalProxy
|
||||
|
||||
from pillar import current_app
|
||||
@ -222,35 +221,6 @@ def get_blender_id_oauth_token():
|
||||
return None
|
||||
|
||||
|
||||
def config_oauth_login(app):
|
||||
config = app.config
|
||||
if not config.get('SOCIAL_BLENDER_ID'):
|
||||
log.info('OAuth Blender-ID login not set up, no app config SOCIAL_BLENDER_ID.')
|
||||
return None
|
||||
if not config.get('BLENDER_ID_OAUTH_URL'):
|
||||
log.error('Unable to use Blender ID, missing configuration BLENDER_ID_OAUTH_URL.')
|
||||
return None
|
||||
|
||||
oauth = flask_oauthlib.client.OAuth(app)
|
||||
social_blender_id = config.get('SOCIAL_BLENDER_ID')
|
||||
|
||||
oauth_blender_id = oauth.remote_app(
|
||||
'blender_id',
|
||||
consumer_key=social_blender_id['app_id'],
|
||||
consumer_secret=social_blender_id['app_secret'],
|
||||
request_token_params={'scope': 'email'},
|
||||
base_url=config['BLENDER_ID_OAUTH_URL'],
|
||||
request_token_url=None,
|
||||
access_token_url=config['BLENDER_ID_BASE_ACCESS_TOKEN_URL'],
|
||||
authorize_url=config['BLENDER_ID_AUTHORIZE_URL']
|
||||
)
|
||||
|
||||
oauth_blender_id.tokengetter(get_blender_id_oauth_token)
|
||||
log.info('OAuth Blender-ID login setup as %s', social_blender_id['app_id'])
|
||||
|
||||
return oauth_blender_id
|
||||
|
||||
|
||||
def _get_current_user() -> UserClass:
|
||||
"""Returns the current user as a UserClass instance.
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import json
|
||||
|
||||
from rauth import OAuth2Service
|
||||
from flask import current_app, url_for, request, redirect
|
||||
from flask import current_app, url_for, request, redirect, session
|
||||
|
||||
|
||||
class OAuthSignIn(object):
|
||||
class OAuthSignIn:
|
||||
providers = None
|
||||
|
||||
def __init__(self, provider_name):
|
||||
@ -27,6 +27,7 @@ class OAuthSignIn(object):
|
||||
def get_provider(cls, provider_name):
|
||||
if cls.providers is None:
|
||||
cls.providers = {}
|
||||
# TODO convert to the new __init_subclass__
|
||||
for provider_class in cls.__subclasses__():
|
||||
provider = provider_class()
|
||||
cls.providers[provider.provider_name] = provider
|
||||
@ -35,7 +36,7 @@ class OAuthSignIn(object):
|
||||
|
||||
class BlenderIdSignIn(OAuthSignIn):
|
||||
def __init__(self):
|
||||
super(BlenderIdSignIn, self).__init__('blender-id')
|
||||
super().__init__('blender-id')
|
||||
|
||||
base_url = current_app.config['OAUTH_CREDENTIALS']['blender-id'].get(
|
||||
'base_url', 'https://www.blender.org/id/')
|
||||
@ -73,6 +74,7 @@ class BlenderIdSignIn(OAuthSignIn):
|
||||
|
||||
me = oauth_session.get('user').json()
|
||||
# TODO handle case when user chooses not to disclose en email
|
||||
session['blender_id_oauth_token'] = oauth_session.access_token
|
||||
return (
|
||||
me['id'],
|
||||
me.get('email'),
|
||||
@ -82,7 +84,7 @@ class BlenderIdSignIn(OAuthSignIn):
|
||||
|
||||
class FacebookSignIn(OAuthSignIn):
|
||||
def __init__(self):
|
||||
super(FacebookSignIn, self).__init__('facebook')
|
||||
super().__init__('facebook')
|
||||
self.service = OAuth2Service(
|
||||
name='facebook',
|
||||
client_id=self.consumer_id,
|
||||
@ -122,7 +124,7 @@ class FacebookSignIn(OAuthSignIn):
|
||||
|
||||
class GoogleSignIn(OAuthSignIn):
|
||||
def __init__(self):
|
||||
super(GoogleSignIn, self).__init__('google')
|
||||
super().__init__('google')
|
||||
self.service = OAuth2Service(
|
||||
name='google',
|
||||
client_id=self.consumer_id,
|
||||
|
@ -1,12 +1,10 @@
|
||||
import json
|
||||
import logging
|
||||
import requests
|
||||
|
||||
from werkzeug import exceptions as wz_exceptions
|
||||
from flask import abort, Blueprint, current_app, flash, redirect, render_template, request, session,\
|
||||
url_for
|
||||
from flask_login import login_required, logout_user, current_user
|
||||
from flask_oauthlib.client import OAuthException
|
||||
|
||||
from pillarsdk import exceptions as sdk_exceptions
|
||||
from pillarsdk.users import User
|
||||
@ -16,6 +14,7 @@ import pillar.auth
|
||||
from pillar.web import system_util
|
||||
from pillar.api.local_auth import generate_and_store_token, get_local_user
|
||||
from pillar.api.utils.authentication import find_user_in_db, upsert_user
|
||||
from pillar.api.blender_cloud.subscription import update_subscription
|
||||
from pillar.auth.oauth import OAuthSignIn
|
||||
from . import forms
|
||||
|
||||
@ -45,24 +44,20 @@ def oauth_callback(provider):
|
||||
if social_id is None:
|
||||
log.debug('Authentication failed for user with {}'.format(provider))
|
||||
return redirect(url_for('main.homepage'))
|
||||
# If login from Blender ID we use the token to create the user
|
||||
if provider == 'blender-id':
|
||||
session['blender_id_oauth_token'] = (access_token, '')
|
||||
pillar.auth.login_user(access_token)
|
||||
|
||||
if current_user is not None:
|
||||
# Check with the store for user roles. If the user has an active
|
||||
# subscription, we apply the 'subscriber' role
|
||||
api = system_util.pillar_api(token=access_token)
|
||||
api.get('bcloud/update-subscription')
|
||||
else:
|
||||
# Find or create user
|
||||
user_info = {'id': social_id, 'email': email, 'full_name': ''}
|
||||
db_user = find_user_in_db(user_info, provider=provider)
|
||||
db_id, status = upsert_user(db_user)
|
||||
token = generate_and_store_token(db_id)
|
||||
# Login user
|
||||
pillar.auth.login_user(token['token'])
|
||||
# Find or create user
|
||||
user_info = {'id': social_id, 'email': email, 'full_name': ''}
|
||||
db_user = find_user_in_db(user_info, provider=provider)
|
||||
db_id, status = upsert_user(db_user)
|
||||
token = generate_and_store_token(db_id)
|
||||
|
||||
# Login user
|
||||
pillar.auth.login_user(token['token'], load_from_db=True)
|
||||
|
||||
if provider == 'blender-id' and current_user is not None:
|
||||
# Check with the store for user roles. If the user has an active subscription, we apply
|
||||
# the 'subscriber' role
|
||||
update_subscription()
|
||||
|
||||
next_after_login = session.pop('next_after_login', None)
|
||||
if next_after_login:
|
||||
|
@ -14,7 +14,6 @@ Flask==0.12.2
|
||||
Flask-Cache==0.13.1
|
||||
Flask-Script==2.0.5
|
||||
Flask-Login==0.3.2
|
||||
Flask-OAuthlib==0.9.3
|
||||
Flask-WTF==0.12
|
||||
gcloud==0.12.0
|
||||
google-apitools==0.4.11
|
||||
@ -24,6 +23,7 @@ ndg-httpsclient==0.4.0
|
||||
Pillow==4.1.1
|
||||
pycrypto==2.6.1
|
||||
python-dateutil==2.5.3
|
||||
rauth==0.7.3
|
||||
redis==2.10.5
|
||||
WebOb==1.5.0
|
||||
wheel==0.29.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user