Simplify auth tests, don't create additional root users.
Don't log out the global test client either; keep it logged in as root and use it to create additional non-root users to test Database.add_user, authenticate, logout, and so on.
This commit is contained in:
parent
1732b09155
commit
13cb74a760
@ -51,11 +51,12 @@ from test import (client_context,
|
||||
unittest,
|
||||
host,
|
||||
port,
|
||||
pair,
|
||||
IntegrationTest)
|
||||
IntegrationTest,
|
||||
db_user)
|
||||
from test.utils import (
|
||||
ignore_deprecations,
|
||||
remove_all_users,
|
||||
rs_or_single_client_noauth,
|
||||
server_started_with_auth)
|
||||
|
||||
|
||||
@ -365,58 +366,58 @@ class TestDatabase(IntegrationTest):
|
||||
|
||||
@client_context.require_auth
|
||||
def test_authenticate_add_remove_user(self):
|
||||
db = self.client.pymongo_test
|
||||
# "self.client" is logged in as root.
|
||||
auth_db = self.client.pymongo_test
|
||||
db = rs_or_single_client_noauth().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,
|
||||
self.assertRaises(ValueError, auth_db.add_user, "user", '')
|
||||
self.assertRaises(TypeError, auth_db.add_user, "user", 'password', 15)
|
||||
self.assertRaises(ConfigurationError, auth_db.add_user,
|
||||
"user", 'password', 'True')
|
||||
self.assertRaises(ConfigurationError, db.add_user,
|
||||
self.assertRaises(ConfigurationError, auth_db.add_user,
|
||||
"user", 'password', True, roles=['read'])
|
||||
|
||||
if client_context.version.at_least(2, 5, 3, -1):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("error", DeprecationWarning)
|
||||
self.assertRaises(DeprecationWarning, db.add_user,
|
||||
self.assertRaises(DeprecationWarning, auth_db.add_user,
|
||||
"user", "password")
|
||||
self.assertRaises(DeprecationWarning, db.add_user,
|
||||
self.assertRaises(DeprecationWarning, auth_db.add_user,
|
||||
"user", "password", True)
|
||||
|
||||
with ignore_deprecations():
|
||||
self.assertRaises(ConfigurationError, db.add_user,
|
||||
self.assertRaises(ConfigurationError, auth_db.add_user,
|
||||
"user", "password", digestPassword=True)
|
||||
|
||||
self.client.admin.add_user("admin", "password",
|
||||
roles=["root", "userAdminAnyDatabase"])
|
||||
auth_c = MongoClient(pair)
|
||||
auth_c.admin.authenticate("admin", "password")
|
||||
db = auth_c.pymongo_test
|
||||
|
||||
try:
|
||||
# Add / authenticate / remove
|
||||
db.add_user("mike", "password", roles=["dbOwner"])
|
||||
auth_db.add_user("mike", "password", roles=["dbOwner"])
|
||||
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.authenticate("mike", "password")
|
||||
db.logout()
|
||||
|
||||
# Unicode name and password.
|
||||
db.authenticate(u("mike"), u("password"))
|
||||
db.logout()
|
||||
|
||||
auth_db.remove_user("mike")
|
||||
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"), roles=["dbOwner"])
|
||||
self.assertTrue(db.authenticate("Gustave", u("Dor\xe9")))
|
||||
db.add_user("Gustave", "password", roles=["dbOwner"])
|
||||
auth_db.add_user("Gustave", u("Dor\xe9"), roles=["dbOwner"])
|
||||
db.authenticate("Gustave", u("Dor\xe9"))
|
||||
|
||||
# Change password.
|
||||
auth_db.add_user("Gustave", "password", roles=["dbOwner"])
|
||||
db.logout()
|
||||
self.assertRaises(OperationFailure,
|
||||
db.authenticate, "Gustave", u("Dor\xe9"))
|
||||
@ -425,33 +426,24 @@ class TestDatabase(IntegrationTest):
|
||||
if not client_context.version.at_least(2, 5, 3, -1):
|
||||
# Add a readOnly user
|
||||
with ignore_deprecations():
|
||||
db.add_user("Ross", "password", read_only=True)
|
||||
auth_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
|
||||
db.authenticate("Ross", u("password"))
|
||||
self.assertTrue(
|
||||
auth_db.system.users.find({"readOnly": True}).count())
|
||||
finally:
|
||||
remove_all_users(db)
|
||||
db.logout()
|
||||
auth_c.admin.remove_user("admin")
|
||||
remove_all_users(auth_db)
|
||||
|
||||
@client_context.require_auth
|
||||
def test_make_user_readonly(self):
|
||||
auth_c = MongoClient(pair)
|
||||
admin = auth_c.admin
|
||||
self.client.admin.add_user('admin', 'pw',
|
||||
roles=['root', 'userAdminAnyDatabase'])
|
||||
admin.authenticate('admin', 'pw')
|
||||
|
||||
db = auth_c.pymongo_test
|
||||
# "self.client" is logged in as root.
|
||||
auth_db = self.client.pymongo_test
|
||||
db = rs_or_single_client_noauth().pymongo_test
|
||||
|
||||
try:
|
||||
# Make a read-write user.
|
||||
db.add_user('jesse', 'pw')
|
||||
admin.logout()
|
||||
auth_db.add_user('jesse', 'pw')
|
||||
|
||||
# Check that we're read-write by default.
|
||||
db.authenticate('jesse', 'pw')
|
||||
@ -459,81 +451,54 @@ class TestDatabase(IntegrationTest):
|
||||
db.logout()
|
||||
|
||||
# Make the user read-only.
|
||||
admin.authenticate('admin', 'pw')
|
||||
db.add_user('jesse', 'pw', read_only=True)
|
||||
admin.logout()
|
||||
auth_db.add_user('jesse', 'pw', read_only=True)
|
||||
|
||||
db.authenticate('jesse', 'pw')
|
||||
self.assertRaises(OperationFailure, db.collection.insert, {})
|
||||
finally:
|
||||
# Cleanup
|
||||
admin.authenticate('admin', 'pw')
|
||||
remove_all_users(db)
|
||||
admin.remove_user("admin")
|
||||
remove_all_users(auth_db)
|
||||
|
||||
@client_context.require_version_min(2, 5, 3, -1)
|
||||
@client_context.require_auth
|
||||
def test_default_roles(self):
|
||||
# "Admin" user
|
||||
with ignore_deprecations():
|
||||
self.client.admin.add_user('admin', 'pass')
|
||||
|
||||
auth_c = MongoClient(pair)
|
||||
db = auth_c.admin
|
||||
# "self.client" is logged in as root.
|
||||
auth_admin = self.client.admin
|
||||
try:
|
||||
db.authenticate('admin', 'pass')
|
||||
info = db.command('usersInfo', 'admin')['users'][0]
|
||||
info = auth_admin.command('usersInfo', db_user)['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]
|
||||
auth_admin.add_user('ro-admin', 'pass', read_only=True)
|
||||
info = auth_admin.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()
|
||||
auth_admin.remove_user('ro-admin')
|
||||
|
||||
# "Non-admin" user
|
||||
db = auth_c.pymongo_test
|
||||
self.client.pymongo_test.add_user('user', 'pass')
|
||||
auth_db = self.client.pymongo_test
|
||||
auth_db.add_user('user', 'pass')
|
||||
try:
|
||||
db.authenticate('user', 'pass')
|
||||
info = db.command('usersInfo', 'user')['users'][0]
|
||||
info = auth_db.command('usersInfo', 'user')['users'][0]
|
||||
self.assertEqual("dbOwner", info['roles'][0]['role'])
|
||||
db.logout()
|
||||
|
||||
# Read only "Non-admin" user
|
||||
self.client.pymongo_test.add_user('ro-user', 'pass',
|
||||
read_only=True)
|
||||
db.authenticate('ro-user', 'pass')
|
||||
info = db.command('usersInfo', 'ro-user')['users'][0]
|
||||
auth_db.add_user('ro-user', 'pass', read_only=True)
|
||||
info = auth_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)
|
||||
remove_all_users(auth_db)
|
||||
|
||||
@client_context.require_version_min(2, 5, 3, -1)
|
||||
@client_context.require_auth
|
||||
def test_new_user_cmds(self):
|
||||
auth_c = MongoClient(pair)
|
||||
db = auth_c.pymongo_test
|
||||
self.client.pymongo_test.add_user("amalia", "password",
|
||||
roles=["userAdmin"])
|
||||
# "self.client" is logged in as root.
|
||||
auth_db = self.client.pymongo_test
|
||||
auth_db.add_user("amalia", "password", roles=["userAdmin"])
|
||||
|
||||
db.authenticate("amalia", "password")
|
||||
try:
|
||||
db = rs_or_single_client_noauth().pymongo_test
|
||||
db.authenticate("amalia", "password")
|
||||
|
||||
# This tests the ability to update user attributes.
|
||||
db.add_user("amalia", "new_password",
|
||||
customData={"secret": "koalas"})
|
||||
@ -544,61 +509,33 @@ class TestDatabase(IntegrationTest):
|
||||
self.assertEqual(amalia_user["user"], "amalia")
|
||||
self.assertEqual(amalia_user["customData"], {"secret": "koalas"})
|
||||
finally:
|
||||
db.remove_user("amalia")
|
||||
|
||||
@client_context.require_auth
|
||||
def test_authenticate_and_safe(self):
|
||||
auth_c = MongoClient(pair)
|
||||
db = auth_c.auth_test
|
||||
|
||||
self.client.auth_test.add_user(
|
||||
"bernie", "password",
|
||||
roles=["userAdmin", "dbAdmin", "readWrite"])
|
||||
db.authenticate("bernie", "password")
|
||||
try:
|
||||
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())
|
||||
finally:
|
||||
db.remove_user("bernie")
|
||||
auth_db.remove_user("amalia")
|
||||
|
||||
@client_context.require_auth
|
||||
def test_authenticate_multiple(self):
|
||||
# Setup
|
||||
# "self.client" is logged in as root.
|
||||
self.client.drop_database("pymongo_test")
|
||||
self.client.drop_database("pymongo_test1")
|
||||
auth_c = MongoClient(pair)
|
||||
users_db = auth_c.pymongo_test
|
||||
admin_db = auth_c.admin
|
||||
other_db = auth_c.pymongo_test1
|
||||
admin_db_auth = self.client.admin
|
||||
users_db_auth = self.client.pymongo_test
|
||||
|
||||
# Non-root client.
|
||||
client = rs_or_single_client_noauth()
|
||||
admin_db = client.admin
|
||||
users_db = client.pymongo_test
|
||||
other_db = client.pymongo_test1
|
||||
|
||||
self.client.admin.add_user(
|
||||
'admin', 'pass',
|
||||
roles=["userAdminAnyDatabase", "dbAdmin",
|
||||
"clusterAdmin", "readWrite"])
|
||||
try:
|
||||
self.assertTrue(admin_db.authenticate('admin', 'pass'))
|
||||
self.assertRaises(OperationFailure, users_db.test.find_one)
|
||||
|
||||
if client_context.version.at_least(2, 5, 3, -1):
|
||||
admin_db.add_user('ro-admin', 'pass',
|
||||
roles=["userAdmin", "readAnyDatabase"])
|
||||
admin_db_auth.add_user('ro-admin', 'pass',
|
||||
roles=["userAdmin", "readAnyDatabase"])
|
||||
else:
|
||||
admin_db.add_user('ro-admin', 'pass', read_only=True)
|
||||
admin_db_auth.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)
|
||||
users_db_auth.add_user('user', 'pass',
|
||||
roles=["userAdmin", "readWrite"])
|
||||
|
||||
# Regular user should be able to query its own db, but
|
||||
# no other.
|
||||
@ -613,22 +550,21 @@ class TestDatabase(IntegrationTest):
|
||||
self.assertRaises(OperationFailure,
|
||||
other_db.test.insert, {})
|
||||
|
||||
# Force close all sockets
|
||||
auth_c.disconnect()
|
||||
# Close all sockets.
|
||||
client.disconnect()
|
||||
|
||||
# We should still be able to write to the regular user's db
|
||||
# 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...
|
||||
|
||||
# But still not write to other dbs.
|
||||
self.assertRaises(OperationFailure,
|
||||
other_db.test.insert, {})
|
||||
|
||||
# Cleanup
|
||||
finally:
|
||||
remove_all_users(users_db)
|
||||
self.client.admin.remove_user('ro-admin')
|
||||
self.client.admin.remove_user('admin')
|
||||
remove_all_users(users_db_auth)
|
||||
admin_db_auth.remove_user('ro-admin')
|
||||
|
||||
def test_id_ordering(self):
|
||||
# PyMongo attempts to have _id show up first
|
||||
|
||||
@ -15,14 +15,13 @@
|
||||
"""Test that pymongo is thread safe."""
|
||||
|
||||
import threading
|
||||
import traceback
|
||||
|
||||
from test import unittest, client_context, IntegrationTest, db_user, db_pwd
|
||||
from test.utils import (frequent_thread_switches,
|
||||
joinall,
|
||||
remove_all_users,
|
||||
RendezvousThread,
|
||||
rs_or_single_client)
|
||||
rs_or_single_client,
|
||||
rs_or_single_client_noauth)
|
||||
from test.utils import get_pool
|
||||
from pymongo.pool import SocketInfo, _closed
|
||||
from pymongo.errors import AutoReconnect, OperationFailure
|
||||
@ -39,17 +38,15 @@ class AutoAuthenticateThreads(threading.Thread):
|
||||
threading.Thread.__init__(self)
|
||||
self.coll = collection
|
||||
self.num = num
|
||||
self.success = True
|
||||
self.success = False
|
||||
self.setDaemon(True)
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
for i in range(self.num):
|
||||
self.coll.insert({'num':i})
|
||||
self.coll.find_one({'num':i})
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
self.success = False
|
||||
for i in range(self.num):
|
||||
self.coll.insert({'num': i})
|
||||
self.coll.find_one({'num': i})
|
||||
|
||||
self.success = True
|
||||
|
||||
|
||||
class SaveAndFind(threading.Thread):
|
||||
@ -331,56 +328,17 @@ class TestThreadsAuth(IntegrationTest):
|
||||
def setUpClass(cls):
|
||||
super(TestThreadsAuth, cls).setUpClass()
|
||||
|
||||
def setUp(self):
|
||||
self.client.admin.add_user('admin-user', 'password',
|
||||
roles=['clusterAdmin',
|
||||
'dbAdminAnyDatabase',
|
||||
'readWriteAnyDatabase',
|
||||
'userAdminAnyDatabase'])
|
||||
|
||||
# client is already authenticated to get around restricted
|
||||
# localhost exception in MongoDB >= 2.7.1.
|
||||
self.client.admin.logout()
|
||||
self.client.admin.authenticate("admin-user", "password")
|
||||
self.client.auth_test.add_user("test-user", "password",
|
||||
roles=['readWrite'])
|
||||
|
||||
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')
|
||||
self.client.admin.remove_user('admin-user')
|
||||
self.client.admin.logout()
|
||||
self.client.admin.authenticate(db_user, db_pwd)
|
||||
|
||||
def test_auto_auth_login(self):
|
||||
client = self.client
|
||||
client.admin.logout()
|
||||
client = rs_or_single_client_noauth()
|
||||
self.assertRaises(OperationFailure, client.auth_test.test.find_one)
|
||||
|
||||
# Admin auth
|
||||
client.admin.authenticate("admin-user", "password")
|
||||
client.admin.authenticate(db_user, db_pwd)
|
||||
|
||||
nthreads = 10
|
||||
threads = []
|
||||
for _ in range(nthreads):
|
||||
t = AutoAuthenticateThreads(client.auth_test.test, 100)
|
||||
t.start()
|
||||
threads.append(t)
|
||||
|
||||
joinall(threads)
|
||||
|
||||
for t in threads:
|
||||
self.assertTrue(t.success)
|
||||
|
||||
# Database-specific auth
|
||||
client.admin.logout()
|
||||
client.auth_test.authenticate("test-user", "password")
|
||||
|
||||
threads = []
|
||||
for _ in range(nthreads):
|
||||
t = AutoAuthenticateThreads(client.auth_test.test, 100)
|
||||
t = AutoAuthenticateThreads(client.auth_test.test, 10)
|
||||
t.start()
|
||||
threads.append(t)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user