def test_provider_not_configured(self): from pillar.auth.oauth import OAuthSignIn, ProviderConfigurationMissing # Before we start this test, the providers dict # may not be initialized yet. self.assertIsNone(OAuthSignIn._providers) del self.app.config['OAUTH_CREDENTIALS']['blender-id'] with self.assertRaises(ProviderConfigurationMissing): OAuthSignIn.get_provider('blender-id')
def test_providers_init(self): from pillar.auth.oauth import OAuthSignIn, BlenderIdSignIn oauth_provider = OAuthSignIn.get_provider('blender-id') self.assertIsInstance(oauth_provider, BlenderIdSignIn) self.assertEqual(oauth_provider.service.base_url, 'http://id.local:8001/api/')
def test_provider_callback_happy(self): from pillar.auth.oauth import OAuthSignIn responses.add(responses.POST, 'http://id.local:8001/oauth/token', json={'access_token': 'successful-token'}, status=200) responses.add(responses.GET, 'http://id.local:8001/api/user', json={ 'id': '7', 'email': '*****@*****.**' }, status=200) oauth_provider = OAuthSignIn.get_provider('blender-id') with self.app.test_request_context( '/oauth/blender-id/authorized?code=123'): # We override the call to blender-id cb = oauth_provider.callback() self.assertEqual(cb.id, '7') self.assertEqual(cb.email, '*****@*****.**') self.assertEqual(cb.access_token, 'successful-token') self.assertEqual(cb.scopes, ['email', 'badge'])
def oauth_callback(provider): if current_user.is_authenticated: return redirect(url_for('main.homepage')) oauth = OAuthSignIn.get_provider(provider) try: oauth_user = oauth.callback() except OAuthCodeNotProvided as e: log.error(e) raise wz_exceptions.Forbidden() if oauth_user.id is None: log.debug('Authentication failed for user with {}'.format(provider)) return redirect(url_for('main.homepage')) # Find or create user user_info = {'id': oauth_user.id, 'email': oauth_user.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_authenticated: # Check with Blender ID to update certain user roles. update_subscription() next_after_login = session.pop('next_after_login', None) if next_after_login: log.debug('Redirecting user to %s', next_after_login) return redirect(next_after_login) return redirect(url_for('main.homepage'))
def test_provider_callback_missing_code(self): from pillar.auth.oauth import OAuthSignIn, OAuthCodeNotProvided oauth_provider = OAuthSignIn.get_provider('blender-id') # Check exception when the 'code' argument is not returned with self.assertRaises(OAuthCodeNotProvided): with self.app.test_request_context('/oauth/blender-id/authorized'): oauth_provider.callback()
def test_provider_authorize(self): from pillar.auth.oauth import OAuthSignIn from urllib.parse import urlparse, parse_qsl oauth_provider = OAuthSignIn.get_provider('blender-id') r = oauth_provider.authorize() self.assertEqual(r.status_code, 302) url_parts = list(urlparse(r.location)) # Get the query arguments as a dict query = dict(parse_qsl(url_parts[4])) self.assertEqual(query['client_id'], oauth_provider.service.client_id)
def oauth_callback(provider): import datetime from pillar.api.utils.authentication import store_token from pillar.api.utils import utcnow next_after_login = session.pop('next_after_login', None) or url_for('main.homepage') if current_user.is_authenticated: log.debug('Redirecting user to %s', next_after_login) return redirect(next_after_login) oauth = OAuthSignIn.get_provider(provider) try: oauth_user = oauth.callback() except OAuthCodeNotProvided as e: log.error(e) raise wz_exceptions.Forbidden() if oauth_user.id is None: log.debug('Authentication failed for user with {}'.format(provider)) return redirect(next_after_login) # Find or create user user_info = { 'id': oauth_user.id, 'email': oauth_user.email, 'full_name': '' } db_user = find_user_in_db(user_info, provider=provider) db_id, status = upsert_user(db_user) # TODO(Sybren): If the user doesn't have any badges, but the access token # does have 'badge' scope, we should fetch the badges in the background. if oauth_user.access_token: # TODO(Sybren): make nr of days configurable, or get from OAuthSignIn subclass. token_expiry = utcnow() + datetime.timedelta(days=15) token = store_token(db_id, oauth_user.access_token, token_expiry, oauth_scopes=oauth_user.scopes) else: 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_authenticated: # Check with Blender ID to update certain user roles. update_subscription() log.debug('Redirecting user to %s', next_after_login) return redirect(next_after_login)
def oauth_authorize(provider): if not current_user.is_anonymous: return redirect(url_for('main.homepage')) try: oauth = OAuthSignIn.get_provider(provider) except ProviderConfigurationMissing as e: log.error('Login with OAuth failed: %s', e) raise wz_exceptions.NotFound() except ProviderNotImplemented as e: log.error('Login with OAuth failed: %s', e) raise wz_exceptions.NotFound() return oauth.authorize()
def oauth_authorize(provider): if current_user.is_authenticated: next_after_login = session.pop('next_after_login', None) or url_for('main.homepage') log.debug('Redirecting user to %s', next_after_login) return redirect(next_after_login) try: oauth = OAuthSignIn.get_provider(provider) except ProviderConfigurationMissing as e: log.error('Login with OAuth failed: %s', e) raise wz_exceptions.NotFound() except ProviderNotImplemented as e: log.error('Login with OAuth failed: %s', e) raise wz_exceptions.NotFound() return oauth.authorize()
def test_provider_not_implemented(self): from pillar.auth.oauth import OAuthSignIn, ProviderNotImplemented with self.assertRaises(ProviderNotImplemented): OAuthSignIn.get_provider('jonny')