Exemplo n.º 1
0
    def test_some_users(self):
        authorizator = Authorizator(self.db)

        app1_id = self.db.applications.insert({
            'client_id': 'app1',
            'callback_url': 'https://example.com/callback/1',
        })
        app2_id = self.db.applications.insert({
            'client_id': 'app2',
            'callback_url': 'https://example.com/callback/2',
        })

        u1_id = self.db.users.insert({
            'first_name': 'John',
            'last_name': 'Doe',
            'email': '*****@*****.**',
            'authorized_apps': [app1_id, app2_id],
        })
        auths = authorizator.get_user_authorizations({'_id': u1_id})
        self.assertEqual(auths.count(), 0)
        u2_id = self.db.users.insert({
            'first_name': 'John2',
            'last_name': 'Doe2',
            'email': '*****@*****.**',
            'send_passwords_periodically': False,
            'authorized_apps': [app1_id],
        })
        auths = authorizator.get_user_authorizations({'_id': u2_id})
        self.assertEqual(auths.count(), 0)

        sys.argv = ['notused', self.conf_file_path, 'new_authorized_apps_collection']
        sys.stdout = StringIO()
        result = migrate()
        self.assertEqual(result, None)
        stdout = sys.stdout.getvalue()
        stdout = sys.stdout.getvalue()
        expected_output = """Storing authorized app "app1" for user John Doe <*****@*****.**>
Storing authorized app "app2" for user John Doe <*****@*****.**>
Storing authorized app "app1" for user John2 Doe2 <*****@*****.**>
"""
        self.assertEqual(stdout, expected_output)

        user1 = self.db.users.find_one({'_id': u1_id})
        self.assertFalse('authorized_apps' in user1)
        auths = authorizator.get_user_authorizations({'_id': u1_id})
        self.assertEqual(auths.count(), 2)

        user2 = self.db.users.find_one({'_id': u2_id})
        self.assertFalse('authorized_apps' in user2)
        auths = authorizator.get_user_authorizations({'_id': u2_id})
        self.assertEqual(auths.count(), 1)
Exemplo n.º 2
0
    def test_already_authorized_app(self):
        user_id = self._login()
        self._create_client()

        authorizator = Authorizator(self.db)
        auths = authorizator.get_user_authorizations({'_id': user_id})
        self.assertEqual(auths.count(), 0)

        # do an initial authorization
        res = self.testapp.get('/oauth2/endpoints/authorization', {
            'response_type': 'code',
            'client_id': '123456',
            'redirect_uri': 'https://example.com/callback',
        })
        self.assertEqual(res.status, '200 OK')

        res = self.testapp.post('/oauth2/endpoints/authorization', {
            'submit': 'Authorize',
            'response_type': 'code',
            'client_id': '123456',
            'redirect_uri': 'https://example.com/callback',
            'scope': 'read-passwords',
        })
        self.assertEqual(res.status, '302 Found')

        auths = authorizator.get_user_authorizations({'_id': user_id})
        self.assertEqual(auths.count(), 1)

        # Now do a second authorization
        res = self.testapp.get('/oauth2/endpoints/authorization', {
            'response_type': 'code',
            'client_id': '123456',
            'redirect_uri': 'https://example.com/callback',
        })
        self.assertEqual(res.status, '302 Found')

        auths = authorizator.get_user_authorizations({'_id': user_id})
        self.assertEqual(auths.count(), 1)

        grants = self.db.authorization_codes.find({
            'client_id': '123456',
            'user': user_id,
        })

        # There are two grants now
        self.assertEqual(grants.count(), 2)
        code = grants[1]['code']
        location = 'https://example.com/callback?code=%s' % code
        self.assertEqual(res.location, location)
Exemplo n.º 3
0
    def test_non_authorized_app_yet(self):
        user_id = self._login()
        self._create_client()

        authorizator = Authorizator(self.db)
        auths = authorizator.get_user_authorizations({'_id': user_id})
        self.assertEqual(auths.count(), 0)

        res = self.testapp.get('/oauth2/endpoints/authorization', {
            'response_type': 'code',
            'client_id': '123456',
            'redirect_uri': 'https://example.com/callback',
        })
        self.assertEqual(res.status, '200 OK')
        res.mustcontain('Authorize Application')
        res.mustcontain('Permissions:')
        res.mustcontain('Access your passwords')
        res.mustcontain('Allow access')
        res.mustcontain('No, thanks')
        res.mustcontain('You can revoke this authorization in the future.')

        res = self.testapp.post('/oauth2/endpoints/authorization', {
            'submit': 'Authorize',
            'response_type': 'code',
            'client_id': '123456',
            'redirect_uri': 'https://example.com/callback',
            'scope': 'read-passwords',
        })
        self.assertEqual(res.status, '302 Found')

        # Check that the app is authorized now
        auths = authorizator.get_user_authorizations({'_id': user_id})
        self.assertEqual(auths.count(), 1)
        auth = auths[0]
        self.assertEqual(auth['redirect_uri'], 'https://example.com/callback')
        self.assertEqual(auth['response_type'], 'code')
        self.assertEqual(auth['client_id'], '123456')
        self.assertEqual(auth['scope'], 'read-passwords')
        self.assertEqual(auth['user'], user_id)

        # Check the right redirect url
        grant = self.db.authorization_codes.find_one({
            'client_id': '123456',
            'user': user_id,
        })
        self.assertNotEqual(grant, None)
        code = grant['code']
        location = 'https://example.com/callback?code=%s' % code
        self.assertEqual(res.location, location)
Exemplo n.º 4
0
def merge_users(db, user1, user2):
    # move all passwords of user2 to user1
    db.passwords.update({'owner': user2['_id']}, {
        '$set': {
            'owner': user1['_id'],
        },
    }, multi=True)

    # move authorized_apps from user2 to user1
    authorizator = Authorizator(db)
    for auth in authorizator.get_user_authorizations(user2):
        credentials = {
            'client_id': auth['client_id'],
            'user': user1,
            'redirect_uri': auth['redirect_uri'],
            'response_type': auth['response_type'],
        }
        scopes = auth['scope'].split(' ')
        authorizator.store_user_authorization(scopes, credentials)
    authorizator.remove_all_user_authorizations(user2)

    updates = {}
    # copy the providers
    for provider in get_available_providers():
        key = provider + '_id'
        if key in user2 and key not in user1:
            sets = updates.setdefault('$set', {})
            sets[key] = user2[key]

    db.users.update({'_id': user1['_id']}, updates)

    # remove user2
    db.users.remove(user2['_id'])
class AuthorizatorTests(testing.TestCase):

    def setUp(self):
        super(AuthorizatorTests, self).setUp()
        self.authorizator = Authorizator(self.db)

    def test_is_app_authorized_no_authorized_apps(self):
        self.assertFalse(self.authorizator.is_app_authorized([
            'scope1', 'scope2',
        ], {
            'client_id': 1,
            'user': {'_id': 1},
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
        }))

    def test_is_app_authorized_different_client_id(self):
        self.db.authorized_apps.insert({
            'client_id': 1,
            'user': 1,
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
            'scope': 'scope1 scope2',
        })
        self.assertFalse(self.authorizator.is_app_authorized([
            'scope1', 'scope2',
        ], {
            'client_id': 2,
            'user': {'_id': 1},
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
        }))

    def test_is_app_authorized_different_user(self):
        self.db.authorized_apps.insert({
            'client_id': 1,
            'user': 1,
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
            'scope': 'scope1 scope2',
        })
        self.assertFalse(self.authorizator.is_app_authorized([
            'scope1', 'scope2',
        ], {
            'client_id': 1,
            'user': {'_id': 2},
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
        }))

    def test_is_app_authorized_different_redirect_uri(self):
        self.db.authorized_apps.insert({
            'client_id': 1,
            'user': 1,
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
            'scope': 'scope1 scope2',
        })
        self.assertFalse(self.authorizator.is_app_authorized([
            'scope1', 'scope2',
        ], {
            'client_id': 1,
            'user': {'_id': 1},
            'redirect_uri': 'http://example.com/callback-new',
            'response_type': 'code',
        }))

    def test_is_app_authorized_different_response_type(self):
        self.db.authorized_apps.insert({
            'client_id': 1,
            'user': 1,
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
            'scope': 'scope1 scope2',
        })
        self.assertFalse(self.authorizator.is_app_authorized([
            'scope1', 'scope2',
        ], {
            'client_id': 1,
            'user': {'_id': 1},
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'token',
        }))

    def test_is_app_authorized_different_scopes(self):
        self.db.authorized_apps.insert({
            'client_id': 1,
            'user': 1,
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
            'scope': 'scope1 scope2',
        })
        self.assertFalse(self.authorizator.is_app_authorized([
            'scope1', 'scope2', 'scope3',
        ], {
            'client_id': 1,
            'user': {'_id': 1},
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
        }))

    def test_is_app_authorized_everything_equal(self):
        self.db.authorized_apps.insert({
            'client_id': 1,
            'user': 1,
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
            'scope': 'scope1 scope2',
        })
        self.assertTrue(self.authorizator.is_app_authorized([
            'scope1', 'scope2',
        ], {
            'client_id': 1,
            'user': {'_id': 1},
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
        }))

    def test_store_user_authorization_no_previous_authorization(self):
        self.assertEqual(self.db.authorized_apps.count(), 0)
        self.authorizator.store_user_authorization([
            'scope1', 'scope2',
        ], {
            'client_id': 1,
            'user': {'_id': 1},
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
        })
        self.assertEqual(self.db.authorized_apps.count(), 1)

    def test_store_user_authorization_previous_authorization(self):
        self.assertEqual(self.db.authorized_apps.count(), 0)
        self.authorizator.store_user_authorization([
            'scope1', 'scope2',
        ], {
            'client_id': 1,
            'user': {'_id': 1},
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
        })
        self.assertEqual(self.db.authorized_apps.count(), 1)

        # Store the same authorization again
        self.authorizator.store_user_authorization([
            'scope1', 'scope2',
        ], {
            'client_id': 1,
            'user': {'_id': 1},
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
        })
        # still only one record
        self.assertEqual(self.db.authorized_apps.count(), 1)

    def test_get_user_authorizations_empty(self):
        auths = self.authorizator.get_user_authorizations({'_id': 1})
        self.assertEqual(auths.count(), 0)

    def test_get_user_authorizations_one_authorization(self):
        self.authorizator.store_user_authorization([
            'scope1', 'scope2',
        ], {
            'client_id': 1,
            'user': {'_id': 1},
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
        })
        auths = self.authorizator.get_user_authorizations({'_id': 1})
        self.assertEqual(auths.count(), 1)
        self.assertEqual(auths[0]['client_id'], 1)
        self.assertEqual(auths[0]['redirect_uri'], 'http://example.com/callback')
        self.assertEqual(auths[0]['response_type'], 'code')
        self.assertEqual(auths[0]['scope'], 'scope1 scope2')

    def test_get_user_authorizations_two_authorization(self):
        self.authorizator.store_user_authorization([
            'scope1', 'scope2',
        ], {
            'client_id': 1,
            'user': {'_id': 1},
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
        })
        self.authorizator.store_user_authorization([
            'scope1', 'scope2',
        ], {
            'client_id': 2,
            'user': {'_id': 1},
            'redirect_uri': 'http://example.com/callback2',
            'response_type': 'code',
        })
        self.authorizator.store_user_authorization([
            'scope1', 'scope2',
        ], {
            'client_id': 2,
            'user': {'_id': 2},
            'redirect_uri': 'http://example.com/callback2',
            'response_type': 'code',
        })
        auths = self.authorizator.get_user_authorizations({'_id': 1})
        self.assertEqual(auths.count(), 2)
        self.assertEqual(auths[0]['client_id'], 1)
        self.assertEqual(auths[0]['redirect_uri'], 'http://example.com/callback')
        self.assertEqual(auths[0]['response_type'], 'code')
        self.assertEqual(auths[0]['scope'], 'scope1 scope2')

        self.assertEqual(auths[1]['client_id'], 2)
        self.assertEqual(auths[1]['redirect_uri'], 'http://example.com/callback2')
        self.assertEqual(auths[1]['response_type'], 'code')
        self.assertEqual(auths[1]['scope'], 'scope1 scope2')

    def test_remove_user_authorization(self):
        auths = self.authorizator.get_user_authorizations({'_id': 1})
        self.assertEqual(auths.count(), 0)
        self.authorizator.store_user_authorization([
            'scope1', 'scope2',
        ], {
            'client_id': 1,
            'user': {'_id': 1},
            'redirect_uri': 'http://example.com/callback',
            'response_type': 'code',
        })
        auths = self.authorizator.get_user_authorizations({'_id': 1})
        self.assertEqual(auths.count(), 1)
        self.authorizator.remove_user_authorization({'_id': 1}, 1)
        auths = self.authorizator.get_user_authorizations({'_id': 1})
        self.assertEqual(auths.count(), 0)

    def test_remove_all_user_authorizations(self):
        auths = self.authorizator.get_user_authorizations({'_id': 1})
        self.assertEqual(auths.count(), 0)
        self.authorizator.store_user_authorization([
            'scope1', 'scope2',
        ], {
            'client_id': 1,
            'user': {'_id': 1},
            'redirect_uri': 'http://example.com/callback/1',
            'response_type': 'code',
        })
        self.authorizator.store_user_authorization([
            'scope1', 'scope2',
        ], {
            'client_id': 2,
            'user': {'_id': 1},
            'redirect_uri': 'http://example.com/callback/2',
            'response_type': 'code',
        })
        auths = self.authorizator.get_user_authorizations({'_id': 1})
        self.assertEqual(auths.count(), 2)
        self.authorizator.remove_all_user_authorizations({'_id': 1})
        auths = self.authorizator.get_user_authorizations({'_id': 1})
        self.assertEqual(auths.count(), 0)
Exemplo n.º 6
0
    def test_identity_providers(self):
        # this view required authentication
        res = self.testapp.get('/identity-providers')
        self.assertEqual(res.status, '200 OK')
        res.mustcontain('Log in')

        authorizator = Authorizator(self.db)

        # Log in
        user1_id = self.db.users.insert({
            'twitter_id': 'twitter1',
            'screen_name': 'John Doe',
            'first_name': 'John',
            'last_name': 'Doe',
            'email': '*****@*****.**',
            'email_verified': True,
        })
        authorizator.store_user_authorization(['scope1'], {
            'client_id': 'app1',
            'user': {'_id': user1_id},
            'redirect_uri': 'http://example.com/callback/1',
            'response_type': 'code',
        })
        authorizator.store_user_authorization(['scope1'], {
            'client_id': 'app2',
            'user': {'_id': user1_id},
            'redirect_uri': 'http://example.com/callback/2',
            'response_type': 'code',
        })
        self.testapp.get('/__login/' + str(user1_id))
        self.db.passwords.insert({
            'owner': user1_id,
            'password': '******',
        })

        # one account is not enough for merging
        res = self.testapp.post('/identity-providers', {
            'submit': 'Merge my accounts',
        }, status=400)
        self.assertEqual(res.status, '400 Bad Request')
        res.mustcontain('You do not have enough accounts to merge')

        # so let's create another account with the same email
        user2_id = self.db.users.insert({
            'google_id': 'google1',
            'screen_name': 'John Doe',
            'first_name': 'John',
            'last_name': 'Doe',
            'email': '*****@*****.**',
            'email_verified': True,
        })
        authorizator.store_user_authorization(['scope1'], {
            'client_id': 'app2',
            'user': {'_id': user2_id},
            'redirect_uri': 'http://example.com/callback/2',
            'response_type': 'code',
        })
        authorizator.store_user_authorization(['scope1'], {
            'client_id': 'app3',
            'user': {'_id': user2_id},
            'redirect_uri': 'http://example.com/callback/3',
            'response_type': 'code',
        })
        self.db.passwords.insert({
            'owner': user2_id,
            'password': '******',
        })

        # now the profile view should say I can merge my accounts
        res = self.testapp.get('/identity-providers')
        self.assertEqual(res.status, '200 OK')
        res.mustcontain('You are registered with the following accounts',
                        'Merge my accounts',
                        'If you merge your accounts')

        # if only one account is selected or fake accounts
        # are selected nothing is merged
        res = self.testapp.post('/identity-providers', {
            'account-%s' % str(user1_id): 'on',
            'account-000000000000000000000000': 'on',
            'submit': 'Merge my accounts',
        }, status=302)
        self.assertEqual(res.status, '302 Found')
        self.assertEqual(res.location, 'http://localhost/identity-providers')
        self.assertEqual(2, self.db.users.count())
        self.assertEqual(1, self.db.passwords.find(
            {'owner': user1_id}).count())
        self.assertEqual(1, self.db.passwords.find(
            {'owner': user2_id}).count())

        # let's merge them
        res = self.testapp.post('/identity-providers', {
            'account-%s' % str(user1_id): 'on',
            'account-%s' % str(user2_id): 'on',
            'submit': 'Merge my accounts',
        }, status=302)
        self.assertEqual(res.status, '302 Found')
        self.assertEqual(res.location, 'http://localhost/identity-providers')

        # the accounts have been merged
        self.assertEqual(1, self.db.users.count())
        user1_refreshed = self.db.users.find_one({'_id': user1_id})
        self.assertEqual(user1_refreshed['google_id'], 'google1')
        auths = authorizator.get_user_authorizations(user1_refreshed)
        for real, expected in zip(auths, ['app1', 'app2', 'app3']):
            self.assertEqual(real['client_id'], expected)

        user2_refreshed = self.db.users.find_one({'_id': user2_id})
        self.assertEqual(user2_refreshed, None)

        self.assertEqual(2, self.db.passwords.find(
            {'owner': user1_id}).count())