def test_copy_db(self):
        authed_client = auth_context.client
        if is_mongos(authed_client):
            raise SkipTest("SERVER-6427")

        c = MongoClient(host, port)

        authed_client.admin.add_user("admin", "password")
        c.admin.authenticate("admin", "password")
        c.drop_database("pymongo_test")
        c.drop_database("pymongo_test1")
        c.pymongo_test.test.insert({"foo": "bar"})

        try:
            c.pymongo_test.add_user("mike", "password")

            self.assertRaises(OperationFailure, c.copy_database,
                              "pymongo_test", "pymongo_test1",
                              username="******", password="******")
            self.assertFalse("pymongo_test1" in c.database_names())

            self.assertRaises(OperationFailure, c.copy_database,
                              "pymongo_test", "pymongo_test1",
                              username="******", password="******")
            self.assertFalse("pymongo_test1" in c.database_names())

            c.copy_database("pymongo_test", "pymongo_test1",
                            username="******", password="******")
            self.assertTrue("pymongo_test1" in c.database_names())
            self.assertEqual("bar", c.pymongo_test1.test.find_one()["foo"])
        finally:
            # Cleanup
            remove_all_users(c.pymongo_test)
            c.admin.remove_user("admin")
            c.disconnect()
    def test_make_user_readonly(self):
        admin = self.client.admin
        auth_context.client.admin.add_user('admin', 'pw')
        admin.authenticate('admin', 'pw')

        db = self.client.pymongo_test

        try:
            # Make a read-write user.
            db.add_user('jesse', 'pw')
            admin.logout()

            # Check that we're read-write by default.
            db.authenticate('jesse', 'pw')
            db.collection.insert({})
            db.logout()

            # Make the user read-only.
            admin.authenticate('admin', 'pw')
            db.add_user('jesse', 'pw', read_only=True)
            admin.logout()

            db.authenticate('jesse', 'pw')
            self.assertRaises(OperationFailure, db.collection.insert, {})
        finally:
            # Cleanup
            admin.authenticate('admin', 'pw')
            remove_all_users(db)
            admin.remove_user("admin")
            admin.logout()
    def test_authenticate_and_request(self):
        if (is_mongos(self.client) and not
            version.at_least(self.client, (2, 0, 0))):
            raise SkipTest("Auth with sharding requires MongoDB >= 2.0.0")

        # Database.authenticate() needs to be in a request - check that it
        # always runs in a request, and that it restores the request state
        # (in or not in a request) properly when it's finished.
        self.assertFalse(self.client.auto_start_request)
        db = self.client.pymongo_test
        remove_all_users(db)
        db.add_user("mike", "password",
                    roles=["userAdmin", "dbAdmin", "readWrite"])
        self.assertFalse(self.client.in_request())
        self.assertTrue(db.authenticate("mike", "password"))
        self.assertFalse(self.client.in_request())

        request_cx = get_client(auto_start_request=True)
        request_db = request_cx.pymongo_test
        self.assertTrue(request_cx.in_request())
        self.assertTrue(request_db.authenticate("mike", "password"))
        self.assertTrue(request_cx.in_request())

        # just make sure there are no exceptions here
        db.remove_user("mike")
        db.logout()
        request_db.logout()
    def test_authenticate_and_request(self):
        if (is_mongos(self.client) and not
            version.at_least(self.client, (2, 0, 0))):
            raise SkipTest("Auth with sharding requires MongoDB >= 2.0.0")

        # Database.authenticate() needs to be in a request - check that it
        # always runs in a request, and that it restores the request state
        # (in or not in a request) properly when it's finished.
        self.assertFalse(self.client.auto_start_request)
        db = self.client.pymongo_test
        remove_all_users(db)
        db.add_user("mike", "password",
                    roles=["userAdmin", "dbAdmin", "readWrite"])
        self.assertFalse(self.client.in_request())
        self.assertTrue(db.authenticate("mike", "password"))
        self.assertFalse(self.client.in_request())

        request_cx = get_client(auto_start_request=True)
        request_db = request_cx.pymongo_test
        self.assertTrue(request_cx.in_request())
        self.assertTrue(request_db.authenticate("mike", "password"))
        self.assertTrue(request_cx.in_request())

        # just make sure there are no exceptions here
        db.remove_user("mike")
        db.logout()
        request_db.logout()
    def test_auth_network_error(self):
        # Make sure there's no semaphore leak if we get a network error
        # when authenticating a new socket with cached credentials.
        auth_client = self._get_client()
        if not server_started_with_auth(auth_client):
            raise SkipTest('Authentication is not enabled on server')

        auth_client.admin.add_user('admin', 'password')
        auth_client.admin.authenticate('admin', 'password')
        try:
            # Get a client with one socket so we detect if it's leaked.
            c = self._get_client(max_pool_size=1, waitQueueTimeoutMS=1)

            # Simulate an authenticate() call on a different socket.
            credentials = auth._build_credentials_tuple(
                'MONGODB-CR', 'admin', unicode('admin'), unicode('password'),
                {})

            c._cache_credentials('test', credentials, connect=False)

            # Cause a network error on the actual socket.
            pool = get_pool(c)
            socket_info = one(pool.sockets)
            socket_info.sock.close()

            # In __check_auth, the client authenticates its socket with the
            # new credential, but gets a socket.error. Should be reraised as
            # AutoReconnect.
            self.assertRaises(AutoReconnect, c.test.collection.find_one)

            # No semaphore leak, the pool is allowed to make a new socket.
            c.test.collection.find_one()
        finally:
            remove_all_users(auth_client.admin)
    def test_authenticate_and_safe(self):
        if (is_mongos(self.client) and not
            version.at_least(self.client, (2, 0, 0))):
            raise SkipTest("Auth with sharding requires MongoDB >= 2.0.0")
        db = self.client.auth_test
        remove_all_users(db)

        db.add_user("bernie", "password",
                    roles=["userAdmin", "dbAdmin", "readWrite"])
        db.authenticate("bernie", "password")

        db.test.remove({})
        self.assertTrue(db.test.insert({"bim": "baz"}))
        self.assertEqual(1, db.test.count())

        self.assertEqual(1,
                         db.test.update({"bim": "baz"},
                                        {"$set": {"bim": "bar"}}).get('n'))

        self.assertEqual(1,
                         db.test.remove({}).get('n'))

        self.assertEqual(0, db.test.count())
        db.remove_user("bernie")
        db.logout()
Exemple #7
0
    def test_mongodb_x509_auth(self):
        # Expects the server to be running with the server.pem, ca.pem
        # and crl.pem provided in mongodb and the server tests as well as
        # --auth
        #
        #   --sslPEMKeyFile=jstests/libs/server.pem
        #   --sslCAFile=jstests/libs/ca.pem
        #   --sslCRLFile=jstests/libs/crl.pem
        #   --auth
        if not CERT_SSL:
            raise SkipTest("No mongod available over SSL with certs")

        client = MongoClient(host, port, ssl=True, ssl_certfile=CLIENT_PEM)
        if not version.at_least(client, (2, 5, 3, -1)):
            raise SkipTest("MONGODB-X509 tests require MongoDB 2.5.3 or newer")
        if not server_started_with_auth(client):
            raise SkipTest('Authentication is not enabled on server')
        # Give admin all necessary privileges.
        client['$external'].add_user(MONGODB_X509_USERNAME, roles=[
            {'role': 'readWriteAnyDatabase', 'db': 'admin'},
            {'role': 'userAdminAnyDatabase', 'db': 'admin'}])
        coll = client.pymongo_test.test
        self.assertRaises(OperationFailure, coll.count)
        self.assertTrue(client.admin.authenticate(MONGODB_X509_USERNAME,
                                                  mechanism='MONGODB-X509'))
        self.assertTrue(coll.remove())
        uri = ('mongodb://%s@%s:%d/?authMechanism='
               'MONGODB-X509' % (quote_plus(MONGODB_X509_USERNAME), host, port))
        # SSL options aren't supported in the URI...
        self.assertTrue(MongoClient(uri, ssl=True, ssl_certfile=CLIENT_PEM))
        # Cleanup
        remove_all_users(client['$external'])
        client['$external'].logout()
    def test_auth_network_error(self):
        # Make sure there's no semaphore leak if we get a network error
        # when authenticating a new socket with cached credentials.
        auth_client = self._get_client()
        if not server_started_with_auth(auth_client):
            raise SkipTest('Authentication is not enabled on server')

        auth_client.admin.add_user('admin', 'password')
        auth_client.admin.authenticate('admin', 'password')
        try:
            # Get a client with one socket so we detect if it's leaked.
            c = self._get_client(max_pool_size=1, waitQueueTimeoutMS=1)

            # Simulate an authenticate() call on a different socket.
            credentials = auth._build_credentials_tuple(
                'MONGODB-CR', 'admin',
                unicode('admin'), unicode('password'),
                {})

            c._cache_credentials('test', credentials, connect=False)

            # Cause a network error on the actual socket.
            pool = get_pool(c)
            socket_info = one(pool.sockets)
            socket_info.sock.close()

            # In __check_auth, the client authenticates its socket with the
            # new credential, but gets a socket.error. Should be reraised as
            # AutoReconnect.
            self.assertRaises(AutoReconnect, c.test.collection.find_one)

            # No semaphore leak, the pool is allowed to make a new socket.
            c.test.collection.find_one()
        finally:
            remove_all_users(auth_client.admin)
    def test_copy_db(self):
        authed_client = auth_context.client
        if version.at_least(authed_client, (2, 7, 2)):
            raise SkipTest("SERVER-17034")

        authed_client.admin.add_user("admin", "password")
        c = self._get_client()
        c.admin.authenticate("admin", "password")
        c.drop_database("pymongo_test1")
        c.pymongo_test.test.insert({"foo": "bar"})

        try:
            c.pymongo_test.add_user("mike", "password")

            self.assertRaises(OperationFailure, c.copy_database,
                              "pymongo_test", "pymongo_test1",
                              username="******", password="******")
            self.assertFalse("pymongo_test1" in c.database_names())

            self.assertRaises(OperationFailure, c.copy_database,
                              "pymongo_test", "pymongo_test1",
                              username="******", password="******")
            self.assertFalse("pymongo_test1" in c.database_names())

            c.copy_database("pymongo_test", "pymongo_test1",
                            username="******", password="******")
            self.assertTrue("pymongo_test1" in c.database_names())
            res = c.pymongo_test1.test.find_one(_must_use_master=True)
            self.assertEqual("bar", res["foo"])
        finally:
            # Cleanup
            remove_all_users(c.pymongo_test)
            c.admin.remove_user("admin")
        c.close()
    def test_authenticate_and_safe(self):
        if (is_mongos(self.client) and not
            version.at_least(self.client, (2, 0, 0))):
            raise SkipTest("Auth with sharding requires MongoDB >= 2.0.0")
        db = self.client.auth_test
        remove_all_users(db)

        db.add_user("bernie", "password",
                    roles=["userAdmin", "dbAdmin", "readWrite"])
        db.authenticate("bernie", "password")

        db.test.remove({})
        self.assertTrue(db.test.insert({"bim": "baz"}))
        self.assertEqual(1, db.test.count())

        self.assertEqual(1,
                         db.test.update({"bim": "baz"},
                                        {"$set": {"bim": "bar"}}).get('n'))

        self.assertEqual(1,
                         db.test.remove({}).get('n'))

        self.assertEqual(0, db.test.count())
        db.remove_user("bernie")
        db.logout()
    def test_make_user_readonly(self):
        admin = self.client.admin
        auth_context.client.admin.add_user('admin', 'pw')
        admin.authenticate('admin', 'pw')

        db = self.client.pymongo_test

        try:
            # Make a read-write user.
            db.add_user('jesse', 'pw')
            admin.logout()

            # Check that we're read-write by default.
            db.authenticate('jesse', 'pw')
            db.collection.insert({})
            db.logout()

            # Make the user read-only.
            admin.authenticate('admin', 'pw')
            db.add_user('jesse', 'pw', read_only=True)
            admin.logout()

            db.authenticate('jesse', 'pw')
            self.assertRaises(OperationFailure, db.collection.insert, {})
        finally:
            # Cleanup
            admin.authenticate('admin', 'pw')
            remove_all_users(db)
            admin.remove_user("admin")
            admin.logout()
    def test_init_disconnected_with_auth(self):
        c = self._get_client()
        if not server_started_with_auth(c):
            raise SkipTest('Authentication is not enabled on server')

        c.admin.add_user("admin", "pass")
        c.admin.authenticate("admin", "pass")
        try:
            c.pymongo_test.add_user("user", "pass", roles=['readWrite', 'userAdmin'])

            # Auth with lazy connection.
            host = one(self.hosts)
            uri = "mongodb://*****:*****@%s:%d/pymongo_test?replicaSet=%s" % (
                host[0], host[1], self.name)

            authenticated_client = MongoReplicaSetClient(uri, _connect=False)
            authenticated_client.pymongo_test.test.find_one()

            # Wrong password.
            bad_uri = "mongodb://*****:*****@%s:%d/pymongo_test?replicaSet=%s" % (
                host[0], host[1], self.name)

            bad_client = MongoReplicaSetClient(bad_uri, _connect=False)
            self.assertRaises(
                OperationFailure, bad_client.pymongo_test.test.find_one)

        finally:
            # Clean up.
            remove_all_users(c.pymongo_test)
            remove_all_users(c.admin)
    def test_init_disconnected_with_auth(self):
        c = self._get_client()
        if not server_started_with_auth(c):
            raise SkipTest('Authentication is not enabled on server')

        c.admin.add_user("admin", "pass")
        c.admin.authenticate("admin", "pass")
        try:
            c.pymongo_test.add_user("user",
                                    "pass",
                                    roles=['readWrite', 'userAdmin'])

            # Auth with lazy connection.
            host = one(self.hosts)
            uri = "mongodb://*****:*****@%s:%d/pymongo_test?replicaSet=%s" % (
                host[0], host[1], self.name)

            authenticated_client = MongoReplicaSetClient(uri, _connect=False)
            authenticated_client.pymongo_test.test.find_one()

            # Wrong password.
            bad_uri = "mongodb://*****:*****@%s:%d/pymongo_test?replicaSet=%s" % (
                host[0], host[1], self.name)

            bad_client = MongoReplicaSetClient(bad_uri, _connect=False)
            self.assertRaises(OperationFailure,
                              bad_client.pymongo_test.test.find_one)

        finally:
            # Clean up.
            remove_all_users(c.pymongo_test)
            remove_all_users(c.admin)
 def tearDown(self):
     db = self.client.pymongo_test
     db.logout()
     db.authenticate('dbOwner', 'pw')
     db.command('dropRole', 'noremove')
     remove_all_users(db)
     db.logout()
 def tearDown(self):
     db = self.client.pymongo_test
     db.logout()
     db.authenticate('dbOwner', 'pw')
     db.command('dropRole', 'noremove')
     remove_all_users(db)
     db.logout()
    def test_authenticate_multiple(self):
        client = get_client()
        if is_mongos(client) and not version.at_least(self.client, (2, 2, 0)):
            raise SkipTest("Need mongos >= 2.2.0")
        if not server_started_with_auth(client):
            raise SkipTest("Authentication is not enabled on server")

        # Setup
        users_db = client.pymongo_test
        admin_db = client.admin
        other_db = client.pymongo_test1
        users_db.test.remove()
        other_db.test.remove()

        admin_db.add_user("admin", "pass", roles=["userAdminAnyDatabase", "dbAdmin", "clusterAdmin", "readWrite"])
        try:
            self.assertTrue(admin_db.authenticate("admin", "pass"))

            if version.at_least(self.client, (2, 5, 3, -1)):
                admin_db.add_user("ro-admin", "pass", roles=["userAdmin", "readAnyDatabase"])
            else:
                admin_db.add_user("ro-admin", "pass", read_only=True)

            users_db.add_user("user", "pass", roles=["userAdmin", "readWrite"])

            admin_db.logout()
            self.assertRaises(OperationFailure, users_db.test.find_one)

            # Regular user should be able to query its own db, but
            # no other.
            users_db.authenticate("user", "pass")
            self.assertEqual(0, users_db.test.count())
            self.assertRaises(OperationFailure, other_db.test.find_one)

            # Admin read-only user should be able to query any db,
            # but not write.
            admin_db.authenticate("ro-admin", "pass")
            self.assertEqual(0, other_db.test.count())
            self.assertRaises(OperationFailure, other_db.test.insert, {})

            # Force close all sockets
            client.disconnect()

            # We should still be able to write to the regular user's db
            self.assertTrue(users_db.test.remove())
            # And read from other dbs...
            self.assertEqual(0, other_db.test.count())
            # But still not write to other dbs...
            self.assertRaises(OperationFailure, other_db.test.insert, {})

        # Cleanup
        finally:
            admin_db.logout()
            users_db.logout()
            admin_db.authenticate("admin", "pass")
            remove_all_users(users_db)
            remove_all_users(admin_db)
 def tearDown(self):
     # Remove auth users from databases
     self.client.admin.authenticate("admin-user", "password")
     remove_all_users(self.client.auth_test)
     self.client.drop_database('auth_test')
     remove_all_users(self.client.admin)
     # Clear client reference so that RSC's monitor thread
     # dies.
     self.client = None
 def tearDown(self):
     # Remove auth users from databases
     self.client.admin.authenticate("admin-user", "password")
     self.client.drop_database('auth_test')
     remove_all_users(self.client.auth_test)
     self.client.admin.remove_user('admin-user')
     # Clear client reference so that RSC's monitor thread
     # dies.
     self.client = None
Exemple #19
0
    def test_mongodb_x509_auth(self):
        # Expects the server to be running with the server.pem, ca.pem
        # and crl.pem provided in mongodb and the server tests as well as
        # --auth
        #
        #   --sslPEMKeyFile=jstests/libs/server.pem
        #   --sslCAFile=jstests/libs/ca.pem
        #   --sslCRLFile=jstests/libs/crl.pem
        #   --auth
        if not CERT_SSL:
            raise SkipTest("No mongod available over SSL with certs")

        client = MongoClient(host, port, ssl=True, ssl_certfile=CLIENT_PEM)
        if not version.at_least(client, (2, 5, 3, -1)):
            raise SkipTest("MONGODB-X509 tests require MongoDB 2.5.3 or newer")
        if not server_started_with_auth(client):
            raise SkipTest('Authentication is not enabled on server')
        # Give admin all necessary privileges.
        client['$external'].add_user(MONGODB_X509_USERNAME, roles=[
            {'role': 'readWriteAnyDatabase', 'db': 'admin'},
            {'role': 'userAdminAnyDatabase', 'db': 'admin'}])
        coll = client.pymongo_test.test
        self.assertRaises(OperationFailure, coll.count)
        self.assertTrue(client.admin.authenticate(MONGODB_X509_USERNAME,
                                                  mechanism='MONGODB-X509'))
        self.assertTrue(coll.remove())
        uri = ('mongodb://%s@%s:%d/?authMechanism='
               'MONGODB-X509' % (quote_plus(MONGODB_X509_USERNAME), host, port))
        # SSL options aren't supported in the URI...
        self.assertTrue(MongoClient(uri, ssl=True, ssl_certfile=CLIENT_PEM))

        # Should require a username
        uri = ('mongodb://%s:%d/?authMechanism=MONGODB-X509' % (host, port))
        client_bad = MongoClient(uri, ssl=True, ssl_certfile=CLIENT_PEM)
        self.assertRaises(OperationFailure, client_bad.pymongo_test.test.remove)

        # Auth should fail if username and certificate do not match
        uri = ('mongodb://%s@%s:%d/?authMechanism='
               'MONGODB-X509' % (quote_plus("not the username"), host, port))
        self.assertRaises(ConfigurationError, MongoClient, uri,
                          ssl=True, ssl_certfile=CLIENT_PEM)
        self.assertRaises(OperationFailure, client.admin.authenticate,
                          "not the username",
                          mechanism="MONGODB-X509")

        # Invalid certificate (using CA certificate as client certificate)
        uri = ('mongodb://%s@%s:%d/?authMechanism='
               'MONGODB-X509' % (quote_plus(MONGODB_X509_USERNAME), host, port))
        self.assertRaises(ConnectionFailure, MongoClient, uri,
                          ssl=True, ssl_certfile=CA_PEM)
        self.assertRaises(ConnectionFailure, MongoClient, pair,
                          ssl=True, ssl_certfile=CA_PEM)

        # Cleanup
        remove_all_users(client['$external'])
        client['$external'].logout()
Exemple #20
0
    def test_auth_from_uri(self):
        c = MongoClient(host, port)
        # Sharded auth not supported before MongoDB 2.0
        if is_mongos(c) and not version.at_least(c, (2, 0, 0)):
            raise SkipTest("Auth with sharding requires MongoDB >= 2.0.0")
        if not server_started_with_auth(c):
            raise SkipTest('Authentication is not enabled on server')

        c.admin.add_user("admin", "pass")
        c.admin.authenticate("admin", "pass")
        try:
            c.pymongo_test.add_user("user",
                                    "pass",
                                    roles=['userAdmin', 'readWrite'])

            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d" % (host, port))
            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d" % (host, port))
            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d" % (host, port))
            MongoClient("mongodb://*****:*****@%s:%d" % (host, port))

            self.assertRaises(
                ConfigurationError, MongoClient,
                "mongodb://*****:*****@%s:%d/pymongo_test" % (host, port))
            self.assertRaises(
                ConfigurationError, MongoClient,
                "mongodb://*****:*****@%s:%d/pymongo_test" % (host, port))
            MongoClient("mongodb://*****:*****@%s:%d/pymongo_test" %
                        (host, port))

            # Auth with lazy connection.
            MongoClient("mongodb://*****:*****@%s:%d/pymongo_test" %
                        (host, port),
                        _connect=False).pymongo_test.test.find_one()

            # Wrong password.
            bad_client = MongoClient(
                "mongodb://*****:*****@%s:%d/pymongo_test" % (host, port),
                _connect=False)

            # If auth fails with lazy connection, MongoClient raises
            # AutoReconnect instead of the more appropriate OperationFailure,
            # PYTHON-517.
            self.assertRaises(PyMongoError,
                              bad_client.pymongo_test.test.find_one)

        finally:
            # Clean up.
            remove_all_users(c.pymongo_test)
            remove_all_users(c.admin)
    def test_default_roles(self):
        authed_client = auth_context.client
        if not version.at_least(authed_client, (2, 5, 3, -1)):
            raise SkipTest("Default roles only exist in MongoDB >= 2.5.3")

        # "Admin" user
        db = self.client.admin
        authed_client.admin.add_user('admin', 'pass')
        try:
            db.authenticate('admin', 'pass')
            info = db.command('usersInfo', 'admin')['users'][0]
            self.assertEqual("root", info['roles'][0]['role'])

            # Read only "admin" user
            db.add_user('ro-admin', 'pass', read_only=True)
            db.logout()
            db.authenticate('ro-admin', 'pass')
            info = db.command('usersInfo', 'ro-admin')['users'][0]
            self.assertEqual("readAnyDatabase", info['roles'][0]['role'])
            db.logout()

        # Cleanup
        finally:
            db.authenticate('admin', 'pass')
            db.remove_user('ro-admin')
            db.remove_user('admin')
            db.logout()

        db.connection.disconnect()

        # "Non-admin" user
        db = self.client.pymongo_test
        authed_client.pymongo_test.add_user('user', 'pass')
        try:
            db.authenticate('user', 'pass')
            info = db.command('usersInfo', 'user')['users'][0]
            self.assertEqual("dbOwner", info['roles'][0]['role'])

            # Read only "Non-admin" user
            db.add_user('ro-user', 'pass', read_only=True)
            db.logout()
            db.authenticate('ro-user', 'pass')
            info = db.command('usersInfo', 'ro-user')['users'][0]
            self.assertEqual("read", info['roles'][0]['role'])
            db.logout()

        # Cleanup
        finally:
            db.authenticate('user', 'pass')
            remove_all_users(db)
            db.logout()
    def test_default_roles(self):
        if not version.at_least(self.client, (2, 5, 3, -1)):
            raise SkipTest("Default roles only exist in MongoDB >= 2.5.3")
        if not server_started_with_auth(self.client):
            raise SkipTest('Authentication is not enabled on server')

        # "Admin" user
        db = self.client.admin
        db.add_user('admin', 'pass')
        try:
            db.authenticate('admin', 'pass')
            info = db.command('usersInfo', 'admin')['users'][0]
            self.assertEqual("root", info['roles'][0]['role'])

            # Read only "admin" user
            db.add_user('ro-admin', 'pass', read_only=True)
            db.logout()
            db.authenticate('ro-admin', 'pass')
            info = db.command('usersInfo', 'ro-admin')['users'][0]
            self.assertEqual("readAnyDatabase", info['roles'][0]['role'])
            db.logout()

        # Cleanup
        finally:
            db.authenticate('admin', 'pass')
            remove_all_users(db)
            db.logout()

        db.connection.disconnect()

        # "Non-admin" user
        db = self.client.pymongo_test
        db.add_user('user', 'pass')
        try:
            db.authenticate('user', 'pass')
            info = db.command('usersInfo', 'user')['users'][0]
            self.assertEqual("dbOwner", info['roles'][0]['role'])

            # Read only "Non-admin" user
            db.add_user('ro-user', 'pass', read_only=True)
            db.logout()
            db.authenticate('ro-user', 'pass')
            info = db.command('usersInfo', 'ro-user')['users'][0]
            self.assertEqual("read", info['roles'][0]['role'])
            db.logout()

        # Cleanup
        finally:
            db.authenticate('user', 'pass')
            remove_all_users(db)
            db.logout()
    def test_auth_from_uri(self):
        c = MongoClient(host, port)
        # Sharded auth not supported before MongoDB 2.0
        if is_mongos(c) and not version.at_least(c, (2, 0, 0)):
            raise SkipTest("Auth with sharding requires MongoDB >= 2.0.0")
        if not server_started_with_auth(c):
            raise SkipTest('Authentication is not enabled on server')

        c.admin.add_user("admin", "pass")
        c.admin.authenticate("admin", "pass")
        try:
            c.pymongo_test.add_user("user", "pass", roles=['userAdmin', 'readWrite'])

            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d" % (host, port))
            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d" % (host, port))
            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d" % (host, port))
            MongoClient("mongodb://*****:*****@%s:%d" % (host, port))

            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d/pymongo_test" %
                              (host, port))
            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d/pymongo_test" %
                              (host, port))
            MongoClient("mongodb://*****:*****@%s:%d/pymongo_test" %
                       (host, port))

            # Auth with lazy connection.
            MongoClient(
                "mongodb://*****:*****@%s:%d/pymongo_test" % (host, port),
                _connect=False).pymongo_test.test.find_one()

            # Wrong password.
            bad_client = MongoClient(
                "mongodb://*****:*****@%s:%d/pymongo_test" % (host, port),
                _connect=False)

            # If auth fails with lazy connection, MongoClient raises
            # AutoReconnect instead of the more appropriate OperationFailure,
            # PYTHON-517.
            self.assertRaises(
                PyMongoError, bad_client.pymongo_test.test.find_one)

        finally:
            # Clean up.
            remove_all_users(c.pymongo_test)
            remove_all_users(c.admin)
 def setUp(self):
     client = self._get_client()
     if not server_started_with_auth(client):
         raise SkipTest("Authentication is not enabled on server")
     self.client = client
     remove_all_users(self.client.admin)
     self.client.admin.add_user('admin-user', 'password',
                                roles=['clusterAdmin',
                                       'dbAdminAnyDatabase',
                                       'readWriteAnyDatabase',
                                       'userAdminAnyDatabase'])
     self.client.admin.authenticate("admin-user", "password")
     remove_all_users(self.client.auth_test)
     self.client.auth_test.add_user("test-user", "password",
                                    roles=['readWrite'])
    def test_mongodb_x509_auth(self):
        # Expects the server to be running with the server.pem, ca.pem
        # and crl.pem provided in mongodb and the server tests as well as
        # --auth
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        #   --sslCRLFile=/path/to/pymongo/test/certificates/crl.pem
        #   --auth
        if not CERT_SSL:
            raise SkipTest("No mongod available over SSL with certs")

        client = MongoClient(host, port, ssl=True, ssl_certfile=CLIENT_PEM)
        if not version.at_least(client, (2, 5, 3, -1)):
            raise SkipTest("MONGODB-X509 tests require MongoDB 2.5.3 or newer")
        if not server_started_with_auth(client):
            raise SkipTest("Authentication is not enabled on server")
        # Give admin all necessary privileges.
        client["$external"].add_user(
            MONGODB_X509_USERNAME,
            roles=[{"role": "readWriteAnyDatabase", "db": "admin"}, {"role": "userAdminAnyDatabase", "db": "admin"}],
        )
        coll = client.pymongo_test.test
        self.assertRaises(OperationFailure, coll.count)
        self.assertTrue(client.admin.authenticate(MONGODB_X509_USERNAME, mechanism="MONGODB-X509"))
        self.assertTrue(coll.remove())
        uri = "mongodb://%s@%s:%d/?authMechanism=" "MONGODB-X509" % (quote_plus(MONGODB_X509_USERNAME), host, port)
        # SSL options aren't supported in the URI...
        self.assertTrue(MongoClient(uri, ssl=True, ssl_certfile=CLIENT_PEM))

        # Should require a username
        uri = "mongodb://%s:%d/?authMechanism=MONGODB-X509" % (host, port)
        client_bad = MongoClient(uri, ssl=True, ssl_certfile=CLIENT_PEM)
        self.assertRaises(OperationFailure, client_bad.pymongo_test.test.remove)

        # Auth should fail if username and certificate do not match
        uri = "mongodb://%s@%s:%d/?authMechanism=" "MONGODB-X509" % (quote_plus("not the username"), host, port)
        self.assertRaises(ConfigurationError, MongoClient, uri, ssl=True, ssl_certfile=CLIENT_PEM)
        self.assertRaises(OperationFailure, client.admin.authenticate, "not the username", mechanism="MONGODB-X509")

        # Invalid certificate (using CA certificate as client certificate)
        uri = "mongodb://%s@%s:%d/?authMechanism=" "MONGODB-X509" % (quote_plus(MONGODB_X509_USERNAME), host, port)
        self.assertRaises(ConnectionFailure, MongoClient, uri, ssl=True, ssl_certfile=CA_PEM)
        self.assertRaises(ConnectionFailure, MongoClient, pair, ssl=True, ssl_certfile=CA_PEM)

        # Cleanup
        remove_all_users(client["$external"])
        client["$external"].logout()
Exemple #26
0
    def test_authenticate(self):
        db = self.db
        try:
            yield self.cx.admin.add_user("admin", "password")
            yield self.cx.admin.authenticate("admin", "password")
            yield db.add_user("mike", "password")

            # Authenticate many times at once to test concurrency.
            yield [db.authenticate("mike", "password") for _ in range(10)]

            # just make sure there are no exceptions here
            yield db.remove_user("mike")
            yield db.logout()
            if (yield version.at_least(self.cx, (2, 5, 4))):
                info = yield db.command("usersInfo", "mike")
                users = info.get('users', [])
            else:
                users = yield db.system.users.find().to_list(length=10)

            self.assertFalse("mike" in [u['user'] for u in users])

        finally:
            yield remove_all_users(db)
            yield self.cx.admin.remove_user('admin')
            test.sync_cx.disconnect()
Exemple #27
0
    def test_auth_from_uri(self):
        if not test.env.auth:
            raise SkipTest('Authentication is not enabled on server')

        # self.db is logged in as root.
        yield from remove_all_users(self.db)
        db = self.db
        try:
            yield from db.add_user(
                'mike', 'password',
                roles=['userAdmin', 'readWrite'])

            client = motor_asyncio.AsyncIOMotorClient(
                'mongodb://*****:*****@%s:%d' % (host, port),
                io_loop=self.loop)

            # Note: open() only calls ismaster, doesn't throw auth errors.
            yield from client.open()

            with self.assertRaises(OperationFailure):
                yield from client.db.collection.find_one()

            client = motor_asyncio.AsyncIOMotorClient(
                'mongodb://*****:*****@%s:%d/%s' %
                (host, port, db.name),
                io_loop=self.loop)

            yield from client[db.name].collection.find_one()
        finally:
            yield from db.remove_user('mike')
    def test_copy_db_auth_concurrent(self):
        # SERVER-6427, can't copy database via mongos with auth.
        yield skip_if_mongos(self.cx)

        n_copies = 2
        test_db_names = ['motor_test_%s' % i for i in range(n_copies)]

        # 1. Drop old test DBs
        yield self.cx.drop_database('motor_test')
        yield self.collection.insert({'_id': 1})
        yield self.drop_databases(test_db_names)

        # 2. Copy a test DB N times at once
        try:
            # self.cx is logged in as root.
            yield self.cx.motor_test.add_user('mike', 'password')

            client = self.get_client()
            results = yield [
                client.copy_database('motor_test',
                                     test_db_name,
                                     username='******',
                                     password='******')
                for test_db_name in test_db_names
            ]

            self.assertTrue(all(isinstance(i, dict) for i in results))
            yield self.check_copydb_results({'_id': 1}, test_db_names)

        finally:
            yield remove_all_users(client.motor_test)
            yield self.drop_databases(test_db_names,
                                      authenticated_client=self.cx)
    def test_authenticate(self):
        db = self.db
        try:
            yield self.cx.admin.add_user("admin", "password")
            yield self.cx.admin.authenticate("admin", "password")
            yield db.add_user("mike", "password")

            # Authenticate many times at once to test concurrency.
            yield [db.authenticate("mike", "password") for _ in range(10)]

            # just make sure there are no exceptions here
            yield db.remove_user("mike")
            yield db.logout()
            if (yield version.at_least(self.cx, (2, 5, 4))):
                info = yield db.command("usersInfo", "mike")
                users = info.get('users', [])
            else:
                users = yield db.system.users.find().to_list(length=10)

            self.assertFalse("mike" in [u['user'] for u in users])

        finally:
            yield remove_all_users(db)
            yield self.cx.admin.remove_user('admin')
            test.sync_cx.disconnect()
    def test_copy_db_auth_concurrent(self):
        # SERVER-6427, can't copy database via mongos with auth.
        yield skip_if_mongos(self.cx)


        n_copies = 2
        test_db_names = ['motor_test_%s' % i for i in range(n_copies)]

        # 1. Drop old test DBs
        yield self.cx.drop_database('motor_test')
        yield self.collection.insert({'_id': 1})
        yield self.drop_databases(test_db_names)

        # 2. Copy a test DB N times at once
        try:
            # self.cx is logged in as root.
            yield self.cx.motor_test.add_user('mike', 'password')

            client = self.get_client()
            results = yield [
                client.copy_database(
                    'motor_test', test_db_name,
                    username='******', password='******')
                for test_db_name in test_db_names]

            self.assertTrue(all(isinstance(i, dict) for i in results))
            yield self.check_copydb_results({'_id': 1}, test_db_names)

        finally:
            yield remove_all_users(client.motor_test)
            yield self.drop_databases(
                test_db_names,
                authenticated_client=self.cx)
Exemple #31
0
    def test_auth_from_uri(self):
        if not test.env.auth:
            raise SkipTest('Authentication is not enabled on server')

        # self.db is logged in as root.
        yield from remove_all_users(self.db)
        db = self.db
        try:
            yield from db.add_user('mike',
                                   'password',
                                   roles=['userAdmin', 'readWrite'])

            client = motor_asyncio.AsyncIOMotorClient(
                'mongodb://*****:*****@%s:%d' % (host, port), io_loop=self.loop)

            # Note: open() only calls ismaster, doesn't throw auth errors.
            yield from client.open()

            with self.assertRaises(OperationFailure):
                yield from client.db.collection.find_one()

            client = motor_asyncio.AsyncIOMotorClient(
                'mongodb://*****:*****@%s:%d/%s' % (host, port, db.name),
                io_loop=self.loop)

            yield from client[db.name].collection.find_one()
        finally:
            yield from db.remove_user('mike')
    def test_copy_db_auth(self):
        # See SERVER-6427.
        cx = self.get_client()
        if cx.is_mongos:
            raise SkipTest("Can't copy database with auth via mongos.")

        target_db_name = "motor_test_2"

        collection = cx.motor_test.test_collection
        yield collection.remove()
        yield collection.insert({"_id": 1})

        yield cx.admin.add_user("admin", "password")
        yield cx.admin.authenticate("admin", "password")

        try:
            yield cx.motor_test.add_user("mike", "password")

            with assert_raises(pymongo.errors.OperationFailure):
                yield cx.copy_database("motor_test", target_db_name, username="******", password="******")

            with assert_raises(pymongo.errors.OperationFailure):
                yield cx.copy_database("motor_test", target_db_name, username="******", password="******")

            # Copy a database using name and password.
            yield cx.copy_database("motor_test", target_db_name, username="******", password="******")

            self.assertEqual({"_id": 1}, (yield cx[target_db_name].test_collection.find_one()))

            yield cx.drop_database(target_db_name)
        finally:
            yield remove_all_users(cx.motor_test)
            yield cx.admin.remove_user("admin")
    def test_copy_db_auth(self):
        # SERVER-6427, can't copy database via mongos with auth.
        yield skip_if_mongos(self.cx)

        yield self.collection.insert({'_id': 1})

        try:
            # self.cx is logged in as root.
            yield self.cx.motor_test.add_user('mike', 'password')

            client = self.get_client()
            target_db_name = 'motor_test_2'

            with assert_raises(pymongo.errors.OperationFailure):
                yield client.copy_database(
                    'motor_test', target_db_name,
                    username='******', password='******')

            with assert_raises(pymongo.errors.OperationFailure):
                yield client.copy_database(
                    'motor_test', target_db_name,
                    username='******', password='******')

            # Copy a database using name and password.
            yield client.copy_database(
                'motor_test', target_db_name,
                username='******', password='******')

            self.assertEqual(
                {'_id': 1},
                (yield client[target_db_name].test_collection.find_one()))

            yield client.drop_database(target_db_name)
        finally:
            yield remove_all_users(self.cx.motor_test)
    def test_copy_db_auth_concurrent(self):
        cx = self.get_client()
        yield skip_if_mongos(cx)

        n_copies = 2
        test_db_names = ['motor_test_%s' % i for i in range(n_copies)]

        # 1. Drop old test DBs
        yield cx.drop_database('motor_test')
        yield self.drop_databases(test_db_names)

        # 2. Copy a test DB N times at once
        collection = cx.motor_test.test_collection
        yield collection.remove()
        yield collection.insert({'_id': 1})

        yield cx.admin.add_user('admin', 'password', )
        yield cx.admin.authenticate('admin', 'password')

        try:
            yield cx.motor_test.add_user('mike', 'password')

            results = yield [
                cx.copy_database(
                    'motor_test', test_db_name,
                    username='******', password='******')
                for test_db_name in test_db_names]

            self.assertTrue(all(isinstance(i, dict) for i in results))
            yield self.check_copydb_results({'_id': 1}, test_db_names)

        finally:
            yield remove_all_users(cx.motor_test)
            yield self.drop_databases(test_db_names, authenticated_client=cx)
            yield cx.admin.remove_user('admin')
    def test_copy_db(self):
        authed_client = auth_context.client
        if version.at_least(authed_client, (2, 7, 2)):
            raise SkipTest("SERVER-17034")
        if is_mongos(authed_client):
            raise SkipTest("SERVER-6427")

        c = MongoClient(host, port)

        authed_client.admin.add_user("admin", "password")
        c.admin.authenticate("admin", "password")
        c.drop_database("pymongo_test")
        c.drop_database("pymongo_test1")
        c.pymongo_test.test.insert({"foo": "bar"})

        try:
            c.pymongo_test.add_user("mike", "password")

            self.assertRaises(OperationFailure,
                              c.copy_database,
                              "pymongo_test",
                              "pymongo_test1",
                              username="******",
                              password="******")
            self.assertFalse("pymongo_test1" in c.database_names())

            self.assertRaises(OperationFailure,
                              c.copy_database,
                              "pymongo_test",
                              "pymongo_test1",
                              username="******",
                              password="******")
            self.assertFalse("pymongo_test1" in c.database_names())

            c.copy_database("pymongo_test",
                            "pymongo_test1",
                            username="******",
                            password="******")
            self.assertTrue("pymongo_test1" in c.database_names())
            self.assertEqual("bar", c.pymongo_test1.test.find_one()["foo"])
        finally:
            # Cleanup
            remove_all_users(c.pymongo_test)
            c.admin.remove_user("admin")
            c.disconnect()
 def setUp(self):
     client = self._get_client()
     if not server_started_with_auth(client):
         raise SkipTest("Authentication is not enabled on server")
     self.client = client
     remove_all_users(self.client.admin)
     self.client.admin.add_user('admin-user',
                                'password',
                                roles=[
                                    'clusterAdmin', 'dbAdminAnyDatabase',
                                    'readWriteAnyDatabase',
                                    'userAdminAnyDatabase'
                                ])
     self.client.admin.authenticate("admin-user", "password")
     remove_all_users(self.client.auth_test)
     self.client.auth_test.add_user("test-user",
                                    "password",
                                    roles=['readWrite'])
Exemple #37
0
    def test_mongodb_x509_auth(self):
        # Expects the server to be running with the server.pem, ca.pem
        # and crl.pem provided in mongodb and the server tests as well as
        # --auth:
        #
        #   --sslPEMKeyFile=jstests/libs/server.pem
        #   --sslCAFile=jstests/libs/ca.pem
        #   --sslCRLFile=jstests/libs/crl.pem
        #   --auth
        if not test.env.mongod_validates_client_cert:
            raise SkipTest("No mongod available over SSL with certs")

        client = AsyncIOMotorClient(test.env.uri,
                                    ssl_certfile=CLIENT_PEM,
                                    io_loop=self.loop)

        if not (yield from at_least(client, (2, 5, 3, -1))):
            raise SkipTest("MONGODB-X509 tests require MongoDB 2.5.3 or newer")

        if not test.env.auth:
            raise SkipTest('Authentication is not enabled on server')

        # Give admin all necessary privileges.
        yield from client['$external'].add_user(MONGODB_X509_USERNAME,
                                                roles=[{
                                                    'role':
                                                    'readWriteAnyDatabase',
                                                    'db': 'admin'
                                                }, {
                                                    'role':
                                                    'userAdminAnyDatabase',
                                                    'db': 'admin'
                                                }])

        collection = client.motor_test.test
        with test.assert_raises(OperationFailure):
            yield from collection.count()

        yield from client.admin.authenticate(MONGODB_X509_USERNAME,
                                             mechanism='MONGODB-X509')

        yield from collection.remove()
        uri = ('mongodb://%s@%s:%d/?authMechanism='
               'MONGODB-X509' %
               (quote_plus(MONGODB_X509_USERNAME), host, port))

        # SSL options aren't supported in the URI....
        auth_uri_client = AsyncIOMotorClient(uri,
                                             ssl_certfile=CLIENT_PEM,
                                             io_loop=self.loop)

        yield from auth_uri_client.db.collection.find_one()

        # Cleanup.
        yield from remove_all_users(client['$external'])
        yield from client['$external'].logout()
    def test_auth_from_uri(self):
        c = MongoClient(host, port)
        auth_context.client.admin.add_user("admin", "pass")
        c.admin.authenticate("admin", "pass")
        try:
            c.pymongo_test.add_user("user",
                                    "pass",
                                    roles=['userAdmin', 'readWrite'])

            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d" % (host, port))
            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d" % (host, port))
            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d" % (host, port))
            MongoClient("mongodb://*****:*****@%s:%d" % (host, port))

            self.assertRaises(
                ConfigurationError, MongoClient,
                "mongodb://*****:*****@%s:%d/pymongo_test" % (host, port))
            self.assertRaises(
                ConfigurationError, MongoClient,
                "mongodb://*****:*****@%s:%d/pymongo_test" % (host, port))
            MongoClient("mongodb://*****:*****@%s:%d/pymongo_test" %
                        (host, port))

            # Auth with lazy connection.
            MongoClient("mongodb://*****:*****@%s:%d/pymongo_test" %
                        (host, port),
                        _connect=False).pymongo_test.test.find_one()

            # Wrong password.
            bad_client = MongoClient(
                "mongodb://*****:*****@%s:%d/pymongo_test" % (host, port),
                _connect=False)

            self.assertRaises(OperationFailure,
                              bad_client.pymongo_test.test.find_one)

        finally:
            # Clean up.
            remove_all_users(c.pymongo_test)
            c.admin.remove_user('admin')
Exemple #39
0
    def test_auth_from_uri(self):
        if not (yield server_started_with_auth(self.cx)):
            raise SkipTest('Authentication is not enabled on server')

        yield remove_all_users(self.db)
        yield remove_all_users(self.cx.admin)
        yield self.cx.admin.add_user('admin', 'pass')
        yield self.cx.admin.authenticate('admin', 'pass')

        db = self.db
        try:
            yield db.add_user(
                'mike', 'password',
                roles=['userAdmin', 'readWrite'])

            client = motor.MotorClient('mongodb://*****:*****@%s:%d' % (host, port))

            # Note: open() only calls ismaster, doesn't throw auth errors.
            yield client.open()

            with assert_raises(OperationFailure):
                yield client.db.collection.find_one()

            client.close()

            client = motor.MotorClient(
                'mongodb://*****:*****@%s:%d/%s' %
                (host, port, db.name))

            yield client.open()
            client.close()

            client = motor.MotorClient(
                'mongodb://*****:*****@%s:%d/%s' %
                (host, port, db.name))

            yield client[db.name].collection.find_one()
            client.close()

        finally:
            yield db.remove_user('mike')
            yield self.cx.admin.remove_user('admin')
    def test_auth_from_uri(self):
        c = MongoClient(host, port)
        auth_context.client.admin.add_user("admin", "pass")
        c.admin.authenticate("admin", "pass")
        try:
            c.pymongo_test.add_user("user", "pass",
                                    roles=['userAdmin', 'readWrite'])

            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d" % (host, port))
            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d" % (host, port))
            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d" % (host, port))
            MongoClient("mongodb://*****:*****@%s:%d" % (host, port))

            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d/pymongo_test" %
                              (host, port))
            self.assertRaises(ConfigurationError, MongoClient,
                              "mongodb://*****:*****@%s:%d/pymongo_test" %
                              (host, port))
            MongoClient("mongodb://*****:*****@%s:%d/pymongo_test" %
                       (host, port))

            # Auth with lazy connection.
            MongoClient(
                "mongodb://*****:*****@%s:%d/pymongo_test" % (host, port),
                _connect=False).pymongo_test.test.find_one()

            # Wrong password.
            bad_client = MongoClient(
                "mongodb://*****:*****@%s:%d/pymongo_test" % (host, port),
                _connect=False)

            self.assertRaises(OperationFailure,
                              bad_client.pymongo_test.test.find_one)

        finally:
            # Clean up.
            remove_all_users(c.pymongo_test)
            c.admin.remove_user('admin')
    def test_new_user_cmds(self):
        if not version.at_least(self.client, (2, 5, 3, -1)):
            raise SkipTest("User manipulation through commands "
                           "requires MongoDB >= 2.5.3")

        db = self.client.pymongo_test
        remove_all_users(db)
        db.add_user("amalia", "password", roles=["userAdmin"])
        db.authenticate("amalia", "password")
        # This tests the ability to update user attributes.
        db.add_user("amalia", "new_password", customData={"secret": "koalas"})

        user_info = db.command("usersInfo", "amalia")
        self.assertTrue(user_info["users"])
        amalia_user = user_info["users"][0]
        self.assertEqual(amalia_user["name"], "amalia")
        self.assertEqual(amalia_user["customData"], {"secret": "koalas"})

        db.remove_user("amalia")
        db.logout()
    def test_new_user_cmds(self):
        if not version.at_least(self.client, (2, 5, 3, -1)):
            raise SkipTest("User manipulation through commands "
                           "requires MongoDB >= 2.5.3")

        db = self.client.pymongo_test
        remove_all_users(db)
        db.add_user("amalia", "password", roles=["userAdmin"])
        db.authenticate("amalia", "password")
        # This tests the ability to update user attributes.
        db.add_user("amalia", "new_password", customData={"secret": "koalas"})

        user_info = db.command("usersInfo", "amalia")
        self.assertTrue(user_info["users"])
        amalia_user = user_info["users"][0]
        self.assertEqual(amalia_user["user"], "amalia")
        self.assertEqual(amalia_user["customData"], {"secret": "koalas"})

        db.remove_user("amalia")
        db.logout()
Exemple #43
0
    def test_auth_from_uri(self):
        if not (yield server_started_with_auth(self.cx)):
            raise SkipTest('Authentication is not enabled on server')

        yield remove_all_users(self.db)
        yield remove_all_users(self.cx.admin)
        yield self.cx.admin.add_user('admin', 'pass')
        yield self.cx.admin.authenticate('admin', 'pass')

        db = self.db
        try:
            yield db.add_user('mike',
                              'password',
                              roles=['userAdmin', 'readWrite'])

            client = motor.MotorClient('mongodb://*****:*****@%s:%d' %
                                       (host, port))

            # Note: open() only calls ismaster, doesn't throw auth errors.
            yield client.open()

            with assert_raises(OperationFailure):
                yield client.db.collection.find_one()

            client.close()

            client = motor.MotorClient('mongodb://*****:*****@%s:%d/%s' %
                                       (host, port, db.name))

            yield client.open()
            client.close()

            client = motor.MotorClient('mongodb://*****:*****@%s:%d/%s' %
                                       (host, port, db.name))

            yield client[db.name].collection.find_one()
            client.close()

        finally:
            yield db.remove_user('mike')
            yield self.cx.admin.remove_user('admin')
    def test_make_user_readonly(self):
        if (is_mongos(self.client)
                and not version.at_least(self.client, (2, 0, 0))):
            raise SkipTest('Auth with sharding requires MongoDB >= 2.0.0')

        if not server_started_with_auth(self.client):
            raise SkipTest('Authentication is not enabled on server')

        admin = self.client.admin
        admin.add_user('admin', 'pw')
        admin.authenticate('admin', 'pw')

        db = self.client.pymongo_test

        try:
            # Make a read-write user.
            db.add_user('jesse', 'pw')
            admin.logout()

            # Check that we're read-write by default.
            db.authenticate('jesse', 'pw')
            db.collection.insert({})
            db.logout()

            # Make the user read-only.
            admin.authenticate('admin', 'pw')
            db.add_user('jesse', 'pw', read_only=True)
            admin.logout()

            db.authenticate('jesse', 'pw')
            self.assertRaises(OperationFailure, db.collection.insert, {})
        finally:
            # Cleanup
            admin.authenticate('admin', 'pw')
            remove_all_users(db)
            admin.remove_user("admin")
            admin.logout()
Exemple #45
0
    def test_make_user_readonly(self):
        if (is_mongos(self.client)
                and not version.at_least(self.client, (2, 0, 0))):
            raise SkipTest('Auth with sharding requires MongoDB >= 2.0.0')

        if not server_started_with_auth(self.client):
            raise SkipTest('Authentication is not enabled on server')

        admin = self.client.admin
        admin.add_user('admin', 'pw')
        admin.authenticate('admin', 'pw')

        db = self.client.pymongo_test

        try:
            # Make a read-write user.
            db.add_user('jesse', 'pw')
            admin.logout()

            # Check that we're read-write by default.
            db.authenticate('jesse', 'pw')
            db.collection.insert({})
            db.logout()

            # Make the user read-only.
            admin.authenticate('admin', 'pw')
            db.add_user('jesse', 'pw', read_only=True)
            admin.logout()

            db.authenticate('jesse', 'pw')
            self.assertRaises(OperationFailure, db.collection.insert, {})
        finally:
            # Cleanup
            admin.authenticate('admin', 'pw')
            remove_all_users(db)
            admin.remove_user("admin")
            admin.logout()
    def test_mongodb_x509_auth(self):
        # Expects the server to be running with the server.pem, ca.pem
        # and crl.pem provided in mongodb and the server tests as well as
        # --auth:
        #
        #   --sslPEMKeyFile=jstests/libs/server.pem
        #   --sslCAFile=jstests/libs/ca.pem
        #   --sslCRLFile=jstests/libs/crl.pem
        #   --auth
        if not test.env.mongod_validates_client_cert:
            raise SkipTest("No mongod available over SSL with certs")

        client = AsyncIOMotorClient(test.env.uri,
                                    ssl_certfile=CLIENT_PEM,
                                    io_loop=self.loop)

        if not (yield from at_least(client, (2, 5, 3, -1))):
            raise SkipTest("MONGODB-X509 tests require MongoDB 2.5.3 or newer")

        if not test.env.auth:
            raise SkipTest('Authentication is not enabled on server')

        # Give admin all necessary privileges.
        yield from client['$external'].add_user(MONGODB_X509_USERNAME, roles=[
            {'role': 'readWriteAnyDatabase', 'db': 'admin'},
            {'role': 'userAdminAnyDatabase', 'db': 'admin'}])

        collection = client.motor_test.test
        with test.assert_raises(OperationFailure):
            yield from collection.count()

        yield from client.admin.authenticate(
            MONGODB_X509_USERNAME, mechanism='MONGODB-X509')

        yield from collection.remove()
        uri = ('mongodb://%s@%s:%d/?authMechanism='
               'MONGODB-X509' % (
               quote_plus(MONGODB_X509_USERNAME), host, port))

        # SSL options aren't supported in the URI....
        auth_uri_client = AsyncIOMotorClient(uri,
                                             ssl_certfile=CLIENT_PEM,
                                             io_loop=self.loop)

        yield from auth_uri_client.db.collection.find_one()

        # Cleanup.
        yield from remove_all_users(client['$external'])
        yield from client['$external'].logout()
    def test_copy_db_auth(self):
        # This will catch any socket leaks.
        cx = self.get_client(max_pool_size=1, waitQueueTimeoutMS=1)

        # SERVER-6427, can't copy database via mongos with auth.
        yield skip_if_mongos(cx)

        target_db_name = 'motor_test_2'

        collection = cx.motor_test.test_collection
        yield collection.remove()
        yield collection.insert({'_id': 1})

        yield cx.admin.add_user('admin', 'password')
        yield cx.admin.authenticate('admin', 'password')

        try:
            yield cx.motor_test.add_user('mike', 'password')

            with assert_raises(pymongo.errors.OperationFailure):
                yield cx.copy_database(
                    'motor_test', target_db_name,
                    username='******', password='******')

            with assert_raises(pymongo.errors.OperationFailure):
                yield cx.copy_database(
                    'motor_test', target_db_name,
                    username='******', password='******')

            # Copy a database using name and password.
            yield cx.copy_database(
                'motor_test', target_db_name,
                username='******', password='******')

            self.assertEqual(
                {'_id': 1},
                (yield cx[target_db_name].test_collection.find_one()))

            yield cx.drop_database(target_db_name)
        finally:
            yield remove_all_users(cx.motor_test)
            yield cx.admin.remove_user('admin')
            cx.close()
            gc.collect()
Exemple #48
0
    def test_copy_db_auth(self):
        # See SERVER-6427.
        cx = self.get_client()
        yield skip_if_mongos(cx)

        target_db_name = 'motor_test_2'

        collection = cx.motor_test.test_collection
        yield collection.remove()
        yield collection.insert({'_id': 1})

        yield cx.admin.add_user('admin', 'password')
        yield cx.admin.authenticate('admin', 'password')

        try:
            yield cx.motor_test.add_user('mike', 'password')

            with assert_raises(pymongo.errors.OperationFailure):
                yield cx.copy_database('motor_test',
                                       target_db_name,
                                       username='******',
                                       password='******')

            with assert_raises(pymongo.errors.OperationFailure):
                yield cx.copy_database('motor_test',
                                       target_db_name,
                                       username='******',
                                       password='******')

            # Copy a database using name and password.
            yield cx.copy_database('motor_test',
                                   target_db_name,
                                   username='******',
                                   password='******')

            self.assertEqual(
                {'_id': 1},
                (yield cx[target_db_name].test_collection.find_one()))

            yield cx.drop_database(target_db_name)
        finally:
            yield remove_all_users(cx.motor_test)
            yield cx.admin.remove_user('admin')
    def test_copy_db_auth(self):
        # See SERVER-6427.
        cx = self.get_client()
        yield skip_if_mongos(cx)

        target_db_name = 'motor_test_2'

        collection = cx.motor_test.test_collection
        yield collection.remove()
        yield collection.insert({'_id': 1})

        yield cx.admin.add_user('admin', 'password')
        yield cx.admin.authenticate('admin', 'password')

        try:
            yield cx.motor_test.add_user('mike', 'password')

            with assert_raises(pymongo.errors.OperationFailure):
                yield cx.copy_database(
                    'motor_test', target_db_name,
                    username='******', password='******')

            with assert_raises(pymongo.errors.OperationFailure):
                yield cx.copy_database(
                    'motor_test', target_db_name,
                    username='******', password='******')

            # Copy a database using name and password.
            yield cx.copy_database(
                'motor_test', target_db_name,
                username='******', password='******')

            self.assertEqual(
                {'_id': 1},
                (yield cx[target_db_name].test_collection.find_one()))

            yield cx.drop_database(target_db_name)
        finally:
            yield remove_all_users(cx.motor_test)
            yield cx.admin.remove_user('admin')
Exemple #50
0
    def test_copy_db_auth_concurrent(self):
        cx = self.get_client()
        yield skip_if_mongos(cx)

        n_copies = 2
        test_db_names = ['motor_test_%s' % i for i in range(n_copies)]

        # 1. Drop old test DBs
        yield cx.drop_database('motor_test')
        yield self.drop_databases(test_db_names)

        # 2. Copy a test DB N times at once
        collection = cx.motor_test.test_collection
        yield collection.remove()
        yield collection.insert({'_id': 1})

        yield cx.admin.add_user(
            'admin',
            'password',
        )
        yield cx.admin.authenticate('admin', 'password')

        try:
            yield cx.motor_test.add_user('mike', 'password')

            results = yield [
                cx.copy_database('motor_test',
                                 test_db_name,
                                 username='******',
                                 password='******')
                for test_db_name in test_db_names
            ]

            self.assertTrue(all(isinstance(i, dict) for i in results))
            yield self.check_copydb_results({'_id': 1}, test_db_names)

        finally:
            yield remove_all_users(cx.motor_test)
            yield self.drop_databases(test_db_names, authenticated_client=cx)
            yield cx.admin.remove_user('admin')
Exemple #51
0
    def test_authenticate(self):
        # self.db is logged in as root.
        yield self.db.add_user("mike", "password")
        db = motor.MotorClient(host, port).motor_test
        try:
            # Authenticate many times at once to test concurrency.
            yield [db.authenticate("mike", "password") for _ in range(10)]

            # Just make sure there are no exceptions here.
            yield db.remove_user("mike")
            yield db.logout()
            if (yield version.at_least(self.cx, (2, 5, 4))):
                info = yield self.db.command("usersInfo", "mike")
                users = info.get('users', [])
            else:
                users = yield self.db.system.users.find().to_list(length=10)

            self.assertFalse("mike" in [u['user'] for u in users])

        finally:
            yield remove_all_users(self.db)
            test.env.sync_cx.disconnect()
    def test_copy_db_auth(self):
        # SERVER-6427, can't copy database via mongos with auth.
        yield skip_if_mongos(self.cx)

        yield self.collection.insert({'_id': 1})

        try:
            # self.cx is logged in as root.
            yield self.cx.motor_test.add_user('mike', 'password')

            # This will catch any socket leaks.
            client = self.get_client(max_pool_size=1, waitQueueTimeoutMS=1)
            target_db_name = 'motor_test_2'

            with assert_raises(pymongo.errors.OperationFailure):
                yield client.copy_database('motor_test',
                                           target_db_name,
                                           username='******',
                                           password='******')

            with assert_raises(pymongo.errors.OperationFailure):
                yield client.copy_database('motor_test',
                                           target_db_name,
                                           username='******',
                                           password='******')

            # Copy a database using name and password.
            yield client.copy_database('motor_test',
                                       target_db_name,
                                       username='******',
                                       password='******')

            self.assertEqual(
                {'_id': 1},
                (yield client[target_db_name].test_collection.find_one()))

            yield client.drop_database(target_db_name)
        finally:
            yield remove_all_users(self.cx.motor_test)
Exemple #53
0
    def test_auth_from_uri(self):
        if not test.env.auth:
            raise SkipTest("Authentication is not enabled on server")

        # self.db is logged in as root.
        yield remove_all_users(self.db)
        db = self.db
        try:
            yield db.add_user("mike", "password", roles=["userAdmin", "readWrite"])

            client = motor.MotorClient("mongodb://*****:*****@%s:%d" % (host, port))

            # Note: open() only calls ismaster, doesn't throw auth errors.
            yield client.open()

            with assert_raises(OperationFailure):
                yield client.db.collection.find_one()

            client = motor.MotorClient("mongodb://*****:*****@%s:%d/%s" % (host, port, db.name))

            yield client[db.name].collection.find_one()
        finally:
            yield db.remove_user("mike")
Exemple #54
0
 def tearDown(self):
     self.db.command('dropRole', 'noremove')
     remove_all_users(self.db)
    def test_copy_db(self):
        c = self._get_client()
        # We test copy twice; once starting in a request and once not. In
        # either case the copy should succeed (because it starts a request
        # internally) and should leave us in the same state as before the copy.
        c.start_request()

        self.assertRaises(TypeError, c.copy_database, 4, "foo")
        self.assertRaises(TypeError, c.copy_database, "foo", 4)

        self.assertRaises(InvalidName, c.copy_database, "foo", "$foo")

        c.pymongo_test.test.drop()
        c.drop_database("pymongo_test1")
        c.drop_database("pymongo_test2")

        c.pymongo_test.test.insert({"foo": "bar"})

        self.assertFalse("pymongo_test1" in c.database_names())
        self.assertFalse("pymongo_test2" in c.database_names())

        c.copy_database("pymongo_test", "pymongo_test1")
        # copy_database() didn't accidentally end the request
        self.assertTrue(c.in_request())

        self.assertTrue("pymongo_test1" in c.database_names())
        self.assertEqual("bar", c.pymongo_test1.test.find_one()["foo"])

        c.end_request()

        self.assertFalse(c.in_request())
        c.copy_database("pymongo_test", "pymongo_test2", pair)
        # copy_database() didn't accidentally restart the request
        self.assertFalse(c.in_request())

        time.sleep(1)

        self.assertTrue("pymongo_test2" in c.database_names())
        self.assertEqual("bar", c.pymongo_test2.test.find_one()["foo"])

        if version.at_least(c, (1, 3, 3, 1)) and server_started_with_auth(c):
            c.drop_database("pymongo_test1")

            c.admin.add_user("admin", "password")
            c.admin.authenticate("admin", "password")
            try:
                c.pymongo_test.add_user("mike", "password")

                self.assertRaises(OperationFailure,
                                  c.copy_database,
                                  "pymongo_test",
                                  "pymongo_test1",
                                  username="******",
                                  password="******")
                self.assertFalse("pymongo_test1" in c.database_names())

                self.assertRaises(OperationFailure,
                                  c.copy_database,
                                  "pymongo_test",
                                  "pymongo_test1",
                                  username="******",
                                  password="******")
                self.assertFalse("pymongo_test1" in c.database_names())

                c.copy_database("pymongo_test",
                                "pymongo_test1",
                                username="******",
                                password="******")
                self.assertTrue("pymongo_test1" in c.database_names())
                res = c.pymongo_test1.test.find_one(_must_use_master=True)
                self.assertEqual("bar", res["foo"])
            finally:
                # Cleanup
                remove_all_users(c.pymongo_test)
                c.admin.remove_user("admin")
        c.close()
    def test_authenticate_multiple(self):
        client = get_client()
        if (is_mongos(client) and not
            version.at_least(self.client, (2, 0, 0))):
            raise SkipTest("Auth with sharding requires MongoDB >= 2.0.0")
        if not server_started_with_auth(client):
            raise SkipTest("Authentication is not enabled on server")

        # Setup
        users_db = client.pymongo_test
        admin_db = client.admin
        other_db = client.pymongo_test1
        remove_all_users(users_db)
        remove_all_users(admin_db)
        remove_all_users(other_db)
        users_db.test.remove()
        other_db.test.remove()

        admin_db.add_user('admin', 'pass',
                          roles=["userAdminAnyDatabase", "dbAdmin",
                                 "clusterAdmin", "readWrite"])
        self.assertTrue(admin_db.authenticate('admin', 'pass'))

        if version.at_least(self.client, (2, 5, 3, -1)):
            admin_db.add_user('ro-admin', 'pass',
                              roles=["userAdmin", "readAnyDatabase"])
        else:
            admin_db.add_user('ro-admin', 'pass', read_only=True)

        users_db.add_user('user', 'pass',
                          roles=["userAdmin", "readWrite"])

        admin_db.logout()
        self.assertRaises(OperationFailure, users_db.test.find_one)

        # Regular user should be able to query its own db, but
        # no other.
        users_db.authenticate('user', 'pass')
        self.assertEqual(0, users_db.test.count())
        self.assertRaises(OperationFailure, other_db.test.find_one)

        # Admin read-only user should be able to query any db,
        # but not write.
        admin_db.authenticate('ro-admin', 'pass')
        self.assertEqual(0, other_db.test.count())
        self.assertRaises(OperationFailure,
                          other_db.test.insert, {})

        # Force close all sockets
        client.disconnect()

        # We should still be able to write to the regular user's db
        self.assertTrue(users_db.test.remove())
        # And read from other dbs...
        self.assertEqual(0, other_db.test.count())
        # But still not write to other dbs...
        self.assertRaises(OperationFailure,
                          other_db.test.insert, {})

        # Cleanup
        admin_db.logout()
        users_db.logout()
        self.assertTrue(admin_db.authenticate('admin', 'pass'))
        users_db.remove_user('user')
        admin_db.remove_user('ro-admin')
        admin_db.remove_user('admin')
Exemple #57
0
    def test_copy_db(self):
        c = MongoClient(host, port)
        # Due to SERVER-2329, databases may not disappear
        # from a master in a master-slave pair.
        if server_is_master_with_slave(c):
            raise SkipTest("SERVER-2329")
        # We test copy twice; once starting in a request and once not. In
        # either case the copy should succeed (because it starts a request
        # internally) and should leave us in the same state as before the copy.
        c.start_request()

        self.assertRaises(TypeError, c.copy_database, 4, "foo")
        self.assertRaises(TypeError, c.copy_database, "foo", 4)

        self.assertRaises(InvalidName, c.copy_database, "foo", "$foo")

        c.pymongo_test.test.drop()
        c.drop_database("pymongo_test1")
        c.drop_database("pymongo_test2")
        self.assertFalse("pymongo_test1" in c.database_names())
        self.assertFalse("pymongo_test2" in c.database_names())

        c.pymongo_test.test.insert({"foo": "bar"})

        c.copy_database("pymongo_test", "pymongo_test1")
        # copy_database() didn't accidentally end the request
        self.assertTrue(c.in_request())

        self.assertTrue("pymongo_test1" in c.database_names())
        self.assertEqual("bar", c.pymongo_test1.test.find_one()["foo"])

        c.end_request()
        self.assertFalse(c.in_request())
        c.copy_database("pymongo_test", "pymongo_test2",
                        "%s:%d" % (host, port))
        # copy_database() didn't accidentally restart the request
        self.assertFalse(c.in_request())

        self.assertTrue("pymongo_test2" in c.database_names())
        self.assertEqual("bar", c.pymongo_test2.test.find_one()["foo"])

        # See SERVER-6427 for mongos
        if (version.at_least(c, (1, 3, 3, 1)) and not is_mongos(c)
                and server_started_with_auth(c)):

            c.drop_database("pymongo_test1")

            c.admin.add_user("admin", "password")
            c.admin.authenticate("admin", "password")
            try:
                c.pymongo_test.add_user("mike", "password")

                self.assertRaises(OperationFailure,
                                  c.copy_database,
                                  "pymongo_test",
                                  "pymongo_test1",
                                  username="******",
                                  password="******")
                self.assertFalse("pymongo_test1" in c.database_names())

                self.assertRaises(OperationFailure,
                                  c.copy_database,
                                  "pymongo_test",
                                  "pymongo_test1",
                                  username="******",
                                  password="******")
                self.assertFalse("pymongo_test1" in c.database_names())

                c.copy_database("pymongo_test",
                                "pymongo_test1",
                                username="******",
                                password="******")
                self.assertTrue("pymongo_test1" in c.database_names())
                self.assertEqual("bar", c.pymongo_test1.test.find_one()["foo"])
            finally:
                # Cleanup
                remove_all_users(c.pymongo_test)
                c.admin.remove_user("admin")
                c.disconnect()
    def test_authenticate_add_remove_user(self):
        authed_client = auth_context.client
        db = authed_client.pymongo_test

        # Configuration errors
        self.assertRaises(ValueError, db.add_user, "user", '')
        self.assertRaises(TypeError, db.add_user, "user", 'password', 15)
        self.assertRaises(ConfigurationError, db.add_user, "user", 'password',
                          'True')
        self.assertRaises(ConfigurationError,
                          db.add_user,
                          "user",
                          'password',
                          True,
                          roles=['read'])

        if version.at_least(authed_client, (2, 5, 3, -1)):
            ctx = catch_warnings()
            try:
                warnings.simplefilter("error", DeprecationWarning)
                self.assertRaises(DeprecationWarning, db.add_user, "user",
                                  "password")
                self.assertRaises(DeprecationWarning, db.add_user, "user",
                                  "password", True)
            finally:
                ctx.exit()

            self.assertRaises(ConfigurationError,
                              db.add_user,
                              "user",
                              "password",
                              digestPassword=True)

        authed_client.admin.add_user("admin", "password")
        self.client.admin.authenticate("admin", "password")
        db = self.client.pymongo_test

        try:
            # Add / authenticate / remove
            db.add_user("mike", "password")
            self.assertRaises(TypeError, db.authenticate, 5, "password")
            self.assertRaises(TypeError, db.authenticate, "mike", 5)
            self.assertRaises(OperationFailure, db.authenticate, "mike",
                              "not a real password")
            self.assertRaises(OperationFailure, db.authenticate, "faker",
                              "password")
            self.assertTrue(db.authenticate("mike", "password"))
            db.logout()
            self.assertTrue(db.authenticate(u"mike", u"password"))
            db.remove_user("mike")
            db.logout()

            self.assertRaises(OperationFailure, db.authenticate, "mike",
                              "password")

            # Add / authenticate / change password
            self.assertRaises(OperationFailure, db.authenticate, "Gustave",
                              u"Dor\xe9")
            db.add_user("Gustave", u"Dor\xe9")
            self.assertTrue(db.authenticate("Gustave", u"Dor\xe9"))
            db.add_user("Gustave", "password")
            db.logout()
            self.assertRaises(OperationFailure, db.authenticate, "Gustave",
                              u"Dor\xe9")
            self.assertTrue(db.authenticate("Gustave", u"password"))

            if not version.at_least(authed_client, (2, 5, 3, -1)):
                # Add a readOnly user
                db.add_user("Ross", "password", read_only=True)
                db.logout()
                self.assertTrue(db.authenticate("Ross", u"password"))
                self.assertTrue(
                    db.system.users.find({
                        "readOnly": True
                    }).count())
                db.logout()

        # Cleanup
        finally:
            remove_all_users(db)
            self.client.admin.remove_user("admin")
            self.client.admin.logout()
    def test_authenticate_multiple(self):
        client = get_client()
        authed_client = auth_context.client
        if (is_mongos(authed_client)
                and not version.at_least(authed_client, (2, 2, 0))):
            raise SkipTest("Need mongos >= 2.2.0")

        # Setup
        authed_client.pymongo_test.test.drop()
        authed_client.pymongo_test1.test.drop()
        users_db = client.pymongo_test
        admin_db = client.admin
        other_db = client.pymongo_test1

        authed_client.admin.add_user('admin',
                                     'pass',
                                     roles=[
                                         "userAdminAnyDatabase", "dbAdmin",
                                         "clusterAdmin", "readWrite"
                                     ])
        try:
            self.assertTrue(admin_db.authenticate('admin', 'pass'))

            if version.at_least(self.client, (2, 5, 3, -1)):
                admin_db.add_user('ro-admin',
                                  'pass',
                                  roles=["userAdmin", "readAnyDatabase"])
            else:
                admin_db.add_user('ro-admin', 'pass', read_only=True)

            users_db.add_user('user', 'pass', roles=["userAdmin", "readWrite"])

            admin_db.logout()
            self.assertRaises(OperationFailure, users_db.test.find_one)

            # Regular user should be able to query its own db, but
            # no other.
            users_db.authenticate('user', 'pass')
            self.assertEqual(0, users_db.test.count())
            self.assertRaises(OperationFailure, other_db.test.find_one)

            # Admin read-only user should be able to query any db,
            # but not write.
            admin_db.authenticate('ro-admin', 'pass')
            self.assertEqual(0, other_db.test.count())
            self.assertRaises(OperationFailure, other_db.test.insert, {})

            # Force close all sockets
            client.disconnect()

            # We should still be able to write to the regular user's db
            self.assertTrue(users_db.test.remove())
            # And read from other dbs...
            self.assertEqual(0, other_db.test.count())
            # But still not write to other dbs...
            self.assertRaises(OperationFailure, other_db.test.insert, {})

        # Cleanup
        finally:
            admin_db.logout()
            users_db.logout()
            admin_db.authenticate('admin', 'pass')
            remove_all_users(users_db)
            admin_db.remove_user('ro-admin')
            admin_db.remove_user('admin')