Example #1
0
    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')
Example #2
0
    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/')
Example #3
0
    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'])
Example #4
0
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'))
Example #5
0
    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()
Example #6
0
 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)
Example #7
0
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)
Example #8
0
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()
Example #9
0
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()
Example #10
0
    def test_provider_not_implemented(self):
        from pillar.auth.oauth import OAuthSignIn, ProviderNotImplemented

        with self.assertRaises(ProviderNotImplemented):
            OAuthSignIn.get_provider('jonny')