summaryrefslogtreecommitdiff
path: root/jstests/auth
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/auth')
-rw-r--r--jstests/auth/auth3.js40
-rw-r--r--jstests/auth/auth_helpers.js32
-rw-r--r--jstests/auth/auth_mechanism_discovery.js91
-rw-r--r--jstests/auth/auth_mechanisms_parsing.js14
-rw-r--r--jstests/auth/authentication_restrictions.js428
-rw-r--r--jstests/auth/authentication_restrictions_role.js778
-rw-r--r--jstests/auth/authz_modifications_access_control.js1
-rw-r--r--jstests/auth/autocomplete_auth.js58
-rw-r--r--jstests/auth/basic_role_auth.js330
-rw-r--r--jstests/auth/cluster_ip_whitelist.js101
-rw-r--r--jstests/auth/commands_builtin_roles.js12
-rw-r--r--jstests/auth/commands_user_defined_roles.js13
-rw-r--r--jstests/auth/curop_auth_info.js132
-rw-r--r--jstests/auth/currentop_cursors_auth.js262
-rw-r--r--jstests/auth/deleted_recreated_user.js116
-rw-r--r--jstests/auth/getMore.js682
-rw-r--r--jstests/auth/iteration_count_control.js60
-rw-r--r--jstests/auth/iteration_count_defaults.js38
-rw-r--r--jstests/auth/keyfile_rollover.js128
-rw-r--r--jstests/auth/kill_cursors.js328
-rw-r--r--jstests/auth/kill_sessions.js22
-rw-r--r--jstests/auth/killop_own_ops.js277
-rw-r--r--jstests/auth/list_all_local_sessions.js108
-rw-r--r--jstests/auth/list_all_sessions.js98
-rw-r--r--jstests/auth/list_collections_filter_views.js103
-rw-r--r--jstests/auth/list_collections_own_collections.js345
-rw-r--r--jstests/auth/list_databases.js308
-rw-r--r--jstests/auth/list_local_sessions.js117
-rw-r--r--jstests/auth/list_sessions.js158
-rw-r--r--jstests/auth/listcommands_preauth.js54
-rw-r--r--jstests/auth/logs_include_client_info.js36
-rw-r--r--jstests/auth/mongoURIAuth.js102
-rw-r--r--jstests/auth/mongos_cache_invalidation.js2
-rw-r--r--jstests/auth/pinned_users.js347
-rw-r--r--jstests/auth/pre_auth_commands_with_sessions.js95
-rw-r--r--jstests/auth/prepared_transaction.js392
-rw-r--r--jstests/auth/refresh_logical_session_cache_with_long_usernames.js63
-rw-r--r--jstests/auth/renameRestrictedCollections.js218
-rw-r--r--jstests/auth/resource_pattern_matching.js62
-rw-r--r--jstests/auth/role_management_commands_edge_cases.js10
-rw-r--r--jstests/auth/role_management_commands_lib.js8
-rw-r--r--jstests/auth/role_management_commands_sharded_wc_1.js24
-rw-r--r--jstests/auth/role_management_commands_sharded_wc_majority.js24
-rw-r--r--jstests/auth/role_management_commands_standalone.js10
-rw-r--r--jstests/auth/sasl_mechanism_discovery.js122
-rw-r--r--jstests/auth/scram-credentials-invalid.js75
-rw-r--r--jstests/auth/shell.js22
-rw-r--r--jstests/auth/system_auth_scram_mechs.js26
-rw-r--r--jstests/auth/system_roles_collMod.js32
-rw-r--r--jstests/auth/system_user_exception.js24
-rw-r--r--jstests/auth/system_user_privileges.js174
-rw-r--r--jstests/auth/transactions.js276
-rw-r--r--jstests/auth/upgrade_noauth_to_keyfile.js64
-rw-r--r--jstests/auth/upgrade_noauth_to_keyfile_with_sharding.js36
-rw-r--r--jstests/auth/user_cache_doc_source.js86
-rw-r--r--jstests/auth/user_defined_roles.js7
-rw-r--r--jstests/auth/user_defined_roles_on_secondaries.js380
-rw-r--r--jstests/auth/user_management_commands_edge_cases.js1
-rw-r--r--jstests/auth/user_management_commands_lib.js17
-rw-r--r--jstests/auth/user_management_commands_mechanisms.js394
-rw-r--r--jstests/auth/user_management_commands_sharded_wc_1.js14
-rw-r--r--jstests/auth/user_management_commands_sharded_wc_majority.js14
-rw-r--r--jstests/auth/user_management_commands_standalone.js10
-rw-r--r--jstests/auth/user_special_chars.js97
-rw-r--r--jstests/auth/usersInfo.js83
-rw-r--r--jstests/auth/validate_auth_schema_on_startup.js65
-rw-r--r--jstests/auth/views_authz.js261
67 files changed, 4388 insertions, 4519 deletions
diff --git a/jstests/auth/auth3.js b/jstests/auth/auth3.js
index 6ded435c508..29f61f1c7ee 100644
--- a/jstests/auth/auth3.js
+++ b/jstests/auth/auth3.js
@@ -1,33 +1,33 @@
(function() {
- 'use strict';
+'use strict';
- var conn = MongoRunner.runMongod({auth: ""});
+var conn = MongoRunner.runMongod({auth: ""});
- var admin = conn.getDB("admin");
- var errorCodeUnauthorized = 13;
+var admin = conn.getDB("admin");
+var errorCodeUnauthorized = 13;
- admin.createUser({user: "foo", pwd: "bar", roles: jsTest.adminUserRoles});
+admin.createUser({user: "foo", pwd: "bar", roles: jsTest.adminUserRoles});
- print("make sure curop, killop, and unlock fail");
+print("make sure curop, killop, and unlock fail");
- var x = admin.currentOp();
- assert(!("inprog" in x), tojson(x));
- assert.eq(x.code, errorCodeUnauthorized, tojson(x));
+var x = admin.currentOp();
+assert(!("inprog" in x), tojson(x));
+assert.eq(x.code, errorCodeUnauthorized, tojson(x));
- x = admin.killOp(123);
- assert(!("info" in x), tojson(x));
- assert.eq(x.code, errorCodeUnauthorized, tojson(x));
+x = admin.killOp(123);
+assert(!("info" in x), tojson(x));
+assert.eq(x.code, errorCodeUnauthorized, tojson(x));
- x = admin.fsyncUnlock();
- assert(x.errmsg != "fsyncUnlock called when not locked", tojson(x));
- assert.eq(x.code, errorCodeUnauthorized, tojson(x));
+x = admin.fsyncUnlock();
+assert(x.errmsg != "fsyncUnlock called when not locked", tojson(x));
+assert.eq(x.code, errorCodeUnauthorized, tojson(x));
- conn.getDB("admin").auth("foo", "bar");
+conn.getDB("admin").auth("foo", "bar");
- assert("inprog" in admin.currentOp());
- assert("info" in admin.killOp(123));
- assert.eq(admin.fsyncUnlock().errmsg, "fsyncUnlock called when not locked");
+assert("inprog" in admin.currentOp());
+assert("info" in admin.killOp(123));
+assert.eq(admin.fsyncUnlock().errmsg, "fsyncUnlock called when not locked");
- MongoRunner.stopMongod(conn, null, {user: "foo", pwd: "bar"});
+MongoRunner.stopMongod(conn, null, {user: "foo", pwd: "bar"});
})();
diff --git a/jstests/auth/auth_helpers.js b/jstests/auth/auth_helpers.js
index 0e944560e0b..f2d9f458eac 100644
--- a/jstests/auth/auth_helpers.js
+++ b/jstests/auth/auth_helpers.js
@@ -1,24 +1,24 @@
// Test the db.auth() shell helper.
(function() {
- 'use strict';
+'use strict';
- const conn = MongoRunner.runMongod();
- const admin = conn.getDB('admin');
+const conn = MongoRunner.runMongod();
+const admin = conn.getDB('admin');
- admin.createUser({user: 'andy', pwd: 'a', roles: jsTest.adminUserRoles});
- assert(admin.auth({user: 'andy', pwd: 'a'}));
- assert(admin.logout());
+admin.createUser({user: 'andy', pwd: 'a', roles: jsTest.adminUserRoles});
+assert(admin.auth({user: 'andy', pwd: 'a'}));
+assert(admin.logout());
- // Try all the ways to call db.auth that uses SCRAM-SHA-1 or MONGODB-CR.
- assert(admin.auth('andy', 'a'));
- assert(admin.logout());
- assert(admin.auth({user: 'andy', pwd: 'a'}));
- assert(admin.logout());
- assert(admin.auth({mechanism: 'SCRAM-SHA-1', user: 'andy', pwd: 'a'}));
- assert(admin.logout());
+// Try all the ways to call db.auth that uses SCRAM-SHA-1 or MONGODB-CR.
+assert(admin.auth('andy', 'a'));
+assert(admin.logout());
+assert(admin.auth({user: 'andy', pwd: 'a'}));
+assert(admin.logout());
+assert(admin.auth({mechanism: 'SCRAM-SHA-1', user: 'andy', pwd: 'a'}));
+assert(admin.logout());
- // Invalid mechanisms shouldn't lead to authentication, but also shouldn't crash.
- assert(!admin.auth({mechanism: 'this-mechanism-is-fake', user: 'andy', pwd: 'a'}));
- MongoRunner.stopMongod(conn);
+// Invalid mechanisms shouldn't lead to authentication, but also shouldn't crash.
+assert(!admin.auth({mechanism: 'this-mechanism-is-fake', user: 'andy', pwd: 'a'}));
+MongoRunner.stopMongod(conn);
})();
diff --git a/jstests/auth/auth_mechanism_discovery.js b/jstests/auth/auth_mechanism_discovery.js
index e3f7c5d0551..78b150ec1aa 100644
--- a/jstests/auth/auth_mechanism_discovery.js
+++ b/jstests/auth/auth_mechanism_discovery.js
@@ -1,58 +1,55 @@
// Tests that a client will auto-discover a user's supported SASL mechanisms during auth().
// @tags: [requires_sharding]
(function() {
- "use strict";
+"use strict";
- function runTest(conn) {
- const admin = conn.getDB("admin");
- const test = conn.getDB("test");
+function runTest(conn) {
+ const admin = conn.getDB("admin");
+ const test = conn.getDB("test");
- admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
- assert(admin.auth('admin', 'pass'));
+ admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
+ assert(admin.auth('admin', 'pass'));
- // Verify user mechanism discovery.
- function checkUser(username, mechanism) {
- var createUser = {createUser: username, pwd: 'pwd', roles: []};
- if (mechanism !== undefined) {
- createUser.mechanisms = [mechanism];
- } else {
- // Create both variants, expect to prefer 256.
- mechanism = 'SCRAM-SHA-256';
- }
- assert.commandWorked(test.runCommand(createUser));
- assert.eq(test._getDefaultAuthenticationMechanism(username, test.getName()), mechanism);
- assert(test.auth(username, 'pwd'));
- test.logout();
+ // Verify user mechanism discovery.
+ function checkUser(username, mechanism) {
+ var createUser = {createUser: username, pwd: 'pwd', roles: []};
+ if (mechanism !== undefined) {
+ createUser.mechanisms = [mechanism];
+ } else {
+ // Create both variants, expect to prefer 256.
+ mechanism = 'SCRAM-SHA-256';
}
- checkUser('userSha1', 'SCRAM-SHA-1');
- checkUser('userSha256', 'SCRAM-SHA-256');
- checkUser('userAll');
-
- // Verify override of mechanism discovery.
- // Depends on 'userAll' user created above.
- assert.eq(test._getDefaultAuthenticationMechanism('userAll', test.getName()),
- 'SCRAM-SHA-256');
- test._defaultAuthenticationMechanism = 'SCRAM-SHA-1';
- assert.eq(test._getDefaultAuthenticationMechanism('userAll', test.getName()),
- 'SCRAM-SHA-1');
- test._defaultAuthenticationMechanism = 'NO-SUCH-MECHANISM';
- assert.eq(test._getDefaultAuthenticationMechanism('userAll', test.getName()),
- 'SCRAM-SHA-256');
+ assert.commandWorked(test.runCommand(createUser));
+ assert.eq(test._getDefaultAuthenticationMechanism(username, test.getName()), mechanism);
+ assert(test.auth(username, 'pwd'));
+ test.logout();
}
+ checkUser('userSha1', 'SCRAM-SHA-1');
+ checkUser('userSha256', 'SCRAM-SHA-256');
+ checkUser('userAll');
+
+ // Verify override of mechanism discovery.
+ // Depends on 'userAll' user created above.
+ assert.eq(test._getDefaultAuthenticationMechanism('userAll', test.getName()), 'SCRAM-SHA-256');
+ test._defaultAuthenticationMechanism = 'SCRAM-SHA-1';
+ assert.eq(test._getDefaultAuthenticationMechanism('userAll', test.getName()), 'SCRAM-SHA-1');
+ test._defaultAuthenticationMechanism = 'NO-SUCH-MECHANISM';
+ assert.eq(test._getDefaultAuthenticationMechanism('userAll', test.getName()), 'SCRAM-SHA-256');
+}
- // Test standalone.
- const m = MongoRunner.runMongod({auth: ""});
- runTest(m);
- MongoRunner.stopMongod(m);
+// Test standalone.
+const m = MongoRunner.runMongod({auth: ""});
+runTest(m);
+MongoRunner.stopMongod(m);
- // Test sharded.
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- const st = new ShardingTest({
- shards: 1,
- mongos: 1,
- config: 1,
- other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
- });
- runTest(st.s0);
- st.stop();
+// Test sharded.
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+const st = new ShardingTest({
+ shards: 1,
+ mongos: 1,
+ config: 1,
+ other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
+});
+runTest(st.s0);
+st.stop();
})();
diff --git a/jstests/auth/auth_mechanisms_parsing.js b/jstests/auth/auth_mechanisms_parsing.js
index 72f906b3c68..3954963b885 100644
--- a/jstests/auth/auth_mechanisms_parsing.js
+++ b/jstests/auth/auth_mechanisms_parsing.js
@@ -1,13 +1,13 @@
// Test for stripping whitespace for authenticationMechanisms
(function() {
- "use strict";
+"use strict";
- const conn = MongoRunner.runMongod(
- {setParameter: "authenticationMechanisms=SCRAM-SHA-1,SCRAM-SHA-256, PLAIN"});
+const conn = MongoRunner.runMongod(
+ {setParameter: "authenticationMechanisms=SCRAM-SHA-1,SCRAM-SHA-256, PLAIN"});
- const cmdOut = conn.getDB('admin').runCommand({getParameter: 1, authenticationMechanisms: 1});
+const cmdOut = conn.getDB('admin').runCommand({getParameter: 1, authenticationMechanisms: 1});
- // Check to see if whitespace in front of PLAIN is stripped
- assert.sameMembers(cmdOut.authenticationMechanisms, ["SCRAM-SHA-1", "SCRAM-SHA-256", "PLAIN"]);
- MongoRunner.stopMongod(conn);
+// Check to see if whitespace in front of PLAIN is stripped
+assert.sameMembers(cmdOut.authenticationMechanisms, ["SCRAM-SHA-1", "SCRAM-SHA-256", "PLAIN"]);
+MongoRunner.stopMongod(conn);
}());
diff --git a/jstests/auth/authentication_restrictions.js b/jstests/auth/authentication_restrictions.js
index 1f08b3e6d6d..172db043770 100644
--- a/jstests/auth/authentication_restrictions.js
+++ b/jstests/auth/authentication_restrictions.js
@@ -4,224 +4,214 @@
*/
(function() {
- 'use strict';
-
- // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
- TestData.disableImplicitSessions = true;
-
- function testConnection(
- conn, eventuallyConsistentConn, sleepUntilUserDataPropagated, sleepUntilUserDataRefreshed) {
- load("jstests/libs/host_ipaddr.js");
-
- // Create a session which observes an eventually consistent view of user data
- var eventualDb = eventuallyConsistentConn.getDB("admin");
-
- // Create a session for modifying user data during the life of the test
- var adminSession = new Mongo("localhost:" + conn.port);
- var admin = adminSession.getDB("admin");
- assert.commandWorked(admin.runCommand(
- {createUser: "admin", pwd: "admin", roles: [{role: "root", db: "admin"}]}));
- assert(admin.auth("admin", "admin"));
-
- // Create a strongly consistent session for consuming user data
- var db = conn.getDB("admin");
-
- // Create a strongly consistent session for consuming user data, with a non-localhost
- // source IP.
- var externalMongo = new Mongo(get_ipaddr() + ":" + conn.port);
- var externalDb = externalMongo.getDB("admin");
-
- assert.commandWorked(admin.runCommand({
- createUser: "user2",
- pwd: "user",
- roles: [],
- authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]
- }));
- assert.commandWorked(admin.runCommand({createUser: "user3", pwd: "user", roles: []}));
- assert.commandWorked(admin.runCommand(
- {updateUser: "user3", authenticationRestrictions: [{serverAddress: ["127.0.0.1"]}]}));
-
- print("=== User creation tests");
- print(
- "When a client creates users with empty authenticationRestrictions, the operation succeeds, though it has no effect");
- assert.commandWorked(admin.runCommand(
- {createUser: "user4", pwd: "user", roles: [], authenticationRestrictions: []}));
- assert(!Object.keys(admin.system.users.findOne({user: "user4"}))
- .includes("authenticationRestrictions"));
-
- print(
- "When a client updates a user's authenticationRestrictions to be empty, the operation succeeds, and removes the authenticationRestrictions field");
- assert.commandWorked(admin.runCommand({createUser: "user5", pwd: "user", roles: []}));
- assert.commandWorked(
- admin.runCommand({updateUser: "user5", authenticationRestrictions: []}));
- assert(!Object.keys(admin.system.users.findOne({user: "user5"}))
- .includes("authenticationRestrictions"));
- assert.commandWorked(admin.runCommand(
- {updateUser: "user5", authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]}));
- assert(Object.keys(admin.system.users.findOne({user: "user5"}))
- .includes("authenticationRestrictions"));
- assert.commandWorked(
- admin.runCommand({updateUser: "user5", authenticationRestrictions: []}));
- assert(!Object.keys(admin.system.users.findOne({user: "user5"}))
- .includes("authenticationRestrictions"));
-
- print(
- "When a client updates a user's authenticationRestrictions to be null or undefined, the operation fails");
- assert.commandWorked(admin.runCommand(
- {updateUser: "user5", authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]}));
- assert(Object.keys(admin.system.users.findOne({user: "user5"}))
- .includes("authenticationRestrictions"));
- assert.commandFailed(
- admin.runCommand({updateUser: "user5", authenticationRestrictions: null}));
- assert(Object.keys(admin.system.users.findOne({user: "user5"}))
- .includes("authenticationRestrictions"));
- assert.commandFailed(
- admin.runCommand({updateUser: "user5", authenticationRestrictions: undefined}));
- assert(Object.keys(admin.system.users.findOne({user: "user5"}))
- .includes("authenticationRestrictions"));
-
- print(
- "When a client creates users, it may use clientSource and serverAddress authenticationRestrictions");
- assert.commandWorked(admin.runCommand({
- createUser: "user6",
- pwd: "user",
- roles: [],
- authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]
- }));
- assert.commandWorked(admin.runCommand({
- createUser: "user7",
- pwd: "user",
- roles: [],
- authenticationRestrictions: [{serverAddress: ["127.0.0.1"]}]
- }));
- assert.commandWorked(admin.runCommand({
- createUser: "user8",
- pwd: "user",
- roles: [],
- authenticationRestrictions:
- [{clientSource: ["127.0.0.1"], serverAddress: ["127.0.0.1"]}]
- }));
- assert.commandWorked(admin.runCommand({
- createUser: "user9",
- pwd: "user",
- roles: [],
- authenticationRestrictions:
- [{clientSource: ["127.0.0.1"]}, {serverAddress: ["127.0.0.1"]}]
- }));
- assert.commandFailed(admin.runCommand({
- createUser: "user10",
- pwd: "user",
- roles: [],
- authenticationRestrictions: [{invalidRestriction: ["127.0.0.1"]}]
- }));
-
- print("=== Localhost access tests");
-
- print(
- "When a client on the loopback authenticates to a user with {clientSource: \"127.0.0.1\"}, it will succeed");
- assert(db.auth("user6", "user"));
-
- print(
- "When a client on the loopback authenticates to a user with {serverAddress: \"127.0.0.1\"}, it will succeed");
- assert(db.auth("user7", "user"));
-
- print(
- "When a client on the loopback authenticates to a user with {clientSource: \"127.0.0.1\", serverAddress: \"127.0.0.1\"}, it will succeed");
- assert(db.auth("user8", "user"));
-
- print("=== Remote access tests");
- print(
- "When a client on the external interface authenticates to a user with {clientSource: \"127.0.0.1\"}, it will fail");
- assert(!externalDb.auth("user6", "user"));
-
- print(
- "When a client on the external interface authenticates to a user with {serverAddress: \"127.0.0.1\"}, it will fail");
- assert(!externalDb.auth("user7", "user"));
-
- print(
- "When a client on the external interface authenticates to a user with {clientSource: \"127.0.0.1\", serverAddress: \"127.0.0.1\"}, it will fail");
- assert(!externalDb.auth("user8", "user"));
-
- print("=== Invalidation tests");
- print(
- "When a client removes all authenticationRestrictions from a user, authentication will succeed");
- assert.commandWorked(admin.runCommand({
- createUser: "user11",
- pwd: "user",
- roles: [],
- authenticationRestrictions:
- [{clientSource: ["127.0.0.1"], serverAddress: ["127.0.0.1"]}]
- }));
- assert(!externalDb.auth("user11", "user"));
- assert.commandWorked(
- admin.runCommand({updateUser: "user11", authenticationRestrictions: []}));
- assert(externalDb.auth("user11", "user"));
-
- print(
- "When a client sets authenticationRestrictions on a user, authorization privileges are revoked");
- assert.commandWorked(admin.runCommand(
- {createUser: "user12", pwd: "user", roles: [{role: "readWrite", db: "test"}]}));
-
- assert(db.auth("user12", "user"));
- assert.commandWorked(db.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
-
- sleepUntilUserDataPropagated();
- assert(eventualDb.auth("user12", "user"));
- assert.commandWorked(
- eventualDb.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
-
- assert.commandWorked(admin.runCommand(
- {updateUser: "user12", authenticationRestrictions: [{clientSource: ["192.0.2.0"]}]}));
-
- assert.commandFailed(db.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
-
- sleepUntilUserDataRefreshed();
- assert.commandFailed(
- eventualDb.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
- }
-
- print("Testing standalone");
- var conn = MongoRunner.runMongod({bind_ip_all: "", auth: ""});
- testConnection(conn, conn, function() {}, function() {});
- MongoRunner.stopMongod(conn);
-
- var keyfile = "jstests/libs/key1";
-
- print("Testing replicaset");
- var rst = new ReplSetTest(
- {name: 'testset', nodes: 2, nodeOptions: {bind_ip_all: "", auth: ""}, keyFile: keyfile});
- var nodes = rst.startSet();
- rst.initiate();
- rst.awaitSecondaryNodes();
- var awaitReplication = function() {
- authutil.asCluster(nodes, "jstests/libs/key1", function() {
- rst.awaitReplication();
- });
- };
-
- testConnection(rst.getPrimary(), rst.getSecondary(), awaitReplication, awaitReplication);
- rst.stopSet();
-
- print("Testing sharded cluster");
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- var st = new ShardingTest({
- mongos: 2,
- config: 3,
- shard: 1,
- keyFile: keyfile,
- other: {
- mongosOptions: {bind_ip_all: "", auth: null},
- configOptions: {auth: null},
- shardOptions: {auth: null},
- shardAsReplicaSet: false
- }
+'use strict';
+
+// TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+TestData.disableImplicitSessions = true;
+
+function testConnection(
+ conn, eventuallyConsistentConn, sleepUntilUserDataPropagated, sleepUntilUserDataRefreshed) {
+ load("jstests/libs/host_ipaddr.js");
+
+ // Create a session which observes an eventually consistent view of user data
+ var eventualDb = eventuallyConsistentConn.getDB("admin");
+
+ // Create a session for modifying user data during the life of the test
+ var adminSession = new Mongo("localhost:" + conn.port);
+ var admin = adminSession.getDB("admin");
+ assert.commandWorked(admin.runCommand(
+ {createUser: "admin", pwd: "admin", roles: [{role: "root", db: "admin"}]}));
+ assert(admin.auth("admin", "admin"));
+
+ // Create a strongly consistent session for consuming user data
+ var db = conn.getDB("admin");
+
+ // Create a strongly consistent session for consuming user data, with a non-localhost
+ // source IP.
+ var externalMongo = new Mongo(get_ipaddr() + ":" + conn.port);
+ var externalDb = externalMongo.getDB("admin");
+
+ assert.commandWorked(admin.runCommand({
+ createUser: "user2",
+ pwd: "user",
+ roles: [],
+ authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]
+ }));
+ assert.commandWorked(admin.runCommand({createUser: "user3", pwd: "user", roles: []}));
+ assert.commandWorked(admin.runCommand(
+ {updateUser: "user3", authenticationRestrictions: [{serverAddress: ["127.0.0.1"]}]}));
+
+ print("=== User creation tests");
+ print(
+ "When a client creates users with empty authenticationRestrictions, the operation succeeds, though it has no effect");
+ assert.commandWorked(admin.runCommand(
+ {createUser: "user4", pwd: "user", roles: [], authenticationRestrictions: []}));
+ assert(!Object.keys(admin.system.users.findOne({user: "user4"}))
+ .includes("authenticationRestrictions"));
+
+ print(
+ "When a client updates a user's authenticationRestrictions to be empty, the operation succeeds, and removes the authenticationRestrictions field");
+ assert.commandWorked(admin.runCommand({createUser: "user5", pwd: "user", roles: []}));
+ assert.commandWorked(admin.runCommand({updateUser: "user5", authenticationRestrictions: []}));
+ assert(!Object.keys(admin.system.users.findOne({user: "user5"}))
+ .includes("authenticationRestrictions"));
+ assert.commandWorked(admin.runCommand(
+ {updateUser: "user5", authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]}));
+ assert(Object.keys(admin.system.users.findOne({user: "user5"}))
+ .includes("authenticationRestrictions"));
+ assert.commandWorked(admin.runCommand({updateUser: "user5", authenticationRestrictions: []}));
+ assert(!Object.keys(admin.system.users.findOne({user: "user5"}))
+ .includes("authenticationRestrictions"));
+
+ print(
+ "When a client updates a user's authenticationRestrictions to be null or undefined, the operation fails");
+ assert.commandWorked(admin.runCommand(
+ {updateUser: "user5", authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]}));
+ assert(Object.keys(admin.system.users.findOne({user: "user5"}))
+ .includes("authenticationRestrictions"));
+ assert.commandFailed(admin.runCommand({updateUser: "user5", authenticationRestrictions: null}));
+ assert(Object.keys(admin.system.users.findOne({user: "user5"}))
+ .includes("authenticationRestrictions"));
+ assert.commandFailed(
+ admin.runCommand({updateUser: "user5", authenticationRestrictions: undefined}));
+ assert(Object.keys(admin.system.users.findOne({user: "user5"}))
+ .includes("authenticationRestrictions"));
+
+ print(
+ "When a client creates users, it may use clientSource and serverAddress authenticationRestrictions");
+ assert.commandWorked(admin.runCommand({
+ createUser: "user6",
+ pwd: "user",
+ roles: [],
+ authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]
+ }));
+ assert.commandWorked(admin.runCommand({
+ createUser: "user7",
+ pwd: "user",
+ roles: [],
+ authenticationRestrictions: [{serverAddress: ["127.0.0.1"]}]
+ }));
+ assert.commandWorked(admin.runCommand({
+ createUser: "user8",
+ pwd: "user",
+ roles: [],
+ authenticationRestrictions: [{clientSource: ["127.0.0.1"], serverAddress: ["127.0.0.1"]}]
+ }));
+ assert.commandWorked(admin.runCommand({
+ createUser: "user9",
+ pwd: "user",
+ roles: [],
+ authenticationRestrictions: [{clientSource: ["127.0.0.1"]}, {serverAddress: ["127.0.0.1"]}]
+ }));
+ assert.commandFailed(admin.runCommand({
+ createUser: "user10",
+ pwd: "user",
+ roles: [],
+ authenticationRestrictions: [{invalidRestriction: ["127.0.0.1"]}]
+ }));
+
+ print("=== Localhost access tests");
+
+ print(
+ "When a client on the loopback authenticates to a user with {clientSource: \"127.0.0.1\"}, it will succeed");
+ assert(db.auth("user6", "user"));
+
+ print(
+ "When a client on the loopback authenticates to a user with {serverAddress: \"127.0.0.1\"}, it will succeed");
+ assert(db.auth("user7", "user"));
+
+ print(
+ "When a client on the loopback authenticates to a user with {clientSource: \"127.0.0.1\", serverAddress: \"127.0.0.1\"}, it will succeed");
+ assert(db.auth("user8", "user"));
+
+ print("=== Remote access tests");
+ print(
+ "When a client on the external interface authenticates to a user with {clientSource: \"127.0.0.1\"}, it will fail");
+ assert(!externalDb.auth("user6", "user"));
+
+ print(
+ "When a client on the external interface authenticates to a user with {serverAddress: \"127.0.0.1\"}, it will fail");
+ assert(!externalDb.auth("user7", "user"));
+
+ print(
+ "When a client on the external interface authenticates to a user with {clientSource: \"127.0.0.1\", serverAddress: \"127.0.0.1\"}, it will fail");
+ assert(!externalDb.auth("user8", "user"));
+
+ print("=== Invalidation tests");
+ print(
+ "When a client removes all authenticationRestrictions from a user, authentication will succeed");
+ assert.commandWorked(admin.runCommand({
+ createUser: "user11",
+ pwd: "user",
+ roles: [],
+ authenticationRestrictions: [{clientSource: ["127.0.0.1"], serverAddress: ["127.0.0.1"]}]
+ }));
+ assert(!externalDb.auth("user11", "user"));
+ assert.commandWorked(admin.runCommand({updateUser: "user11", authenticationRestrictions: []}));
+ assert(externalDb.auth("user11", "user"));
+
+ print(
+ "When a client sets authenticationRestrictions on a user, authorization privileges are revoked");
+ assert.commandWorked(admin.runCommand(
+ {createUser: "user12", pwd: "user", roles: [{role: "readWrite", db: "test"}]}));
+
+ assert(db.auth("user12", "user"));
+ assert.commandWorked(db.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
+
+ sleepUntilUserDataPropagated();
+ assert(eventualDb.auth("user12", "user"));
+ assert.commandWorked(eventualDb.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
+
+ assert.commandWorked(admin.runCommand(
+ {updateUser: "user12", authenticationRestrictions: [{clientSource: ["192.0.2.0"]}]}));
+
+ assert.commandFailed(db.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
+
+ sleepUntilUserDataRefreshed();
+ assert.commandFailed(eventualDb.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
+}
+
+print("Testing standalone");
+var conn = MongoRunner.runMongod({bind_ip_all: "", auth: ""});
+testConnection(conn, conn, function() {}, function() {});
+MongoRunner.stopMongod(conn);
+
+var keyfile = "jstests/libs/key1";
+
+print("Testing replicaset");
+var rst = new ReplSetTest(
+ {name: 'testset', nodes: 2, nodeOptions: {bind_ip_all: "", auth: ""}, keyFile: keyfile});
+var nodes = rst.startSet();
+rst.initiate();
+rst.awaitSecondaryNodes();
+var awaitReplication = function() {
+ authutil.asCluster(nodes, "jstests/libs/key1", function() {
+ rst.awaitReplication();
});
- testConnection(st.s0,
- st.s1,
- function() {},
- function() {
- sleep(40 * 1000); // Wait for mongos user cache invalidation
- });
- st.stop();
-
+};
+
+testConnection(rst.getPrimary(), rst.getSecondary(), awaitReplication, awaitReplication);
+rst.stopSet();
+
+print("Testing sharded cluster");
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+var st = new ShardingTest({
+ mongos: 2,
+ config: 3,
+ shard: 1,
+ keyFile: keyfile,
+ other: {
+ mongosOptions: {bind_ip_all: "", auth: null},
+ configOptions: {auth: null},
+ shardOptions: {auth: null},
+ shardAsReplicaSet: false
+ }
+});
+testConnection(st.s0,
+ st.s1,
+ function() {},
+ function() {
+ sleep(40 * 1000); // Wait for mongos user cache invalidation
+ });
+st.stop();
}());
diff --git a/jstests/auth/authentication_restrictions_role.js b/jstests/auth/authentication_restrictions_role.js
index 3f23cfdcb92..70256fba7f5 100644
--- a/jstests/auth/authentication_restrictions_role.js
+++ b/jstests/auth/authentication_restrictions_role.js
@@ -4,424 +4,402 @@
*/
(function() {
- 'use strict';
-
- // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
- TestData.disableImplicitSessions = true;
-
- function testRestrictionCreationAndEnforcement(
- conn, eventuallyConsistentConn, sleepUntilUserDataPropagated, sleepUntilUserDataRefreshed) {
- load("jstests/libs/host_ipaddr.js");
-
- // Create a session which observes an eventually consistent view of user data
- var eventualDb = eventuallyConsistentConn.getDB("admin");
-
- // Create a session for modifying user data during the life of the test
- var adminSession = new Mongo("127.0.0.1:" + conn.port);
- var admin = adminSession.getDB("admin");
- assert.commandWorked(admin.runCommand(
- {createUser: "admin", pwd: "admin", roles: [{role: "root", db: "admin"}]}));
- assert(admin.auth("admin", "admin"));
-
- // Create a strongly consistent session for consuming user data
- var db = conn.getDB("admin");
-
- // Create a strongly consistent session for consuming user data, with a non-localhost
- // source IP.
- var externalMongo = new Mongo(get_ipaddr() + ":" + conn.port);
- var externalDb = externalMongo.getDB("admin");
-
- assert.commandWorked(admin.runCommand({
- createRole: "role2",
- roles: [],
- privileges: [],
- authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]
- }));
- assert(Object.keys(admin.system.roles.findOne({role: "role2"}))
- .includes("authenticationRestrictions"));
- assert.commandWorked(admin.runCommand({createRole: "role3", roles: [], privileges: []}));
-
- print("=== Role creation tests");
- print(
- "When a client creates roles with empty authenticationRestrictions, the operation succeeds, though it has no effect");
- assert.commandWorked(admin.runCommand(
- {createRole: "role4", roles: [], privileges: [], authenticationRestrictions: []}));
- assert(!Object.keys(admin.system.roles.findOne({role: "role4"}))
- .includes("authenticationRestrictions"));
-
- print(
- "When a client updates a role's authenticationRestrictions to be empty, the operation succeeds, and removes the authenticationRestrictions field");
- assert.commandWorked(admin.runCommand({createRole: "role5", roles: [], privileges: []}));
- assert.commandWorked(
- admin.runCommand({updateRole: "role5", authenticationRestrictions: []}));
- assert(!Object.keys(admin.system.roles.findOne({role: "role5"}))
- .includes("authenticationRestrictions"));
- assert.commandWorked(admin.runCommand(
- {updateRole: "role5", authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]}));
- assert(Object.keys(admin.system.roles.findOne({role: "role5"}))
- .includes("authenticationRestrictions"));
- assert.commandWorked(
- admin.runCommand({updateRole: "role5", authenticationRestrictions: []}));
- assert(!Object.keys(admin.system.roles.findOne({role: "role5"}))
- .includes("authenticationRestrictions"));
-
- print(
- "When a client creates roles, it may use clientSource and serverAddress authenticationRestrictions");
- assert.commandWorked(admin.runCommand({
- createRole: "role6",
- roles: [],
- privileges: [],
- authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]
- }));
- assert(Object.keys(admin.system.roles.findOne({role: "role6"}))
- .includes("authenticationRestrictions"));
- assert.commandWorked(admin.runCommand({
- createRole: "role7",
- roles: [],
- privileges: [],
- authenticationRestrictions: [{serverAddress: ["127.0.0.1"]}]
- }));
- assert(Object.keys(admin.system.roles.findOne({role: "role7"}))
- .includes("authenticationRestrictions"));
- assert.commandWorked(admin.runCommand({
- createRole: "role8",
- roles: [],
- privileges: [],
- authenticationRestrictions:
- [{clientSource: ["127.0.0.1"], serverAddress: ["127.0.0.1"]}]
- }));
- assert(Object.keys(admin.system.roles.findOne({role: "role8"}))
- .includes("authenticationRestrictions"));
- assert.commandWorked(admin.runCommand({
- createRole: "role9",
- roles: [],
- privileges: [],
- authenticationRestrictions:
- [{clientSource: ["127.0.0.1"]}, {serverAddress: ["127.0.0.1"]}]
- }));
- assert(Object.keys(admin.system.roles.findOne({role: "role9"}))
- .includes("authenticationRestrictions"));
- assert.commandFailed(admin.runCommand({
- createRole: "role10",
- roles: [],
- privileges: [],
- authenticationRestrictions: [{invalidRestriction: ["127.0.0.1"]}]
- }));
-
- print("=== Localhost access tests");
- print(
- "When a client on the loopback authenticates to a user with {clientSource: \"127.0.0.1\"}, it will succeed");
- assert.commandWorked(
- admin.runCommand({createUser: "user6", pwd: "user", roles: ["role6"]}));
- assert(db.auth("user6", "user"));
-
- print(
- "When a client on the loopback authenticates to a user with {serverAddress: \"127.0.0.1\"}, it will succeed");
- assert.commandWorked(
- admin.runCommand({createUser: "user7", pwd: "user", roles: ["role7"]}));
- assert(db.auth("user7", "user"));
-
- print(
- "When a client on the loopback authenticates to a user with {clientSource: \"127.0.0.1\", serverAddress: \"127.0.0.1\"}, it will succeed");
- assert.commandWorked(
- admin.runCommand({createUser: "user8", pwd: "user", roles: ["role8"]}));
- assert(db.auth("user8", "user"));
-
- print("=== Remote access tests");
- print(
- "When a client on the external interface authenticates to a user with {clientSource: \"127.0.0.1\"}, it will fail");
- assert(!externalDb.auth("user6", "user"));
-
- print(
- "When a client on the external interface authenticates to a user with {serverAddress: \"127.0.0.1\"}, it will fail");
- assert(!externalDb.auth("user7", "user"));
-
- print(
- "When a client on the external interface authenticates to a user with {clientSource: \"127.0.0.1\", serverAddress: \"127.0.0.1\"}, it will fail");
- assert(!externalDb.auth("user8", "user"));
-
- print("=== Invalidation tests");
- print(
- "When a client removes all authenticationRestrictions from a role, authentication will succeed");
- assert.commandWorked(admin.runCommand({
- createRole: "role11",
- roles: [],
- privileges: [],
- authenticationRestrictions:
- [{clientSource: ["127.0.0.1"], serverAddress: ["127.0.0.1"]}]
- }));
- assert.commandWorked(
- admin.runCommand({createUser: "user11", pwd: "user", roles: ["role11"]}));
- assert(!externalDb.auth("user11", "user"));
- assert.commandWorked(
- admin.runCommand({updateRole: "role11", authenticationRestrictions: []}));
- assert(externalDb.auth("user11", "user"));
-
- print(
- "When a client sets authenticationRestrictions on a role, authorization privileges are revoked");
- assert.commandWorked(admin.runCommand({
- createRole: "role12",
- roles: [],
- privileges: [{resource: {db: "test", collection: "foo"}, actions: ["find"]}],
- authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]
- }));
- assert.commandWorked(
- admin.runCommand({createUser: "user12", pwd: "user", roles: ["role12"]}));
- assert(db.auth("user12", "user"));
- assert.commandWorked(db.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
- sleepUntilUserDataPropagated();
- assert(eventualDb.auth("user12", "user"));
- assert.commandWorked(
- eventualDb.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
- assert.commandWorked(admin.runCommand(
- {updateRole: "role12", authenticationRestrictions: [{clientSource: ["192.168.2.0"]}]}));
- assert.commandFailed(db.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
- sleepUntilUserDataRefreshed();
- assert.commandFailed(
- eventualDb.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
+'use strict';
+
+// TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+TestData.disableImplicitSessions = true;
+
+function testRestrictionCreationAndEnforcement(
+ conn, eventuallyConsistentConn, sleepUntilUserDataPropagated, sleepUntilUserDataRefreshed) {
+ load("jstests/libs/host_ipaddr.js");
+
+ // Create a session which observes an eventually consistent view of user data
+ var eventualDb = eventuallyConsistentConn.getDB("admin");
+
+ // Create a session for modifying user data during the life of the test
+ var adminSession = new Mongo("127.0.0.1:" + conn.port);
+ var admin = adminSession.getDB("admin");
+ assert.commandWorked(admin.runCommand(
+ {createUser: "admin", pwd: "admin", roles: [{role: "root", db: "admin"}]}));
+ assert(admin.auth("admin", "admin"));
+
+ // Create a strongly consistent session for consuming user data
+ var db = conn.getDB("admin");
+
+ // Create a strongly consistent session for consuming user data, with a non-localhost
+ // source IP.
+ var externalMongo = new Mongo(get_ipaddr() + ":" + conn.port);
+ var externalDb = externalMongo.getDB("admin");
+
+ assert.commandWorked(admin.runCommand({
+ createRole: "role2",
+ roles: [],
+ privileges: [],
+ authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]
+ }));
+ assert(Object.keys(admin.system.roles.findOne({role: "role2"}))
+ .includes("authenticationRestrictions"));
+ assert.commandWorked(admin.runCommand({createRole: "role3", roles: [], privileges: []}));
+
+ print("=== Role creation tests");
+ print(
+ "When a client creates roles with empty authenticationRestrictions, the operation succeeds, though it has no effect");
+ assert.commandWorked(admin.runCommand(
+ {createRole: "role4", roles: [], privileges: [], authenticationRestrictions: []}));
+ assert(!Object.keys(admin.system.roles.findOne({role: "role4"}))
+ .includes("authenticationRestrictions"));
+
+ print(
+ "When a client updates a role's authenticationRestrictions to be empty, the operation succeeds, and removes the authenticationRestrictions field");
+ assert.commandWorked(admin.runCommand({createRole: "role5", roles: [], privileges: []}));
+ assert.commandWorked(admin.runCommand({updateRole: "role5", authenticationRestrictions: []}));
+ assert(!Object.keys(admin.system.roles.findOne({role: "role5"}))
+ .includes("authenticationRestrictions"));
+ assert.commandWorked(admin.runCommand(
+ {updateRole: "role5", authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]}));
+ assert(Object.keys(admin.system.roles.findOne({role: "role5"}))
+ .includes("authenticationRestrictions"));
+ assert.commandWorked(admin.runCommand({updateRole: "role5", authenticationRestrictions: []}));
+ assert(!Object.keys(admin.system.roles.findOne({role: "role5"}))
+ .includes("authenticationRestrictions"));
+
+ print(
+ "When a client creates roles, it may use clientSource and serverAddress authenticationRestrictions");
+ assert.commandWorked(admin.runCommand({
+ createRole: "role6",
+ roles: [],
+ privileges: [],
+ authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]
+ }));
+ assert(Object.keys(admin.system.roles.findOne({role: "role6"}))
+ .includes("authenticationRestrictions"));
+ assert.commandWorked(admin.runCommand({
+ createRole: "role7",
+ roles: [],
+ privileges: [],
+ authenticationRestrictions: [{serverAddress: ["127.0.0.1"]}]
+ }));
+ assert(Object.keys(admin.system.roles.findOne({role: "role7"}))
+ .includes("authenticationRestrictions"));
+ assert.commandWorked(admin.runCommand({
+ createRole: "role8",
+ roles: [],
+ privileges: [],
+ authenticationRestrictions: [{clientSource: ["127.0.0.1"], serverAddress: ["127.0.0.1"]}]
+ }));
+ assert(Object.keys(admin.system.roles.findOne({role: "role8"}))
+ .includes("authenticationRestrictions"));
+ assert.commandWorked(admin.runCommand({
+ createRole: "role9",
+ roles: [],
+ privileges: [],
+ authenticationRestrictions: [{clientSource: ["127.0.0.1"]}, {serverAddress: ["127.0.0.1"]}]
+ }));
+ assert(Object.keys(admin.system.roles.findOne({role: "role9"}))
+ .includes("authenticationRestrictions"));
+ assert.commandFailed(admin.runCommand({
+ createRole: "role10",
+ roles: [],
+ privileges: [],
+ authenticationRestrictions: [{invalidRestriction: ["127.0.0.1"]}]
+ }));
+
+ print("=== Localhost access tests");
+ print(
+ "When a client on the loopback authenticates to a user with {clientSource: \"127.0.0.1\"}, it will succeed");
+ assert.commandWorked(admin.runCommand({createUser: "user6", pwd: "user", roles: ["role6"]}));
+ assert(db.auth("user6", "user"));
+
+ print(
+ "When a client on the loopback authenticates to a user with {serverAddress: \"127.0.0.1\"}, it will succeed");
+ assert.commandWorked(admin.runCommand({createUser: "user7", pwd: "user", roles: ["role7"]}));
+ assert(db.auth("user7", "user"));
+
+ print(
+ "When a client on the loopback authenticates to a user with {clientSource: \"127.0.0.1\", serverAddress: \"127.0.0.1\"}, it will succeed");
+ assert.commandWorked(admin.runCommand({createUser: "user8", pwd: "user", roles: ["role8"]}));
+ assert(db.auth("user8", "user"));
+
+ print("=== Remote access tests");
+ print(
+ "When a client on the external interface authenticates to a user with {clientSource: \"127.0.0.1\"}, it will fail");
+ assert(!externalDb.auth("user6", "user"));
+
+ print(
+ "When a client on the external interface authenticates to a user with {serverAddress: \"127.0.0.1\"}, it will fail");
+ assert(!externalDb.auth("user7", "user"));
+
+ print(
+ "When a client on the external interface authenticates to a user with {clientSource: \"127.0.0.1\", serverAddress: \"127.0.0.1\"}, it will fail");
+ assert(!externalDb.auth("user8", "user"));
+
+ print("=== Invalidation tests");
+ print(
+ "When a client removes all authenticationRestrictions from a role, authentication will succeed");
+ assert.commandWorked(admin.runCommand({
+ createRole: "role11",
+ roles: [],
+ privileges: [],
+ authenticationRestrictions: [{clientSource: ["127.0.0.1"], serverAddress: ["127.0.0.1"]}]
+ }));
+ assert.commandWorked(admin.runCommand({createUser: "user11", pwd: "user", roles: ["role11"]}));
+ assert(!externalDb.auth("user11", "user"));
+ assert.commandWorked(admin.runCommand({updateRole: "role11", authenticationRestrictions: []}));
+ assert(externalDb.auth("user11", "user"));
+
+ print(
+ "When a client sets authenticationRestrictions on a role, authorization privileges are revoked");
+ assert.commandWorked(admin.runCommand({
+ createRole: "role12",
+ roles: [],
+ privileges: [{resource: {db: "test", collection: "foo"}, actions: ["find"]}],
+ authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]
+ }));
+ assert.commandWorked(admin.runCommand({createUser: "user12", pwd: "user", roles: ["role12"]}));
+ assert(db.auth("user12", "user"));
+ assert.commandWorked(db.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
+ sleepUntilUserDataPropagated();
+ assert(eventualDb.auth("user12", "user"));
+ assert.commandWorked(eventualDb.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
+ assert.commandWorked(admin.runCommand(
+ {updateRole: "role12", authenticationRestrictions: [{clientSource: ["192.168.2.0"]}]}));
+ assert.commandFailed(db.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
+ sleepUntilUserDataRefreshed();
+ assert.commandFailed(eventualDb.getSiblingDB("test").runCommand({find: "foo", batchSize: 0}));
+}
+
+function testUsersInfoCommand(conn) {
+ function forEachUser(res, assertFun) {
+ assert(res.hasOwnProperty("users"));
+ print("Users: " + tojson(res.users));
+ assert.gt(res.users.length, 0);
+ res.users.forEach(assertFun);
}
- function testUsersInfoCommand(conn) {
- function forEachUser(res, assertFun) {
- assert(res.hasOwnProperty("users"));
- print("Users: " + tojson(res.users));
- assert.gt(res.users.length, 0);
- res.users.forEach(assertFun);
- }
-
- var admin = conn.getDB("admin");
- assert(admin.auth("admin", "admin"));
-
- assert.commandWorked(admin.runCommand({createUser: "user", pwd: "pwd", roles: []}));
- assert.commandWorked(admin.runCommand({
- createUser: "restrictedUser",
- pwd: "pwd",
- roles: [],
- authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]
- }));
- assert.commandWorked(admin.runCommand({
- createRole: "restrictedRole",
- roles: [],
- privileges: [],
- authenticationRestrictions: [{clientSource: ["127.0.0.2"]}]
- }));
- assert.commandWorked(admin.runCommand(
- {createUser: "userWithRestrictedRole", pwd: "pwd", roles: ["restrictedRole"]}));
- assert.commandWorked(admin.runCommand({
- createUser: "restrictedUserWithRestrictedRole",
- pwd: "pwd",
- roles: ["restrictedRole"],
- authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]
- }));
-
- print(
- "Calling usersInfo for all users on a database with showAuthenticationRestrictions is an error");
- assert.commandFailed(
- admin.runCommand({usersInfo: 1, showAuthenticationRestrictions: true}));
-
- print(
- "Calling usersInfo for all users on a database with showAuthenticationRestrictions false or unset will succeed, and not produce authenticationRestriction fields");
- [{}, {showAuthenticationRestrictions: false}].forEach(function(fragment) {
- forEachUser(
- assert.commandWorked(admin.runCommand(Object.merge({usersInfo: 1}, fragment))),
- function(userDoc) {
- assert(!userDoc.hasOwnProperty("authenticationRestrictions"));
- assert(!userDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
- });
- });
-
- print(
- "If usersInfo is called with showAuthenticationRestrictions true, on a user without authenticationRestrictions, a document with empty authenticationRestrictions and inheritedAuthenticationRestrictions arrays is returned");
- forEachUser(assert.commandWorked(admin.runCommand(
- {usersInfo: "user", showAuthenticationRestrictions: true})),
+ var admin = conn.getDB("admin");
+ assert(admin.auth("admin", "admin"));
+
+ assert.commandWorked(admin.runCommand({createUser: "user", pwd: "pwd", roles: []}));
+ assert.commandWorked(admin.runCommand({
+ createUser: "restrictedUser",
+ pwd: "pwd",
+ roles: [],
+ authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]
+ }));
+ assert.commandWorked(admin.runCommand({
+ createRole: "restrictedRole",
+ roles: [],
+ privileges: [],
+ authenticationRestrictions: [{clientSource: ["127.0.0.2"]}]
+ }));
+ assert.commandWorked(admin.runCommand(
+ {createUser: "userWithRestrictedRole", pwd: "pwd", roles: ["restrictedRole"]}));
+ assert.commandWorked(admin.runCommand({
+ createUser: "restrictedUserWithRestrictedRole",
+ pwd: "pwd",
+ roles: ["restrictedRole"],
+ authenticationRestrictions: [{clientSource: ["127.0.0.1"]}]
+ }));
+
+ print(
+ "Calling usersInfo for all users on a database with showAuthenticationRestrictions is an error");
+ assert.commandFailed(admin.runCommand({usersInfo: 1, showAuthenticationRestrictions: true}));
+
+ print(
+ "Calling usersInfo for all users on a database with showAuthenticationRestrictions false or unset will succeed, and not produce authenticationRestriction fields");
+ [{}, {showAuthenticationRestrictions: false}].forEach(function(fragment) {
+ forEachUser(assert.commandWorked(admin.runCommand(Object.merge({usersInfo: 1}, fragment))),
function(userDoc) {
- assert(userDoc.hasOwnProperty("authenticationRestrictions"));
- assert.eq(0, userDoc["authenticationRestrictions"].length);
-
- assert(userDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
- assert.eq(0, userDoc["inheritedAuthenticationRestrictions"].length);
- });
-
- print(
- "If usersInfo is called and showAuthenticationRestrictions is false or unset, return a document without an authenticationRestrictions or inheritedAuthenticationRestrictions field");
- ["user", "restrictedUser", "userWithRestrictedRole", "restrictedUserWithRestrictedRole"]
- .forEach(function(user) {
- forEachUser(
- assert.commandWorked(admin.runCommand(
- {usersInfo: "user", showAuthenticationRestrictions: false})),
- function(userDoc) {
- assert(!userDoc.hasOwnProperty("authenticationRestrictions"));
- assert(!userDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
- });
- forEachUser(
- assert.commandWorked(admin.runCommand({usersInfo: "user"})), function(userDoc) {
assert(!userDoc.hasOwnProperty("authenticationRestrictions"));
assert(!userDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
});
+ });
- });
+ print(
+ "If usersInfo is called with showAuthenticationRestrictions true, on a user without authenticationRestrictions, a document with empty authenticationRestrictions and inheritedAuthenticationRestrictions arrays is returned");
+ forEachUser(assert.commandWorked(
+ admin.runCommand({usersInfo: "user", showAuthenticationRestrictions: true})),
+ function(userDoc) {
+ assert(userDoc.hasOwnProperty("authenticationRestrictions"));
+ assert.eq(0, userDoc["authenticationRestrictions"].length);
- print(
- "Authentication restrictions can be obtained through usersInfo for a single user with restrictions");
- forEachUser(assert.commandWorked(admin.runCommand(
- {usersInfo: "restrictedUser", showAuthenticationRestrictions: true})),
- function(userDoc) {
- assert(userDoc.hasOwnProperty("authenticationRestrictions"));
- assert.eq(1, userDoc["authenticationRestrictions"].length);
+ assert(userDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
+ assert.eq(0, userDoc["inheritedAuthenticationRestrictions"].length);
+ });
- assert(userDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
- assert.eq(0, userDoc["inheritedAuthenticationRestrictions"].length);
- });
+ print(
+ "If usersInfo is called and showAuthenticationRestrictions is false or unset, return a document without an authenticationRestrictions or inheritedAuthenticationRestrictions field");
+ ["user", "restrictedUser", "userWithRestrictedRole", "restrictedUserWithRestrictedRole"]
+ .forEach(function(user) {
+ forEachUser(assert.commandWorked(admin.runCommand(
+ {usersInfo: "user", showAuthenticationRestrictions: false})),
+ function(userDoc) {
+ assert(!userDoc.hasOwnProperty("authenticationRestrictions"));
+ assert(!userDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
+ });
+ forEachUser(assert.commandWorked(admin.runCommand({usersInfo: "user"})),
+ function(userDoc) {
+ assert(!userDoc.hasOwnProperty("authenticationRestrictions"));
+ assert(!userDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
+ });
+ });
- print(
- "Authentication restrictions can be obtained through usersInfo for a single user with restrictioned roles");
- forEachUser(
- assert.commandWorked(admin.runCommand(
- {usersInfo: "userWithRestrictedRole", showAuthenticationRestrictions: true})),
- function(userDoc) {
- assert(userDoc.hasOwnProperty("authenticationRestrictions"));
- assert.eq(0, userDoc["authenticationRestrictions"].length);
-
- assert(userDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
- assert.eq(1, userDoc["inheritedAuthenticationRestrictions"].length);
- });
-
- print(
- "Authentication restrictions can be obtained through usersInfo for a single restricted user with restrictioned roles");
- forEachUser(assert.commandWorked(admin.runCommand({
- usersInfo: "restrictedUserWithRestrictedRole",
- showAuthenticationRestrictions: true
- })),
- function(userDoc) {
- print("This doc: " + tojson(userDoc));
- assert(userDoc.hasOwnProperty("authenticationRestrictions"));
- assert.eq(1, userDoc["authenticationRestrictions"].length);
+ print(
+ "Authentication restrictions can be obtained through usersInfo for a single user with restrictions");
+ forEachUser(assert.commandWorked(admin.runCommand(
+ {usersInfo: "restrictedUser", showAuthenticationRestrictions: true})),
+ function(userDoc) {
+ assert(userDoc.hasOwnProperty("authenticationRestrictions"));
+ assert.eq(1, userDoc["authenticationRestrictions"].length);
- assert(userDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
- assert.eq(1, userDoc["inheritedAuthenticationRestrictions"].length);
- });
- }
+ assert(userDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
+ assert.eq(0, userDoc["inheritedAuthenticationRestrictions"].length);
+ });
- function testRolesInfoCommand(conn) {
- function forEachRole(res, assertFun) {
- assert(res.hasOwnProperty("roles"));
- print("Users: " + tojson(res.roles));
- assert.gt(res.roles.length, 0);
- res.roles.forEach(assertFun);
- }
+ print(
+ "Authentication restrictions can be obtained through usersInfo for a single user with restrictioned roles");
+ forEachUser(assert.commandWorked(admin.runCommand(
+ {usersInfo: "userWithRestrictedRole", showAuthenticationRestrictions: true})),
+ function(userDoc) {
+ assert(userDoc.hasOwnProperty("authenticationRestrictions"));
+ assert.eq(0, userDoc["authenticationRestrictions"].length);
- var admin = conn.getDB("admin");
- assert(admin.auth("admin", "admin"));
+ assert(userDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
+ assert.eq(1, userDoc["inheritedAuthenticationRestrictions"].length);
+ });
- assert.commandWorked(admin.runCommand({createRole: "role", roles: [], privileges: []}));
- // restrictedRole already created
+ print(
+ "Authentication restrictions can be obtained through usersInfo for a single restricted user with restrictioned roles");
+ forEachUser(
assert.commandWorked(admin.runCommand(
- {createRole: "roleWithRestrictedRole", roles: ["restrictedRole"], privileges: []}));
- assert.commandWorked(admin.runCommand({
- createRole: "restrictedRoleWithRestrictedRole",
- roles: ["restrictedRole"],
- privileges: [],
- authenticationRestrictions: [{clientSource: ["127.0.0.3"]}]
- }));
-
- ["role", "restrictedRole", "roleWithRestrictedRole", "restrictedRoleWithRestrictedRole"]
- .forEach(function(role) {
- forEachRole(
- assert.commandWorked(admin.runCommand({rolesInfo: role})), function(roleDoc) {
- assert(!roleDoc.hasOwnProperty("authenticationRestrictions"));
- assert(!roleDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
- });
- });
-
- forEachRole(assert.commandWorked(admin.runCommand(
- {rolesInfo: "role", showAuthenticationRestrictions: true})),
- function(roleDoc) {
- assert(roleDoc.hasOwnProperty("authenticationRestrictions"));
- assert.eq(0, roleDoc.authenticationRestrictions.length);
- assert(roleDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
- assert.eq(0, roleDoc.inheritedAuthenticationRestrictions.length);
- });
+ {usersInfo: "restrictedUserWithRestrictedRole", showAuthenticationRestrictions: true})),
+ function(userDoc) {
+ print("This doc: " + tojson(userDoc));
+ assert(userDoc.hasOwnProperty("authenticationRestrictions"));
+ assert.eq(1, userDoc["authenticationRestrictions"].length);
+
+ assert(userDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
+ assert.eq(1, userDoc["inheritedAuthenticationRestrictions"].length);
+ });
+}
+
+function testRolesInfoCommand(conn) {
+ function forEachRole(res, assertFun) {
+ assert(res.hasOwnProperty("roles"));
+ print("Users: " + tojson(res.roles));
+ assert.gt(res.roles.length, 0);
+ res.roles.forEach(assertFun);
+ }
- forEachRole(assert.commandWorked(admin.runCommand(
- {rolesInfo: "restrictedRole", showAuthenticationRestrictions: true})),
- function(roleDoc) {
- assert(roleDoc.hasOwnProperty("authenticationRestrictions"));
- assert.eq(1, roleDoc.authenticationRestrictions.length);
- assert(roleDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
- assert.eq(1, roleDoc.inheritedAuthenticationRestrictions.length);
- });
+ var admin = conn.getDB("admin");
+ assert(admin.auth("admin", "admin"));
+
+ assert.commandWorked(admin.runCommand({createRole: "role", roles: [], privileges: []}));
+ // restrictedRole already created
+ assert.commandWorked(admin.runCommand(
+ {createRole: "roleWithRestrictedRole", roles: ["restrictedRole"], privileges: []}));
+ assert.commandWorked(admin.runCommand({
+ createRole: "restrictedRoleWithRestrictedRole",
+ roles: ["restrictedRole"],
+ privileges: [],
+ authenticationRestrictions: [{clientSource: ["127.0.0.3"]}]
+ }));
+
+ ["role", "restrictedRole", "roleWithRestrictedRole", "restrictedRoleWithRestrictedRole"]
+ .forEach(function(role) {
+ forEachRole(assert.commandWorked(admin.runCommand({rolesInfo: role})),
+ function(roleDoc) {
+ assert(!roleDoc.hasOwnProperty("authenticationRestrictions"));
+ assert(!roleDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
+ });
+ });
- forEachRole(
- assert.commandWorked(admin.runCommand(
- {rolesInfo: "roleWithRestrictedRole", showAuthenticationRestrictions: true})),
- function(roleDoc) {
- assert(roleDoc.hasOwnProperty("authenticationRestrictions"));
- assert.eq(0, roleDoc.authenticationRestrictions.length);
- assert(roleDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
- assert.eq(1, roleDoc.inheritedAuthenticationRestrictions.length);
- });
-
- forEachRole(assert.commandWorked(admin.runCommand({
- rolesInfo: "restrictedRoleWithRestrictedRole",
- showAuthenticationRestrictions: true
- })),
- function(roleDoc) {
- assert(roleDoc.hasOwnProperty("authenticationRestrictions"));
- assert.eq(1, roleDoc.authenticationRestrictions.length);
- assert(roleDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
- assert.eq(2, roleDoc.inheritedAuthenticationRestrictions.length);
- });
- }
+ forEachRole(assert.commandWorked(
+ admin.runCommand({rolesInfo: "role", showAuthenticationRestrictions: true})),
+ function(roleDoc) {
+ assert(roleDoc.hasOwnProperty("authenticationRestrictions"));
+ assert.eq(0, roleDoc.authenticationRestrictions.length);
+ assert(roleDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
+ assert.eq(0, roleDoc.inheritedAuthenticationRestrictions.length);
+ });
+
+ forEachRole(assert.commandWorked(admin.runCommand(
+ {rolesInfo: "restrictedRole", showAuthenticationRestrictions: true})),
+ function(roleDoc) {
+ assert(roleDoc.hasOwnProperty("authenticationRestrictions"));
+ assert.eq(1, roleDoc.authenticationRestrictions.length);
+ assert(roleDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
+ assert.eq(1, roleDoc.inheritedAuthenticationRestrictions.length);
+ });
+
+ forEachRole(assert.commandWorked(admin.runCommand(
+ {rolesInfo: "roleWithRestrictedRole", showAuthenticationRestrictions: true})),
+ function(roleDoc) {
+ assert(roleDoc.hasOwnProperty("authenticationRestrictions"));
+ assert.eq(0, roleDoc.authenticationRestrictions.length);
+ assert(roleDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
+ assert.eq(1, roleDoc.inheritedAuthenticationRestrictions.length);
+ });
- var keyfile = "jstests/libs/key1";
-
- print("Testing standalone");
- var conn = MongoRunner.runMongod({bind_ip_all: "", auth: ""});
- testRestrictionCreationAndEnforcement(conn, conn, function() {}, function() {});
- testUsersInfoCommand(conn);
- testRolesInfoCommand(conn);
- MongoRunner.stopMongod(conn);
-
- print("Testing replicaset");
- var rst = new ReplSetTest(
- {name: 'testset', nodes: 2, nodeOptions: {bind_ip_all: "", auth: ""}, keyFile: keyfile});
- var nodes = rst.startSet();
- rst.initiate();
- rst.awaitSecondaryNodes();
- var awaitReplication = function() {
- authutil.asCluster(nodes, "jstests/libs/key1", function() {
- rst.awaitReplication();
+ forEachRole(
+ assert.commandWorked(admin.runCommand(
+ {rolesInfo: "restrictedRoleWithRestrictedRole", showAuthenticationRestrictions: true})),
+ function(roleDoc) {
+ assert(roleDoc.hasOwnProperty("authenticationRestrictions"));
+ assert.eq(1, roleDoc.authenticationRestrictions.length);
+ assert(roleDoc.hasOwnProperty("inheritedAuthenticationRestrictions"));
+ assert.eq(2, roleDoc.inheritedAuthenticationRestrictions.length);
});
- };
-
- testRestrictionCreationAndEnforcement(
- rst.getPrimary(), rst.getSecondary(), awaitReplication, awaitReplication);
- testUsersInfoCommand(rst.getPrimary());
- testRolesInfoCommand(rst.getPrimary());
- rst.stopSet();
-
- print("Testing sharded cluster");
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- var st = new ShardingTest({
- mongos: 2,
- config: 3,
- shard: 1,
- keyFile: keyfile,
- other: {
- mongosOptions: {bind_ip_all: "", auth: null},
- configOptions: {auth: null},
- shardOptions: {auth: null},
- shardAsReplicaSet: false
- }
+}
+
+var keyfile = "jstests/libs/key1";
+
+print("Testing standalone");
+var conn = MongoRunner.runMongod({bind_ip_all: "", auth: ""});
+testRestrictionCreationAndEnforcement(conn, conn, function() {}, function() {});
+testUsersInfoCommand(conn);
+testRolesInfoCommand(conn);
+MongoRunner.stopMongod(conn);
+
+print("Testing replicaset");
+var rst = new ReplSetTest(
+ {name: 'testset', nodes: 2, nodeOptions: {bind_ip_all: "", auth: ""}, keyFile: keyfile});
+var nodes = rst.startSet();
+rst.initiate();
+rst.awaitSecondaryNodes();
+var awaitReplication = function() {
+ authutil.asCluster(nodes, "jstests/libs/key1", function() {
+ rst.awaitReplication();
});
- testRestrictionCreationAndEnforcement(
- st.s0,
- st.s1,
- function() {},
- function() {
- sleep(40 * 1000); // Wait for mongos user cache invalidation
- });
- testUsersInfoCommand(st.s0);
- st.stop();
-
+};
+
+testRestrictionCreationAndEnforcement(
+ rst.getPrimary(), rst.getSecondary(), awaitReplication, awaitReplication);
+testUsersInfoCommand(rst.getPrimary());
+testRolesInfoCommand(rst.getPrimary());
+rst.stopSet();
+
+print("Testing sharded cluster");
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+var st = new ShardingTest({
+ mongos: 2,
+ config: 3,
+ shard: 1,
+ keyFile: keyfile,
+ other: {
+ mongosOptions: {bind_ip_all: "", auth: null},
+ configOptions: {auth: null},
+ shardOptions: {auth: null},
+ shardAsReplicaSet: false
+ }
+});
+testRestrictionCreationAndEnforcement(
+ st.s0,
+ st.s1,
+ function() {},
+ function() {
+ sleep(40 * 1000); // Wait for mongos user cache invalidation
+ });
+testUsersInfoCommand(st.s0);
+st.stop();
}());
diff --git a/jstests/auth/authz_modifications_access_control.js b/jstests/auth/authz_modifications_access_control.js
index 11b9a59e593..f660e861908 100644
--- a/jstests/auth/authz_modifications_access_control.js
+++ b/jstests/auth/authz_modifications_access_control.js
@@ -70,7 +70,6 @@ function runTest(conn) {
var roleObj = adminUserAdmin.system.roles.findOne({role: "readWrite", db: "admin"});
// double check that no role object named "readWrite" has been created
assert(!roleObj, "user-defined \"readWrite\" role was created: " + tojson(roleObj));
-
})();
(function testViewUser() {
diff --git a/jstests/auth/autocomplete_auth.js b/jstests/auth/autocomplete_auth.js
index c0057bf1e52..35450ecbca6 100644
--- a/jstests/auth/autocomplete_auth.js
+++ b/jstests/auth/autocomplete_auth.js
@@ -15,38 +15,38 @@
const self = this;
(function() {
- 'use strict';
+'use strict';
- const testName = jsTest.name();
- const conn = MongoRunner.runMongod({auth: ''});
- const admin = conn.getDB('admin');
- admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
- assert(admin.auth('admin', 'pass'));
+const testName = jsTest.name();
+const conn = MongoRunner.runMongod({auth: ''});
+const admin = conn.getDB('admin');
+admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
+assert(admin.auth('admin', 'pass'));
- admin.getSiblingDB(testName).createRole({
- role: 'coachTicket',
- privileges: [{resource: {db: testName, collection: 'coachClass'}, actions: ['find']}],
- roles: []
- });
+admin.getSiblingDB(testName).createRole({
+ role: 'coachTicket',
+ privileges: [{resource: {db: testName, collection: 'coachClass'}, actions: ['find']}],
+ roles: []
+});
- admin.getSiblingDB(testName).createUser(
- {user: 'coachPassenger', pwd: 'password', roles: ['coachTicket']});
+admin.getSiblingDB(testName).createUser(
+ {user: 'coachPassenger', pwd: 'password', roles: ['coachTicket']});
- const testDB = conn.getDB(testName);
- testDB.coachClass.insertOne({});
- testDB.businessClass.insertOne({});
+const testDB = conn.getDB(testName);
+testDB.coachClass.insertOne({});
+testDB.businessClass.insertOne({});
- // Must use 'db' to test autocompletion.
- self.db = new Mongo(conn.host).getDB(testName);
- assert(db.auth('coachPassenger', 'password'));
- const authzErrorCode = 13;
- assert.commandFailedWithCode(db.runCommand({listCollections: 1}), authzErrorCode);
- assert.commandWorked(db.runCommand({find: 'coachClass'}));
- assert.commandFailedWithCode(db.runCommand({find: 'businessClass'}), authzErrorCode);
- shellAutocomplete('db.');
- assert(__autocomplete__.includes('db.coachClass'),
- `Completions should include 'coachClass': ${__autocomplete__}`);
- assert(!__autocomplete__.includes('db.businessClass'),
- `Completions should NOT include 'businessClass': ${__autocomplete__}`);
- MongoRunner.stopMongod(conn);
+// Must use 'db' to test autocompletion.
+self.db = new Mongo(conn.host).getDB(testName);
+assert(db.auth('coachPassenger', 'password'));
+const authzErrorCode = 13;
+assert.commandFailedWithCode(db.runCommand({listCollections: 1}), authzErrorCode);
+assert.commandWorked(db.runCommand({find: 'coachClass'}));
+assert.commandFailedWithCode(db.runCommand({find: 'businessClass'}), authzErrorCode);
+shellAutocomplete('db.');
+assert(__autocomplete__.includes('db.coachClass'),
+ `Completions should include 'coachClass': ${__autocomplete__}`);
+assert(!__autocomplete__.includes('db.businessClass'),
+ `Completions should NOT include 'businessClass': ${__autocomplete__}`);
+MongoRunner.stopMongod(conn);
})();
diff --git a/jstests/auth/basic_role_auth.js b/jstests/auth/basic_role_auth.js
index e610d1ed493..6f481afc2e6 100644
--- a/jstests/auth/basic_role_auth.js
+++ b/jstests/auth/basic_role_auth.js
@@ -231,215 +231,215 @@ var testOps = function(db, allowedActions) {
// }
var TESTS = [
{
- name: 'Test multiple user login separate connection',
- test: function(conn) {
- var testDB = conn.getDB('test');
- assert.eq(1, testDB.auth('ro', AUTH_INFO.test.ro.pwd));
-
- var conn2 = new Mongo(conn.host);
- var testDB2 = conn2.getDB('test');
- assert.eq(1, testDB2.auth('uadmin', AUTH_INFO.test.uadmin.pwd));
-
- testOps(testDB, READ_PERM);
- testOps(testDB2, UADMIN_PERM);
- }
+ name: 'Test multiple user login separate connection',
+ test: function(conn) {
+ var testDB = conn.getDB('test');
+ assert.eq(1, testDB.auth('ro', AUTH_INFO.test.ro.pwd));
+
+ var conn2 = new Mongo(conn.host);
+ var testDB2 = conn2.getDB('test');
+ assert.eq(1, testDB2.auth('uadmin', AUTH_INFO.test.uadmin.pwd));
+
+ testOps(testDB, READ_PERM);
+ testOps(testDB2, UADMIN_PERM);
+ }
},
{
- name: 'Test user with no role',
- test: function(conn) {
- var testDB = conn.getDB('test');
- assert.eq(1, testDB.auth('none', AUTH_INFO.test.none.pwd));
+ name: 'Test user with no role',
+ test: function(conn) {
+ var testDB = conn.getDB('test');
+ assert.eq(1, testDB.auth('none', AUTH_INFO.test.none.pwd));
- testOps(testDB, {});
- }
+ testOps(testDB, {});
+ }
},
{
- name: 'Test read only user',
- test: function(conn) {
- var testDB = conn.getDB('test');
- assert.eq(1, testDB.auth('ro', AUTH_INFO.test.ro.pwd));
+ name: 'Test read only user',
+ test: function(conn) {
+ var testDB = conn.getDB('test');
+ assert.eq(1, testDB.auth('ro', AUTH_INFO.test.ro.pwd));
- testOps(testDB, READ_PERM);
- }
+ testOps(testDB, READ_PERM);
+ }
},
{
- name: 'Test read/write user',
- test: function(conn) {
- var testDB = conn.getDB('test');
- assert.eq(1, testDB.auth('rw', AUTH_INFO.test.rw.pwd));
+ name: 'Test read/write user',
+ test: function(conn) {
+ var testDB = conn.getDB('test');
+ assert.eq(1, testDB.auth('rw', AUTH_INFO.test.rw.pwd));
- testOps(testDB, READ_WRITE_PERM);
- }
+ testOps(testDB, READ_WRITE_PERM);
+ }
},
{
- name: 'Test read + dbAdmin user',
- test: function(conn) {
- var testDB = conn.getDB('test');
- assert.eq(1, testDB.auth('roadmin', AUTH_INFO.test.roadmin.pwd));
-
- var combinedPerm = Object.extend({}, READ_PERM);
- combinedPerm = Object.extend(combinedPerm, ADMIN_PERM);
- testOps(testDB, combinedPerm);
- }
+ name: 'Test read + dbAdmin user',
+ test: function(conn) {
+ var testDB = conn.getDB('test');
+ assert.eq(1, testDB.auth('roadmin', AUTH_INFO.test.roadmin.pwd));
+
+ var combinedPerm = Object.extend({}, READ_PERM);
+ combinedPerm = Object.extend(combinedPerm, ADMIN_PERM);
+ testOps(testDB, combinedPerm);
+ }
},
{
- name: 'Test dbAdmin user',
- test: function(conn) {
- var testDB = conn.getDB('test');
- assert.eq(1, testDB.auth('admin', AUTH_INFO.test.admin.pwd));
+ name: 'Test dbAdmin user',
+ test: function(conn) {
+ var testDB = conn.getDB('test');
+ assert.eq(1, testDB.auth('admin', AUTH_INFO.test.admin.pwd));
- testOps(testDB, ADMIN_PERM);
- }
+ testOps(testDB, ADMIN_PERM);
+ }
},
{
- name: 'Test userAdmin user',
- test: function(conn) {
- var testDB = conn.getDB('test');
- assert.eq(1, testDB.auth('uadmin', AUTH_INFO.test.uadmin.pwd));
+ name: 'Test userAdmin user',
+ test: function(conn) {
+ var testDB = conn.getDB('test');
+ assert.eq(1, testDB.auth('uadmin', AUTH_INFO.test.uadmin.pwd));
- testOps(testDB, UADMIN_PERM);
- }
+ testOps(testDB, UADMIN_PERM);
+ }
},
{
- name: 'Test cluster user',
- test: function(conn) {
- var adminDB = conn.getDB('admin');
- assert.eq(1, adminDB.auth('cluster', AUTH_INFO.admin.cluster.pwd));
+ name: 'Test cluster user',
+ test: function(conn) {
+ var adminDB = conn.getDB('admin');
+ assert.eq(1, adminDB.auth('cluster', AUTH_INFO.admin.cluster.pwd));
- testOps(conn.getDB('test'), CLUSTER_PERM);
- }
+ testOps(conn.getDB('test'), CLUSTER_PERM);
+ }
},
{
- name: 'Test admin user with no role',
- test: function(conn) {
- var adminDB = conn.getDB('admin');
- assert.eq(1, adminDB.auth('anone', AUTH_INFO.admin.anone.pwd));
-
- testOps(adminDB, {});
- testOps(conn.getDB('test'), {});
- }
+ name: 'Test admin user with no role',
+ test: function(conn) {
+ var adminDB = conn.getDB('admin');
+ assert.eq(1, adminDB.auth('anone', AUTH_INFO.admin.anone.pwd));
+
+ testOps(adminDB, {});
+ testOps(conn.getDB('test'), {});
+ }
},
{
- name: 'Test read only admin user',
- test: function(conn) {
- var adminDB = conn.getDB('admin');
- assert.eq(1, adminDB.auth('aro', AUTH_INFO.admin.aro.pwd));
-
- testOps(adminDB, READ_PERM);
- testOps(conn.getDB('test'), {});
- }
+ name: 'Test read only admin user',
+ test: function(conn) {
+ var adminDB = conn.getDB('admin');
+ assert.eq(1, adminDB.auth('aro', AUTH_INFO.admin.aro.pwd));
+
+ testOps(adminDB, READ_PERM);
+ testOps(conn.getDB('test'), {});
+ }
},
{
- name: 'Test read/write admin user',
- test: function(conn) {
- var adminDB = conn.getDB('admin');
- assert.eq(1, adminDB.auth('arw', AUTH_INFO.admin.arw.pwd));
-
- testOps(adminDB, READ_WRITE_PERM);
- testOps(conn.getDB('test'), {});
- }
+ name: 'Test read/write admin user',
+ test: function(conn) {
+ var adminDB = conn.getDB('admin');
+ assert.eq(1, adminDB.auth('arw', AUTH_INFO.admin.arw.pwd));
+
+ testOps(adminDB, READ_WRITE_PERM);
+ testOps(conn.getDB('test'), {});
+ }
},
{
- name: 'Test dbAdmin admin user',
- test: function(conn) {
- var adminDB = conn.getDB('admin');
- assert.eq(1, adminDB.auth('aadmin', AUTH_INFO.admin.aadmin.pwd));
-
- testOps(adminDB, ADMIN_PERM);
- testOps(conn.getDB('test'), {});
- }
+ name: 'Test dbAdmin admin user',
+ test: function(conn) {
+ var adminDB = conn.getDB('admin');
+ assert.eq(1, adminDB.auth('aadmin', AUTH_INFO.admin.aadmin.pwd));
+
+ testOps(adminDB, ADMIN_PERM);
+ testOps(conn.getDB('test'), {});
+ }
},
{
- name: 'Test userAdmin admin user',
- test: function(conn) {
- var adminDB = conn.getDB('admin');
- assert.eq(1, adminDB.auth('auadmin', AUTH_INFO.admin.auadmin.pwd));
-
- testOps(adminDB, UADMIN_PERM);
- testOps(conn.getDB('test'), {});
- }
+ name: 'Test userAdmin admin user',
+ test: function(conn) {
+ var adminDB = conn.getDB('admin');
+ assert.eq(1, adminDB.auth('auadmin', AUTH_INFO.admin.auadmin.pwd));
+
+ testOps(adminDB, UADMIN_PERM);
+ testOps(conn.getDB('test'), {});
+ }
},
{
- name: 'Test read only any db user',
- test: function(conn) {
- var adminDB = conn.getDB('admin');
- assert.eq(1, adminDB.auth('any_ro', AUTH_INFO.admin.any_ro.pwd));
-
- testOps(adminDB, READ_PERM);
- testOps(conn.getDB('test'), READ_PERM);
- }
+ name: 'Test read only any db user',
+ test: function(conn) {
+ var adminDB = conn.getDB('admin');
+ assert.eq(1, adminDB.auth('any_ro', AUTH_INFO.admin.any_ro.pwd));
+
+ testOps(adminDB, READ_PERM);
+ testOps(conn.getDB('test'), READ_PERM);
+ }
},
{
- name: 'Test read/write any db user',
- test: function(conn) {
- var adminDB = conn.getDB('admin');
- assert.eq(1, adminDB.auth('any_rw', AUTH_INFO.admin.any_rw.pwd));
-
- testOps(adminDB, READ_WRITE_PERM);
- testOps(conn.getDB('test'), READ_WRITE_PERM);
- }
+ name: 'Test read/write any db user',
+ test: function(conn) {
+ var adminDB = conn.getDB('admin');
+ assert.eq(1, adminDB.auth('any_rw', AUTH_INFO.admin.any_rw.pwd));
+
+ testOps(adminDB, READ_WRITE_PERM);
+ testOps(conn.getDB('test'), READ_WRITE_PERM);
+ }
},
{
- name: 'Test dbAdmin any db user',
- test: function(conn) {
- var adminDB = conn.getDB('admin');
- assert.eq(1, adminDB.auth('any_admin', AUTH_INFO.admin.any_admin.pwd));
-
- testOps(adminDB, ADMIN_PERM);
- testOps(conn.getDB('test'), ADMIN_PERM);
- }
+ name: 'Test dbAdmin any db user',
+ test: function(conn) {
+ var adminDB = conn.getDB('admin');
+ assert.eq(1, adminDB.auth('any_admin', AUTH_INFO.admin.any_admin.pwd));
+
+ testOps(adminDB, ADMIN_PERM);
+ testOps(conn.getDB('test'), ADMIN_PERM);
+ }
},
{
- name: 'Test userAdmin any db user',
- test: function(conn) {
- var adminDB = conn.getDB('admin');
- assert.eq(1, adminDB.auth('any_uadmin', AUTH_INFO.admin.any_uadmin.pwd));
-
- testOps(adminDB, UADMIN_PERM);
- testOps(conn.getDB('test'), UADMIN_PERM);
- }
+ name: 'Test userAdmin any db user',
+ test: function(conn) {
+ var adminDB = conn.getDB('admin');
+ assert.eq(1, adminDB.auth('any_uadmin', AUTH_INFO.admin.any_uadmin.pwd));
+
+ testOps(adminDB, UADMIN_PERM);
+ testOps(conn.getDB('test'), UADMIN_PERM);
+ }
},
{
- name: 'Test change role',
- test: function(conn) {
- var testDB = conn.getDB('test');
- assert.eq(1, testDB.auth('rw', AUTH_INFO.test.rw.pwd));
-
- var newConn = new Mongo(conn.host);
- assert.eq(1, newConn.getDB('admin').auth('any_uadmin', AUTH_INFO.admin.any_uadmin.pwd));
- newConn.getDB('test').updateUser('rw', {roles: ['read']});
- var origSpec = newConn.getDB("test").getUser("rw");
-
- // role change should affect users already authenticated.
- testOps(testDB, READ_PERM);
-
- // role change should affect active connections.
- testDB.runCommand({logout: 1});
- assert.eq(1, testDB.auth('rw', AUTH_INFO.test.rw.pwd));
- testOps(testDB, READ_PERM);
-
- // role change should also affect new connections.
- var newConn3 = new Mongo(conn.host);
- var testDB3 = newConn3.getDB('test');
- assert.eq(1, testDB3.auth('rw', AUTH_INFO.test.rw.pwd));
- testOps(testDB3, READ_PERM);
-
- newConn.getDB('test').updateUser('rw', {roles: origSpec.roles});
- }
+ name: 'Test change role',
+ test: function(conn) {
+ var testDB = conn.getDB('test');
+ assert.eq(1, testDB.auth('rw', AUTH_INFO.test.rw.pwd));
+
+ var newConn = new Mongo(conn.host);
+ assert.eq(1, newConn.getDB('admin').auth('any_uadmin', AUTH_INFO.admin.any_uadmin.pwd));
+ newConn.getDB('test').updateUser('rw', {roles: ['read']});
+ var origSpec = newConn.getDB("test").getUser("rw");
+
+ // role change should affect users already authenticated.
+ testOps(testDB, READ_PERM);
+
+ // role change should affect active connections.
+ testDB.runCommand({logout: 1});
+ assert.eq(1, testDB.auth('rw', AUTH_INFO.test.rw.pwd));
+ testOps(testDB, READ_PERM);
+
+ // role change should also affect new connections.
+ var newConn3 = new Mongo(conn.host);
+ var testDB3 = newConn3.getDB('test');
+ assert.eq(1, testDB3.auth('rw', AUTH_INFO.test.rw.pwd));
+ testOps(testDB3, READ_PERM);
+
+ newConn.getDB('test').updateUser('rw', {roles: origSpec.roles});
+ }
},
{
- name: 'Test override user',
- test: function(conn) {
- var testDB = conn.getDB('test');
- assert.eq(1, testDB.auth('rw', AUTH_INFO.test.rw.pwd));
- assert.eq(1, testDB.auth('ro', AUTH_INFO.test.ro.pwd));
- testOps(testDB, READ_PERM);
-
- testDB.runCommand({logout: 1});
- testOps(testDB, {});
- }
+ name: 'Test override user',
+ test: function(conn) {
+ var testDB = conn.getDB('test');
+ assert.eq(1, testDB.auth('rw', AUTH_INFO.test.rw.pwd));
+ assert.eq(1, testDB.auth('ro', AUTH_INFO.test.ro.pwd));
+ testOps(testDB, READ_PERM);
+
+ testDB.runCommand({logout: 1});
+ testOps(testDB, {});
+ }
}
];
diff --git a/jstests/auth/cluster_ip_whitelist.js b/jstests/auth/cluster_ip_whitelist.js
index b82262a7551..401133dcf71 100644
--- a/jstests/auth/cluster_ip_whitelist.js
+++ b/jstests/auth/cluster_ip_whitelist.js
@@ -3,55 +3,54 @@
*/
(function() {
- 'use strict';
-
- print("When whitelist is empty, the server does not start.");
- assert.eq(null,
- MongoRunner.runMongod(
- {auth: null, keyFile: "jstests/libs/key1", clusterIpSourceWhitelist: ""}));
-
- function testIpWhitelist(description, whitelistString, authResult) {
- print(description);
-
- var conn = MongoRunner.runMongod(
- {auth: null, keyFile: "jstests/libs/key1", clusterIpSourceWhitelist: whitelistString});
- assert.eq(authResult, conn.getDB("local").auth("__system", "foopdedoop"));
- MongoRunner.stopMongod(conn);
- }
-
- testIpWhitelist(
- "When 127.0.0.1 is whitelisted, a client connected via localhost may auth as __system.",
- "127.0.0.1",
- true);
-
- testIpWhitelist(
- "When 127.0.0.0 is whitelisted as a 24-bit CIDR block, a client connected via localhost may auth as __system.",
- "127.0.0.0/24",
- true);
-
- testIpWhitelist(
- "When 127.0.0.5 is whitelisted as a 24-bit CIDR block, a client connected via localhost may auth as __system.",
- "127.0.0.5/24",
- true);
-
- testIpWhitelist(
- "When 127.0.0.0 is whitelisted as a 8-bit CIDR block, a client connected via localhost may auth as __system.",
- "127.0.0.0/8",
- true);
-
- testIpWhitelist(
- "When the IP block reserved for documentation and the 127.0.0.0/8 block are both whitelisted, a client connected via localhost may auth as __system.",
- "192.0.2.0/24,127.0.0.0/8",
- true);
-
- testIpWhitelist(
- "When 127.0.0.0/8 and the IP block reserved for documentation are both whitelisted, a client connected via localhost may auth as __system.",
- "127.0.0.0/8,192.0.2.0/24",
- true);
-
- testIpWhitelist(
- "When the IP block reserved for documentation and examples is whitelisted, a client connected via localhost may not auth as __system.",
- "192.0.2.0/24",
- false);
-
+'use strict';
+
+print("When whitelist is empty, the server does not start.");
+assert.eq(null,
+ MongoRunner.runMongod(
+ {auth: null, keyFile: "jstests/libs/key1", clusterIpSourceWhitelist: ""}));
+
+function testIpWhitelist(description, whitelistString, authResult) {
+ print(description);
+
+ var conn = MongoRunner.runMongod(
+ {auth: null, keyFile: "jstests/libs/key1", clusterIpSourceWhitelist: whitelistString});
+ assert.eq(authResult, conn.getDB("local").auth("__system", "foopdedoop"));
+ MongoRunner.stopMongod(conn);
+}
+
+testIpWhitelist(
+ "When 127.0.0.1 is whitelisted, a client connected via localhost may auth as __system.",
+ "127.0.0.1",
+ true);
+
+testIpWhitelist(
+ "When 127.0.0.0 is whitelisted as a 24-bit CIDR block, a client connected via localhost may auth as __system.",
+ "127.0.0.0/24",
+ true);
+
+testIpWhitelist(
+ "When 127.0.0.5 is whitelisted as a 24-bit CIDR block, a client connected via localhost may auth as __system.",
+ "127.0.0.5/24",
+ true);
+
+testIpWhitelist(
+ "When 127.0.0.0 is whitelisted as a 8-bit CIDR block, a client connected via localhost may auth as __system.",
+ "127.0.0.0/8",
+ true);
+
+testIpWhitelist(
+ "When the IP block reserved for documentation and the 127.0.0.0/8 block are both whitelisted, a client connected via localhost may auth as __system.",
+ "192.0.2.0/24,127.0.0.0/8",
+ true);
+
+testIpWhitelist(
+ "When 127.0.0.0/8 and the IP block reserved for documentation are both whitelisted, a client connected via localhost may auth as __system.",
+ "127.0.0.0/8,192.0.2.0/24",
+ true);
+
+testIpWhitelist(
+ "When the IP block reserved for documentation and examples is whitelisted, a client connected via localhost may not auth as __system.",
+ "192.0.2.0/24",
+ false);
}());
diff --git a/jstests/auth/commands_builtin_roles.js b/jstests/auth/commands_builtin_roles.js
index 32674cd8a41..0c87ea82763 100644
--- a/jstests/auth/commands_builtin_roles.js
+++ b/jstests/auth/commands_builtin_roles.js
@@ -58,15 +58,16 @@ function testProperAuthorization(conn, t, testcase, r) {
assert(r.db.auth("user|" + r.key, "password"));
authCommandsLib.authenticatedSetup(t, runOnDb);
var command = t.command;
- if (typeof(command) === "function") {
+ if (typeof (command) === "function") {
command = t.command(state, testcase.commandArgs);
}
var res = runOnDb.runCommand(command);
if (testcase.roles[r.key]) {
if (res.ok == 0 && res.code == authErrCode) {
- out = "expected authorization success" + " but received " + tojson(res) + " on db " +
- testcase.runOnDb + " with role " + r.key;
+ out = "expected authorization success" +
+ " but received " + tojson(res) + " on db " + testcase.runOnDb + " with role " +
+ r.key;
} else if (res.ok == 0 && !testcase.expectFail && res.code != commandNotSupportedCode) {
// don't error if the test failed with code commandNotSupported since
// some storage engines (e.g wiredTiger) don't support some commands (e.g. touch)
@@ -75,8 +76,9 @@ function testProperAuthorization(conn, t, testcase, r) {
}
} else {
if (res.ok == 1 || (res.ok == 0 && res.code != authErrCode)) {
- out = "expected authorization failure" + " but received result " + tojson(res) +
- " on db " + testcase.runOnDb + " with role " + r.key;
+ out = "expected authorization failure" +
+ " but received result " + tojson(res) + " on db " + testcase.runOnDb +
+ " with role " + r.key;
}
}
diff --git a/jstests/auth/commands_user_defined_roles.js b/jstests/auth/commands_user_defined_roles.js
index 049034f4c86..003957abe64 100644
--- a/jstests/auth/commands_user_defined_roles.js
+++ b/jstests/auth/commands_user_defined_roles.js
@@ -40,7 +40,7 @@ function testProperAuthorization(conn, t, testcase, privileges) {
authCommandsLib.authenticatedSetup(t, runOnDb);
var command = t.command;
- if (typeof(command) === "function") {
+ if (typeof (command) === "function") {
command = t.command(state, testcase.commandArgs);
}
var res = runOnDb.runCommand(command);
@@ -51,8 +51,9 @@ function testProperAuthorization(conn, t, testcase, privileges) {
out = "command failed with " + tojson(res) + " on db " + testcase.runOnDb +
" with privileges " + tojson(privileges);
} else if (testcase.expectFail && res.code == authErrCode) {
- out = "expected authorization success" + " but received " + tojson(res) + " on db " +
- testcase.runOnDb + " with privileges " + tojson(privileges);
+ out = "expected authorization success" +
+ " but received " + tojson(res) + " on db " + testcase.runOnDb + " with privileges " +
+ tojson(privileges);
}
firstDb.logout();
@@ -78,14 +79,14 @@ function testInsufficientPrivileges(conn, t, testcase, privileges) {
authCommandsLib.authenticatedSetup(t, runOnDb);
var command = t.command;
- if (typeof(command) === "function") {
+ if (typeof (command) === "function") {
command = t.command(state, testcase.commandArgs);
}
var res = runOnDb.runCommand(command);
if (res.ok == 1 || res.code != authErrCode) {
- out = "expected authorization failure " + " but received " + tojson(res) +
- " with privileges " + tojson(privileges);
+ out = "expected authorization failure " +
+ " but received " + tojson(res) + " with privileges " + tojson(privileges);
}
firstDb.logout();
diff --git a/jstests/auth/curop_auth_info.js b/jstests/auth/curop_auth_info.js
index 94f7426e4f1..2bb329b1eee 100644
--- a/jstests/auth/curop_auth_info.js
+++ b/jstests/auth/curop_auth_info.js
@@ -1,77 +1,77 @@
(function() {
- 'use strict';
+'use strict';
- const runTest = function(conn, failPointConn) {
- jsTestLog("Setting up users");
- const db = conn.getDB("admin");
- assert.commandWorked(
- db.runCommand({createUser: "admin", pwd: "pwd", roles: jsTest.adminUserRoles}));
- assert.eq(db.auth("admin", "pwd"), 1);
- assert.commandWorked(db.runCommand({createUser: "testuser", pwd: "pwd", roles: []}));
- db.grantRolesToUser("testuser", [{role: "readWrite", db: "test"}]);
+const runTest = function(conn, failPointConn) {
+ jsTestLog("Setting up users");
+ const db = conn.getDB("admin");
+ assert.commandWorked(
+ db.runCommand({createUser: "admin", pwd: "pwd", roles: jsTest.adminUserRoles}));
+ assert.eq(db.auth("admin", "pwd"), 1);
+ assert.commandWorked(db.runCommand({createUser: "testuser", pwd: "pwd", roles: []}));
+ db.grantRolesToUser("testuser", [{role: "readWrite", db: "test"}]);
- const queryFn = function() {
- assert.eq(db.getSiblingDB("admin").auth("testuser", "pwd"), 1);
- let testDB = db.getSiblingDB("test");
- testDB.test.insert({});
- assert.eq(testDB.test.find({}).comment("curop_auth_info.js query").itcount(), 1);
- };
-
- jsTestLog("blocking finds and starting parallel shell to create op");
- assert.commandWorked(failPointConn.getDB("admin").runCommand(
- {configureFailPoint: "waitInFindBeforeMakingBatch", mode: "alwaysOn"}));
- let finderWait = startParallelShell(queryFn, conn.port);
- let myOp;
+ const queryFn = function() {
+ assert.eq(db.getSiblingDB("admin").auth("testuser", "pwd"), 1);
+ let testDB = db.getSiblingDB("test");
+ testDB.test.insert({});
+ assert.eq(testDB.test.find({}).comment("curop_auth_info.js query").itcount(), 1);
+ };
- assert.soon(function() {
- const curOpResults = db.runCommand({currentOp: 1});
- assert.commandWorked(curOpResults);
- print(tojson(curOpResults));
- const myOps = curOpResults["inprog"].filter((op) => {
- return (op["command"]["comment"] == "curop_auth_info.js query");
- });
+ jsTestLog("blocking finds and starting parallel shell to create op");
+ assert.commandWorked(failPointConn.getDB("admin").runCommand(
+ {configureFailPoint: "waitInFindBeforeMakingBatch", mode: "alwaysOn"}));
+ let finderWait = startParallelShell(queryFn, conn.port);
+ let myOp;
- if (myOps.length == 0) {
- return false;
- }
- myOp = myOps[0];
- return true;
+ assert.soon(function() {
+ const curOpResults = db.runCommand({currentOp: 1});
+ assert.commandWorked(curOpResults);
+ print(tojson(curOpResults));
+ const myOps = curOpResults["inprog"].filter((op) => {
+ return (op["command"]["comment"] == "curop_auth_info.js query");
});
- jsTestLog("found op");
- assert.commandWorked(failPointConn.getDB("admin").runCommand(
- {configureFailPoint: "waitInFindBeforeMakingBatch", mode: "off"}));
- finderWait();
-
- const authedUsers = myOp["effectiveUsers"];
- const impersonators = myOp["runBy"];
- print(tojson(authedUsers), tojson(impersonators));
- if (impersonators) {
- assert.eq(authedUsers.length, 1);
- assert.docEq(authedUsers[0], {user: "testuser", db: "admin"});
- assert(impersonators);
- assert.eq(impersonators.length, 1);
- assert.docEq(impersonators[0], {user: "__system", db: "local"});
- } else {
- assert(authedUsers);
- assert.eq(authedUsers.length, 1);
- assert.docEq(authedUsers[0], {user: "testuser", db: "admin"});
+ if (myOps.length == 0) {
+ return false;
}
- };
+ myOp = myOps[0];
+ return true;
+ });
- const m = MongoRunner.runMongod();
- runTest(m, m);
- MongoRunner.stopMongod(m);
+ jsTestLog("found op");
+ assert.commandWorked(failPointConn.getDB("admin").runCommand(
+ {configureFailPoint: "waitInFindBeforeMakingBatch", mode: "off"}));
+ finderWait();
- const st = new ShardingTest({
- shards: 1,
- mongos: 1,
- config: 1,
- keyFile: 'jstests/libs/key1',
- other: {
- shardAsReplicaSet: false,
- }
- });
- runTest(st.s0, st.d0);
- st.stop();
+ const authedUsers = myOp["effectiveUsers"];
+ const impersonators = myOp["runBy"];
+ print(tojson(authedUsers), tojson(impersonators));
+ if (impersonators) {
+ assert.eq(authedUsers.length, 1);
+ assert.docEq(authedUsers[0], {user: "testuser", db: "admin"});
+ assert(impersonators);
+ assert.eq(impersonators.length, 1);
+ assert.docEq(impersonators[0], {user: "__system", db: "local"});
+ } else {
+ assert(authedUsers);
+ assert.eq(authedUsers.length, 1);
+ assert.docEq(authedUsers[0], {user: "testuser", db: "admin"});
+ }
+};
+
+const m = MongoRunner.runMongod();
+runTest(m, m);
+MongoRunner.stopMongod(m);
+
+const st = new ShardingTest({
+ shards: 1,
+ mongos: 1,
+ config: 1,
+ keyFile: 'jstests/libs/key1',
+ other: {
+ shardAsReplicaSet: false,
+ }
+});
+runTest(st.s0, st.d0);
+st.stop();
})();
diff --git a/jstests/auth/currentop_cursors_auth.js b/jstests/auth/currentop_cursors_auth.js
index ca196be176f..70ee354273a 100644
--- a/jstests/auth/currentop_cursors_auth.js
+++ b/jstests/auth/currentop_cursors_auth.js
@@ -4,164 +4,156 @@
* @tags: [assumes_read_concern_unchanged, requires_auth, requires_journaling, requires_replication]
*/
(function() {
- "use strict";
+"use strict";
- load("jstests/libs/fixture_helpers.js"); // For isMongos.
+load("jstests/libs/fixture_helpers.js"); // For isMongos.
- // TODO SERVER-32672: remove the 'skipGossipingClusterTime' flag.
- TestData.skipGossipingClusterTime = true;
+// TODO SERVER-32672: remove the 'skipGossipingClusterTime' flag.
+TestData.skipGossipingClusterTime = true;
- // Create a new sharded cluster for testing and enable auth.
- const key = "jstests/libs/key1";
- const st = new ShardingTest({name: jsTestName(), keyFile: key, shards: 1});
+// Create a new sharded cluster for testing and enable auth.
+const key = "jstests/libs/key1";
+const st = new ShardingTest({name: jsTestName(), keyFile: key, shards: 1});
- const shardConn = st.rs0.getPrimary();
- const mongosConn = st.s;
+const shardConn = st.rs0.getPrimary();
+const mongosConn = st.s;
- shardConn.waitForClusterTime(60);
+shardConn.waitForClusterTime(60);
- Random.setRandomSeed();
- const pass = "a" + Random.rand();
+Random.setRandomSeed();
+const pass = "a" + Random.rand();
- // Create one root user and one regular user on the given connection.
- function createUsers(conn) {
- const adminDB = conn.getDB("admin");
- adminDB.createUser({user: "ted", pwd: pass, roles: ["root"]});
- assert(adminDB.auth("ted", pass), "Authentication 1 Failed");
- adminDB.createUser({user: "yuta", pwd: pass, roles: ["readWriteAnyDatabase"]});
- }
+// Create one root user and one regular user on the given connection.
+function createUsers(conn) {
+ const adminDB = conn.getDB("admin");
+ adminDB.createUser({user: "ted", pwd: pass, roles: ["root"]});
+ assert(adminDB.auth("ted", pass), "Authentication 1 Failed");
+ adminDB.createUser({user: "yuta", pwd: pass, roles: ["readWriteAnyDatabase"]});
+}
- // Create the necessary users at both cluster and shard-local level.
- createUsers(shardConn);
- createUsers(mongosConn);
-
- // Run the various auth tests on the given shard or mongoS connection.
- function runCursorTests(conn) {
- const db = conn.getDB("test");
- const adminDB = db.getSiblingDB("admin");
-
- // Log in as the root user.
- assert.commandWorked(adminDB.logout());
- assert(adminDB.auth("ted", pass), "Authentication 2 Failed");
-
- const coll = db.jstests_currentop_cursors_auth;
- coll.drop();
- for (let i = 0; i < 5; ++i) {
- assert.commandWorked(coll.insert({val: i}));
- }
-
- // Verify that we can see our own cursor with {allUsers: false}.
- const cursorId = assert
- .commandWorked(db.runCommand(
- {find: "jstests_currentop_cursors_auth", batchSize: 2}))
- .cursor.id;
-
- let result =
- adminDB
- .aggregate([
- {$currentOp: {localOps: true, allUsers: false, idleCursors: true}},
- {$match: {$and: [{type: "idleCursor"}, {"cursor.cursorId": cursorId}]}}
- ])
- .toArray();
- assert.eq(result.length, 1, result);
-
- // Log in as the non-root user.
- assert.commandWorked(adminDB.logout());
- assert(adminDB.auth("yuta", pass), "Authentication 3 Failed");
-
- // Verify that we cannot see the root user's cursor.
- result = adminDB
- .aggregate([
- {$currentOp: {localOps: true, allUsers: false, idleCursors: true}},
- {$match: {$and: [{type: "idleCursor"}, {"cursor.cursorId": cursorId}]}}
- ])
- .toArray();
- assert.eq(result.length, 0, result);
+// Create the necessary users at both cluster and shard-local level.
+createUsers(shardConn);
+createUsers(mongosConn);
- // Make sure that the behavior is the same when 'allUsers' is not explicitly specified.
- result = adminDB
- .aggregate([
- {$currentOp: {localOps: true, idleCursors: true}},
- {$match: {$and: [{type: "idleCursor"}, {"cursor.cursorId": cursorId}]}}
- ])
- .toArray();
- assert.eq(result.length, 0, result);
-
- // Verify that the user without the 'inprog' privilege cannot view shard cursors via mongoS.
- if (FixtureHelpers.isMongos(db)) {
- assert.commandFailedWithCode(adminDB.runCommand({
- aggregate: 1,
- pipeline: [{$currentOp: {localOps: false, idleCursors: true}}],
- cursor: {}
- }),
- ErrorCodes.Unauthorized);
- }
-
- // Create a cursor with the second (non-root) user and confirm that we can see it.
- const secondCursorId = assert
- .commandWorked(db.runCommand(
- {find: "jstests_currentop_cursors_auth", batchSize: 2}))
- .cursor.id;
-
- result =
- adminDB
- .aggregate([
- {$currentOp: {localOps: true, allUsers: false, idleCursors: true}},
- {$match: {$and: [{type: "idleCursor"}, {"cursor.cursorId": secondCursorId}]}}
- ])
- .toArray();
- assert.eq(result.length, 1, result);
-
- // Log back in with the root user and confirm that the first cursor is still present.
- assert.commandWorked(adminDB.logout());
- assert(adminDB.auth("ted", pass), "Authentication 4 Failed");
+// Run the various auth tests on the given shard or mongoS connection.
+function runCursorTests(conn) {
+ const db = conn.getDB("test");
+ const adminDB = db.getSiblingDB("admin");
- result = adminDB
+ // Log in as the root user.
+ assert.commandWorked(adminDB.logout());
+ assert(adminDB.auth("ted", pass), "Authentication 2 Failed");
+
+ const coll = db.jstests_currentop_cursors_auth;
+ coll.drop();
+ for (let i = 0; i < 5; ++i) {
+ assert.commandWorked(coll.insert({val: i}));
+ }
+
+ // Verify that we can see our own cursor with {allUsers: false}.
+ const cursorId =
+ assert.commandWorked(db.runCommand({find: "jstests_currentop_cursors_auth", batchSize: 2}))
+ .cursor.id;
+
+ let result = adminDB
.aggregate([
{$currentOp: {localOps: true, allUsers: false, idleCursors: true}},
{$match: {$and: [{type: "idleCursor"}, {"cursor.cursorId": cursorId}]}}
])
.toArray();
- assert.eq(result.length, 1, result);
+ assert.eq(result.length, 1, result);
+
+ // Log in as the non-root user.
+ assert.commandWorked(adminDB.logout());
+ assert(adminDB.auth("yuta", pass), "Authentication 3 Failed");
+
+ // Verify that we cannot see the root user's cursor.
+ result = adminDB
+ .aggregate([
+ {$currentOp: {localOps: true, allUsers: false, idleCursors: true}},
+ {$match: {$and: [{type: "idleCursor"}, {"cursor.cursorId": cursorId}]}}
+ ])
+ .toArray();
+ assert.eq(result.length, 0, result);
+
+ // Make sure that the behavior is the same when 'allUsers' is not explicitly specified.
+ result = adminDB
+ .aggregate([
+ {$currentOp: {localOps: true, idleCursors: true}},
+ {$match: {$and: [{type: "idleCursor"}, {"cursor.cursorId": cursorId}]}}
+ ])
+ .toArray();
+ assert.eq(result.length, 0, result);
+
+ // Verify that the user without the 'inprog' privilege cannot view shard cursors via mongoS.
+ if (FixtureHelpers.isMongos(db)) {
+ assert.commandFailedWithCode(adminDB.runCommand({
+ aggregate: 1,
+ pipeline: [{$currentOp: {localOps: false, idleCursors: true}}],
+ cursor: {}
+ }),
+ ErrorCodes.Unauthorized);
+ }
- // Confirm that the root user can see both users' cursors with {allUsers: true}.
+ // Create a cursor with the second (non-root) user and confirm that we can see it.
+ const secondCursorId =
+ assert.commandWorked(db.runCommand({find: "jstests_currentop_cursors_auth", batchSize: 2}))
+ .cursor.id;
+
+ result = adminDB
+ .aggregate([
+ {$currentOp: {localOps: true, allUsers: false, idleCursors: true}},
+ {$match: {$and: [{type: "idleCursor"}, {"cursor.cursorId": secondCursorId}]}}
+ ])
+ .toArray();
+ assert.eq(result.length, 1, result);
+
+ // Log back in with the root user and confirm that the first cursor is still present.
+ assert.commandWorked(adminDB.logout());
+ assert(adminDB.auth("ted", pass), "Authentication 4 Failed");
+
+ result = adminDB
+ .aggregate([
+ {$currentOp: {localOps: true, allUsers: false, idleCursors: true}},
+ {$match: {$and: [{type: "idleCursor"}, {"cursor.cursorId": cursorId}]}}
+ ])
+ .toArray();
+ assert.eq(result.length, 1, result);
+
+ // Confirm that the root user can see both users' cursors with {allUsers: true}.
+ result =
+ adminDB
+ .aggregate([
+ {$currentOp: {localOps: true, allUsers: true, idleCursors: true}},
+ {$match: {type: "idleCursor", "cursor.cursorId": {$in: [cursorId, secondCursorId]}}}
+ ])
+ .toArray();
+ assert.eq(result.length, 2, result);
+
+ // The root user can also see both cursors on the shard via mongoS with {localOps: false}.
+ if (FixtureHelpers.isMongos(db)) {
result = adminDB
.aggregate([
- {$currentOp: {localOps: true, allUsers: true, idleCursors: true}},
- {
- $match: {
- type: "idleCursor",
- "cursor.cursorId": {$in: [cursorId, secondCursorId]}
- }
- }
+ {$currentOp: {localOps: false, allUsers: true, idleCursors: true}},
+ {$match: {type: "idleCursor", shard: st.rs0.name}}
])
.toArray();
assert.eq(result.length, 2, result);
-
- // The root user can also see both cursors on the shard via mongoS with {localOps: false}.
- if (FixtureHelpers.isMongos(db)) {
- result = adminDB
- .aggregate([
- {$currentOp: {localOps: false, allUsers: true, idleCursors: true}},
- {$match: {type: "idleCursor", shard: st.rs0.name}}
- ])
- .toArray();
- assert.eq(result.length, 2, result);
- }
-
- // Clean up the cursors so that they don't affect subsequent tests.
- assert.commandWorked(
- db.runCommand({killCursors: coll.getName(), cursors: [cursorId, secondCursorId]}));
-
- // Make sure to logout to allow __system user to use the implicit session.
- assert.commandWorked(adminDB.logout());
}
- jsTestLog("Running cursor tests on mongoD");
- runCursorTests(shardConn);
+ // Clean up the cursors so that they don't affect subsequent tests.
+ assert.commandWorked(
+ db.runCommand({killCursors: coll.getName(), cursors: [cursorId, secondCursorId]}));
+
+ // Make sure to logout to allow __system user to use the implicit session.
+ assert.commandWorked(adminDB.logout());
+}
+
+jsTestLog("Running cursor tests on mongoD");
+runCursorTests(shardConn);
- jsTestLog("Running cursor tests on mongoS");
- runCursorTests(mongosConn);
+jsTestLog("Running cursor tests on mongoS");
+runCursorTests(mongosConn);
- st.stop();
+st.stop();
})();
diff --git a/jstests/auth/deleted_recreated_user.js b/jstests/auth/deleted_recreated_user.js
index 87517f48297..704710107c0 100644
--- a/jstests/auth/deleted_recreated_user.js
+++ b/jstests/auth/deleted_recreated_user.js
@@ -1,74 +1,74 @@
// Test that sessions can not be resumed by deleted and recreated user.
(function() {
- 'use strict';
+'use strict';
- const kInvalidationIntervalSecs = 5;
+const kInvalidationIntervalSecs = 5;
- function runTest(s0, s1) {
- assert(s0);
- assert(s1);
- const admin = s0.getDB('admin');
+function runTest(s0, s1) {
+ assert(s0);
+ assert(s1);
+ const admin = s0.getDB('admin');
- function checkIdType(username) {
- const user = admin.system.users.find({user: username, db: 'admin'}).toArray()[0];
- const id = user._id;
- const userId = user.userId;
- assert.eq(typeof(id), 'string');
- assert.eq(id, 'admin.' + username);
- assert.eq(typeof(userId), 'object');
- assert.eq(tojson(userId).substring(0, 5), 'UUID(');
- }
-
- admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
- assert(admin.auth('admin', 'pass'));
- checkIdType('admin');
+ function checkIdType(username) {
+ const user = admin.system.users.find({user: username, db: 'admin'}).toArray()[0];
+ const id = user._id;
+ const userId = user.userId;
+ assert.eq(typeof (id), 'string');
+ assert.eq(id, 'admin.' + username);
+ assert.eq(typeof (userId), 'object');
+ assert.eq(tojson(userId).substring(0, 5), 'UUID(');
+ }
- admin.createUser({user: 'user', pwd: 'pass', roles: jsTest.basicUserRoles});
- checkIdType('user');
- admin.logout();
+ admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
+ assert(admin.auth('admin', 'pass'));
+ checkIdType('admin');
- // Connect as basic user and create a session.
- assert(admin.auth('user', 'pass'));
- assert.writeOK(admin.mycoll.insert({_id: "foo", data: "bar"}));
+ admin.createUser({user: 'user', pwd: 'pass', roles: jsTest.basicUserRoles});
+ checkIdType('user');
+ admin.logout();
- // Perform administrative commands via separate shell.
- function evalCmd(cmd) {
- const uri = 'mongodb://admin:pass@localhost:' + s1.port + '/admin';
- const result = runMongoProgram('./mongo', uri, '--eval', cmd);
- assert.eq(result, 0, "Command failed");
- }
- evalCmd('db.dropUser("user"); ');
- evalCmd('db.createUser({user: "user", pwd: "secret", roles: ["root"]});');
+ // Connect as basic user and create a session.
+ assert(admin.auth('user', 'pass'));
+ assert.writeOK(admin.mycoll.insert({_id: "foo", data: "bar"}));
- if (s0 !== s1) {
- // Wait for twice the invalidation interval when sharding.
- sleep(2 * kInvalidationIntervalSecs * 1000);
- }
+ // Perform administrative commands via separate shell.
+ function evalCmd(cmd) {
+ const uri = 'mongodb://admin:pass@localhost:' + s1.port + '/admin';
+ const result = runMongoProgram('./mongo', uri, '--eval', cmd);
+ assert.eq(result, 0, "Command failed");
+ }
+ evalCmd('db.dropUser("user"); ');
+ evalCmd('db.createUser({user: "user", pwd: "secret", roles: ["root"]});');
- // This should fail due to invalid user session.
- const thrown =
- assert.throws(() => admin.mycoll.find({}).toArray(), [], "Able to find after recreate");
- assert.eq(thrown.code, ErrorCodes.Unauthorized, "Threw something other than unauthorized");
+ if (s0 !== s1) {
+ // Wait for twice the invalidation interval when sharding.
+ sleep(2 * kInvalidationIntervalSecs * 1000);
}
- const mongod = MongoRunner.runMongod({auth: ''});
- runTest(mongod, mongod);
- MongoRunner.stopMongod(mongod);
+ // This should fail due to invalid user session.
+ const thrown =
+ assert.throws(() => admin.mycoll.find({}).toArray(), [], "Able to find after recreate");
+ assert.eq(thrown.code, ErrorCodes.Unauthorized, "Threw something other than unauthorized");
+}
+
+const mongod = MongoRunner.runMongod({auth: ''});
+runTest(mongod, mongod);
+MongoRunner.stopMongod(mongod);
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- const st = new ShardingTest({
- shards: 1,
- mongos: 2,
- config: 1,
- other: {
- keyFile: 'jstests/libs/key1',
- shardAsReplicaSet: false,
- mongosOptions: {
- setParameter: 'userCacheInvalidationIntervalSecs=' + kInvalidationIntervalSecs,
- },
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+const st = new ShardingTest({
+ shards: 1,
+ mongos: 2,
+ config: 1,
+ other: {
+ keyFile: 'jstests/libs/key1',
+ shardAsReplicaSet: false,
+ mongosOptions: {
+ setParameter: 'userCacheInvalidationIntervalSecs=' + kInvalidationIntervalSecs,
},
- });
- runTest(st.s0, st.s1);
- st.stop();
+ },
+});
+runTest(st.s0, st.s1);
+st.stop();
})();
diff --git a/jstests/auth/getMore.js b/jstests/auth/getMore.js
index d58c52a205c..4495d61200b 100644
--- a/jstests/auth/getMore.js
+++ b/jstests/auth/getMore.js
@@ -1,351 +1,341 @@
// Tests that a user can only run a getMore on a cursor that they created.
// @tags: [requires_sharding]
(function() {
- "use strict";
-
- // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
- TestData.disableImplicitSessions = true;
-
- function runTest(conn) {
- let adminDB = conn.getDB("admin");
- let isMaster = adminDB.runCommand("ismaster");
- assert.commandWorked(isMaster);
- const isMongos = (isMaster.msg === "isdbgrid");
-
- // Create the admin user.
- assert.commandWorked(
- adminDB.runCommand({createUser: "admin", pwd: "admin", roles: ["root"]}));
- assert.eq(1, adminDB.auth("admin", "admin"));
-
- // Set up the test database.
- const testDBName = "auth_getMore";
- let testDB = adminDB.getSiblingDB(testDBName);
- testDB.dropDatabase();
- assert.writeOK(testDB.foo.insert({_id: 0}));
- assert.writeOK(testDB.foo.insert({_id: 1}));
- assert.writeOK(testDB.foo.insert({_id: 2}));
-
- //
- // Test that a user can only run a getMore on a cursor that they created.
- //
-
- // Create two users, "Alice" and "Mallory".
- assert.commandWorked(
- testDB.runCommand({createUser: "Alice", pwd: "pwd", roles: ["readWrite"]}));
- assert.commandWorked(
- testDB.runCommand({createUser: "Mallory", pwd: "pwd", roles: ["readWrite"]}));
- adminDB.logout();
-
- // Test that "Mallory" cannot use a find cursor created by "Alice".
- assert.eq(1, testDB.auth("Alice", "pwd"));
- let res = assert.commandWorked(testDB.runCommand({find: "foo", batchSize: 0}));
- let cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- testDB.logout();
- assert.eq(1, testDB.auth("Mallory", "pwd"));
- assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "foo"}),
- ErrorCodes.Unauthorized,
- "read from another user's find cursor");
- testDB.logout();
-
- // Test that "Mallory" cannot use a legacy find cursor created by "Alice".
- testDB.getMongo().forceReadMode("legacy");
- assert.eq(1, testDB.auth("Alice", "pwd"));
- let cursor = testDB.foo.find().batchSize(2);
+"use strict";
+
+// TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+TestData.disableImplicitSessions = true;
+
+function runTest(conn) {
+ let adminDB = conn.getDB("admin");
+ let isMaster = adminDB.runCommand("ismaster");
+ assert.commandWorked(isMaster);
+ const isMongos = (isMaster.msg === "isdbgrid");
+
+ // Create the admin user.
+ assert.commandWorked(adminDB.runCommand({createUser: "admin", pwd: "admin", roles: ["root"]}));
+ assert.eq(1, adminDB.auth("admin", "admin"));
+
+ // Set up the test database.
+ const testDBName = "auth_getMore";
+ let testDB = adminDB.getSiblingDB(testDBName);
+ testDB.dropDatabase();
+ assert.writeOK(testDB.foo.insert({_id: 0}));
+ assert.writeOK(testDB.foo.insert({_id: 1}));
+ assert.writeOK(testDB.foo.insert({_id: 2}));
+
+ //
+ // Test that a user can only run a getMore on a cursor that they created.
+ //
+
+ // Create two users, "Alice" and "Mallory".
+ assert.commandWorked(
+ testDB.runCommand({createUser: "Alice", pwd: "pwd", roles: ["readWrite"]}));
+ assert.commandWorked(
+ testDB.runCommand({createUser: "Mallory", pwd: "pwd", roles: ["readWrite"]}));
+ adminDB.logout();
+
+ // Test that "Mallory" cannot use a find cursor created by "Alice".
+ assert.eq(1, testDB.auth("Alice", "pwd"));
+ let res = assert.commandWorked(testDB.runCommand({find: "foo", batchSize: 0}));
+ let cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ testDB.logout();
+ assert.eq(1, testDB.auth("Mallory", "pwd"));
+ assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "foo"}),
+ ErrorCodes.Unauthorized,
+ "read from another user's find cursor");
+ testDB.logout();
+
+ // Test that "Mallory" cannot use a legacy find cursor created by "Alice".
+ testDB.getMongo().forceReadMode("legacy");
+ assert.eq(1, testDB.auth("Alice", "pwd"));
+ let cursor = testDB.foo.find().batchSize(2);
+ cursor.next();
+ cursor.next();
+ testDB.logout();
+ assert.eq(1, testDB.auth("Mallory", "pwd"));
+ assert.throws(function() {
cursor.next();
- cursor.next();
- testDB.logout();
- assert.eq(1, testDB.auth("Mallory", "pwd"));
- assert.throws(function() {
- cursor.next();
- }, [], "read from another user's legacy find cursor");
- testDB.logout();
- testDB.getMongo().forceReadMode("commands");
-
- // Test that "Mallory" cannot use an aggregation cursor created by "Alice".
- assert.eq(1, testDB.auth("Alice", "pwd"));
- res = assert.commandWorked(
- testDB.runCommand({aggregate: "foo", pipeline: [], cursor: {batchSize: 0}}));
- cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- testDB.logout();
- assert.eq(1, testDB.auth("Mallory", "pwd"));
- assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "foo"}),
- ErrorCodes.Unauthorized,
- "read from another user's aggregate cursor");
- testDB.logout();
-
- // Test that "Mallory" cannot use a listCollections cursor created by "Alice".
- assert.eq(1, testDB.auth("Alice", "pwd"));
- res = assert.commandWorked(testDB.runCommand({listCollections: 1, cursor: {batchSize: 0}}));
- cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- testDB.logout();
- assert.eq(1, testDB.auth("Mallory", "pwd"));
- assert.commandFailedWithCode(
- testDB.runCommand({getMore: cursorId, collection: "$cmd.listCollections"}),
- ErrorCodes.Unauthorized,
- "read from another user's listCollections cursor");
- testDB.logout();
-
- // Test that "Mallory" cannot use a listIndexes cursor created by "Alice".
- assert.eq(1, testDB.auth("Alice", "pwd"));
- res = assert.commandWorked(testDB.runCommand({listIndexes: "foo", cursor: {batchSize: 0}}));
- cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- testDB.logout();
- assert.eq(1, testDB.auth("Mallory", "pwd"));
- assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "foo"}),
- ErrorCodes.Unauthorized,
- "read from another user's listIndexes cursor");
- testDB.logout();
-
- //
- // Test that a user can call getMore on an indexStats cursor they created, unless the
- // indexStats privilege has been revoked in the meantime.
- //
-
- assert.eq(1, adminDB.auth("admin", "admin"));
- assert.commandWorked(testDB.runCommand({
- createRole: "indexStatsOnly",
- privileges: [{resource: {db: testDBName, collection: "foo"}, actions: ["indexStats"]}],
- roles: []
- }));
- assert.commandWorked(
- testDB.runCommand({createUser: "Bob", pwd: "pwd", roles: ["indexStatsOnly"]}));
- adminDB.logout();
-
- assert.eq(1, testDB.auth("Bob", "pwd"));
- res = assert.commandWorked(testDB.runCommand(
- {aggregate: "foo", pipeline: [{$indexStats: {}}], cursor: {batchSize: 0}}));
- cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- assert.commandWorked(testDB.runCommand({getMore: cursorId, collection: "foo"}));
-
- res = assert.commandWorked(testDB.runCommand(
- {aggregate: "foo", pipeline: [{$indexStats: {}}], cursor: {batchSize: 0}}));
- cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- testDB.logout();
-
- assert.eq(1, adminDB.auth("admin", "admin"));
- assert.commandWorked(
- testDB.runCommand({revokeRolesFromUser: "Bob", roles: ["indexStatsOnly"]}));
- adminDB.logout();
-
- assert.eq(1, testDB.auth("Bob", "pwd"));
- assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "foo"}),
- ErrorCodes.Unauthorized,
- "read from a cursor without required privileges");
- testDB.logout();
-
- //
- // Test that a user can call getMore on a listCollections cursor they created, unless the
- // readWrite privilege has been revoked in the meantime.
- //
-
- assert.eq(1, adminDB.auth("admin", "admin"));
-
- assert.commandWorked(
- testDB.runCommand({createUser: "Tom", pwd: "pwd", roles: ["readWrite"]}));
- adminDB.logout();
-
- assert.eq(1, testDB.auth("Tom", "pwd"));
- res = assert.commandWorked(testDB.runCommand({listCollections: 1, cursor: {batchSize: 0}}));
- cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- assert.commandWorked(
- testDB.runCommand({getMore: cursorId, collection: "$cmd.listCollections"}));
-
- res = assert.commandWorked(testDB.runCommand({listCollections: 1, cursor: {batchSize: 0}}));
- cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- testDB.logout();
-
- assert.eq(1, adminDB.auth("admin", "admin"));
- assert.commandWorked(testDB.runCommand({revokeRolesFromUser: "Tom", roles: ["readWrite"]}));
- adminDB.logout();
-
- assert.eq(1, testDB.auth("Tom", "pwd"));
- assert.commandFailedWithCode(
- testDB.runCommand({getMore: cursorId, collection: "$cmd.listCollections"}),
- ErrorCodes.Unauthorized,
- "read from a cursor without required privileges");
- testDB.logout();
- //
- // Test that a user can call getMore on a listIndexes cursor they created, unless the
- // readWrite privilege has been revoked in the meantime.
- //
-
- assert.eq(1, adminDB.auth("admin", "admin"));
-
- assert.commandWorked(
- testDB.runCommand({createUser: "Bill", pwd: "pwd", roles: ["readWrite"]}));
- adminDB.logout();
-
- assert.eq(1, testDB.auth("Bill", "pwd"));
- res = assert.commandWorked(testDB.runCommand({listIndexes: "foo", cursor: {batchSize: 0}}));
- cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- assert.commandWorked(testDB.runCommand({getMore: cursorId, collection: "foo"}));
-
- res = assert.commandWorked(testDB.runCommand({listIndexes: "foo", cursor: {batchSize: 0}}));
- cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- testDB.logout();
-
- assert.eq(1, adminDB.auth("admin", "admin"));
- assert.commandWorked(
- testDB.runCommand({revokeRolesFromUser: "Bill", roles: ["readWrite"]}));
- adminDB.logout();
-
- assert.eq(1, testDB.auth("Bill", "pwd"));
- assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "foo"}),
- ErrorCodes.Unauthorized,
- "read from a cursor without required privileges");
- testDB.logout();
-
- //
- // Test that a user can run a getMore on an aggregate cursor they created, unless some
- // privileges required for the pipeline have been revoked in the meantime.
- //
-
- assert.eq(1, testDB.auth("Alice", "pwd"));
- res = assert.commandWorked(testDB.runCommand({
- aggregate: "foo",
- pipeline: [{$match: {_id: 0}}, {$out: "out"}],
- cursor: {batchSize: 0}
- }));
- cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- assert.commandWorked(testDB.runCommand({getMore: cursorId, collection: "foo"}));
-
- res = assert.commandWorked(testDB.runCommand({
- aggregate: "foo",
- pipeline: [{$match: {_id: 0}}, {$out: "out"}],
- cursor: {batchSize: 0}
- }));
- cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- testDB.logout();
-
- assert.eq(1, adminDB.auth("admin", "admin"));
- testDB.revokeRolesFromUser("Alice", ["readWrite"]);
- testDB.grantRolesToUser("Alice", ["read"]);
- adminDB.logout();
-
- assert.eq(1, testDB.auth("Alice", "pwd"));
- assert.commandFailedWithCode(
- testDB.runCommand(
- {aggregate: "foo", pipeline: [{$match: {_id: 0}}, {$out: "out"}], cursor: {}}),
- ErrorCodes.Unauthorized,
- "user should no longer have write privileges");
- assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "foo"}),
- ErrorCodes.Unauthorized,
- "wrote from a cursor without required privileges");
- testDB.logout();
-
- //
- // Test that if there were multiple users authenticated when the cursor was created, then at
- // least one of them must be authenticated in order to run getMore on the cursor.
- //
-
- assert.eq(1, adminDB.auth("admin", "admin"));
- assert.writeOK(testDB.bar.insert({_id: 0}));
-
- // Create a user "fooUser" on the test database that can read the "foo" collection.
- assert.commandWorked(testDB.runCommand({
- createRole: "readFoo",
- privileges: [{resource: {db: testDBName, collection: "foo"}, actions: ["find"]}],
- roles: []
- }));
- assert.commandWorked(
- testDB.runCommand({createUser: "fooUser", pwd: "pwd", roles: ["readFoo"]}));
-
- // Create a user "fooBarUser" on the admin database that can read the "foo" and "bar"
- // collections.
- assert.commandWorked(adminDB.runCommand({
- createRole: "readFooBar",
- privileges: [
- {resource: {db: testDBName, collection: "foo"}, actions: ["find"]},
- {resource: {db: testDBName, collection: "bar"}, actions: ["find"]}
- ],
- roles: []
- }));
- assert.commandWorked(
- adminDB.runCommand({createUser: "fooBarUser", pwd: "pwd", roles: ["readFooBar"]}));
-
- adminDB.logout();
-
- // Test that a cursor created by "fooUser" and "fooBarUser" can be used by "fooUser".
- assert.eq(1, testDB.auth("fooUser", "pwd"));
- assert.eq(1, adminDB.auth("fooBarUser", "pwd"));
- res = assert.commandWorked(testDB.runCommand({find: "foo", batchSize: 0}));
- cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- adminDB.logout();
- assert.commandWorked(testDB.runCommand({getMore: cursorId, collection: "foo"}));
- testDB.logout();
-
- // Test that a cursor created by "fooUser" and "fooBarUser" cannot be used by "fooUser" if
- // "fooUser" does not have the privilege to read the collection.
- assert.eq(1, testDB.auth("fooUser", "pwd"));
- assert.eq(1, adminDB.auth("fooBarUser", "pwd"));
- res = assert.commandWorked(testDB.runCommand({find: "bar", batchSize: 0}));
- cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- adminDB.logout();
- assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "bar"}),
- ErrorCodes.Unauthorized,
- "read from a cursor without required privileges");
- testDB.logout();
-
- // Test that an aggregate cursor created by "fooUser" and "fooBarUser" cannot be used by
- // "fooUser" if "fooUser" does not have all privileges required by the pipeline.
- assert.eq(1, testDB.auth("fooUser", "pwd"));
- assert.eq(1, adminDB.auth("fooBarUser", "pwd"));
- res = assert.commandWorked(testDB.runCommand({
- aggregate: "foo",
- pipeline: [
- {$match: {_id: 0}},
- {$lookup: {from: "bar", localField: "_id", foreignField: "_id", as: "bar"}}
- ],
- cursor: {batchSize: 0}
- }));
- cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- assert.commandWorked(testDB.runCommand({getMore: cursorId, collection: "foo"}));
-
- res = assert.commandWorked(testDB.runCommand({
- aggregate: "foo",
- pipeline: [
- {$match: {_id: 0}},
- {$lookup: {from: "bar", localField: "_id", foreignField: "_id", as: "bar"}}
- ],
- cursor: {batchSize: 0}
- }));
- cursorId = res.cursor.id;
- assert.neq(0, cursorId);
- adminDB.logout();
- assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "foo"}),
- ErrorCodes.Unauthorized,
- "read from a cursor without required privileges");
- testDB.logout();
- }
-
- // Run the test on a standalone.
- let conn = MongoRunner.runMongod({auth: "", bind_ip: "127.0.0.1"});
- runTest(conn);
- MongoRunner.stopMongod(conn);
-
- // Run the test on a sharded cluster.
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- let cluster = new ShardingTest({
- shards: 1,
- mongos: 1,
- keyFile: "jstests/libs/key1",
- other: {shardOptions: {auth: ""}, shardAsReplicaSet: false}
- });
- runTest(cluster);
- cluster.stop();
+ }, [], "read from another user's legacy find cursor");
+ testDB.logout();
+ testDB.getMongo().forceReadMode("commands");
+
+ // Test that "Mallory" cannot use an aggregation cursor created by "Alice".
+ assert.eq(1, testDB.auth("Alice", "pwd"));
+ res = assert.commandWorked(
+ testDB.runCommand({aggregate: "foo", pipeline: [], cursor: {batchSize: 0}}));
+ cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ testDB.logout();
+ assert.eq(1, testDB.auth("Mallory", "pwd"));
+ assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "foo"}),
+ ErrorCodes.Unauthorized,
+ "read from another user's aggregate cursor");
+ testDB.logout();
+
+ // Test that "Mallory" cannot use a listCollections cursor created by "Alice".
+ assert.eq(1, testDB.auth("Alice", "pwd"));
+ res = assert.commandWorked(testDB.runCommand({listCollections: 1, cursor: {batchSize: 0}}));
+ cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ testDB.logout();
+ assert.eq(1, testDB.auth("Mallory", "pwd"));
+ assert.commandFailedWithCode(
+ testDB.runCommand({getMore: cursorId, collection: "$cmd.listCollections"}),
+ ErrorCodes.Unauthorized,
+ "read from another user's listCollections cursor");
+ testDB.logout();
+
+ // Test that "Mallory" cannot use a listIndexes cursor created by "Alice".
+ assert.eq(1, testDB.auth("Alice", "pwd"));
+ res = assert.commandWorked(testDB.runCommand({listIndexes: "foo", cursor: {batchSize: 0}}));
+ cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ testDB.logout();
+ assert.eq(1, testDB.auth("Mallory", "pwd"));
+ assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "foo"}),
+ ErrorCodes.Unauthorized,
+ "read from another user's listIndexes cursor");
+ testDB.logout();
+
+ //
+ // Test that a user can call getMore on an indexStats cursor they created, unless the
+ // indexStats privilege has been revoked in the meantime.
+ //
+
+ assert.eq(1, adminDB.auth("admin", "admin"));
+ assert.commandWorked(testDB.runCommand({
+ createRole: "indexStatsOnly",
+ privileges: [{resource: {db: testDBName, collection: "foo"}, actions: ["indexStats"]}],
+ roles: []
+ }));
+ assert.commandWorked(
+ testDB.runCommand({createUser: "Bob", pwd: "pwd", roles: ["indexStatsOnly"]}));
+ adminDB.logout();
+
+ assert.eq(1, testDB.auth("Bob", "pwd"));
+ res = assert.commandWorked(testDB.runCommand(
+ {aggregate: "foo", pipeline: [{$indexStats: {}}], cursor: {batchSize: 0}}));
+ cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ assert.commandWorked(testDB.runCommand({getMore: cursorId, collection: "foo"}));
+
+ res = assert.commandWorked(testDB.runCommand(
+ {aggregate: "foo", pipeline: [{$indexStats: {}}], cursor: {batchSize: 0}}));
+ cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ testDB.logout();
+
+ assert.eq(1, adminDB.auth("admin", "admin"));
+ assert.commandWorked(
+ testDB.runCommand({revokeRolesFromUser: "Bob", roles: ["indexStatsOnly"]}));
+ adminDB.logout();
+
+ assert.eq(1, testDB.auth("Bob", "pwd"));
+ assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "foo"}),
+ ErrorCodes.Unauthorized,
+ "read from a cursor without required privileges");
+ testDB.logout();
+
+ //
+ // Test that a user can call getMore on a listCollections cursor they created, unless the
+ // readWrite privilege has been revoked in the meantime.
+ //
+
+ assert.eq(1, adminDB.auth("admin", "admin"));
+
+ assert.commandWorked(testDB.runCommand({createUser: "Tom", pwd: "pwd", roles: ["readWrite"]}));
+ adminDB.logout();
+
+ assert.eq(1, testDB.auth("Tom", "pwd"));
+ res = assert.commandWorked(testDB.runCommand({listCollections: 1, cursor: {batchSize: 0}}));
+ cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ assert.commandWorked(
+ testDB.runCommand({getMore: cursorId, collection: "$cmd.listCollections"}));
+
+ res = assert.commandWorked(testDB.runCommand({listCollections: 1, cursor: {batchSize: 0}}));
+ cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ testDB.logout();
+
+ assert.eq(1, adminDB.auth("admin", "admin"));
+ assert.commandWorked(testDB.runCommand({revokeRolesFromUser: "Tom", roles: ["readWrite"]}));
+ adminDB.logout();
+
+ assert.eq(1, testDB.auth("Tom", "pwd"));
+ assert.commandFailedWithCode(
+ testDB.runCommand({getMore: cursorId, collection: "$cmd.listCollections"}),
+ ErrorCodes.Unauthorized,
+ "read from a cursor without required privileges");
+ testDB.logout();
+ //
+ // Test that a user can call getMore on a listIndexes cursor they created, unless the
+ // readWrite privilege has been revoked in the meantime.
+ //
+
+ assert.eq(1, adminDB.auth("admin", "admin"));
+
+ assert.commandWorked(testDB.runCommand({createUser: "Bill", pwd: "pwd", roles: ["readWrite"]}));
+ adminDB.logout();
+
+ assert.eq(1, testDB.auth("Bill", "pwd"));
+ res = assert.commandWorked(testDB.runCommand({listIndexes: "foo", cursor: {batchSize: 0}}));
+ cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ assert.commandWorked(testDB.runCommand({getMore: cursorId, collection: "foo"}));
+
+ res = assert.commandWorked(testDB.runCommand({listIndexes: "foo", cursor: {batchSize: 0}}));
+ cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ testDB.logout();
+
+ assert.eq(1, adminDB.auth("admin", "admin"));
+ assert.commandWorked(testDB.runCommand({revokeRolesFromUser: "Bill", roles: ["readWrite"]}));
+ adminDB.logout();
+
+ assert.eq(1, testDB.auth("Bill", "pwd"));
+ assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "foo"}),
+ ErrorCodes.Unauthorized,
+ "read from a cursor without required privileges");
+ testDB.logout();
+
+ //
+ // Test that a user can run a getMore on an aggregate cursor they created, unless some
+ // privileges required for the pipeline have been revoked in the meantime.
+ //
+
+ assert.eq(1, testDB.auth("Alice", "pwd"));
+ res = assert.commandWorked(testDB.runCommand(
+ {aggregate: "foo", pipeline: [{$match: {_id: 0}}, {$out: "out"}], cursor: {batchSize: 0}}));
+ cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ assert.commandWorked(testDB.runCommand({getMore: cursorId, collection: "foo"}));
+
+ res = assert.commandWorked(testDB.runCommand(
+ {aggregate: "foo", pipeline: [{$match: {_id: 0}}, {$out: "out"}], cursor: {batchSize: 0}}));
+ cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ testDB.logout();
+
+ assert.eq(1, adminDB.auth("admin", "admin"));
+ testDB.revokeRolesFromUser("Alice", ["readWrite"]);
+ testDB.grantRolesToUser("Alice", ["read"]);
+ adminDB.logout();
+
+ assert.eq(1, testDB.auth("Alice", "pwd"));
+ assert.commandFailedWithCode(
+ testDB.runCommand(
+ {aggregate: "foo", pipeline: [{$match: {_id: 0}}, {$out: "out"}], cursor: {}}),
+ ErrorCodes.Unauthorized,
+ "user should no longer have write privileges");
+ assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "foo"}),
+ ErrorCodes.Unauthorized,
+ "wrote from a cursor without required privileges");
+ testDB.logout();
+
+ //
+ // Test that if there were multiple users authenticated when the cursor was created, then at
+ // least one of them must be authenticated in order to run getMore on the cursor.
+ //
+
+ assert.eq(1, adminDB.auth("admin", "admin"));
+ assert.writeOK(testDB.bar.insert({_id: 0}));
+
+ // Create a user "fooUser" on the test database that can read the "foo" collection.
+ assert.commandWorked(testDB.runCommand({
+ createRole: "readFoo",
+ privileges: [{resource: {db: testDBName, collection: "foo"}, actions: ["find"]}],
+ roles: []
+ }));
+ assert.commandWorked(
+ testDB.runCommand({createUser: "fooUser", pwd: "pwd", roles: ["readFoo"]}));
+
+ // Create a user "fooBarUser" on the admin database that can read the "foo" and "bar"
+ // collections.
+ assert.commandWorked(adminDB.runCommand({
+ createRole: "readFooBar",
+ privileges: [
+ {resource: {db: testDBName, collection: "foo"}, actions: ["find"]},
+ {resource: {db: testDBName, collection: "bar"}, actions: ["find"]}
+ ],
+ roles: []
+ }));
+ assert.commandWorked(
+ adminDB.runCommand({createUser: "fooBarUser", pwd: "pwd", roles: ["readFooBar"]}));
+
+ adminDB.logout();
+
+ // Test that a cursor created by "fooUser" and "fooBarUser" can be used by "fooUser".
+ assert.eq(1, testDB.auth("fooUser", "pwd"));
+ assert.eq(1, adminDB.auth("fooBarUser", "pwd"));
+ res = assert.commandWorked(testDB.runCommand({find: "foo", batchSize: 0}));
+ cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ adminDB.logout();
+ assert.commandWorked(testDB.runCommand({getMore: cursorId, collection: "foo"}));
+ testDB.logout();
+
+ // Test that a cursor created by "fooUser" and "fooBarUser" cannot be used by "fooUser" if
+ // "fooUser" does not have the privilege to read the collection.
+ assert.eq(1, testDB.auth("fooUser", "pwd"));
+ assert.eq(1, adminDB.auth("fooBarUser", "pwd"));
+ res = assert.commandWorked(testDB.runCommand({find: "bar", batchSize: 0}));
+ cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ adminDB.logout();
+ assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "bar"}),
+ ErrorCodes.Unauthorized,
+ "read from a cursor without required privileges");
+ testDB.logout();
+
+ // Test that an aggregate cursor created by "fooUser" and "fooBarUser" cannot be used by
+ // "fooUser" if "fooUser" does not have all privileges required by the pipeline.
+ assert.eq(1, testDB.auth("fooUser", "pwd"));
+ assert.eq(1, adminDB.auth("fooBarUser", "pwd"));
+ res = assert.commandWorked(testDB.runCommand({
+ aggregate: "foo",
+ pipeline: [
+ {$match: {_id: 0}},
+ {$lookup: {from: "bar", localField: "_id", foreignField: "_id", as: "bar"}}
+ ],
+ cursor: {batchSize: 0}
+ }));
+ cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ assert.commandWorked(testDB.runCommand({getMore: cursorId, collection: "foo"}));
+
+ res = assert.commandWorked(testDB.runCommand({
+ aggregate: "foo",
+ pipeline: [
+ {$match: {_id: 0}},
+ {$lookup: {from: "bar", localField: "_id", foreignField: "_id", as: "bar"}}
+ ],
+ cursor: {batchSize: 0}
+ }));
+ cursorId = res.cursor.id;
+ assert.neq(0, cursorId);
+ adminDB.logout();
+ assert.commandFailedWithCode(testDB.runCommand({getMore: cursorId, collection: "foo"}),
+ ErrorCodes.Unauthorized,
+ "read from a cursor without required privileges");
+ testDB.logout();
+}
+
+// Run the test on a standalone.
+let conn = MongoRunner.runMongod({auth: "", bind_ip: "127.0.0.1"});
+runTest(conn);
+MongoRunner.stopMongod(conn);
+
+// Run the test on a sharded cluster.
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+let cluster = new ShardingTest({
+ shards: 1,
+ mongos: 1,
+ keyFile: "jstests/libs/key1",
+ other: {shardOptions: {auth: ""}, shardAsReplicaSet: false}
+});
+runTest(cluster);
+cluster.stop();
}());
diff --git a/jstests/auth/iteration_count_control.js b/jstests/auth/iteration_count_control.js
index 6ae57fdd6f7..d003347bdbc 100644
--- a/jstests/auth/iteration_count_control.js
+++ b/jstests/auth/iteration_count_control.js
@@ -1,43 +1,43 @@
// Test SCRAM iterationCount control.
(function() {
- 'use strict';
+'use strict';
- load('./jstests/multiVersion/libs/auth_helpers.js');
+load('./jstests/multiVersion/libs/auth_helpers.js');
- const conn = MongoRunner.runMongod({auth: ''});
- const adminDB = conn.getDB('admin');
+const conn = MongoRunner.runMongod({auth: ''});
+const adminDB = conn.getDB('admin');
- adminDB.createUser({user: 'user1', pwd: 'pass', roles: jsTest.adminUserRoles});
- assert(adminDB.auth({user: 'user1', pwd: 'pass'}));
+adminDB.createUser({user: 'user1', pwd: 'pass', roles: jsTest.adminUserRoles});
+assert(adminDB.auth({user: 'user1', pwd: 'pass'}));
- var userDoc = getUserDoc(adminDB, 'user1');
- assert.eq(10000, userDoc.credentials['SCRAM-SHA-1'].iterationCount);
+var userDoc = getUserDoc(adminDB, 'user1');
+assert.eq(10000, userDoc.credentials['SCRAM-SHA-1'].iterationCount);
- // Changing iterationCount should not affect existing users.
- assert.commandWorked(adminDB.runCommand({setParameter: 1, scramIterationCount: 5000}));
- userDoc = getUserDoc(adminDB, 'user1');
- assert.eq(10000, userDoc.credentials['SCRAM-SHA-1'].iterationCount);
+// Changing iterationCount should not affect existing users.
+assert.commandWorked(adminDB.runCommand({setParameter: 1, scramIterationCount: 5000}));
+userDoc = getUserDoc(adminDB, 'user1');
+assert.eq(10000, userDoc.credentials['SCRAM-SHA-1'].iterationCount);
- // But it should take effect when the user's password is changed.
- adminDB.updateUser('user1', {pwd: 'pass', roles: jsTest.adminUserRoles});
- userDoc = getUserDoc(adminDB, 'user1');
- assert.eq(5000, userDoc.credentials['SCRAM-SHA-1'].iterationCount);
+// But it should take effect when the user's password is changed.
+adminDB.updateUser('user1', {pwd: 'pass', roles: jsTest.adminUserRoles});
+userDoc = getUserDoc(adminDB, 'user1');
+assert.eq(5000, userDoc.credentials['SCRAM-SHA-1'].iterationCount);
- // Test (in)valid values for scramIterationCount. 5000 is the minimum value.
- assert.commandFailed(adminDB.runCommand({setParameter: 1, scramIterationCount: 4999}));
- assert.commandFailed(adminDB.runCommand({setParameter: 1, scramIterationCount: -5000}));
- assert.commandWorked(adminDB.runCommand({setParameter: 1, scramIterationCount: 5000}));
- assert.commandWorked(adminDB.runCommand({setParameter: 1, scramIterationCount: 10000}));
- assert.commandWorked(adminDB.runCommand({setParameter: 1, scramIterationCount: 1000000}));
+// Test (in)valid values for scramIterationCount. 5000 is the minimum value.
+assert.commandFailed(adminDB.runCommand({setParameter: 1, scramIterationCount: 4999}));
+assert.commandFailed(adminDB.runCommand({setParameter: 1, scramIterationCount: -5000}));
+assert.commandWorked(adminDB.runCommand({setParameter: 1, scramIterationCount: 5000}));
+assert.commandWorked(adminDB.runCommand({setParameter: 1, scramIterationCount: 10000}));
+assert.commandWorked(adminDB.runCommand({setParameter: 1, scramIterationCount: 1000000}));
- assert.commandFailed(adminDB.runCommand({setParameter: 1, scramSHA256IterationCount: -5000}));
- assert.commandFailed(adminDB.runCommand({setParameter: 1, scramSHA256IterationCount: 4095}));
- assert.commandFailed(adminDB.runCommand({setParameter: 1, scramSHA256IterationCount: 4096}));
- assert.commandFailed(adminDB.runCommand({setParameter: 1, scramSHA256IterationCount: 4999}));
- assert.commandWorked(adminDB.runCommand({setParameter: 1, scramSHA256IterationCount: 5000}));
- assert.commandWorked(adminDB.runCommand({setParameter: 1, scramSHA256IterationCount: 10000}));
- assert.commandWorked(adminDB.runCommand({setParameter: 1, scramSHA256IterationCount: 1000000}));
+assert.commandFailed(adminDB.runCommand({setParameter: 1, scramSHA256IterationCount: -5000}));
+assert.commandFailed(adminDB.runCommand({setParameter: 1, scramSHA256IterationCount: 4095}));
+assert.commandFailed(adminDB.runCommand({setParameter: 1, scramSHA256IterationCount: 4096}));
+assert.commandFailed(adminDB.runCommand({setParameter: 1, scramSHA256IterationCount: 4999}));
+assert.commandWorked(adminDB.runCommand({setParameter: 1, scramSHA256IterationCount: 5000}));
+assert.commandWorked(adminDB.runCommand({setParameter: 1, scramSHA256IterationCount: 10000}));
+assert.commandWorked(adminDB.runCommand({setParameter: 1, scramSHA256IterationCount: 1000000}));
- MongoRunner.stopMongod(conn);
+MongoRunner.stopMongod(conn);
})();
diff --git a/jstests/auth/iteration_count_defaults.js b/jstests/auth/iteration_count_defaults.js
index 6ebe74abec1..560704e274c 100644
--- a/jstests/auth/iteration_count_defaults.js
+++ b/jstests/auth/iteration_count_defaults.js
@@ -1,28 +1,28 @@
// Test SCRAM iterationCount defaults.
(function() {
- 'use strict';
+'use strict';
- function runOpt(params, sha1Value, sha256Value) {
- const conn = MongoRunner.runMongod({auth: '', setParameter: params});
- const adminDB = conn.getDB('admin');
+function runOpt(params, sha1Value, sha256Value) {
+ const conn = MongoRunner.runMongod({auth: '', setParameter: params});
+ const adminDB = conn.getDB('admin');
- adminDB.createUser({user: 'user1', pwd: 'pass', roles: jsTest.adminUserRoles});
- assert(adminDB.auth({user: 'user1', pwd: 'pass'}));
+ adminDB.createUser({user: 'user1', pwd: 'pass', roles: jsTest.adminUserRoles});
+ assert(adminDB.auth({user: 'user1', pwd: 'pass'}));
- const response = assert.commandWorked(adminDB.runCommand(
- {getParameter: 1, scramIterationCount: 1, scramSHA256IterationCount: 1}));
- assert.eq(response.scramIterationCount, sha1Value);
- assert.eq(response.scramSHA256IterationCount, sha256Value);
+ const response = assert.commandWorked(adminDB.runCommand(
+ {getParameter: 1, scramIterationCount: 1, scramSHA256IterationCount: 1}));
+ assert.eq(response.scramIterationCount, sha1Value);
+ assert.eq(response.scramSHA256IterationCount, sha256Value);
- MongoRunner.stopMongod(conn);
- }
+ MongoRunner.stopMongod(conn);
+}
- runOpt({}, 10000, 15000);
- runOpt({scramIterationCount: 12500}, 12500, 15000);
- runOpt({scramIterationCount: 20000}, 20000, 20000);
- runOpt({scramSHA256IterationCount: 9999}, 10000, 9999);
- runOpt({scramSHA256IterationCount: 10001}, 10000, 10001);
- runOpt({scramIterationCount: 7000, scramSHA256IterationCount: 8000}, 7000, 8000);
- runOpt({scramIterationCount: 8000, scramSHA256IterationCount: 7000}, 8000, 7000);
+runOpt({}, 10000, 15000);
+runOpt({scramIterationCount: 12500}, 12500, 15000);
+runOpt({scramIterationCount: 20000}, 20000, 20000);
+runOpt({scramSHA256IterationCount: 9999}, 10000, 9999);
+runOpt({scramSHA256IterationCount: 10001}, 10000, 10001);
+runOpt({scramIterationCount: 7000, scramSHA256IterationCount: 8000}, 7000, 8000);
+runOpt({scramIterationCount: 8000, scramSHA256IterationCount: 7000}, 8000, 7000);
})();
diff --git a/jstests/auth/keyfile_rollover.js b/jstests/auth/keyfile_rollover.js
index bbc704797ad..ea66397d8c8 100644
--- a/jstests/auth/keyfile_rollover.js
+++ b/jstests/auth/keyfile_rollover.js
@@ -11,82 +11,82 @@
TestData.skipGossipingClusterTime = true;
(function() {
- 'use strict';
+'use strict';
- let rst = new ReplSetTest({nodes: 3, keyFile: "jstests/libs/key1"});
- rst.startSet();
- rst.initiate();
+let rst = new ReplSetTest({nodes: 3, keyFile: "jstests/libs/key1"});
+rst.startSet();
+rst.initiate();
- const runPrimaryTest = function(fn) {
- const curPrimary = rst.getPrimary();
- assert(curPrimary.getDB("admin").auth("root", "root"));
- try {
- fn(curPrimary);
- rst.awaitSecondaryNodes();
- } finally {
- curPrimary.getDB("admin").logout();
- }
- };
+const runPrimaryTest = function(fn) {
+ const curPrimary = rst.getPrimary();
+ assert(curPrimary.getDB("admin").auth("root", "root"));
+ try {
+ fn(curPrimary);
+ rst.awaitSecondaryNodes();
+ } finally {
+ curPrimary.getDB("admin").logout();
+ }
+};
- // Create a user to login as when auth is enabled later
- rst.getPrimary().getDB('admin').createUser({user: 'root', pwd: 'root', roles: ['root']});
-
- runPrimaryTest((curPrimary) => {
- assert.writeOK(curPrimary.getDB('test').a.insert({a: 1, str: 'TESTTESTTEST'}));
- assert.eq(1, curPrimary.getDB('test').a.count(), 'Error interacting with replSet');
- });
+// Create a user to login as when auth is enabled later
+rst.getPrimary().getDB('admin').createUser({user: 'root', pwd: 'root', roles: ['root']});
- jsTestLog("Using keyForRollover to transition auth to both keys");
+runPrimaryTest((curPrimary) => {
+ assert.writeOK(curPrimary.getDB('test').a.insert({a: 1, str: 'TESTTESTTEST'}));
+ assert.eq(1, curPrimary.getDB('test').a.count(), 'Error interacting with replSet');
+});
- /*
- * This rolls over the cluster from one keyfile to another. The first argument is the keyfile
- * servers should use, and the second is the keyfile the shell should use to authenticate
- * with the servers.
- */
- const rolloverKey = function(keyFileForServers, keyFileForAuth) {
- // Update the keyFile parameter for the ReplSetTest as a whole
- rst.keyFile = keyFileForServers;
- // Function to restart a node with a new keyfile parameter and wait for secondaries
- // to come back online
- const restart = function(node) {
- const nodeId = rst.getNodeId(node);
- rst.stop(nodeId);
- rst.start(nodeId, {keyFile: keyFileForServers});
- authutil.asCluster(rst.nodes, keyFileForAuth, () => {
- rst.awaitSecondaryNodes();
- });
- };
+jsTestLog("Using keyForRollover to transition auth to both keys");
- // First we restart the secondaries.
- rst.getSecondaries().forEach(function(secondary) {
- restart(secondary);
- });
-
- // Then we restart the primary and wait for it to come back up with an ismaster call.
- const primary = rst.getPrimary();
- restart(primary);
- assert.soonNoExcept(() => {
- authutil.asCluster(rst.nodes, keyFileForAuth, () => {
- assert.commandWorked(primary.getDB("admin").runCommand({isMaster: 1}));
- });
- return true;
+/*
+ * This rolls over the cluster from one keyfile to another. The first argument is the keyfile
+ * servers should use, and the second is the keyfile the shell should use to authenticate
+ * with the servers.
+ */
+const rolloverKey = function(keyFileForServers, keyFileForAuth) {
+ // Update the keyFile parameter for the ReplSetTest as a whole
+ rst.keyFile = keyFileForServers;
+ // Function to restart a node with a new keyfile parameter and wait for secondaries
+ // to come back online
+ const restart = function(node) {
+ const nodeId = rst.getNodeId(node);
+ rst.stop(nodeId);
+ rst.start(nodeId, {keyFile: keyFileForServers});
+ authutil.asCluster(rst.nodes, keyFileForAuth, () => {
+ rst.awaitSecondaryNodes();
});
};
- rolloverKey("jstests/libs/keyForRollover", "jstests/libs/key1");
+ // First we restart the secondaries.
+ rst.getSecondaries().forEach(function(secondary) {
+ restart(secondary);
+ });
- runPrimaryTest((curPrimary) => {
- assert.writeOK(curPrimary.getDB('test').a.insert({a: 1, str: 'TESTTESTTEST'}));
- assert.eq(2, curPrimary.getDB('test').a.count(), 'Error interacting with replSet');
+ // Then we restart the primary and wait for it to come back up with an ismaster call.
+ const primary = rst.getPrimary();
+ restart(primary);
+ assert.soonNoExcept(() => {
+ authutil.asCluster(rst.nodes, keyFileForAuth, () => {
+ assert.commandWorked(primary.getDB("admin").runCommand({isMaster: 1}));
+ });
+ return true;
});
+};
- jsTestLog("Upgrading set to use key2");
- rolloverKey("jstests/libs/key2", "jstests/libs/key2");
+rolloverKey("jstests/libs/keyForRollover", "jstests/libs/key1");
- runPrimaryTest((curPrimary) => {
- assert.writeOK(curPrimary.getDB('test').a.insert({a: 1, str: 'TESTTESTTEST'}));
- assert.eq(3, curPrimary.getDB('test').a.count(), 'Error interacting with replSet');
- });
+runPrimaryTest((curPrimary) => {
+ assert.writeOK(curPrimary.getDB('test').a.insert({a: 1, str: 'TESTTESTTEST'}));
+ assert.eq(2, curPrimary.getDB('test').a.count(), 'Error interacting with replSet');
+});
+
+jsTestLog("Upgrading set to use key2");
+rolloverKey("jstests/libs/key2", "jstests/libs/key2");
+
+runPrimaryTest((curPrimary) => {
+ assert.writeOK(curPrimary.getDB('test').a.insert({a: 1, str: 'TESTTESTTEST'}));
+ assert.eq(3, curPrimary.getDB('test').a.count(), 'Error interacting with replSet');
+});
- rst.stopSet();
+rst.stopSet();
})();
diff --git a/jstests/auth/kill_cursors.js b/jstests/auth/kill_cursors.js
index dc49c7dba59..3d9a535311b 100644
--- a/jstests/auth/kill_cursors.js
+++ b/jstests/auth/kill_cursors.js
@@ -1,190 +1,174 @@
// Test the killCursors command.
// @tags: [requires_sharding]
(function() {
- 'use strict';
-
- // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
- TestData.disableImplicitSessions = true;
-
- function runTest(mongod) {
- /**
- * Open a cursor on `db` while authenticated as `authUsers`.
- * Then logout, and log back in as `killUsers` and try to kill that cursor.
- *
- * @param db - The db to create a cursor on and ultimately kill agains.
- * @param authUsers - Array of ['username', db] pairs to create the cursor under.
- * @param killUsers - Array of ['username', dn] pairs to use when killing.
- * @param shouldWork - Whether we expect success
- */
- function tryKill(db, authUsers, killUsers, shouldWork) {
- function loginAll(users) {
- users.forEach(function(u) {
- assert(u[1].auth(u[0], 'pass'));
- });
- }
+'use strict';
+
+// TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+TestData.disableImplicitSessions = true;
+
+function runTest(mongod) {
+ /**
+ * Open a cursor on `db` while authenticated as `authUsers`.
+ * Then logout, and log back in as `killUsers` and try to kill that cursor.
+ *
+ * @param db - The db to create a cursor on and ultimately kill agains.
+ * @param authUsers - Array of ['username', db] pairs to create the cursor under.
+ * @param killUsers - Array of ['username', dn] pairs to use when killing.
+ * @param shouldWork - Whether we expect success
+ */
+ function tryKill(db, authUsers, killUsers, shouldWork) {
+ function loginAll(users) {
+ users.forEach(function(u) {
+ assert(u[1].auth(u[0], 'pass'));
+ });
+ }
- function logoutAll() {
- [testA, testB].forEach(function(d) {
- const users = assert.commandWorked(d.runCommand({connectionStatus: 1}))
- .authInfo.authenticatedUsers;
- users.forEach(function(u) {
- mongod.getDB(u.db).logout();
- });
+ function logoutAll() {
+ [testA, testB].forEach(function(d) {
+ const users = assert.commandWorked(d.runCommand({connectionStatus: 1}))
+ .authInfo.authenticatedUsers;
+ users.forEach(function(u) {
+ mongod.getDB(u.db).logout();
});
- }
+ });
+ }
- function doKill(extra) {
- // Create a cursor to be killed later.
- loginAll(authUsers);
- let cmd = {find: db.coll.getName(), batchSize: 2};
- Object.assign(cmd, extra);
- const id = assert.commandWorked(db.runCommand(cmd)).cursor.id;
- assert.neq(id, 0, "Invalid cursor ID");
- logoutAll();
-
- loginAll(killUsers);
- const killCmd = db.runCommand({killCursors: db.coll.getName(), cursors: [id]});
- logoutAll();
- if (shouldWork) {
- assert.commandWorked(killCmd, "Unable to kill cursor");
- } else {
- assert.commandFailed(killCmd, "Should not have been able to kill cursor");
- }
+ function doKill(extra) {
+ // Create a cursor to be killed later.
+ loginAll(authUsers);
+ let cmd = {find: db.coll.getName(), batchSize: 2};
+ Object.assign(cmd, extra);
+ const id = assert.commandWorked(db.runCommand(cmd)).cursor.id;
+ assert.neq(id, 0, "Invalid cursor ID");
+ logoutAll();
+
+ loginAll(killUsers);
+ const killCmd = db.runCommand({killCursors: db.coll.getName(), cursors: [id]});
+ logoutAll();
+ if (shouldWork) {
+ assert.commandWorked(killCmd, "Unable to kill cursor");
+ } else {
+ assert.commandFailed(killCmd, "Should not have been able to kill cursor");
}
+ }
- doKill({});
+ doKill({});
- if ((authUsers.length === 1) && (killUsers.length === 1)) {
- // Session variant only makes sense with single auth'd users.
- doKill({lsid: {id: BinData(4, "QlLfPHTySm6tqfuV+EOsVA==")}});
- }
+ if ((authUsers.length === 1) && (killUsers.length === 1)) {
+ // Session variant only makes sense with single auth'd users.
+ doKill({lsid: {id: BinData(4, "QlLfPHTySm6tqfuV+EOsVA==")}});
}
+ }
- function trySelfKill(user) {
- const db = user[1];
- assert(db.auth(user[0], 'pass'));
-
- assert.commandWorked(db.runCommand({startSession: 1}));
+ function trySelfKill(user) {
+ const db = user[1];
+ assert(db.auth(user[0], 'pass'));
- const cmd = {
- aggregate: 1,
- pipeline: [{$listLocalSessions: {}}],
- cursor: {batchSize: 0}
- };
- const res = assert.commandWorked(db.runCommand(cmd));
- print(tojson(res));
- const id = res.cursor.id;
- assert.neq(id, 0, "Invalid cursor ID");
+ assert.commandWorked(db.runCommand({startSession: 1}));
- const killCmdRes = db.runCommand({killCursors: db.getName() + ".$cmd", cursors: [id]});
- db.logout();
+ const cmd = {aggregate: 1, pipeline: [{$listLocalSessions: {}}], cursor: {batchSize: 0}};
+ const res = assert.commandWorked(db.runCommand(cmd));
+ print(tojson(res));
+ const id = res.cursor.id;
+ assert.neq(id, 0, "Invalid cursor ID");
- assert.commandWorked(killCmdRes, "Unable to kill cursor");
- }
+ const killCmdRes = db.runCommand({killCursors: db.getName() + ".$cmd", cursors: [id]});
+ db.logout();
- /**
- * Create user1/user2 in testA, and user3/user4 in testB.
- * Create two 101 element collections in testA and testB.
- * Use various combinations of those users to open cursors,
- * then (potentially) different combinations of users to kill them.
- *
- * A cursor should only be killable if at least one of the users
- * who created it is trying to kill it.
- */
-
- const testA = mongod.getDB('testA');
- const testB = mongod.getDB('testB');
- const admin = mongod.getDB('admin');
-
- // Setup users
- admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
- assert(admin.auth('admin', 'pass'));
-
- testA.createUser({user: 'user1', pwd: 'pass', roles: jsTest.basicUserRoles});
- testA.createUser({user: 'user2', pwd: 'pass', roles: jsTest.basicUserRoles});
- testB.createUser({user: 'user3', pwd: 'pass', roles: jsTest.basicUserRoles});
- testB.createUser({user: 'user4', pwd: 'pass', roles: jsTest.basicUserRoles});
- testB.createUser({user: 'user5', pwd: 'pass', roles: []});
- admin.logout();
-
- // Create a collection with batchable data
- assert(testA.auth('user1', 'pass'));
- assert(testB.auth('user3', 'pass'));
- for (var i = 0; i < 101; ++i) {
- assert.writeOK(testA.coll.insert({_id: i}));
- assert.writeOK(testB.coll.insert({_id: i}));
- }
- testA.logout();
- testB.logout();
-
- // A user can kill their own cursor.
- tryKill(testA, [['user1', testA]], [['user1', testA]], true);
- tryKill(testA, [['user2', testA]], [['user2', testA]], true);
- tryKill(testB, [['user3', testB]], [['user3', testB]], true);
- tryKill(testB, [['user4', testB]], [['user4', testB]], true);
- trySelfKill(['user1', testA]);
- trySelfKill(['user5', testB]);
- trySelfKill(['admin', admin]);
-
- // A user cannot kill someone else's cursor.
- tryKill(testA, [['user1', testA]], [['user2', testA]], false);
- tryKill(testA, [['user1', testA]], [['user2', testA], ['user3', testB]], false);
- tryKill(testA, [['user2', testA]], [['user1', testA]], false);
- tryKill(testA, [['user2', testA]], [['user1', testA], ['user3', testB]], false);
- tryKill(testB, [['user3', testB]], [['user1', testA], ['user4', testB]], false);
- tryKill(testB, [['user3', testB]], [['user2', testA], ['user4', testB]], false);
-
- // A multi-owned cursor can be killed by any/all owner.
- tryKill(testA, [['user1', testA], ['user3', testB]], [['user1', testA]], true);
- tryKill(testB, [['user1', testA], ['user3', testB]], [['user3', testB]], true);
- tryKill(testA,
- [['user1', testA], ['user3', testB]],
- [['user1', testA], ['user3', testB]],
- true);
- tryKill(testA,
- [['user1', testA], ['user3', testB]],
- [['user2', testA], ['user3', testB]],
- true);
- tryKill(testB,
- [['user1', testA], ['user3', testB]],
- [['user1', testA], ['user3', testB]],
- true);
- tryKill(testB,
- [['user1', testA], ['user3', testB]],
- [['user1', testA], ['user4', testB]],
- true);
-
- // An owned cursor can not be killed by other user(s).
- tryKill(testA,
- [['user1', testA], ['user3', testB]],
- [['user2', testA], ['user4', testB]],
- false);
- tryKill(testA, [['user1', testA]], [['user2', testA], ['user3', testB]], false);
- tryKill(testA,
- [['user1', testA], ['user3', testB]],
- [['user2', testA], ['user4', testB]],
- false);
-
- // Admin can kill anything.
- tryKill(testA, [['user1', testA]], [['admin', admin]], true);
- tryKill(testA, [['user2', testA]], [['admin', admin]], true);
- tryKill(testB, [['user3', testB]], [['admin', admin]], true);
- tryKill(testB, [['user4', testB]], [['admin', admin]], true);
- tryKill(testA, [['user1', testA], ['user3', testB]], [['admin', admin]], true);
- tryKill(testB, [['user2', testA], ['user4', testB]], [['admin', admin]], true);
+ assert.commandWorked(killCmdRes, "Unable to kill cursor");
}
- const mongod = MongoRunner.runMongod({auth: ""});
- runTest(mongod);
- MongoRunner.stopMongod(mongod);
-
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- const st = new ShardingTest({
- shards: 1,
- mongos: 1,
- config: 1,
- other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
- });
- runTest(st.s0);
- st.stop();
+ /**
+ * Create user1/user2 in testA, and user3/user4 in testB.
+ * Create two 101 element collections in testA and testB.
+ * Use various combinations of those users to open cursors,
+ * then (potentially) different combinations of users to kill them.
+ *
+ * A cursor should only be killable if at least one of the users
+ * who created it is trying to kill it.
+ */
+
+ const testA = mongod.getDB('testA');
+ const testB = mongod.getDB('testB');
+ const admin = mongod.getDB('admin');
+
+ // Setup users
+ admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
+ assert(admin.auth('admin', 'pass'));
+
+ testA.createUser({user: 'user1', pwd: 'pass', roles: jsTest.basicUserRoles});
+ testA.createUser({user: 'user2', pwd: 'pass', roles: jsTest.basicUserRoles});
+ testB.createUser({user: 'user3', pwd: 'pass', roles: jsTest.basicUserRoles});
+ testB.createUser({user: 'user4', pwd: 'pass', roles: jsTest.basicUserRoles});
+ testB.createUser({user: 'user5', pwd: 'pass', roles: []});
+ admin.logout();
+
+ // Create a collection with batchable data
+ assert(testA.auth('user1', 'pass'));
+ assert(testB.auth('user3', 'pass'));
+ for (var i = 0; i < 101; ++i) {
+ assert.writeOK(testA.coll.insert({_id: i}));
+ assert.writeOK(testB.coll.insert({_id: i}));
+ }
+ testA.logout();
+ testB.logout();
+
+ // A user can kill their own cursor.
+ tryKill(testA, [['user1', testA]], [['user1', testA]], true);
+ tryKill(testA, [['user2', testA]], [['user2', testA]], true);
+ tryKill(testB, [['user3', testB]], [['user3', testB]], true);
+ tryKill(testB, [['user4', testB]], [['user4', testB]], true);
+ trySelfKill(['user1', testA]);
+ trySelfKill(['user5', testB]);
+ trySelfKill(['admin', admin]);
+
+ // A user cannot kill someone else's cursor.
+ tryKill(testA, [['user1', testA]], [['user2', testA]], false);
+ tryKill(testA, [['user1', testA]], [['user2', testA], ['user3', testB]], false);
+ tryKill(testA, [['user2', testA]], [['user1', testA]], false);
+ tryKill(testA, [['user2', testA]], [['user1', testA], ['user3', testB]], false);
+ tryKill(testB, [['user3', testB]], [['user1', testA], ['user4', testB]], false);
+ tryKill(testB, [['user3', testB]], [['user2', testA], ['user4', testB]], false);
+
+ // A multi-owned cursor can be killed by any/all owner.
+ tryKill(testA, [['user1', testA], ['user3', testB]], [['user1', testA]], true);
+ tryKill(testB, [['user1', testA], ['user3', testB]], [['user3', testB]], true);
+ tryKill(
+ testA, [['user1', testA], ['user3', testB]], [['user1', testA], ['user3', testB]], true);
+ tryKill(
+ testA, [['user1', testA], ['user3', testB]], [['user2', testA], ['user3', testB]], true);
+ tryKill(
+ testB, [['user1', testA], ['user3', testB]], [['user1', testA], ['user3', testB]], true);
+ tryKill(
+ testB, [['user1', testA], ['user3', testB]], [['user1', testA], ['user4', testB]], true);
+
+ // An owned cursor can not be killed by other user(s).
+ tryKill(
+ testA, [['user1', testA], ['user3', testB]], [['user2', testA], ['user4', testB]], false);
+ tryKill(testA, [['user1', testA]], [['user2', testA], ['user3', testB]], false);
+ tryKill(
+ testA, [['user1', testA], ['user3', testB]], [['user2', testA], ['user4', testB]], false);
+
+ // Admin can kill anything.
+ tryKill(testA, [['user1', testA]], [['admin', admin]], true);
+ tryKill(testA, [['user2', testA]], [['admin', admin]], true);
+ tryKill(testB, [['user3', testB]], [['admin', admin]], true);
+ tryKill(testB, [['user4', testB]], [['admin', admin]], true);
+ tryKill(testA, [['user1', testA], ['user3', testB]], [['admin', admin]], true);
+ tryKill(testB, [['user2', testA], ['user4', testB]], [['admin', admin]], true);
+}
+
+const mongod = MongoRunner.runMongod({auth: ""});
+runTest(mongod);
+MongoRunner.stopMongod(mongod);
+
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+const st = new ShardingTest({
+ shards: 1,
+ mongos: 1,
+ config: 1,
+ other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
+});
+runTest(st.s0);
+st.stop();
})();
diff --git a/jstests/auth/kill_sessions.js b/jstests/auth/kill_sessions.js
index f32a69ae2e8..99ddc51296f 100644
--- a/jstests/auth/kill_sessions.js
+++ b/jstests/auth/kill_sessions.js
@@ -1,17 +1,17 @@
load("jstests/libs/kill_sessions.js");
(function() {
- 'use strict';
+'use strict';
- // TODO SERVER-35447: This test involves killing all sessions, which will not work as expected
- // if the kill command is sent with an implicit session.
- TestData.disableImplicitSessions = true;
+// TODO SERVER-35447: This test involves killing all sessions, which will not work as expected
+// if the kill command is sent with an implicit session.
+TestData.disableImplicitSessions = true;
- var forExec = MongoRunner.runMongod({auth: ""});
- var forKill = new Mongo(forExec.host);
- var forVerify = new Mongo(forExec.host);
- KillSessionsTestHelper.initializeAuth(forExec);
- forVerify.getDB("admin").auth("super", "password");
- KillSessionsTestHelper.runAuth(forExec, forKill, [forVerify]);
- MongoRunner.stopMongod(forExec);
+var forExec = MongoRunner.runMongod({auth: ""});
+var forKill = new Mongo(forExec.host);
+var forVerify = new Mongo(forExec.host);
+KillSessionsTestHelper.initializeAuth(forExec);
+forVerify.getDB("admin").auth("super", "password");
+KillSessionsTestHelper.runAuth(forExec, forKill, [forVerify]);
+MongoRunner.stopMongod(forExec);
})();
diff --git a/jstests/auth/killop_own_ops.js b/jstests/auth/killop_own_ops.js
index 37498b53586..dbb1689708c 100644
--- a/jstests/auth/killop_own_ops.js
+++ b/jstests/auth/killop_own_ops.js
@@ -8,153 +8,148 @@
*/
(function() {
- 'use strict';
-
- load("jstests/libs/fixture_helpers.js"); // For isMongos.
-
- function runTest(m, failPointName) {
- var db = m.getDB("foo");
- var admin = m.getDB("admin");
-
- admin.createUser({user: 'admin', pwd: 'password', roles: jsTest.adminUserRoles});
- admin.auth('admin', 'password');
- db.createUser({user: 'reader', pwd: 'reader', roles: [{db: 'foo', role: 'read'}]});
- db.createUser(
- {user: 'otherReader', pwd: 'otherReader', roles: [{db: 'foo', role: 'read'}]});
- admin.createRole({
- role: 'opAdmin',
- roles: [],
- privileges: [{resource: {cluster: true}, actions: ['inprog', 'killop']}]
- });
- db.createUser({user: 'opAdmin', pwd: 'opAdmin', roles: [{role: 'opAdmin', db: 'admin'}]});
-
- var t = db.jstests_killop;
- t.save({x: 1});
-
- if (!FixtureHelpers.isMongos(db)) {
- assert.commandWorked(
- db.adminCommand({setParameter: 1, internalQueryExecYieldIterations: 1}));
- }
+'use strict';
- admin.logout();
+load("jstests/libs/fixture_helpers.js"); // For isMongos.
- // Only used for nice error messages.
- function getAllLocalOps() {
- admin.aggregate([{$currentOp: {allUsers: true, localOps: true}}]).toArray();
- }
+function runTest(m, failPointName) {
+ var db = m.getDB("foo");
+ var admin = m.getDB("admin");
- /**
- * This function filters for the operations that we're looking for, based on their state and
- * the contents of their query object.
- */
- function ops(ownOps = true) {
- const ops =
- admin.aggregate([{$currentOp: {allUsers: !ownOps, localOps: true}}]).toArray();
-
- var ids = [];
- for (let o of ops) {
- if ((o.active || o.waitingForLock) && o.command &&
- o.command.find === "jstests_killop" && o.command.comment === "kill_own_ops") {
- ids.push(o.opid);
- }
- }
- return ids;
- }
+ admin.createUser({user: 'admin', pwd: 'password', roles: jsTest.adminUserRoles});
+ admin.auth('admin', 'password');
+ db.createUser({user: 'reader', pwd: 'reader', roles: [{db: 'foo', role: 'read'}]});
+ db.createUser({user: 'otherReader', pwd: 'otherReader', roles: [{db: 'foo', role: 'read'}]});
+ admin.createRole({
+ role: 'opAdmin',
+ roles: [],
+ privileges: [{resource: {cluster: true}, actions: ['inprog', 'killop']}]
+ });
+ db.createUser({user: 'opAdmin', pwd: 'opAdmin', roles: [{role: 'opAdmin', db: 'admin'}]});
- var queryAsReader =
- 'db = db.getSiblingDB("foo"); db.auth("reader", "reader"); db.jstests_killop.find().comment("kill_own_ops").toArray()';
+ var t = db.jstests_killop;
+ t.save({x: 1});
- jsTestLog("Starting long-running operation");
- db.auth('reader', 'reader');
- assert.commandWorked(
- db.adminCommand({configureFailPoint: failPointName, mode: "alwaysOn"}));
- var s1 = startParallelShell(queryAsReader, m.port);
- jsTestLog("Finding ops in $currentOp output");
- var o = [];
- assert.soon(
- function() {
- o = ops();
- return o.length == 1;
- },
- () => {
- return tojson(getAllLocalOps());
- },
- 60000);
- jsTestLog("Checking that another user cannot see or kill the op");
- db.logout();
- db.auth('otherReader', 'otherReader');
- assert.eq([], ops());
- assert.commandFailed(db.killOp(o[0]));
- db.logout();
- db.auth('reader', 'reader');
- assert.eq(1, ops().length);
- db.logout();
- jsTestLog("Checking that originating user can kill operation");
- var start = new Date();
- db.auth('reader', 'reader');
- assert.commandWorked(db.killOp(o[0]));
- assert.commandWorked(db.adminCommand({configureFailPoint: failPointName, mode: "off"}));
-
- jsTestLog("Waiting for ops to terminate");
- var exitCode = s1({checkExitSuccess: false});
- assert.neq(0,
- exitCode,
- "expected shell to exit abnormally due to operation execution being terminated");
-
- // don't want to pass if timeout killed the js function.
- var end = new Date();
- var diff = end - start;
- assert.lt(diff, 30000, "Start: " + start + "; end: " + end + "; diff: " + diff);
-
- jsTestLog("Starting a second long-running operation");
+ if (!FixtureHelpers.isMongos(db)) {
assert.commandWorked(
- db.adminCommand({configureFailPoint: failPointName, mode: "alwaysOn"}));
- var s2 = startParallelShell(queryAsReader, m.port);
- jsTestLog("Finding ops in $currentOp output");
- var o2 = [];
- assert.soon(
- function() {
- o2 = ops();
- return o2.length == 1;
- },
- () => {
- return tojson(getAllLocalOps());
- },
- 60000);
-
- db.logout();
- db.auth('opAdmin', 'opAdmin');
-
- jsTestLog("Checking that an administrative user can find others' operations");
- assert.eq(o2, ops(false));
-
- jsTestLog(
- "Checking that an administrative user cannot find others' operations with ownOps");
- assert.eq([], ops());
-
- jsTestLog("Checking that an administrative user can kill others' operations");
- var start = new Date();
- assert.commandWorked(db.killOp(o2[0]));
- assert.commandWorked(db.adminCommand({configureFailPoint: failPointName, mode: "off"}));
- jsTestLog("Waiting for ops to terminate");
- var exitCode = s2({checkExitSuccess: false});
- assert.neq(
- 0, exitCode, "expected shell to exit abnormally due to JS execution being terminated");
-
- var end = new Date();
- var diff = end - start;
- assert.lt(diff, 30000, "Start: " + start + "; end: " + end + "; diff: " + diff);
+ db.adminCommand({setParameter: 1, internalQueryExecYieldIterations: 1}));
+ }
+
+ admin.logout();
+
+ // Only used for nice error messages.
+ function getAllLocalOps() {
+ admin.aggregate([{$currentOp: {allUsers: true, localOps: true}}]).toArray();
+ }
+
+ /**
+ * This function filters for the operations that we're looking for, based on their state and
+ * the contents of their query object.
+ */
+ function ops(ownOps = true) {
+ const ops = admin.aggregate([{$currentOp: {allUsers: !ownOps, localOps: true}}]).toArray();
+
+ var ids = [];
+ for (let o of ops) {
+ if ((o.active || o.waitingForLock) && o.command &&
+ o.command.find === "jstests_killop" && o.command.comment === "kill_own_ops") {
+ ids.push(o.opid);
+ }
+ }
+ return ids;
}
- var conn = MongoRunner.runMongod({auth: ""});
- runTest(conn, "setYieldAllLocksHang");
- MongoRunner.stopMongod(conn);
-
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- var st = new ShardingTest(
- {shards: 1, keyFile: 'jstests/libs/key1', other: {shardAsReplicaSet: false}});
- // Use a different failpoint in the sharded version, since the mongos does not have a
- // setYieldAlllocksHang failpoint.
- runTest(st.s, "waitInFindBeforeMakingBatch");
- st.stop();
+ var queryAsReader =
+ 'db = db.getSiblingDB("foo"); db.auth("reader", "reader"); db.jstests_killop.find().comment("kill_own_ops").toArray()';
+
+ jsTestLog("Starting long-running operation");
+ db.auth('reader', 'reader');
+ assert.commandWorked(db.adminCommand({configureFailPoint: failPointName, mode: "alwaysOn"}));
+ var s1 = startParallelShell(queryAsReader, m.port);
+ jsTestLog("Finding ops in $currentOp output");
+ var o = [];
+ assert.soon(
+ function() {
+ o = ops();
+ return o.length == 1;
+ },
+ () => {
+ return tojson(getAllLocalOps());
+ },
+ 60000);
+ jsTestLog("Checking that another user cannot see or kill the op");
+ db.logout();
+ db.auth('otherReader', 'otherReader');
+ assert.eq([], ops());
+ assert.commandFailed(db.killOp(o[0]));
+ db.logout();
+ db.auth('reader', 'reader');
+ assert.eq(1, ops().length);
+ db.logout();
+ jsTestLog("Checking that originating user can kill operation");
+ var start = new Date();
+ db.auth('reader', 'reader');
+ assert.commandWorked(db.killOp(o[0]));
+ assert.commandWorked(db.adminCommand({configureFailPoint: failPointName, mode: "off"}));
+
+ jsTestLog("Waiting for ops to terminate");
+ var exitCode = s1({checkExitSuccess: false});
+ assert.neq(0,
+ exitCode,
+ "expected shell to exit abnormally due to operation execution being terminated");
+
+ // don't want to pass if timeout killed the js function.
+ var end = new Date();
+ var diff = end - start;
+ assert.lt(diff, 30000, "Start: " + start + "; end: " + end + "; diff: " + diff);
+
+ jsTestLog("Starting a second long-running operation");
+ assert.commandWorked(db.adminCommand({configureFailPoint: failPointName, mode: "alwaysOn"}));
+ var s2 = startParallelShell(queryAsReader, m.port);
+ jsTestLog("Finding ops in $currentOp output");
+ var o2 = [];
+ assert.soon(
+ function() {
+ o2 = ops();
+ return o2.length == 1;
+ },
+ () => {
+ return tojson(getAllLocalOps());
+ },
+ 60000);
+
+ db.logout();
+ db.auth('opAdmin', 'opAdmin');
+
+ jsTestLog("Checking that an administrative user can find others' operations");
+ assert.eq(o2, ops(false));
+
+ jsTestLog("Checking that an administrative user cannot find others' operations with ownOps");
+ assert.eq([], ops());
+
+ jsTestLog("Checking that an administrative user can kill others' operations");
+ var start = new Date();
+ assert.commandWorked(db.killOp(o2[0]));
+ assert.commandWorked(db.adminCommand({configureFailPoint: failPointName, mode: "off"}));
+ jsTestLog("Waiting for ops to terminate");
+ var exitCode = s2({checkExitSuccess: false});
+ assert.neq(
+ 0, exitCode, "expected shell to exit abnormally due to JS execution being terminated");
+
+ var end = new Date();
+ var diff = end - start;
+ assert.lt(diff, 30000, "Start: " + start + "; end: " + end + "; diff: " + diff);
+}
+
+var conn = MongoRunner.runMongod({auth: ""});
+runTest(conn, "setYieldAllLocksHang");
+MongoRunner.stopMongod(conn);
+
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+var st =
+ new ShardingTest({shards: 1, keyFile: 'jstests/libs/key1', other: {shardAsReplicaSet: false}});
+// Use a different failpoint in the sharded version, since the mongos does not have a
+// setYieldAlllocksHang failpoint.
+runTest(st.s, "waitInFindBeforeMakingBatch");
+st.stop();
})();
diff --git a/jstests/auth/list_all_local_sessions.js b/jstests/auth/list_all_local_sessions.js
index 3b7c19d1cbe..92363515a00 100644
--- a/jstests/auth/list_all_local_sessions.js
+++ b/jstests/auth/list_all_local_sessions.js
@@ -2,60 +2,60 @@
// @tags: [requires_sharding]
(function() {
- 'use strict';
- load('jstests/aggregation/extras/utils.js');
-
- // This test makes assertions about the number of sessions, which are not compatible with
- // implicit sessions.
- TestData.disableImplicitSessions = true;
-
- function runListAllLocalSessionsTest(mongod) {
- assert(mongod);
- const admin = mongod.getDB("admin");
- const db = mongod.getDB("test");
-
- const pipeline = [{'$listLocalSessions': {allUsers: true}}];
- function listAllLocalSessions() {
- return admin.aggregate(pipeline);
- }
-
- admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
- assert(admin.auth('admin', 'pass'));
- db.createUser({user: 'user1', pwd: 'pass', roles: jsTest.basicUserRoles});
- admin.logout();
-
- // Shouldn't be able to listLocalSessions when not logged in.
- assertErrorCode(admin, pipeline, ErrorCodes.Unauthorized);
-
- // Start a new session and capture its sessionId.
- assert(db.auth('user1', 'pass'));
- const myid = assert.commandWorked(db.runCommand({startSession: 1})).id.id;
- assert(myid !== undefined);
-
- // Ensure that a normal user can NOT listAllLocalSessions to view their session.
- assertErrorCode(admin, pipeline, ErrorCodes.Unauthorized);
- db.logout();
-
- // Ensure that the cache now contains the session and is visible by admin.
- assert(admin.auth('admin', 'pass'));
- const resultArray = assert.doesNotThrow(listAllLocalSessions).toArray();
- assert.eq(resultArray.length, 1);
- const cacheid = resultArray[0]._id.id;
- assert(cacheid !== undefined);
- assert.eq(0, bsonWoCompare({x: cacheid}, {x: myid}));
+'use strict';
+load('jstests/aggregation/extras/utils.js');
+
+// This test makes assertions about the number of sessions, which are not compatible with
+// implicit sessions.
+TestData.disableImplicitSessions = true;
+
+function runListAllLocalSessionsTest(mongod) {
+ assert(mongod);
+ const admin = mongod.getDB("admin");
+ const db = mongod.getDB("test");
+
+ const pipeline = [{'$listLocalSessions': {allUsers: true}}];
+ function listAllLocalSessions() {
+ return admin.aggregate(pipeline);
}
- const mongod = MongoRunner.runMongod({auth: ""});
- runListAllLocalSessionsTest(mongod);
- MongoRunner.stopMongod(mongod);
-
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- const st = new ShardingTest({
- shards: 1,
- mongos: 1,
- config: 1,
- other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
- });
- runListAllLocalSessionsTest(st.s0);
- st.stop();
+ admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
+ assert(admin.auth('admin', 'pass'));
+ db.createUser({user: 'user1', pwd: 'pass', roles: jsTest.basicUserRoles});
+ admin.logout();
+
+ // Shouldn't be able to listLocalSessions when not logged in.
+ assertErrorCode(admin, pipeline, ErrorCodes.Unauthorized);
+
+ // Start a new session and capture its sessionId.
+ assert(db.auth('user1', 'pass'));
+ const myid = assert.commandWorked(db.runCommand({startSession: 1})).id.id;
+ assert(myid !== undefined);
+
+ // Ensure that a normal user can NOT listAllLocalSessions to view their session.
+ assertErrorCode(admin, pipeline, ErrorCodes.Unauthorized);
+ db.logout();
+
+ // Ensure that the cache now contains the session and is visible by admin.
+ assert(admin.auth('admin', 'pass'));
+ const resultArray = assert.doesNotThrow(listAllLocalSessions).toArray();
+ assert.eq(resultArray.length, 1);
+ const cacheid = resultArray[0]._id.id;
+ assert(cacheid !== undefined);
+ assert.eq(0, bsonWoCompare({x: cacheid}, {x: myid}));
+}
+
+const mongod = MongoRunner.runMongod({auth: ""});
+runListAllLocalSessionsTest(mongod);
+MongoRunner.stopMongod(mongod);
+
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+const st = new ShardingTest({
+ shards: 1,
+ mongos: 1,
+ config: 1,
+ other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
+});
+runListAllLocalSessionsTest(st.s0);
+st.stop();
})();
diff --git a/jstests/auth/list_all_sessions.js b/jstests/auth/list_all_sessions.js
index 7f077bee537..9ba823564a7 100644
--- a/jstests/auth/list_all_sessions.js
+++ b/jstests/auth/list_all_sessions.js
@@ -2,67 +2,67 @@
// @tags: [requires_sharding]
(function() {
- 'use strict';
- load('jstests/aggregation/extras/utils.js');
+'use strict';
+load('jstests/aggregation/extras/utils.js');
- // This test makes assertions about the number of sessions, which are not compatible with
- // implicit sessions.
- TestData.disableImplicitSessions = true;
+// This test makes assertions about the number of sessions, which are not compatible with
+// implicit sessions.
+TestData.disableImplicitSessions = true;
- function runListAllSessionsTest(mongod) {
- assert(mongod);
- const admin = mongod.getDB("admin");
- const config = mongod.getDB("config");
+function runListAllSessionsTest(mongod) {
+ assert(mongod);
+ const admin = mongod.getDB("admin");
+ const config = mongod.getDB("config");
- const pipeline = [{'$listSessions': {allUsers: true}}];
- function listSessions() {
- return config.system.sessions.aggregate(pipeline);
- }
+ const pipeline = [{'$listSessions': {allUsers: true}}];
+ function listSessions() {
+ return config.system.sessions.aggregate(pipeline);
+ }
- admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
- assert(admin.auth('admin', 'pass'));
- admin.createUser({user: 'user1', pwd: 'pass', roles: jsTest.basicUserRoles});
- admin.logout();
+ admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
+ assert(admin.auth('admin', 'pass'));
+ admin.createUser({user: 'user1', pwd: 'pass', roles: jsTest.basicUserRoles});
+ admin.logout();
- // Fail if we're not logged in.
- assertErrorCode(config.system.sessions, pipeline, ErrorCodes.Unauthorized);
+ // Fail if we're not logged in.
+ assertErrorCode(config.system.sessions, pipeline, ErrorCodes.Unauthorized);
- // Start a new session and capture its sessionId.
- assert(admin.auth('user1', 'pass'));
- const myid = assert.commandWorked(admin.runCommand({startSession: 1})).id.id;
- assert(myid !== undefined);
- assert.commandWorked(admin.runCommand({refreshLogicalSessionCacheNow: 1}));
+ // Start a new session and capture its sessionId.
+ assert(admin.auth('user1', 'pass'));
+ const myid = assert.commandWorked(admin.runCommand({startSession: 1})).id.id;
+ assert(myid !== undefined);
+ assert.commandWorked(admin.runCommand({refreshLogicalSessionCacheNow: 1}));
- // Ensure that a normal user can NOT listSessions{allUsers:true} to view their session.
- assertErrorCode(config.system.sessions, pipeline, ErrorCodes.Unauthorized);
+ // Ensure that a normal user can NOT listSessions{allUsers:true} to view their session.
+ assertErrorCode(config.system.sessions, pipeline, ErrorCodes.Unauthorized);
- // Ensure that a normal user can NOT listSessions to view others' sessions.
- const viewAdminPipeline = [{'$listSessions': {users: [{user: 'admin', db: 'admin'}]}}];
- assertErrorCode(config.system.sessions, viewAdminPipeline, ErrorCodes.Unauthorized);
+ // Ensure that a normal user can NOT listSessions to view others' sessions.
+ const viewAdminPipeline = [{'$listSessions': {users: [{user: 'admin', db: 'admin'}]}}];
+ assertErrorCode(config.system.sessions, viewAdminPipeline, ErrorCodes.Unauthorized);
- // Ensure that the cache now contains the session and is visible by admin
- assert(admin.auth('admin', 'pass'));
- const resultArray = listSessions().toArray();
- assert.eq(resultArray.length, 1);
- const cacheid = resultArray[0]._id.id;
- assert(cacheid !== undefined);
- assert.eq(0, bsonWoCompare({x: cacheid}, {x: myid}));
+ // Ensure that the cache now contains the session and is visible by admin
+ assert(admin.auth('admin', 'pass'));
+ const resultArray = listSessions().toArray();
+ assert.eq(resultArray.length, 1);
+ const cacheid = resultArray[0]._id.id;
+ assert(cacheid !== undefined);
+ assert.eq(0, bsonWoCompare({x: cacheid}, {x: myid}));
- // Make sure pipelining other collections fail.
- assertErrorCode(admin.system.collections, pipeline, ErrorCodes.InvalidNamespace);
- }
+ // Make sure pipelining other collections fail.
+ assertErrorCode(admin.system.collections, pipeline, ErrorCodes.InvalidNamespace);
+}
- const mongod = MongoRunner.runMongod({auth: ""});
- runListAllSessionsTest(mongod);
- MongoRunner.stopMongod(mongod);
+const mongod = MongoRunner.runMongod({auth: ""});
+runListAllSessionsTest(mongod);
+MongoRunner.stopMongod(mongod);
- const st =
- new ShardingTest({shards: 1, mongos: 1, config: 1, other: {keyFile: 'jstests/libs/key1'}});
+const st =
+ new ShardingTest({shards: 1, mongos: 1, config: 1, other: {keyFile: 'jstests/libs/key1'}});
- // Ensure that the sessions collection exists.
- st.c0.getDB("admin").runCommand({refreshLogicalSessionCacheNow: 1});
- st.rs0.getPrimary().getDB("admin").runCommand({refreshLogicalSessionCacheNow: 1});
+// Ensure that the sessions collection exists.
+st.c0.getDB("admin").runCommand({refreshLogicalSessionCacheNow: 1});
+st.rs0.getPrimary().getDB("admin").runCommand({refreshLogicalSessionCacheNow: 1});
- runListAllSessionsTest(st.s0);
- st.stop();
+runListAllSessionsTest(st.s0);
+st.stop();
})();
diff --git a/jstests/auth/list_collections_filter_views.js b/jstests/auth/list_collections_filter_views.js
index d17c9d82101..eeb12c74051 100644
--- a/jstests/auth/list_collections_filter_views.js
+++ b/jstests/auth/list_collections_filter_views.js
@@ -1,58 +1,57 @@
// Test listCollections with unauthorized views.
(function() {
- "use strict";
-
- const dbName = "list_collections_filter_views";
-
- function runTestOnConnection(conn) {
- const admin = conn.getDB("admin");
- const db = conn.getDB("test");
-
- assert.commandWorked(admin.runCommand({createUser: "root", pwd: "root", roles: ["root"]}));
- assert(admin.auth("root", "root"));
-
- assert.commandWorked(db.foo.insert({x: 123}));
- assert.commandWorked(db.createView("bar", "foo", []));
- assert.commandWorked(db.createView("baz", "foo", []));
-
- assert.commandWorked(db.runCommand({
- createRole: "role",
- roles: [],
- privileges: [
- {resource: {db: "test", collection: "foo"}, actions: ["find"]},
- {resource: {db: "test", collection: "bar"}, actions: ["find"]}
- ]
- }));
-
- assert.commandWorked(
- db.runCommand({createUser: "user", pwd: "pwd", roles: [{role: "role", db: "test"}]}));
- admin.logout();
-
- assert(db.auth("user", "pwd"));
-
- const res = assert.commandWorked(
- db.runCommand({listCollections: 1, nameOnly: true, authorizedCollections: true}));
- assert.eq(2, res.cursor.firstBatch.length, tojson(res.cursor.firstBatch));
-
- function nameSort(a, b) {
- return a.name > b.name;
- }
- assert.eq(
- [{"name": "bar", "type": "view"}, {"name": "foo", "type": "collection"}].sort(nameSort),
- res.cursor.firstBatch.sort(nameSort));
- }
+"use strict";
+
+const dbName = "list_collections_filter_views";
+
+function runTestOnConnection(conn) {
+ const admin = conn.getDB("admin");
+ const db = conn.getDB("test");
+
+ assert.commandWorked(admin.runCommand({createUser: "root", pwd: "root", roles: ["root"]}));
+ assert(admin.auth("root", "root"));
- const mongod = MongoRunner.runMongod({auth: ''});
- runTestOnConnection(mongod);
- MongoRunner.stopMongod(mongod);
+ assert.commandWorked(db.foo.insert({x: 123}));
+ assert.commandWorked(db.createView("bar", "foo", []));
+ assert.commandWorked(db.createView("baz", "foo", []));
- const st = new ShardingTest({
- shards: 1,
- mongos: 1,
- config: 1,
- other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false},
- });
- runTestOnConnection(st.s0);
- st.stop();
+ assert.commandWorked(db.runCommand({
+ createRole: "role",
+ roles: [],
+ privileges: [
+ {resource: {db: "test", collection: "foo"}, actions: ["find"]},
+ {resource: {db: "test", collection: "bar"}, actions: ["find"]}
+ ]
+ }));
+ assert.commandWorked(
+ db.runCommand({createUser: "user", pwd: "pwd", roles: [{role: "role", db: "test"}]}));
+ admin.logout();
+
+ assert(db.auth("user", "pwd"));
+
+ const res = assert.commandWorked(
+ db.runCommand({listCollections: 1, nameOnly: true, authorizedCollections: true}));
+ assert.eq(2, res.cursor.firstBatch.length, tojson(res.cursor.firstBatch));
+
+ function nameSort(a, b) {
+ return a.name > b.name;
+ }
+ assert.eq(
+ [{"name": "bar", "type": "view"}, {"name": "foo", "type": "collection"}].sort(nameSort),
+ res.cursor.firstBatch.sort(nameSort));
+}
+
+const mongod = MongoRunner.runMongod({auth: ''});
+runTestOnConnection(mongod);
+MongoRunner.stopMongod(mongod);
+
+const st = new ShardingTest({
+ shards: 1,
+ mongos: 1,
+ config: 1,
+ other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false},
+});
+runTestOnConnection(st.s0);
+st.stop();
}());
diff --git a/jstests/auth/list_collections_own_collections.js b/jstests/auth/list_collections_own_collections.js
index 82d17afc787..08acf45ab02 100644
--- a/jstests/auth/list_collections_own_collections.js
+++ b/jstests/auth/list_collections_own_collections.js
@@ -1,183 +1,186 @@
// Test nameOnly option of listCollections
(function() {
- "use strict";
-
- const dbName = "list_collections_own_collections";
-
- const nameSort = (a, b) => a.name > b.name;
- const resFoo = {"name": "foo", "type": "collection"};
- const resBar = {"name": "bar", "type": "view"};
- const resOther =
- [{"name": "otherCollection", "type": "collection"}, {"name": "otherView", "type": "view"}];
- const resSystemViews = {"name": "system.views", "type": "collection"};
-
- function runTestOnConnection(conn) {
- const admin = conn.getDB("admin");
- const db = conn.getDB(dbName);
-
- assert.commandWorked(admin.runCommand({createUser: "root", pwd: "root", roles: ["root"]}));
- assert(admin.auth("root", "root"));
-
- function createTestRoleAndUser(roleName, privs) {
- assert.commandWorked(
- admin.runCommand({createRole: roleName, roles: [], privileges: privs}));
-
- const userName = "user|" + roleName;
- assert.commandWorked(db.runCommand(
- {createUser: userName, pwd: "pwd", roles: [{role: roleName, db: "admin"}]}));
- }
-
- createTestRoleAndUser("roleWithExactNamespacePrivileges", [
- {resource: {db: dbName, collection: "foo"}, actions: ["find"]},
- {resource: {db: dbName, collection: "bar"}, actions: ["find"]}
- ]);
-
- createTestRoleAndUser("roleWithExactNamespaceAndSystemPrivileges", [
- {resource: {db: dbName, collection: "foo"}, actions: ["find"]},
- {resource: {db: dbName, collection: "bar"}, actions: ["find"]},
- {resource: {db: dbName, collection: "system.views"}, actions: ["find"]}
- ]);
-
- createTestRoleAndUser("roleWithCollectionPrivileges", [
- {resource: {db: "", collection: "foo"}, actions: ["find"]},
- {resource: {db: "", collection: "bar"}, actions: ["find"]}
- ]);
-
- createTestRoleAndUser("roleWithCollectionAndSystemPrivileges", [
- {resource: {db: "", collection: "foo"}, actions: ["find"]},
- {resource: {db: "", collection: "bar"}, actions: ["find"]},
- {resource: {db: "", collection: "system.views"}, actions: ["find"]}
- ]);
-
- createTestRoleAndUser("roleWithDatabasePrivileges", [
- {resource: {db: dbName, collection: ""}, actions: ["find"]},
- ]);
-
- createTestRoleAndUser("roleWithDatabaseAndSystemPrivileges", [
- {resource: {db: dbName, collection: ""}, actions: ["find"]},
- {resource: {db: dbName, collection: "system.views"}, actions: ["find"]}
- ]);
-
- createTestRoleAndUser("roleWithAnyNormalResourcePrivileges", [
- {resource: {db: "", collection: ""}, actions: ["find"]},
- ]);
-
- createTestRoleAndUser("roleWithAnyNormalResourceAndSystemPrivileges", [
- {resource: {db: "", collection: ""}, actions: ["find"]},
- {resource: {db: "", collection: "system.views"}, actions: ["find"]}
- ]);
-
- // Create the collection and view used by the tests.
- assert.commandWorked(db.dropDatabase());
- assert.commandWorked(db.createCollection("foo"));
- assert.commandWorked(db.createView("bar", "foo", []));
-
- // Create a collection and view that are never granted specific permissions, to ensure
- // they're only returned by listCollections when the role has access to the whole db/server.
- assert.commandWorked(db.createCollection("otherCollection"));
- assert.commandWorked(db.createView("otherView", "otherCollection", []));
-
- admin.logout();
-
- function runTestOnRole(roleName, expectedColls) {
- jsTestLog(roleName);
- const userName = "user|" + roleName;
- assert(db.auth(userName, "pwd"));
-
- let res;
-
- res = db.runCommand({listCollections: 1});
- assert.commandFailed(res);
- res = db.runCommand({listCollections: 1, nameOnly: true});
- assert.commandFailed(res);
- res = db.runCommand({listCollections: 1, authorizedCollections: true});
- assert.commandFailed(res);
-
- res = db.runCommand({listCollections: 1, nameOnly: true, authorizedCollections: true});
- assert.commandWorked(res);
- assert.eq(expectedColls.sort(nameSort), res.cursor.firstBatch.sort(nameSort));
-
- res = db.runCommand({
- listCollections: 1,
- nameOnly: true,
- authorizedCollections: true,
- filter: {"name": "foo"}
- });
- assert.commandWorked(res);
- assert.eq([resFoo], res.cursor.firstBatch);
-
- db.logout();
- }
-
- runTestOnRole("roleWithExactNamespacePrivileges", [resFoo, resBar]);
- runTestOnRole("roleWithExactNamespaceAndSystemPrivileges",
- [resFoo, resBar, resSystemViews]);
-
- runTestOnRole("roleWithCollectionPrivileges", [resFoo, resBar]);
- runTestOnRole("roleWithCollectionAndSystemPrivileges", [resFoo, resBar, resSystemViews]);
-
- runTestOnRole("roleWithDatabasePrivileges", [resFoo, resBar, ...resOther]);
- runTestOnRole("roleWithDatabaseAndSystemPrivileges",
- [resFoo, resBar, ...resOther, resSystemViews]);
-
- runTestOnRole("roleWithAnyNormalResourcePrivileges", [resFoo, resBar, ...resOther]);
- runTestOnRole("roleWithAnyNormalResourceAndSystemPrivileges",
- [resFoo, resBar, ...resOther, resSystemViews]);
+"use strict";
+
+const dbName = "list_collections_own_collections";
+
+const nameSort = (a, b) => a.name > b.name;
+const resFoo = {
+ "name": "foo",
+ "type": "collection"
+};
+const resBar = {
+ "name": "bar",
+ "type": "view"
+};
+const resOther =
+ [{"name": "otherCollection", "type": "collection"}, {"name": "otherView", "type": "view"}];
+const resSystemViews = {
+ "name": "system.views",
+ "type": "collection"
+};
+
+function runTestOnConnection(conn) {
+ const admin = conn.getDB("admin");
+ const db = conn.getDB(dbName);
+
+ assert.commandWorked(admin.runCommand({createUser: "root", pwd: "root", roles: ["root"]}));
+ assert(admin.auth("root", "root"));
+
+ function createTestRoleAndUser(roleName, privs) {
+ assert.commandWorked(
+ admin.runCommand({createRole: roleName, roles: [], privileges: privs}));
+
+ const userName = "user|" + roleName;
+ assert.commandWorked(db.runCommand(
+ {createUser: userName, pwd: "pwd", roles: [{role: roleName, db: "admin"}]}));
}
- function runNoAuthTestOnConnection(conn) {
- const admin = conn.getDB("admin");
- const db = conn.getDB(dbName);
-
- assert.commandWorked(db.dropDatabase());
- assert.commandWorked(db.createCollection("foo"));
- assert.commandWorked(db.createView("bar", "foo", []));
-
- var resFull = db.runCommand({listCollections: 1});
- assert.commandWorked(resFull);
- var resAuthColls = db.runCommand({listCollections: 1, authorizedCollections: true});
- assert.commandWorked(resAuthColls);
- assert.eq(resFull.cursor.firstBatch.sort(nameSort),
- resAuthColls.cursor.firstBatch.sort(nameSort));
-
- var resNameOnly = db.runCommand({listCollections: 1, nameOnly: true});
- assert.commandWorked(resNameOnly);
- var resNameOnlyAuthColls =
- db.runCommand({listCollections: 1, nameOnly: true, authorizedCollections: true});
- assert.commandWorked(resNameOnlyAuthColls);
- assert.eq(resNameOnly.cursor.firstBatch.sort(nameSort),
- resNameOnlyAuthColls.cursor.firstBatch.sort(nameSort));
-
- var resWithFilter = db.runCommand({
+ createTestRoleAndUser("roleWithExactNamespacePrivileges", [
+ {resource: {db: dbName, collection: "foo"}, actions: ["find"]},
+ {resource: {db: dbName, collection: "bar"}, actions: ["find"]}
+ ]);
+
+ createTestRoleAndUser("roleWithExactNamespaceAndSystemPrivileges", [
+ {resource: {db: dbName, collection: "foo"}, actions: ["find"]},
+ {resource: {db: dbName, collection: "bar"}, actions: ["find"]},
+ {resource: {db: dbName, collection: "system.views"}, actions: ["find"]}
+ ]);
+
+ createTestRoleAndUser("roleWithCollectionPrivileges", [
+ {resource: {db: "", collection: "foo"}, actions: ["find"]},
+ {resource: {db: "", collection: "bar"}, actions: ["find"]}
+ ]);
+
+ createTestRoleAndUser("roleWithCollectionAndSystemPrivileges", [
+ {resource: {db: "", collection: "foo"}, actions: ["find"]},
+ {resource: {db: "", collection: "bar"}, actions: ["find"]},
+ {resource: {db: "", collection: "system.views"}, actions: ["find"]}
+ ]);
+
+ createTestRoleAndUser("roleWithDatabasePrivileges", [
+ {resource: {db: dbName, collection: ""}, actions: ["find"]},
+ ]);
+
+ createTestRoleAndUser("roleWithDatabaseAndSystemPrivileges", [
+ {resource: {db: dbName, collection: ""}, actions: ["find"]},
+ {resource: {db: dbName, collection: "system.views"}, actions: ["find"]}
+ ]);
+
+ createTestRoleAndUser("roleWithAnyNormalResourcePrivileges", [
+ {resource: {db: "", collection: ""}, actions: ["find"]},
+ ]);
+
+ createTestRoleAndUser("roleWithAnyNormalResourceAndSystemPrivileges", [
+ {resource: {db: "", collection: ""}, actions: ["find"]},
+ {resource: {db: "", collection: "system.views"}, actions: ["find"]}
+ ]);
+
+ // Create the collection and view used by the tests.
+ assert.commandWorked(db.dropDatabase());
+ assert.commandWorked(db.createCollection("foo"));
+ assert.commandWorked(db.createView("bar", "foo", []));
+
+ // Create a collection and view that are never granted specific permissions, to ensure
+ // they're only returned by listCollections when the role has access to the whole db/server.
+ assert.commandWorked(db.createCollection("otherCollection"));
+ assert.commandWorked(db.createView("otherView", "otherCollection", []));
+
+ admin.logout();
+
+ function runTestOnRole(roleName, expectedColls) {
+ jsTestLog(roleName);
+ const userName = "user|" + roleName;
+ assert(db.auth(userName, "pwd"));
+
+ let res;
+
+ res = db.runCommand({listCollections: 1});
+ assert.commandFailed(res);
+ res = db.runCommand({listCollections: 1, nameOnly: true});
+ assert.commandFailed(res);
+ res = db.runCommand({listCollections: 1, authorizedCollections: true});
+ assert.commandFailed(res);
+
+ res = db.runCommand({listCollections: 1, nameOnly: true, authorizedCollections: true});
+ assert.commandWorked(res);
+ assert.eq(expectedColls.sort(nameSort), res.cursor.firstBatch.sort(nameSort));
+
+ res = db.runCommand({
listCollections: 1,
nameOnly: true,
authorizedCollections: true,
filter: {"name": "foo"}
});
- assert.commandWorked(resWithFilter);
- assert.eq([{"name": "foo", "type": "collection"}], resWithFilter.cursor.firstBatch);
- }
-
- const mongod = MongoRunner.runMongod({auth: ''});
- runTestOnConnection(mongod);
- MongoRunner.stopMongod(mongod);
-
- const st = new ShardingTest({
- shards: 1,
- mongos: 1,
- config: 1,
- other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
- });
- runTestOnConnection(st.s0);
- st.stop();
+ assert.commandWorked(res);
+ assert.eq([resFoo], res.cursor.firstBatch);
- const mongodNoAuth = MongoRunner.runMongod();
- runNoAuthTestOnConnection(mongodNoAuth);
- MongoRunner.stopMongod(mongodNoAuth);
-
- const stNoAuth =
- new ShardingTest({shards: 1, mongos: 1, config: 1, other: {shardAsReplicaSet: false}});
- runNoAuthTestOnConnection(stNoAuth.s0);
- stNoAuth.stop();
+ db.logout();
+ }
+ runTestOnRole("roleWithExactNamespacePrivileges", [resFoo, resBar]);
+ runTestOnRole("roleWithExactNamespaceAndSystemPrivileges", [resFoo, resBar, resSystemViews]);
+
+ runTestOnRole("roleWithCollectionPrivileges", [resFoo, resBar]);
+ runTestOnRole("roleWithCollectionAndSystemPrivileges", [resFoo, resBar, resSystemViews]);
+
+ runTestOnRole("roleWithDatabasePrivileges", [resFoo, resBar, ...resOther]);
+ runTestOnRole("roleWithDatabaseAndSystemPrivileges",
+ [resFoo, resBar, ...resOther, resSystemViews]);
+
+ runTestOnRole("roleWithAnyNormalResourcePrivileges", [resFoo, resBar, ...resOther]);
+ runTestOnRole("roleWithAnyNormalResourceAndSystemPrivileges",
+ [resFoo, resBar, ...resOther, resSystemViews]);
+}
+
+function runNoAuthTestOnConnection(conn) {
+ const admin = conn.getDB("admin");
+ const db = conn.getDB(dbName);
+
+ assert.commandWorked(db.dropDatabase());
+ assert.commandWorked(db.createCollection("foo"));
+ assert.commandWorked(db.createView("bar", "foo", []));
+
+ var resFull = db.runCommand({listCollections: 1});
+ assert.commandWorked(resFull);
+ var resAuthColls = db.runCommand({listCollections: 1, authorizedCollections: true});
+ assert.commandWorked(resAuthColls);
+ assert.eq(resFull.cursor.firstBatch.sort(nameSort),
+ resAuthColls.cursor.firstBatch.sort(nameSort));
+
+ var resNameOnly = db.runCommand({listCollections: 1, nameOnly: true});
+ assert.commandWorked(resNameOnly);
+ var resNameOnlyAuthColls =
+ db.runCommand({listCollections: 1, nameOnly: true, authorizedCollections: true});
+ assert.commandWorked(resNameOnlyAuthColls);
+ assert.eq(resNameOnly.cursor.firstBatch.sort(nameSort),
+ resNameOnlyAuthColls.cursor.firstBatch.sort(nameSort));
+
+ var resWithFilter = db.runCommand(
+ {listCollections: 1, nameOnly: true, authorizedCollections: true, filter: {"name": "foo"}});
+ assert.commandWorked(resWithFilter);
+ assert.eq([{"name": "foo", "type": "collection"}], resWithFilter.cursor.firstBatch);
+}
+
+const mongod = MongoRunner.runMongod({auth: ''});
+runTestOnConnection(mongod);
+MongoRunner.stopMongod(mongod);
+
+const st = new ShardingTest({
+ shards: 1,
+ mongos: 1,
+ config: 1,
+ other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
+});
+runTestOnConnection(st.s0);
+st.stop();
+
+const mongodNoAuth = MongoRunner.runMongod();
+runNoAuthTestOnConnection(mongodNoAuth);
+MongoRunner.stopMongod(mongodNoAuth);
+
+const stNoAuth =
+ new ShardingTest({shards: 1, mongos: 1, config: 1, other: {shardAsReplicaSet: false}});
+runNoAuthTestOnConnection(stNoAuth.s0);
+stNoAuth.stop();
}());
diff --git a/jstests/auth/list_databases.js b/jstests/auth/list_databases.js
index a69472fb77f..2e374e54fd6 100644
--- a/jstests/auth/list_databases.js
+++ b/jstests/auth/list_databases.js
@@ -1,167 +1,167 @@
// Auth tests for the listDatabases command.
(function() {
- 'use strict';
+'use strict';
- function runTest(mongod) {
- const admin = mongod.getDB('admin');
- admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
- assert(admin.auth('admin', 'pass'));
+function runTest(mongod) {
+ const admin = mongod.getDB('admin');
+ admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
+ assert(admin.auth('admin', 'pass'));
- // Establish db0..db7
- for (let i = 0; i < 8; ++i) {
- mongod.getDB('db' + i).foo.insert({bar: "baz"});
- }
- mongod.getDB("db0").baz.insert({x: "y"});
- mongod.getDB("db2").baz.insert({x: "y"});
-
- admin.createRole({
- role: 'dbLister',
- privileges: [{resource: {cluster: true}, actions: ['listDatabases']}],
- roles: []
- });
-
- admin.createRole({
- role: 'specificCollection',
- privileges: [{resource: {db: "db0", collection: "baz"}, actions: ['find']}],
- roles: []
- });
-
- admin.createRole({
- role: 'sharedNameCollections',
- privileges: [{resource: {db: "", collection: "baz"}, actions: ['find']}],
- roles: []
- });
-
- // Make db0, db2, db4, db6 readable to user1 abd user3.
- // Make db0, db1, db2, db3 read/writable to user 2 and user3.
- function makeRole(perm, dbNum) {
- return {role: perm, db: ("db" + dbNum)};
+ // Establish db0..db7
+ for (let i = 0; i < 8; ++i) {
+ mongod.getDB('db' + i).foo.insert({bar: "baz"});
+ }
+ mongod.getDB("db0").baz.insert({x: "y"});
+ mongod.getDB("db2").baz.insert({x: "y"});
+
+ admin.createRole({
+ role: 'dbLister',
+ privileges: [{resource: {cluster: true}, actions: ['listDatabases']}],
+ roles: []
+ });
+
+ admin.createRole({
+ role: 'specificCollection',
+ privileges: [{resource: {db: "db0", collection: "baz"}, actions: ['find']}],
+ roles: []
+ });
+
+ admin.createRole({
+ role: 'sharedNameCollections',
+ privileges: [{resource: {db: "", collection: "baz"}, actions: ['find']}],
+ roles: []
+ });
+
+ // Make db0, db2, db4, db6 readable to user1 abd user3.
+ // Make db0, db1, db2, db3 read/writable to user 2 and user3.
+ function makeRole(perm, dbNum) {
+ return {role: perm, db: ("db" + dbNum)};
+ }
+ const readEven = [0, 2, 4, 6].map(function(i) {
+ return makeRole("read", i);
+ });
+ const readWriteLow = [0, 1, 2, 3].map(function(i) {
+ return makeRole("readWrite", i);
+ });
+ admin.createUser({user: 'user1', pwd: 'pass', roles: readEven});
+ admin.createUser({user: 'user2', pwd: 'pass', roles: readWriteLow});
+ admin.createUser({user: 'user3', pwd: 'pass', roles: readEven.concat(readWriteLow)});
+
+ // Make db4 readable by user 4, and let them list all dbs.
+ // Make db5 readable by user 5, and let them list all dbs.
+ // Make collection baz in db0 findable by user6, and let them list db0.
+ // Make all baz collections findable by user7, and let them list all dbs.
+ admin.createUser({user: 'user4', pwd: 'pass', roles: [makeRole('read', 4), 'dbLister']});
+ admin.createUser({user: 'user5', pwd: 'pass', roles: [makeRole('read', 5), 'dbLister']});
+ admin.createUser({user: 'user6', pwd: 'pass', roles: ['specificCollection']});
+ admin.createUser({user: 'user7', pwd: 'pass', roles: ['sharedNameCollections']});
+ admin.logout();
+
+ const admin_dbs = ["admin", "db0", "db1", "db2", "db3", "db4", "db5", "db6", "db7"];
+
+ [{user: "user1", dbs: ["db0", "db2", "db4", "db6"]},
+ {user: "user2", dbs: ["db0", "db1", "db2", "db3"]},
+ {user: "user3", dbs: ["db0", "db1", "db2", "db3", "db4", "db6"]},
+ {user: "user4", dbs: admin_dbs, authDbs: ["db4"]},
+ {user: "user5", dbs: admin_dbs, authDbs: ["db5"]},
+ {user: "user6", dbs: ["db0"]},
+ {user: "user7", dbs: admin_dbs},
+ {user: "admin", dbs: admin_dbs, authDbs: admin_dbs},
+ ].forEach(function(test) {
+ function filterSpecial(db) {
+ // Returning of local/config varies with sharding/mobile/etc..
+ // Ignore these for simplicity.
+ return (db !== 'local') && (db !== 'config');
}
- const readEven = [0, 2, 4, 6].map(function(i) {
- return makeRole("read", i);
- });
- const readWriteLow = [0, 1, 2, 3].map(function(i) {
- return makeRole("readWrite", i);
- });
- admin.createUser({user: 'user1', pwd: 'pass', roles: readEven});
- admin.createUser({user: 'user2', pwd: 'pass', roles: readWriteLow});
- admin.createUser({user: 'user3', pwd: 'pass', roles: readEven.concat(readWriteLow)});
-
- // Make db4 readable by user 4, and let them list all dbs.
- // Make db5 readable by user 5, and let them list all dbs.
- // Make collection baz in db0 findable by user6, and let them list db0.
- // Make all baz collections findable by user7, and let them list all dbs.
- admin.createUser({user: 'user4', pwd: 'pass', roles: [makeRole('read', 4), 'dbLister']});
- admin.createUser({user: 'user5', pwd: 'pass', roles: [makeRole('read', 5), 'dbLister']});
- admin.createUser({user: 'user6', pwd: 'pass', roles: ['specificCollection']});
- admin.createUser({user: 'user7', pwd: 'pass', roles: ['sharedNameCollections']});
- admin.logout();
- const admin_dbs = ["admin", "db0", "db1", "db2", "db3", "db4", "db5", "db6", "db7"];
-
- [{user: "user1", dbs: ["db0", "db2", "db4", "db6"]},
- {user: "user2", dbs: ["db0", "db1", "db2", "db3"]},
- {user: "user3", dbs: ["db0", "db1", "db2", "db3", "db4", "db6"]},
- {user: "user4", dbs: admin_dbs, authDbs: ["db4"]},
- {user: "user5", dbs: admin_dbs, authDbs: ["db5"]},
- {user: "user6", dbs: ["db0"]},
- {user: "user7", dbs: admin_dbs},
- {user: "admin", dbs: admin_dbs, authDbs: admin_dbs},
- ].forEach(function(test) {
- function filterSpecial(db) {
- // Returning of local/config varies with sharding/mobile/etc..
- // Ignore these for simplicity.
- return (db !== 'local') && (db !== 'config');
- }
-
- // Invoking {listDatabases: 1} directly.
- function tryList(cmd, expect_dbs) {
- const dbs = assert.commandWorked(admin.runCommand(cmd));
- assert.eq(dbs.databases
- .map(function(db) {
- return db.name;
- })
- .filter(filterSpecial)
- .sort(),
- expect_dbs,
- test.user + " permissions");
- }
+ // Invoking {listDatabases: 1} directly.
+ function tryList(cmd, expect_dbs) {
+ const dbs = assert.commandWorked(admin.runCommand(cmd));
+ assert.eq(dbs.databases
+ .map(function(db) {
+ return db.name;
+ })
+ .filter(filterSpecial)
+ .sort(),
+ expect_dbs,
+ test.user + " permissions");
+ }
- admin.auth(test.user, 'pass');
- tryList({listDatabases: 1}, test.dbs);
- tryList({listDatabases: 1, authorizedDatabases: true}, test.authDbs || test.dbs);
+ admin.auth(test.user, 'pass');
+ tryList({listDatabases: 1}, test.dbs);
+ tryList({listDatabases: 1, authorizedDatabases: true}, test.authDbs || test.dbs);
- if (test.authDbs) {
- tryList({listDatabases: 1, authorizedDatabases: false}, test.dbs);
- } else {
- // Users without listDatabases cluster perm may not
- // request authorizedDatabases: false.
- assert.throws(tryList, [{listDatabases: 1, authorizedDatabases: false}, test.dbs]);
- }
+ if (test.authDbs) {
+ tryList({listDatabases: 1, authorizedDatabases: false}, test.dbs);
+ } else {
+ // Users without listDatabases cluster perm may not
+ // request authorizedDatabases: false.
+ assert.throws(tryList, [{listDatabases: 1, authorizedDatabases: false}, test.dbs]);
+ }
- // Test using shell helper Mongo.getDBs().
- assert.eq(mongod.getDBs(undefined, {}, true).filter(filterSpecial),
- test.dbs,
- "Shell helper speaking to same version");
- if (test.user !== 'admin' && test.user !== "user7") {
- // Admin and user7 don't have an explicit list of DBs to parse.
- assert.eq(mongod._getDatabaseNamesFromPrivileges(), test.authDbs || test.dbs);
-
- // Test (non-admin) call to Mongo.getDBs() on a < 4.0 MongoD
- // by injecting a command failure into Mongo.adminCommand().
- // This will allow us to resemble a < 4.0 server.
- const adminCommandFunction = mongod.adminCommand;
- const adminCommandMethod = adminCommandFunction.bind(mongod);
-
- try {
- mongod.adminCommand = function(cmd) {
- if (cmd.hasOwnProperty('listDatabases')) {
- return {
- ok: 0,
- errmsg: 'Stubbed command failure: ' + tojson(cmd),
- code: ErrorCodes.Unauthorized,
- codeName: 'Unauthorized'
- };
- }
- return adminCommandMethod(cmd);
- };
- // Command fails, but we dispatch via _getDatabaseNamesFromPrivileges().
- assert.eq(mongod.getDBs().databases.map(function(x) {
- return x.name;
- }),
- test.authDbs || test.dbs);
-
- // Still dispatches with explicit nameOnly===true, returns only names.
- assert.eq(mongod.getDBs(undefined, undefined, true), test.authDbs || test.dbs);
-
- // Command fails and unable to dispatch because nameOnly !== true.
- assert.throws(() => mongod.getDBs(undefined, undefined, false));
-
- // Command fails and unable to dispatch because filter is not empty.
- assert.throws(() => mongod.getDBs(undefined, {name: 'foo'}));
- } finally {
- mongod.adminCommand = adminCommandFunction;
- }
+ // Test using shell helper Mongo.getDBs().
+ assert.eq(mongod.getDBs(undefined, {}, true).filter(filterSpecial),
+ test.dbs,
+ "Shell helper speaking to same version");
+ if (test.user !== 'admin' && test.user !== "user7") {
+ // Admin and user7 don't have an explicit list of DBs to parse.
+ assert.eq(mongod._getDatabaseNamesFromPrivileges(), test.authDbs || test.dbs);
+
+ // Test (non-admin) call to Mongo.getDBs() on a < 4.0 MongoD
+ // by injecting a command failure into Mongo.adminCommand().
+ // This will allow us to resemble a < 4.0 server.
+ const adminCommandFunction = mongod.adminCommand;
+ const adminCommandMethod = adminCommandFunction.bind(mongod);
+
+ try {
+ mongod.adminCommand = function(cmd) {
+ if (cmd.hasOwnProperty('listDatabases')) {
+ return {
+ ok: 0,
+ errmsg: 'Stubbed command failure: ' + tojson(cmd),
+ code: ErrorCodes.Unauthorized,
+ codeName: 'Unauthorized'
+ };
+ }
+ return adminCommandMethod(cmd);
+ };
+ // Command fails, but we dispatch via _getDatabaseNamesFromPrivileges().
+ assert.eq(mongod.getDBs().databases.map(function(x) {
+ return x.name;
+ }),
+ test.authDbs || test.dbs);
+
+ // Still dispatches with explicit nameOnly===true, returns only names.
+ assert.eq(mongod.getDBs(undefined, undefined, true), test.authDbs || test.dbs);
+
+ // Command fails and unable to dispatch because nameOnly !== true.
+ assert.throws(() => mongod.getDBs(undefined, undefined, false));
+
+ // Command fails and unable to dispatch because filter is not empty.
+ assert.throws(() => mongod.getDBs(undefined, {name: 'foo'}));
+ } finally {
+ mongod.adminCommand = adminCommandFunction;
}
+ }
- admin.logout();
- });
- }
-
- const mongod = MongoRunner.runMongod({auth: ""});
- runTest(mongod);
- MongoRunner.stopMongod(mongod);
-
- if (jsTest.options().storageEngine !== "mobile") {
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- const st = new ShardingTest({
- shards: 1,
- mongos: 1,
- config: 1,
- other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
- });
- runTest(st.s0);
- st.stop();
- }
+ admin.logout();
+ });
+}
+
+const mongod = MongoRunner.runMongod({auth: ""});
+runTest(mongod);
+MongoRunner.stopMongod(mongod);
+
+if (jsTest.options().storageEngine !== "mobile") {
+ // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+ const st = new ShardingTest({
+ shards: 1,
+ mongos: 1,
+ config: 1,
+ other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
+ });
+ runTest(st.s0);
+ st.stop();
+}
})();
diff --git a/jstests/auth/list_local_sessions.js b/jstests/auth/list_local_sessions.js
index b943ba45955..3c16df48b8e 100644
--- a/jstests/auth/list_local_sessions.js
+++ b/jstests/auth/list_local_sessions.js
@@ -1,76 +1,75 @@
// All tests for the $listLocalSessions aggregation stage.
(function() {
- 'use strict';
- load('jstests/aggregation/extras/utils.js');
+'use strict';
+load('jstests/aggregation/extras/utils.js');
- // This test makes assertions about the number of sessions, which are not compatible with
- // implicit sessions.
- TestData.disableImplicitSessions = true;
+// This test makes assertions about the number of sessions, which are not compatible with
+// implicit sessions.
+TestData.disableImplicitSessions = true;
- function runListLocalSessionsTest(mongod) {
- assert(mongod);
- const admin = mongod.getDB('admin');
- const db = mongod.getDB("test");
+function runListLocalSessionsTest(mongod) {
+ assert(mongod);
+ const admin = mongod.getDB('admin');
+ const db = mongod.getDB("test");
- const pipeline = [{'$listLocalSessions': {}}];
- function listLocalSessions() {
- return admin.aggregate(pipeline);
- }
+ const pipeline = [{'$listLocalSessions': {}}];
+ function listLocalSessions() {
+ return admin.aggregate(pipeline);
+ }
- admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
- assert(admin.auth('admin', 'pass'));
+ admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
+ assert(admin.auth('admin', 'pass'));
- db.createUser({user: 'user1', pwd: 'pass', roles: jsTest.basicUserRoles});
- db.createUser({user: 'user2', pwd: 'pass', roles: jsTest.basicUserRoles});
- admin.logout();
+ db.createUser({user: 'user1', pwd: 'pass', roles: jsTest.basicUserRoles});
+ db.createUser({user: 'user2', pwd: 'pass', roles: jsTest.basicUserRoles});
+ admin.logout();
- // Shouldn't be able to listLocalSessions when not logged in.
- assertErrorCode(admin, pipeline, ErrorCodes.Unauthorized);
+ // Shouldn't be able to listLocalSessions when not logged in.
+ assertErrorCode(admin, pipeline, ErrorCodes.Unauthorized);
- // Start a new session and capture its sessionId.
- assert(db.auth('user1', 'pass'));
- const myid = assert.commandWorked(db.runCommand({startSession: 1})).id.id;
- assert(myid !== undefined);
+ // Start a new session and capture its sessionId.
+ assert(db.auth('user1', 'pass'));
+ const myid = assert.commandWorked(db.runCommand({startSession: 1})).id.id;
+ assert(myid !== undefined);
- // Ensure that the cache now contains the session.
- const resultArray = assert.doesNotThrow(listLocalSessions).toArray();
- assert.eq(resultArray.length, 1);
- const cacheid = resultArray[0]._id.id;
- const myuid = resultArray[0]._id.uid;
- assert(cacheid !== undefined);
- assert.eq(0, bsonWoCompare({x: cacheid}, {x: myid}));
+ // Ensure that the cache now contains the session.
+ const resultArray = assert.doesNotThrow(listLocalSessions).toArray();
+ assert.eq(resultArray.length, 1);
+ const cacheid = resultArray[0]._id.id;
+ const myuid = resultArray[0]._id.uid;
+ assert(cacheid !== undefined);
+ assert.eq(0, bsonWoCompare({x: cacheid}, {x: myid}));
- // Try asking for the session by username.
- function listMyLocalSessions() {
- return admin.aggregate(
- [{'$listLocalSessions': {users: [{user: "user1", db: "test"}]}}]);
- }
- const resultArrayMine = assert.doesNotThrow(listMyLocalSessions).toArray();
- assert.eq(bsonWoCompare(resultArray, resultArrayMine), 0);
+ // Try asking for the session by username.
+ function listMyLocalSessions() {
+ return admin.aggregate([{'$listLocalSessions': {users: [{user: "user1", db: "test"}]}}]);
+ }
+ const resultArrayMine = assert.doesNotThrow(listMyLocalSessions).toArray();
+ assert.eq(bsonWoCompare(resultArray, resultArrayMine), 0);
- // Ensure that changing users hides the session.
- assert(db.auth('user2', 'pass'));
- const otherArray = assert.doesNotThrow(listLocalSessions).toArray();
- assert.eq(otherArray.length, 0);
+ // Ensure that changing users hides the session.
+ assert(db.auth('user2', 'pass'));
+ const otherArray = assert.doesNotThrow(listLocalSessions).toArray();
+ assert.eq(otherArray.length, 0);
- // Ensure that one user can not explicitly ask for another's sessions.
- assertErrorCode(admin,
- [{'$listLocalSessions': {users: [{user: "user1", db: "test"}]}}],
- ErrorCodes.Unauthorized);
- }
+ // Ensure that one user can not explicitly ask for another's sessions.
+ assertErrorCode(admin,
+ [{'$listLocalSessions': {users: [{user: "user1", db: "test"}]}}],
+ ErrorCodes.Unauthorized);
+}
- const mongod = MongoRunner.runMongod({auth: ""});
- runListLocalSessionsTest(mongod);
- MongoRunner.stopMongod(mongod);
+const mongod = MongoRunner.runMongod({auth: ""});
+runListLocalSessionsTest(mongod);
+MongoRunner.stopMongod(mongod);
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- const st = new ShardingTest({
- shards: 1,
- mongos: 1,
- config: 1,
- other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
- });
- runListLocalSessionsTest(st.s0);
- st.stop();
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+const st = new ShardingTest({
+ shards: 1,
+ mongos: 1,
+ config: 1,
+ other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
+});
+runListLocalSessionsTest(st.s0);
+st.stop();
})();
diff --git a/jstests/auth/list_sessions.js b/jstests/auth/list_sessions.js
index 2b6c8a0f8f1..f91218d22e4 100644
--- a/jstests/auth/list_sessions.js
+++ b/jstests/auth/list_sessions.js
@@ -4,85 +4,85 @@
*/
(function() {
- 'use strict';
- load('jstests/aggregation/extras/utils.js');
-
- // This test makes assertions about the number of sessions, which are not compatible with
- // implicit sessions.
- TestData.disableImplicitSessions = true;
-
- function runListSessionsTest(mongod) {
- assert(mongod);
- const admin = mongod.getDB('admin');
- const config = mongod.getDB('config');
-
- const pipeline = [{'$listSessions': {}}];
- function listSessions() {
- return config.system.sessions.aggregate(pipeline);
- }
-
- admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
- assert(admin.auth('admin', 'pass'));
-
- admin.createUser({user: 'user1', pwd: 'pass', roles: jsTest.basicUserRoles});
- admin.createUser({user: 'user2', pwd: 'pass', roles: jsTest.basicUserRoles});
- admin.logout();
-
- // Fail when not logged in.
- assertErrorCode(config.system.sessions, pipeline, ErrorCodes.Unauthorized);
-
- // Start a new session and capture its sessionId.
- assert(admin.auth('user1', 'pass'));
- const myid = assert.commandWorked(admin.runCommand({startSession: 1})).id.id;
- assert(myid !== undefined);
-
- // Sync cache to collection and ensure it arrived.
- assert.commandWorked(admin.runCommand({refreshLogicalSessionCacheNow: 1}));
- const resultArray = listSessions().toArray();
- assert.eq(resultArray.length, 1);
- const cacheid = resultArray[0]._id.id;
- assert(cacheid !== undefined);
- assert.eq(bsonWoCompare(cacheid, myid), 0);
-
- // Ask again using explicit UID.
- const user1Pipeline = [{'$listSessions': {users: [{user: "user1", db: "admin"}]}}];
- function listUser1Sessions() {
- return config.system.sessions.aggregate(user1Pipeline);
- }
- const resultArrayMine = listUser1Sessions().toArray();
- assert.eq(bsonWoCompare(resultArray, resultArrayMine), 0);
-
- // Make sure pipelining other collections fail
- assertErrorCode(admin.system.collections, pipeline, ErrorCodes.InvalidNamespace);
-
- // Ensure that changing users hides the session everwhere.
- assert(admin.auth('user2', 'pass'));
- assert.eq(listSessions().toArray().length, 0);
-
- // Ensure users can't view either other's sessions.
- assertErrorCode(config.system.sessions, user1Pipeline, ErrorCodes.Unauthorized);
-
- if (true) {
- // TODO SERVER-29141: Support forcing pipelines to run on mongos
- return;
- }
- function listLocalSessions() {
- return config.aggregate([{'$listLocalSessions': {}}]);
- }
- assert.eq(listLocalSessions().toArray().length, 0);
+'use strict';
+load('jstests/aggregation/extras/utils.js');
+
+// This test makes assertions about the number of sessions, which are not compatible with
+// implicit sessions.
+TestData.disableImplicitSessions = true;
+
+function runListSessionsTest(mongod) {
+ assert(mongod);
+ const admin = mongod.getDB('admin');
+ const config = mongod.getDB('config');
+
+ const pipeline = [{'$listSessions': {}}];
+ function listSessions() {
+ return config.system.sessions.aggregate(pipeline);
+ }
+
+ admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
+ assert(admin.auth('admin', 'pass'));
+
+ admin.createUser({user: 'user1', pwd: 'pass', roles: jsTest.basicUserRoles});
+ admin.createUser({user: 'user2', pwd: 'pass', roles: jsTest.basicUserRoles});
+ admin.logout();
+
+ // Fail when not logged in.
+ assertErrorCode(config.system.sessions, pipeline, ErrorCodes.Unauthorized);
+
+ // Start a new session and capture its sessionId.
+ assert(admin.auth('user1', 'pass'));
+ const myid = assert.commandWorked(admin.runCommand({startSession: 1})).id.id;
+ assert(myid !== undefined);
+
+ // Sync cache to collection and ensure it arrived.
+ assert.commandWorked(admin.runCommand({refreshLogicalSessionCacheNow: 1}));
+ const resultArray = listSessions().toArray();
+ assert.eq(resultArray.length, 1);
+ const cacheid = resultArray[0]._id.id;
+ assert(cacheid !== undefined);
+ assert.eq(bsonWoCompare(cacheid, myid), 0);
+
+ // Ask again using explicit UID.
+ const user1Pipeline = [{'$listSessions': {users: [{user: "user1", db: "admin"}]}}];
+ function listUser1Sessions() {
+ return config.system.sessions.aggregate(user1Pipeline);
}
+ const resultArrayMine = listUser1Sessions().toArray();
+ assert.eq(bsonWoCompare(resultArray, resultArrayMine), 0);
- const mongod = MongoRunner.runMongod({auth: ""});
- runListSessionsTest(mongod);
- MongoRunner.stopMongod(mongod);
-
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- const st = new ShardingTest({
- shards: 1,
- mongos: 1,
- config: 1,
- other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
- });
- runListSessionsTest(st.s0);
- st.stop();
+ // Make sure pipelining other collections fail
+ assertErrorCode(admin.system.collections, pipeline, ErrorCodes.InvalidNamespace);
+
+ // Ensure that changing users hides the session everwhere.
+ assert(admin.auth('user2', 'pass'));
+ assert.eq(listSessions().toArray().length, 0);
+
+ // Ensure users can't view either other's sessions.
+ assertErrorCode(config.system.sessions, user1Pipeline, ErrorCodes.Unauthorized);
+
+ if (true) {
+ // TODO SERVER-29141: Support forcing pipelines to run on mongos
+ return;
+ }
+ function listLocalSessions() {
+ return config.aggregate([{'$listLocalSessions': {}}]);
+ }
+ assert.eq(listLocalSessions().toArray().length, 0);
+}
+
+const mongod = MongoRunner.runMongod({auth: ""});
+runListSessionsTest(mongod);
+MongoRunner.stopMongod(mongod);
+
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+const st = new ShardingTest({
+ shards: 1,
+ mongos: 1,
+ config: 1,
+ other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
+});
+runListSessionsTest(st.s0);
+st.stop();
})();
diff --git a/jstests/auth/listcommands_preauth.js b/jstests/auth/listcommands_preauth.js
index 4967628bc22..fae33cf65db 100644
--- a/jstests/auth/listcommands_preauth.js
+++ b/jstests/auth/listcommands_preauth.js
@@ -1,38 +1,36 @@
// Make sure that listCommands doesn't require authentication.
(function() {
- 'use strict';
+'use strict';
- function runTest(conn) {
- const admin = conn.getDB('admin');
+function runTest(conn) {
+ const admin = conn.getDB('admin');
- // Commands should succeed in auth-bypass mode regardless of requiresAuth().
- assert.commandWorked(admin.runCommand({listDatabases: 1}),
- "listDatabases shouldn't work pre-auth");
- assert.commandWorked(admin.runCommand({listCommands: 1}),
- "listCommands should work pre-auth");
+ // Commands should succeed in auth-bypass mode regardless of requiresAuth().
+ assert.commandWorked(admin.runCommand({listDatabases: 1}),
+ "listDatabases shouldn't work pre-auth");
+ assert.commandWorked(admin.runCommand({listCommands: 1}), "listCommands should work pre-auth");
- admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
+ admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
- // listDatabases should now fail, because auth bypass is no longer valid.
- assert.commandFailed(admin.runCommand({listDatabases: 1}),
- "listDatabases shouldn't work pre-auth");
- // listCommands should STILL work, because it does not require auth.
- assert.commandWorked(admin.runCommand({listCommands: 1}),
- "listCommands should work pre-auth");
- }
+ // listDatabases should now fail, because auth bypass is no longer valid.
+ assert.commandFailed(admin.runCommand({listDatabases: 1}),
+ "listDatabases shouldn't work pre-auth");
+ // listCommands should STILL work, because it does not require auth.
+ assert.commandWorked(admin.runCommand({listCommands: 1}), "listCommands should work pre-auth");
+}
- const mongod = MongoRunner.runMongod({auth: ""});
- runTest(mongod);
- MongoRunner.stopMongod(mongod);
+const mongod = MongoRunner.runMongod({auth: ""});
+runTest(mongod);
+MongoRunner.stopMongod(mongod);
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- const st = new ShardingTest({
- shards: 1,
- mongos: 1,
- config: 1,
- other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
- });
- runTest(st.s0);
- st.stop();
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+const st = new ShardingTest({
+ shards: 1,
+ mongos: 1,
+ config: 1,
+ other: {keyFile: 'jstests/libs/key1', shardAsReplicaSet: false}
+});
+runTest(st.s0);
+st.stop();
})();
diff --git a/jstests/auth/logs_include_client_info.js b/jstests/auth/logs_include_client_info.js
index 5e793100686..31594a60de5 100644
--- a/jstests/auth/logs_include_client_info.js
+++ b/jstests/auth/logs_include_client_info.js
@@ -2,28 +2,28 @@
// address of the client attempting to authenticate.
(function() {
- const conn = MongoRunner.runMongod({auth: ""});
- const admin = conn.getDB("admin");
+const conn = MongoRunner.runMongod({auth: ""});
+const admin = conn.getDB("admin");
- admin.createUser({
- user: "root",
- pwd: "root",
- roles: ["root"],
- });
+admin.createUser({
+ user: "root",
+ pwd: "root",
+ roles: ["root"],
+});
- assert(admin.auth("root", "root"));
+assert(admin.auth("root", "root"));
- const failConn = new Mongo(conn.host);
- failConn.getDB("admin").auth("root", "toot");
+const failConn = new Mongo(conn.host);
+failConn.getDB("admin").auth("root", "toot");
- const log = assert.commandWorked(admin.runCommand({getLog: "global"})).log;
+const log = assert.commandWorked(admin.runCommand({getLog: "global"})).log;
- const successRegex =
- /Successfully authenticated as principal root on admin from client (?:\d{1,3}\.){3}\d{1,3}:\d+/;
- const failRegex =
- /SASL SCRAM-SHA-\d+ authentication failed for root on admin from client (?:\d{1,3}\.){3}\d{1,3}:\d+/;
+const successRegex =
+ /Successfully authenticated as principal root on admin from client (?:\d{1,3}\.){3}\d{1,3}:\d+/;
+const failRegex =
+ /SASL SCRAM-SHA-\d+ authentication failed for root on admin from client (?:\d{1,3}\.){3}\d{1,3}:\d+/;
- assert(log.some((line) => successRegex.test(line)));
- assert(log.some((line) => failRegex.test(line)));
- MongoRunner.stopMongod(conn);
+assert(log.some((line) => successRegex.test(line)));
+assert(log.some((line) => failRegex.test(line)));
+MongoRunner.stopMongod(conn);
})();
diff --git a/jstests/auth/mongoURIAuth.js b/jstests/auth/mongoURIAuth.js
index 7f60b2e750e..0ceff7b4b31 100644
--- a/jstests/auth/mongoURIAuth.js
+++ b/jstests/auth/mongoURIAuth.js
@@ -2,71 +2,69 @@
// the specified auth mechanism.
(function() {
- 'use strict';
+'use strict';
- const runURIAuthTest = function(userMech, uriMech, authMechanism, regexMechanism) {
- const conn = MongoRunner.runMongod({auth: ""});
- const adminDB = conn.getDB("admin");
+const runURIAuthTest = function(userMech, uriMech, authMechanism, regexMechanism) {
+ const conn = MongoRunner.runMongod({auth: ""});
+ const adminDB = conn.getDB("admin");
+ adminDB.createUser({
+ user: "u",
+ pwd: "p",
+ roles: ["root"],
+
+ });
+ adminDB.auth("u", "p");
+ adminDB.setLogLevel(2, "command");
+
+ if (userMech) {
adminDB.createUser({
- user: "u",
- pwd: "p",
+ user: "user",
+ pwd: "password",
roles: ["root"],
-
+ mechanisms: [authMechanism],
});
- adminDB.auth("u", "p");
- adminDB.setLogLevel(2, "command");
-
- if (userMech) {
- adminDB.createUser({
- user: "user",
- pwd: "password",
- roles: ["root"],
- mechanisms: [authMechanism],
- });
- } else {
- adminDB.createUser({
- user: "user",
- pwd: "password",
- roles: ["root"],
- });
- }
-
- var uri;
+ } else {
+ adminDB.createUser({
+ user: "user",
+ pwd: "password",
+ roles: ["root"],
+ });
+ }
- if (uriMech) {
- uri = "mongodb://user:password@localhost:" + conn.port + "/admin?authMechanism=" +
- authMechanism;
- } else {
- uri = "mongodb://user:password@localhost:" + conn.port;
- }
+ var uri;
- var shell = runMongoProgram('./mongo', uri, "--eval", "db.getName()");
- assert.eq(shell, 0, "Should be able to connect with specified params.");
+ if (uriMech) {
+ uri = "mongodb://user:password@localhost:" + conn.port +
+ "/admin?authMechanism=" + authMechanism;
+ } else {
+ uri = "mongodb://user:password@localhost:" + conn.port;
+ }
- const log = adminDB.runCommand({getLog: "global"});
- adminDB.logout();
- const matches = tojson(log.log).match(regexMechanism);
- assert(matches);
- assert.eq(2, matches.length);
+ var shell = runMongoProgram('./mongo', uri, "--eval", "db.getName()");
+ assert.eq(shell, 0, "Should be able to connect with specified params.");
- MongoRunner.stopMongod(conn);
- };
+ const log = adminDB.runCommand({getLog: "global"});
+ adminDB.logout();
+ const matches = tojson(log.log).match(regexMechanism);
+ assert(matches);
+ assert.eq(2, matches.length);
- const SCRAM_SHA_256 = "SCRAM-SHA-256";
- const SCRAM_SHA_1 = "SCRAM-SHA-1";
+ MongoRunner.stopMongod(conn);
+};
- const SCRAM_SHA_256_regex = /saslStart.*mechanism:.*SCRAM-SHA-256/g;
- const SCRAM_SHA_1_regex = /saslStart.*mechanism:.*SCRAM-SHA-1/g;
+const SCRAM_SHA_256 = "SCRAM-SHA-256";
+const SCRAM_SHA_1 = "SCRAM-SHA-1";
- jsTestLog("Test that a mechanism specified in the URI is the chosen authentication method.");
- runURIAuthTest(false, true, SCRAM_SHA_256, SCRAM_SHA_256_regex);
+const SCRAM_SHA_256_regex = /saslStart.*mechanism:.*SCRAM-SHA-256/g;
+const SCRAM_SHA_1_regex = /saslStart.*mechanism:.*SCRAM-SHA-1/g;
- jsTestLog(
- "Test that a mechanism specified in CreateUser() is the chosen authentication method.");
- runURIAuthTest(true, false, SCRAM_SHA_1, SCRAM_SHA_1_regex);
+jsTestLog("Test that a mechanism specified in the URI is the chosen authentication method.");
+runURIAuthTest(false, true, SCRAM_SHA_256, SCRAM_SHA_256_regex);
- jsTestLog("Test that SCRAM-SHA-1 is the default authentication method.");
- runURIAuthTest(false, false, SCRAM_SHA_256, SCRAM_SHA_256_regex);
+jsTestLog("Test that a mechanism specified in CreateUser() is the chosen authentication method.");
+runURIAuthTest(true, false, SCRAM_SHA_1, SCRAM_SHA_1_regex);
+jsTestLog("Test that SCRAM-SHA-1 is the default authentication method.");
+runURIAuthTest(false, false, SCRAM_SHA_256, SCRAM_SHA_256_regex);
})(); \ No newline at end of file
diff --git a/jstests/auth/mongos_cache_invalidation.js b/jstests/auth/mongos_cache_invalidation.js
index 1f7064f558d..0917cb68f36 100644
--- a/jstests/auth/mongos_cache_invalidation.js
+++ b/jstests/auth/mongos_cache_invalidation.js
@@ -120,7 +120,6 @@ db3.auth('spencer', 'pwd');
db3.adminCommand("invalidateUserCache");
assert.writeOK(db3.foo.update({}, {$inc: {a: 1}}));
assert.eq(4, db3.foo.findOne().a);
-
})();
(function testRevokingPrivileges() {
@@ -212,7 +211,6 @@ db3.auth('spencer', 'pwd');
// We manually invalidate the cache on s2/db3.
db3.adminCommand("invalidateUserCache");
assert.commandFailedWithCode(db3.foo.runCommand("collStats"), authzErrorCode);
-
})();
st.stop();
diff --git a/jstests/auth/pinned_users.js b/jstests/auth/pinned_users.js
index f57bfa85f74..72e6b21fb8b 100644
--- a/jstests/auth/pinned_users.js
+++ b/jstests/auth/pinned_users.js
@@ -8,191 +8,188 @@
*
*/
(function() {
- 'use strict';
- jsTest.setOption("enableTestCommands", true);
- // Start a mongod with the user cache size set to zero, so we know that users who have
- // logged out always get fetched cleanly from disk.
- const rs = new ReplSetTest({
- nodes: 3,
- nodeOptions: {auth: "", setParameter: "authorizationManagerCacheSize=0"},
- keyFile: "jstests/libs/key1"
- });
-
- rs.startSet();
- rs.initiate();
- const mongod = rs.getPrimary();
- const admin = mongod.getDB("admin");
-
- admin.createUser({user: "admin", pwd: "admin", roles: ["root"]});
- admin.auth("admin", "admin");
-
- // Mark the "admin2" user as pinned in memory, we'll use this later on to recover from
- // the deadlock
- assert.commandWorked(admin.runCommand({
- setParameter: 1,
- logLevel: 2,
- authorizationManagerPinnedUsers: [
- {user: "admin2", db: "admin"},
- ],
- }));
-
- admin.createUser({user: "admin2", pwd: "admin", roles: ["root"]});
-
- let secondConn = new Mongo(mongod.host);
- let secondAdmin = secondConn.getDB("admin");
- secondAdmin.auth("admin2", "admin");
-
- // Invalidate the user cache so we know only "admin" is in there
- assert.commandWorked(admin.runCommand({invalidateUserCache: 1}));
+'use strict';
+jsTest.setOption("enableTestCommands", true);
+// Start a mongod with the user cache size set to zero, so we know that users who have
+// logged out always get fetched cleanly from disk.
+const rs = new ReplSetTest({
+ nodes: 3,
+ nodeOptions: {auth: "", setParameter: "authorizationManagerCacheSize=0"},
+ keyFile: "jstests/libs/key1"
+});
+
+rs.startSet();
+rs.initiate();
+const mongod = rs.getPrimary();
+const admin = mongod.getDB("admin");
+
+admin.createUser({user: "admin", pwd: "admin", roles: ["root"]});
+admin.auth("admin", "admin");
+
+// Mark the "admin2" user as pinned in memory, we'll use this later on to recover from
+// the deadlock
+assert.commandWorked(admin.runCommand({
+ setParameter: 1,
+ logLevel: 2,
+ authorizationManagerPinnedUsers: [
+ {user: "admin2", db: "admin"},
+ ],
+}));
+
+admin.createUser({user: "admin2", pwd: "admin", roles: ["root"]});
+
+let secondConn = new Mongo(mongod.host);
+let secondAdmin = secondConn.getDB("admin");
+secondAdmin.auth("admin2", "admin");
+
+// Invalidate the user cache so we know only "admin" is in there
+assert.commandWorked(admin.runCommand({invalidateUserCache: 1}));
+assert.soon(function() {
+ let cacheContents = admin.aggregate([{$listCachedAndActiveUsers: {}}]).toArray();
+ print("User cache after initialization: ", tojson(cacheContents));
+
+ const admin2Doc = sortDoc({"username": "admin2", "db": "admin", "active": true});
+ return cacheContents.some((doc) => friendlyEqual(admin2Doc, sortDoc(doc)));
+});
+
+const waitForCommand = function(waitingFor, opFilter) {
+ let opId = -1;
assert.soon(function() {
- let cacheContents = admin.aggregate([{$listCachedAndActiveUsers: {}}]).toArray();
- print("User cache after initialization: ", tojson(cacheContents));
-
- const admin2Doc = sortDoc({"username": "admin2", "db": "admin", "active": true});
- return cacheContents.some((doc) => friendlyEqual(admin2Doc, sortDoc(doc)));
+ print(`Checking for ${waitingFor}`);
+ const curopRes = admin.currentOp();
+ assert.commandWorked(curopRes);
+ const foundOp = curopRes["inprog"].filter(opFilter);
+
+ if (foundOp.length == 1) {
+ opId = foundOp[0]["opid"];
+ }
+ return (foundOp.length == 1);
});
-
- const waitForCommand = function(waitingFor, opFilter) {
- let opId = -1;
- assert.soon(function() {
- print(`Checking for ${waitingFor}`);
- const curopRes = admin.currentOp();
- assert.commandWorked(curopRes);
- const foundOp = curopRes["inprog"].filter(opFilter);
-
- if (foundOp.length == 1) {
- opId = foundOp[0]["opid"];
- }
- return (foundOp.length == 1);
- });
- return opId;
- };
-
- // The deadlock happens in two phases. First we run a command that acquires a read lock and
- // holds it for forever.
- let readLockShell = startParallelShell(function() {
- assert.eq(db.getSiblingDB("admin").auth("admin", "admin"), 1);
- assert.commandFailed(db.adminCommand(
- {sleep: 1, secs: 500, lock: "r", lockTarget: "admin", $comment: "Read lock sleep"}));
- }, mongod.port);
-
- // Wait for that command to appear in currentOp
- const readID = waitForCommand(
- "readlock",
- op => (op["ns"] == "admin.$cmd" && op["command"]["$comment"] == "Read lock sleep"));
-
- // Then we run a command that tries to acquire a write lock, which will wait for forever
- // because we're already holding a read lock, but will also prevent any new read locks from
- // being taken.
- let writeLockShell = startParallelShell(function() {
- assert.eq(db.getSiblingDB("admin").auth("admin", "admin"), 1);
- assert.commandFailed(db.adminCommand(
- {sleep: 1, secs: 500, lock: "w", lockTarget: "admin", $comment: "Write lock sleep"}));
- }, mongod.port);
-
- // Wait for that to appear in currentOp
- const writeID = waitForCommand(
- "writeLock",
- op => (op["ns"] == "admin.$cmd" && op["command"]["$comment"] == "Write lock sleep"));
-
- print("killing ops and moving on!");
-
- // If "admin2" wasn't pinned in memory, then these would hang.
- assert.commandWorked(secondAdmin.currentOp());
- assert.commandWorked(secondAdmin.killOp(readID));
- assert.commandWorked(secondAdmin.killOp(writeID));
-
- readLockShell();
- writeLockShell();
-
- admin.logout();
- secondAdmin.logout();
- rs.stopSet();
+ return opId;
+};
+
+// The deadlock happens in two phases. First we run a command that acquires a read lock and
+// holds it for forever.
+let readLockShell = startParallelShell(function() {
+ assert.eq(db.getSiblingDB("admin").auth("admin", "admin"), 1);
+ assert.commandFailed(db.adminCommand(
+ {sleep: 1, secs: 500, lock: "r", lockTarget: "admin", $comment: "Read lock sleep"}));
+}, mongod.port);
+
+// Wait for that command to appear in currentOp
+const readID = waitForCommand(
+ "readlock", op => (op["ns"] == "admin.$cmd" && op["command"]["$comment"] == "Read lock sleep"));
+
+// Then we run a command that tries to acquire a write lock, which will wait for forever
+// because we're already holding a read lock, but will also prevent any new read locks from
+// being taken.
+let writeLockShell = startParallelShell(function() {
+ assert.eq(db.getSiblingDB("admin").auth("admin", "admin"), 1);
+ assert.commandFailed(db.adminCommand(
+ {sleep: 1, secs: 500, lock: "w", lockTarget: "admin", $comment: "Write lock sleep"}));
+}, mongod.port);
+
+// Wait for that to appear in currentOp
+const writeID = waitForCommand(
+ "writeLock",
+ op => (op["ns"] == "admin.$cmd" && op["command"]["$comment"] == "Write lock sleep"));
+
+print("killing ops and moving on!");
+
+// If "admin2" wasn't pinned in memory, then these would hang.
+assert.commandWorked(secondAdmin.currentOp());
+assert.commandWorked(secondAdmin.killOp(readID));
+assert.commandWorked(secondAdmin.killOp(writeID));
+
+readLockShell();
+writeLockShell();
+
+admin.logout();
+secondAdmin.logout();
+rs.stopSet();
})();
// This checks that removing a user document actually unpins a user. This is a round-about way
// of making sure that updates to the authz manager by the opObserver correctly invalidates the
// cache and that pinned users don't stick around after they're removed.
(function() {
- 'use strict';
- jsTest.setOption("enableTestCommands", true);
- // Start a mongod with the user cache size set to zero, so we know that users who have
- // logged out always get fetched cleanly from disk.
- const mongod =
- MongoRunner.runMongod({auth: "", setParameter: "authorizationManagerCacheSize=0"});
- let admin = mongod.getDB("admin");
-
- admin.createUser({user: "admin", pwd: "admin", roles: ["root"]});
- admin.auth("admin", "admin");
-
- // Mark the "admin2" user as pinned in memory
- assert.commandWorked(admin.runCommand({
- setParameter: 1,
- logLevel: 2,
- authorizationManagerPinnedUsers: [
- {user: "admin2", db: "admin"},
- ],
- }));
-
- admin.createUser({user: "admin2", pwd: "admin", roles: ["root"]});
-
- // Invalidate the user cache so we know only "admin" is in there
- assert.commandWorked(admin.runCommand({invalidateUserCache: 1}));
- print("User cache after initialization: ",
- tojson(admin.aggregate([{$listCachedAndActiveUsers: {}}]).toArray()));
-
- assert.commandWorked(admin.getCollection("system.users").remove({user: "admin2"}));
-
- print("User cache after removing user doc: ",
- tojson(admin.aggregate([{$listCachedAndActiveUsers: {}}]).toArray()));
-
- assert.eq(admin.auth("admin2", "admin"), 0);
- MongoRunner.stopMongod(mongod);
+'use strict';
+jsTest.setOption("enableTestCommands", true);
+// Start a mongod with the user cache size set to zero, so we know that users who have
+// logged out always get fetched cleanly from disk.
+const mongod = MongoRunner.runMongod({auth: "", setParameter: "authorizationManagerCacheSize=0"});
+let admin = mongod.getDB("admin");
+
+admin.createUser({user: "admin", pwd: "admin", roles: ["root"]});
+admin.auth("admin", "admin");
+
+// Mark the "admin2" user as pinned in memory
+assert.commandWorked(admin.runCommand({
+ setParameter: 1,
+ logLevel: 2,
+ authorizationManagerPinnedUsers: [
+ {user: "admin2", db: "admin"},
+ ],
+}));
+
+admin.createUser({user: "admin2", pwd: "admin", roles: ["root"]});
+
+// Invalidate the user cache so we know only "admin" is in there
+assert.commandWorked(admin.runCommand({invalidateUserCache: 1}));
+print("User cache after initialization: ",
+ tojson(admin.aggregate([{$listCachedAndActiveUsers: {}}]).toArray()));
+
+assert.commandWorked(admin.getCollection("system.users").remove({user: "admin2"}));
+
+print("User cache after removing user doc: ",
+ tojson(admin.aggregate([{$listCachedAndActiveUsers: {}}]).toArray()));
+
+assert.eq(admin.auth("admin2", "admin"), 0);
+MongoRunner.stopMongod(mongod);
})();
// This checks that clearing the pinned user list actually unpins a user.
(function() {
- 'use strict';
- jsTest.setOption("enableTestCommands", true);
- // Start a mongod with the user cache size set to zero, so we know that users who have
- // logged out always get fetched cleanly from disk.
- const mongod =
- MongoRunner.runMongod({auth: "", setParameter: "authorizationManagerCacheSize=0"});
- let admin = mongod.getDB("admin");
-
- admin.createUser({user: "admin", pwd: "admin", roles: ["root"]});
- admin.auth("admin", "admin");
-
- // Mark the "admin2" user as pinned in memory
- assert.commandWorked(admin.runCommand({
- setParameter: 1,
- logLevel: 2,
- authorizationManagerPinnedUsers: [
- {user: "admin2", db: "admin"},
- ],
- }));
-
- admin.createUser({user: "admin2", pwd: "admin", roles: ["root"]});
- assert.soon(function() {
- let cacheContents = admin.aggregate([{$listCachedAndActiveUsers: {}}]).toArray();
- print("User cache after initialization: ", tojson(cacheContents));
-
- const admin2Doc = sortDoc({"username": "admin2", "db": "admin", "active": true});
- return cacheContents.some((doc) => friendlyEqual(admin2Doc, sortDoc(doc)));
- });
-
- // Clear the pinned users list
- assert.commandWorked(admin.runCommand({setParameter: 1, authorizationManagerPinnedUsers: []}));
-
- // Check that admin2 gets removed from the cache
- assert.commandWorked(admin.runCommand({invalidateUserCache: 1}));
- assert.soon(function() {
- let cacheContents = admin.aggregate([{$listCachedAndActiveUsers: {}}]).toArray();
- print("User cache after initialization: ", tojson(cacheContents));
-
- const admin2Doc = sortDoc({"username": "admin2", "db": "admin", "active": true});
- return !cacheContents.some((doc) => friendlyEqual(admin2Doc, sortDoc(doc)));
- });
-
- MongoRunner.stopMongod(mongod);
+'use strict';
+jsTest.setOption("enableTestCommands", true);
+// Start a mongod with the user cache size set to zero, so we know that users who have
+// logged out always get fetched cleanly from disk.
+const mongod = MongoRunner.runMongod({auth: "", setParameter: "authorizationManagerCacheSize=0"});
+let admin = mongod.getDB("admin");
+
+admin.createUser({user: "admin", pwd: "admin", roles: ["root"]});
+admin.auth("admin", "admin");
+
+// Mark the "admin2" user as pinned in memory
+assert.commandWorked(admin.runCommand({
+ setParameter: 1,
+ logLevel: 2,
+ authorizationManagerPinnedUsers: [
+ {user: "admin2", db: "admin"},
+ ],
+}));
+
+admin.createUser({user: "admin2", pwd: "admin", roles: ["root"]});
+assert.soon(function() {
+ let cacheContents = admin.aggregate([{$listCachedAndActiveUsers: {}}]).toArray();
+ print("User cache after initialization: ", tojson(cacheContents));
+
+ const admin2Doc = sortDoc({"username": "admin2", "db": "admin", "active": true});
+ return cacheContents.some((doc) => friendlyEqual(admin2Doc, sortDoc(doc)));
+});
+
+// Clear the pinned users list
+assert.commandWorked(admin.runCommand({setParameter: 1, authorizationManagerPinnedUsers: []}));
+
+// Check that admin2 gets removed from the cache
+assert.commandWorked(admin.runCommand({invalidateUserCache: 1}));
+assert.soon(function() {
+ let cacheContents = admin.aggregate([{$listCachedAndActiveUsers: {}}]).toArray();
+ print("User cache after initialization: ", tojson(cacheContents));
+
+ const admin2Doc = sortDoc({"username": "admin2", "db": "admin", "active": true});
+ return !cacheContents.some((doc) => friendlyEqual(admin2Doc, sortDoc(doc)));
+});
+
+MongoRunner.stopMongod(mongod);
})();
diff --git a/jstests/auth/pre_auth_commands_with_sessions.js b/jstests/auth/pre_auth_commands_with_sessions.js
index 0e440a01c13..19bee66efb6 100644
--- a/jstests/auth/pre_auth_commands_with_sessions.js
+++ b/jstests/auth/pre_auth_commands_with_sessions.js
@@ -1,52 +1,51 @@
(function() {
- 'use strict';
-
- var conn = MongoRunner.runMongod({auth: ""});
- var admin = conn.getDB("admin");
- var db = conn.getDB("otherdb");
-
- admin.createUser({user: "admin", pwd: "pwd", roles: jsTest.adminUserRoles});
- admin.auth("admin", "pwd");
- db.createUser({user: "lily", pwd: "pwd", roles: jsTest.basicUserRoles});
+'use strict';
+
+var conn = MongoRunner.runMongod({auth: ""});
+var admin = conn.getDB("admin");
+var db = conn.getDB("otherdb");
+
+admin.createUser({user: "admin", pwd: "pwd", roles: jsTest.adminUserRoles});
+admin.auth("admin", "pwd");
+db.createUser({user: "lily", pwd: "pwd", roles: jsTest.basicUserRoles});
+admin.logout();
+
+var testCommand = function(cmd) {
+ // Test that we can run a pre-auth command without authenticating.
+ var command = {[cmd]: 1};
+
+ assert.commandWorked(admin.runCommand(command));
+
+ // Test that we can authenticate and start a session
+ db.auth("lily", "pwd");
+ var res = admin.runCommand({startSession: 1});
+ assert.commandWorked(res);
+ var id = res.id;
+
+ var commandWithSession = {[cmd]: 1, lsid: res.id};
+
+ // Test that we can run a pre-auth command with a session while
+ // the session owner is logged in (and the session gets ignored)
+ assert.commandWorked(db.runCommand(command),
+ "failed to run command " + cmd + " while logged in");
+ assert.commandWorked(db.runCommand(commandWithSession),
+ "failed to run command " + cmd + " with session while logged in");
+
+ // Test that we can run a pre-auth command with a session while
+ // nobody is logged in (and the session gets ignored)
+ db.logout();
+ assert.commandWorked(db.runCommand(command),
+ "failed to run command " + cmd + " without being logged in");
+ assert.commandWorked(db.runCommand(commandWithSession),
+ "failed to run command " + cmd + " with session without being logged in");
+
+ db.logout();
admin.logout();
+};
- var testCommand = function(cmd) {
- // Test that we can run a pre-auth command without authenticating.
- var command = {[cmd]: 1};
-
- assert.commandWorked(admin.runCommand(command));
-
- // Test that we can authenticate and start a session
- db.auth("lily", "pwd");
- var res = admin.runCommand({startSession: 1});
- assert.commandWorked(res);
- var id = res.id;
-
- var commandWithSession = {[cmd]: 1, lsid: res.id};
-
- // Test that we can run a pre-auth command with a session while
- // the session owner is logged in (and the session gets ignored)
- assert.commandWorked(db.runCommand(command),
- "failed to run command " + cmd + " while logged in");
- assert.commandWorked(db.runCommand(commandWithSession),
- "failed to run command " + cmd + " with session while logged in");
-
- // Test that we can run a pre-auth command with a session while
- // nobody is logged in (and the session gets ignored)
- db.logout();
- assert.commandWorked(db.runCommand(command),
- "failed to run command " + cmd + " without being logged in");
- assert.commandWorked(
- db.runCommand(commandWithSession),
- "failed to run command " + cmd + " with session without being logged in");
-
- db.logout();
- admin.logout();
- };
-
- var commands = ["ping", "ismaster"];
- for (var i = 0; i < commands.length; i++) {
- testCommand(commands[i]);
- }
- MongoRunner.stopMongod(conn, null, {user: "admin", pwd: "pwd"});
+var commands = ["ping", "ismaster"];
+for (var i = 0; i < commands.length; i++) {
+ testCommand(commands[i]);
+}
+MongoRunner.stopMongod(conn, null, {user: "admin", pwd: "pwd"});
})();
diff --git a/jstests/auth/prepared_transaction.js b/jstests/auth/prepared_transaction.js
index 2864dea5fd5..9605fe32973 100644
--- a/jstests/auth/prepared_transaction.js
+++ b/jstests/auth/prepared_transaction.js
@@ -6,200 +6,200 @@
* @tags: [uses_transactions, uses_prepare_transaction]
*/
(function() {
- "use strict";
-
- const rst = new ReplSetTest({nodes: 2, keyFile: "jstests/libs/key1"});
- rst.startSet();
- rst.initiate();
-
- const adminDB = rst.getPrimary().getDB("admin");
-
- // Create the admin user.
- assert.commandWorked(adminDB.runCommand({createUser: "admin", pwd: "admin", roles: ["root"]}));
- assert.eq(1, adminDB.auth("admin", "admin"));
-
- // Set up the test database.
- const dbName = "test";
- const collName = "transactions";
- const testDB = adminDB.getSiblingDB(dbName);
- testDB.dropDatabase();
- assert.commandWorked(testDB.runCommand({create: collName, writeConcern: {w: "majority"}}));
-
- // Create two users. Alice will be given the 'internal' privilege.
- assert.commandWorked(
- adminDB.runCommand({createUser: "Alice", pwd: "pwd", roles: ["root", "__system"]}));
- assert.commandWorked(adminDB.runCommand({createUser: "Mallory", pwd: "pwd", roles: ["root"]}));
- adminDB.logout();
-
- /**
- * Test the prepareTransaction command with Alice who has the 'internal' privilege.
- */
- assert.eq(1, adminDB.auth("Alice", "pwd"));
- let lsid = assert.commandWorked(testDB.runCommand({startSession: 1})).id;
-
- // Start the transaction and insert a document.
- assert.commandWorked(testDB.runCommand({
- insert: collName,
- documents: [{_id: "alice"}],
- lsid: lsid,
- txnNumber: NumberLong(0),
- stmtId: NumberInt(0),
- startTransaction: true,
- autocommit: false
- }));
-
- // Try to run prepareTransaction against the secondary.
- assert.commandFailedWithCode(rst.getSecondary().getDB(dbName).adminCommand({
- prepareTransaction: 1,
- lsid: lsid,
- txnNumber: NumberLong(0),
- stmtId: NumberInt(1),
- autocommit: false,
- writeConcern: {w: "majority"}
- }),
- ErrorCodes.Unauthorized);
-
- // Run prepareTransaction against the primary.
- const prepareTimestamp = assert
- .commandWorked(testDB.adminCommand({
- prepareTransaction: 1,
- lsid: lsid,
- txnNumber: NumberLong(0),
- stmtId: NumberInt(1),
- autocommit: false,
- writeConcern: {w: "majority"}
- }))
- .prepareTimestamp;
- const commitTimestamp = Timestamp(prepareTimestamp.getTime(), prepareTimestamp.getInc() + 1);
-
- // Commit the prepared transaction.
- assert.commandWorked(testDB.adminCommand({
- commitTransaction: 1,
- commitTimestamp: commitTimestamp,
- lsid: lsid,
- txnNumber: NumberLong(0),
- stmtId: NumberInt(2),
- autocommit: false
- }));
-
- assert.eq(1, testDB[collName].find({_id: "alice"}).itcount());
- adminDB.logout();
-
- /**
- * Test the prepareTransaction command with Mallory who does not have the 'internal' privilege.
- */
- assert.eq(1, adminDB.auth("Mallory", "pwd"));
-
- // Start the transaction and insert a document.
- assert.commandWorked(testDB.runCommand({
- insert: collName,
- documents: [{_id: "mallory"}],
- lsid: lsid,
- txnNumber: NumberLong(1),
- stmtId: NumberInt(0),
- startTransaction: true,
- autocommit: false
- }));
-
- // Try to run prepareTransaction against the secondary.
- assert.commandFailedWithCode(rst.getSecondary().getDB(dbName).adminCommand({
- prepareTransaction: 1,
- lsid: lsid,
- txnNumber: NumberLong(1),
- stmtId: NumberInt(1),
- autocommit: false,
- writeConcern: {w: "majority"}
- }),
- ErrorCodes.Unauthorized);
-
- // Run prepareTransaction against the primary.
- assert.commandFailedWithCode(testDB.adminCommand({
- prepareTransaction: 1,
- lsid: lsid,
- txnNumber: NumberLong(1),
- stmtId: NumberInt(1),
- autocommit: false,
- writeConcern: {w: "majority"}
- }),
- ErrorCodes.Unauthorized);
-
- // Cannot commit the transaction with 'commitTimestamp'.
- assert.commandFailedWithCode(testDB.adminCommand({
- commitTransaction: 1,
- commitTimestamp: Timestamp(0, 0),
- lsid: lsid,
- txnNumber: NumberLong(1),
- stmtId: NumberInt(1),
- autocommit: false
- }),
- ErrorCodes.InvalidOptions);
-
- // The transaction should be aborted.
- assert.commandFailedWithCode(testDB.adminCommand({
- commitTransaction: 1,
- lsid: lsid,
- txnNumber: NumberLong(1),
- stmtId: NumberInt(1),
- autocommit: false
- }),
- ErrorCodes.NoSuchTransaction);
-
- assert.eq(0, testDB[collName].find({_id: "mallory"}).itcount());
- adminDB.logout();
-
- /**
- * Test the prepareTransaction command with an unauthenticated user.
- */
-
- // Start the transaction and insert a document.
- assert.commandFailedWithCode(testDB.runCommand({
- insert: collName,
- documents: [{_id: "unauthenticated"}],
- lsid: lsid,
- txnNumber: NumberLong(2),
- stmtId: NumberInt(0),
- startTransaction: true,
- autocommit: false
- }),
- ErrorCodes.Unauthorized);
-
- // Try to run prepareTransaction against the secondary.
- assert.commandFailedWithCode(rst.getSecondary().getDB(dbName).adminCommand({
- prepareTransaction: 1,
- lsid: lsid,
- txnNumber: NumberLong(2),
- stmtId: NumberInt(0),
- autocommit: false,
- writeConcern: {w: "majority"}
- }),
- ErrorCodes.Unauthorized);
-
- // Run prepareTransaction against the primary.
- assert.commandFailedWithCode(testDB.adminCommand({
- prepareTransaction: 1,
- lsid: lsid,
- txnNumber: NumberLong(2),
- stmtId: NumberInt(0),
- autocommit: false,
- writeConcern: {w: "majority"}
- }),
- ErrorCodes.Unauthorized);
-
- // Cannot commit the transaction.
- assert.commandFailedWithCode(testDB.adminCommand({
- commitTransaction: 1,
- commitTimestamp: Timestamp(0, 0),
- lsid: lsid,
- txnNumber: NumberLong(2),
- stmtId: NumberInt(0),
- autocommit: false
- }),
- ErrorCodes.Unauthorized);
-
- assert.eq(1, adminDB.auth("Alice", "pwd"));
- assert.eq(0, testDB[collName].find({_id: "unauthenticated"}).itcount());
- assert.commandWorked(testDB.runCommand({endSessions: [lsid]}));
- adminDB.logout();
-
- rst.stopSet();
+"use strict";
+
+const rst = new ReplSetTest({nodes: 2, keyFile: "jstests/libs/key1"});
+rst.startSet();
+rst.initiate();
+
+const adminDB = rst.getPrimary().getDB("admin");
+
+// Create the admin user.
+assert.commandWorked(adminDB.runCommand({createUser: "admin", pwd: "admin", roles: ["root"]}));
+assert.eq(1, adminDB.auth("admin", "admin"));
+
+// Set up the test database.
+const dbName = "test";
+const collName = "transactions";
+const testDB = adminDB.getSiblingDB(dbName);
+testDB.dropDatabase();
+assert.commandWorked(testDB.runCommand({create: collName, writeConcern: {w: "majority"}}));
+
+// Create two users. Alice will be given the 'internal' privilege.
+assert.commandWorked(
+ adminDB.runCommand({createUser: "Alice", pwd: "pwd", roles: ["root", "__system"]}));
+assert.commandWorked(adminDB.runCommand({createUser: "Mallory", pwd: "pwd", roles: ["root"]}));
+adminDB.logout();
+
+/**
+ * Test the prepareTransaction command with Alice who has the 'internal' privilege.
+ */
+assert.eq(1, adminDB.auth("Alice", "pwd"));
+let lsid = assert.commandWorked(testDB.runCommand({startSession: 1})).id;
+
+// Start the transaction and insert a document.
+assert.commandWorked(testDB.runCommand({
+ insert: collName,
+ documents: [{_id: "alice"}],
+ lsid: lsid,
+ txnNumber: NumberLong(0),
+ stmtId: NumberInt(0),
+ startTransaction: true,
+ autocommit: false
+}));
+
+// Try to run prepareTransaction against the secondary.
+assert.commandFailedWithCode(rst.getSecondary().getDB(dbName).adminCommand({
+ prepareTransaction: 1,
+ lsid: lsid,
+ txnNumber: NumberLong(0),
+ stmtId: NumberInt(1),
+ autocommit: false,
+ writeConcern: {w: "majority"}
+}),
+ ErrorCodes.Unauthorized);
+
+// Run prepareTransaction against the primary.
+const prepareTimestamp = assert
+ .commandWorked(testDB.adminCommand({
+ prepareTransaction: 1,
+ lsid: lsid,
+ txnNumber: NumberLong(0),
+ stmtId: NumberInt(1),
+ autocommit: false,
+ writeConcern: {w: "majority"}
+ }))
+ .prepareTimestamp;
+const commitTimestamp = Timestamp(prepareTimestamp.getTime(), prepareTimestamp.getInc() + 1);
+
+// Commit the prepared transaction.
+assert.commandWorked(testDB.adminCommand({
+ commitTransaction: 1,
+ commitTimestamp: commitTimestamp,
+ lsid: lsid,
+ txnNumber: NumberLong(0),
+ stmtId: NumberInt(2),
+ autocommit: false
+}));
+
+assert.eq(1, testDB[collName].find({_id: "alice"}).itcount());
+adminDB.logout();
+
+/**
+ * Test the prepareTransaction command with Mallory who does not have the 'internal' privilege.
+ */
+assert.eq(1, adminDB.auth("Mallory", "pwd"));
+
+// Start the transaction and insert a document.
+assert.commandWorked(testDB.runCommand({
+ insert: collName,
+ documents: [{_id: "mallory"}],
+ lsid: lsid,
+ txnNumber: NumberLong(1),
+ stmtId: NumberInt(0),
+ startTransaction: true,
+ autocommit: false
+}));
+
+// Try to run prepareTransaction against the secondary.
+assert.commandFailedWithCode(rst.getSecondary().getDB(dbName).adminCommand({
+ prepareTransaction: 1,
+ lsid: lsid,
+ txnNumber: NumberLong(1),
+ stmtId: NumberInt(1),
+ autocommit: false,
+ writeConcern: {w: "majority"}
+}),
+ ErrorCodes.Unauthorized);
+
+// Run prepareTransaction against the primary.
+assert.commandFailedWithCode(testDB.adminCommand({
+ prepareTransaction: 1,
+ lsid: lsid,
+ txnNumber: NumberLong(1),
+ stmtId: NumberInt(1),
+ autocommit: false,
+ writeConcern: {w: "majority"}
+}),
+ ErrorCodes.Unauthorized);
+
+// Cannot commit the transaction with 'commitTimestamp'.
+assert.commandFailedWithCode(testDB.adminCommand({
+ commitTransaction: 1,
+ commitTimestamp: Timestamp(0, 0),
+ lsid: lsid,
+ txnNumber: NumberLong(1),
+ stmtId: NumberInt(1),
+ autocommit: false
+}),
+ ErrorCodes.InvalidOptions);
+
+// The transaction should be aborted.
+assert.commandFailedWithCode(testDB.adminCommand({
+ commitTransaction: 1,
+ lsid: lsid,
+ txnNumber: NumberLong(1),
+ stmtId: NumberInt(1),
+ autocommit: false
+}),
+ ErrorCodes.NoSuchTransaction);
+
+assert.eq(0, testDB[collName].find({_id: "mallory"}).itcount());
+adminDB.logout();
+
+/**
+ * Test the prepareTransaction command with an unauthenticated user.
+ */
+
+// Start the transaction and insert a document.
+assert.commandFailedWithCode(testDB.runCommand({
+ insert: collName,
+ documents: [{_id: "unauthenticated"}],
+ lsid: lsid,
+ txnNumber: NumberLong(2),
+ stmtId: NumberInt(0),
+ startTransaction: true,
+ autocommit: false
+}),
+ ErrorCodes.Unauthorized);
+
+// Try to run prepareTransaction against the secondary.
+assert.commandFailedWithCode(rst.getSecondary().getDB(dbName).adminCommand({
+ prepareTransaction: 1,
+ lsid: lsid,
+ txnNumber: NumberLong(2),
+ stmtId: NumberInt(0),
+ autocommit: false,
+ writeConcern: {w: "majority"}
+}),
+ ErrorCodes.Unauthorized);
+
+// Run prepareTransaction against the primary.
+assert.commandFailedWithCode(testDB.adminCommand({
+ prepareTransaction: 1,
+ lsid: lsid,
+ txnNumber: NumberLong(2),
+ stmtId: NumberInt(0),
+ autocommit: false,
+ writeConcern: {w: "majority"}
+}),
+ ErrorCodes.Unauthorized);
+
+// Cannot commit the transaction.
+assert.commandFailedWithCode(testDB.adminCommand({
+ commitTransaction: 1,
+ commitTimestamp: Timestamp(0, 0),
+ lsid: lsid,
+ txnNumber: NumberLong(2),
+ stmtId: NumberInt(0),
+ autocommit: false
+}),
+ ErrorCodes.Unauthorized);
+
+assert.eq(1, adminDB.auth("Alice", "pwd"));
+assert.eq(0, testDB[collName].find({_id: "unauthenticated"}).itcount());
+assert.commandWorked(testDB.runCommand({endSessions: [lsid]}));
+adminDB.logout();
+
+rst.stopSet();
}());
diff --git a/jstests/auth/refresh_logical_session_cache_with_long_usernames.js b/jstests/auth/refresh_logical_session_cache_with_long_usernames.js
index e584a1b8345..fb3cdb294d8 100644
--- a/jstests/auth/refresh_logical_session_cache_with_long_usernames.js
+++ b/jstests/auth/refresh_logical_session_cache_with_long_usernames.js
@@ -2,46 +2,49 @@
// usernames)
(function() {
- 'use strict';
+'use strict';
- // This test makes assertions about the number of sessions, which are not compatible with
- // implicit sessions.
- TestData.disableImplicitSessions = true;
+// This test makes assertions about the number of sessions, which are not compatible with
+// implicit sessions.
+TestData.disableImplicitSessions = true;
- const mongod = MongoRunner.runMongod({auth: ""});
+const mongod = MongoRunner.runMongod({auth: ""});
- const refresh = {refreshLogicalSessionCacheNow: 1};
- const startSession = {startSession: 1};
+const refresh = {
+ refreshLogicalSessionCacheNow: 1
+};
+const startSession = {
+ startSession: 1
+};
- const admin = mongod.getDB('admin');
- const db = mongod.getDB("test");
- const config = mongod.getDB("config");
+const admin = mongod.getDB('admin');
+const db = mongod.getDB("test");
+const config = mongod.getDB("config");
- admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
- assert(admin.auth('admin', 'pass'));
+admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
+assert(admin.auth('admin', 'pass'));
- const longUserName = "x".repeat(1000);
+const longUserName = "x".repeat(1000);
- // Create a user with a long name, so that the refresh records have a chance to blow out the
- // 16MB limit, if all the sessions are flushed in one batch
- db.createUser({user: longUserName, pwd: 'pass', roles: jsTest.basicUserRoles});
- admin.logout();
+// Create a user with a long name, so that the refresh records have a chance to blow out the
+// 16MB limit, if all the sessions are flushed in one batch
+db.createUser({user: longUserName, pwd: 'pass', roles: jsTest.basicUserRoles});
+admin.logout();
- assert(db.auth(longUserName, 'pass'));
+assert(db.auth(longUserName, 'pass'));
- // 20k * 1k = 20mb which is greater than 16mb
- const numSessions = 20000;
- for (var i = 0; i < numSessions; i++) {
- assert.commandWorked(admin.runCommand(startSession), "unable to start session");
- }
+// 20k * 1k = 20mb which is greater than 16mb
+const numSessions = 20000;
+for (var i = 0; i < numSessions; i++) {
+ assert.commandWorked(admin.runCommand(startSession), "unable to start session");
+}
- assert.commandWorked(admin.runCommand(refresh), "failed to refresh");
+assert.commandWorked(admin.runCommand(refresh), "failed to refresh");
- // Make sure we actually flushed the sessions
- assert.eq(numSessions,
- config.system.sessions.aggregate([{'$listSessions': {}}, {'$count': "count"}])
- .next()
- .count);
+// Make sure we actually flushed the sessions
+assert.eq(
+ numSessions,
+ config.system.sessions.aggregate([{'$listSessions': {}}, {'$count': "count"}]).next().count);
- MongoRunner.stopMongod(mongod);
+MongoRunner.stopMongod(mongod);
})();
diff --git a/jstests/auth/renameRestrictedCollections.js b/jstests/auth/renameRestrictedCollections.js
index 1105da4eb3d..40169bef2d6 100644
--- a/jstests/auth/renameRestrictedCollections.js
+++ b/jstests/auth/renameRestrictedCollections.js
@@ -1,109 +1,113 @@
(function() {
- 'use strict';
-
- // SERVER-8623: Test that renameCollection can't be used to bypass auth checks on system
- // namespaces
- const conn = MongoRunner.runMongod({auth: ""});
-
- const adminDB = conn.getDB("admin");
- const configDB = conn.getDB("config");
- const localDB = conn.getDB("local");
- const CodeUnauthorized = 13;
-
- const backdoorUserDoc = {user: 'backdoor', db: 'admin', pwd: 'hashed', roles: ['root']};
-
- adminDB.createUser({user: 'userAdmin', pwd: 'password', roles: ['userAdminAnyDatabase']});
-
- adminDB.auth('userAdmin', 'password');
- adminDB.createUser({user: 'readWriteAdmin', pwd: 'password', roles: ['readWriteAnyDatabase']});
- adminDB.createUser({
- user: 'readWriteAndUserAdmin',
- pwd: 'password',
- roles: ['readWriteAnyDatabase', 'userAdminAnyDatabase']
- });
- adminDB.createUser({user: 'root', pwd: 'password', roles: ['root']});
- adminDB.createUser({user: 'rootier', pwd: 'password', roles: ['__system']});
- adminDB.logout();
-
- jsTestLog("Test that a readWrite user can't rename system.profile to something they can read");
- adminDB.auth('readWriteAdmin', 'password');
- var res = adminDB.system.profile.renameCollection("profile");
- assert.eq(0, res.ok);
- assert.eq(CodeUnauthorized, res.code);
-
- jsTestLog("Test that a readWrite user can't rename system.users to something they can read");
- res = adminDB.system.users.renameCollection("users");
- assert.eq(0, res.ok);
- assert.eq(CodeUnauthorized, res.code);
- assert.eq(0, adminDB.users.count());
-
- jsTestLog("Test that a readWrite user can't use renameCollection to override system.users");
- adminDB.users.insert(backdoorUserDoc);
- res = adminDB.users.renameCollection("system.users", true);
- assert.eq(0, res.ok);
- assert.eq(CodeUnauthorized, res.code);
- adminDB.users.drop();
-
- jsTestLog("Test that a userAdmin can't rename system.users without readWrite");
- adminDB.logout();
- adminDB.auth('userAdmin', 'password');
- res = adminDB.system.users.renameCollection("users");
- assert.eq(0, res.ok);
- assert.eq(CodeUnauthorized, res.code);
- assert.eq(5, adminDB.system.users.count());
-
- adminDB.auth('readWriteAndUserAdmin', 'password');
- assert.eq(0, adminDB.users.count());
-
- jsTestLog("Test that even with userAdmin AND dbAdmin you CANNOT rename to/from system.users");
- res = adminDB.system.users.renameCollection("users");
- assert.eq(0, res.ok);
- assert.eq(CodeUnauthorized, res.code);
- assert.eq(5, adminDB.system.users.count());
-
- adminDB.users.drop();
- adminDB.users.insert(backdoorUserDoc);
- res = adminDB.users.renameCollection("system.users");
- assert.eq(0, res.ok);
- assert.eq(CodeUnauthorized, res.code);
-
- assert.eq(null, adminDB.system.users.findOne({user: backdoorUserDoc.user}));
- assert.neq(null, adminDB.system.users.findOne({user: 'userAdmin'}));
-
- adminDB.auth('rootier', 'password');
-
- jsTestLog("Test that with __system you CAN rename to/from system.users");
- res = adminDB.system.users.renameCollection("users", true);
- assert.eq(1, res.ok, tojson(res));
-
- // Test permissions against the configDB and localDB
-
- // Start with test against inserting to and renaming collections in config and local
- // as userAdminAnyDatabase.
- assert.writeOK(configDB.test.insert({'a': 1}));
- assert.commandWorked(configDB.test.renameCollection('test2'));
-
- assert.writeOK(localDB.test.insert({'a': 1}));
- assert.commandWorked(localDB.test.renameCollection('test2'));
- adminDB.logout();
-
- // Test renaming collection in config with readWriteAnyDatabase
- assert(adminDB.auth('readWriteAdmin', 'password'));
- res = configDB.test2.insert({'b': 2});
- assert.writeError(res, 13, "not authorized on config to execute command");
- res = configDB.test2.renameCollection('test');
- assert.eq(0, res.ok);
- assert.eq(CodeUnauthorized, res.code);
-
- // Test renaming collection in local with readWriteAnyDatabase
- res = localDB.test2.insert({'b': 2});
- assert.writeError(res, 13, "not authorized on config to execute command");
- res = localDB.test2.renameCollection('test');
- assert.eq(0, res.ok);
- assert.eq(CodeUnauthorized, res.code);
-
- // At this point, all the user documents are gone, so further activity may be unauthorized,
- // depending on cluster configuration. So, this is the end of the test.
- MongoRunner.stopMongod(conn, {user: 'userAdmin', pwd: 'password'});
-
+'use strict';
+
+// SERVER-8623: Test that renameCollection can't be used to bypass auth checks on system
+// namespaces
+const conn = MongoRunner.runMongod({auth: ""});
+
+const adminDB = conn.getDB("admin");
+const configDB = conn.getDB("config");
+const localDB = conn.getDB("local");
+const CodeUnauthorized = 13;
+
+const backdoorUserDoc = {
+ user: 'backdoor',
+ db: 'admin',
+ pwd: 'hashed',
+ roles: ['root']
+};
+
+adminDB.createUser({user: 'userAdmin', pwd: 'password', roles: ['userAdminAnyDatabase']});
+
+adminDB.auth('userAdmin', 'password');
+adminDB.createUser({user: 'readWriteAdmin', pwd: 'password', roles: ['readWriteAnyDatabase']});
+adminDB.createUser({
+ user: 'readWriteAndUserAdmin',
+ pwd: 'password',
+ roles: ['readWriteAnyDatabase', 'userAdminAnyDatabase']
+});
+adminDB.createUser({user: 'root', pwd: 'password', roles: ['root']});
+adminDB.createUser({user: 'rootier', pwd: 'password', roles: ['__system']});
+adminDB.logout();
+
+jsTestLog("Test that a readWrite user can't rename system.profile to something they can read");
+adminDB.auth('readWriteAdmin', 'password');
+var res = adminDB.system.profile.renameCollection("profile");
+assert.eq(0, res.ok);
+assert.eq(CodeUnauthorized, res.code);
+
+jsTestLog("Test that a readWrite user can't rename system.users to something they can read");
+res = adminDB.system.users.renameCollection("users");
+assert.eq(0, res.ok);
+assert.eq(CodeUnauthorized, res.code);
+assert.eq(0, adminDB.users.count());
+
+jsTestLog("Test that a readWrite user can't use renameCollection to override system.users");
+adminDB.users.insert(backdoorUserDoc);
+res = adminDB.users.renameCollection("system.users", true);
+assert.eq(0, res.ok);
+assert.eq(CodeUnauthorized, res.code);
+adminDB.users.drop();
+
+jsTestLog("Test that a userAdmin can't rename system.users without readWrite");
+adminDB.logout();
+adminDB.auth('userAdmin', 'password');
+res = adminDB.system.users.renameCollection("users");
+assert.eq(0, res.ok);
+assert.eq(CodeUnauthorized, res.code);
+assert.eq(5, adminDB.system.users.count());
+
+adminDB.auth('readWriteAndUserAdmin', 'password');
+assert.eq(0, adminDB.users.count());
+
+jsTestLog("Test that even with userAdmin AND dbAdmin you CANNOT rename to/from system.users");
+res = adminDB.system.users.renameCollection("users");
+assert.eq(0, res.ok);
+assert.eq(CodeUnauthorized, res.code);
+assert.eq(5, adminDB.system.users.count());
+
+adminDB.users.drop();
+adminDB.users.insert(backdoorUserDoc);
+res = adminDB.users.renameCollection("system.users");
+assert.eq(0, res.ok);
+assert.eq(CodeUnauthorized, res.code);
+
+assert.eq(null, adminDB.system.users.findOne({user: backdoorUserDoc.user}));
+assert.neq(null, adminDB.system.users.findOne({user: 'userAdmin'}));
+
+adminDB.auth('rootier', 'password');
+
+jsTestLog("Test that with __system you CAN rename to/from system.users");
+res = adminDB.system.users.renameCollection("users", true);
+assert.eq(1, res.ok, tojson(res));
+
+// Test permissions against the configDB and localDB
+
+// Start with test against inserting to and renaming collections in config and local
+// as userAdminAnyDatabase.
+assert.writeOK(configDB.test.insert({'a': 1}));
+assert.commandWorked(configDB.test.renameCollection('test2'));
+
+assert.writeOK(localDB.test.insert({'a': 1}));
+assert.commandWorked(localDB.test.renameCollection('test2'));
+adminDB.logout();
+
+// Test renaming collection in config with readWriteAnyDatabase
+assert(adminDB.auth('readWriteAdmin', 'password'));
+res = configDB.test2.insert({'b': 2});
+assert.writeError(res, 13, "not authorized on config to execute command");
+res = configDB.test2.renameCollection('test');
+assert.eq(0, res.ok);
+assert.eq(CodeUnauthorized, res.code);
+
+// Test renaming collection in local with readWriteAnyDatabase
+res = localDB.test2.insert({'b': 2});
+assert.writeError(res, 13, "not authorized on config to execute command");
+res = localDB.test2.renameCollection('test');
+assert.eq(0, res.ok);
+assert.eq(CodeUnauthorized, res.code);
+
+// At this point, all the user documents are gone, so further activity may be unauthorized,
+// depending on cluster configuration. So, this is the end of the test.
+MongoRunner.stopMongod(conn, {user: 'userAdmin', pwd: 'password'});
})(); \ No newline at end of file
diff --git a/jstests/auth/resource_pattern_matching.js b/jstests/auth/resource_pattern_matching.js
index ca3c9b50195..ccefb8f51f5 100644
--- a/jstests/auth/resource_pattern_matching.js
+++ b/jstests/auth/resource_pattern_matching.js
@@ -13,12 +13,8 @@ function setup_users(granter) {
admindb.runCommand({
createUser: "admin",
pwd: "admin",
- roles: [
- "userAdminAnyDatabase",
- "dbAdminAnyDatabase",
- "clusterAdmin",
- "readWriteAnyDatabase"
- ]
+ roles:
+ ["userAdminAnyDatabase", "dbAdminAnyDatabase", "clusterAdmin", "readWriteAnyDatabase"]
});
admindb.auth("admin", "admin");
@@ -143,10 +139,10 @@ function run_tests(granter, verifier) {
verifier,
[{resource: {db: "a", collection: "a"}, actions: ["find"]}],
{
- "a.a": should_find,
- "a.b": should_fail_find,
- "b.a": should_fail_find,
- "b.b": should_fail_find
+ "a.a": should_find,
+ "a.b": should_fail_find,
+ "b.a": should_fail_find,
+ "b.b": should_fail_find
});
run_test(
@@ -183,12 +179,12 @@ function run_tests(granter, verifier) {
verifier,
[{resource: {db: "$", collection: "cmd"}, actions: ["find"]}],
{
- "a.a": function(testdb, testcol) {
- var r = testdb.stats();
+ "a.a": function(testdb, testcol) {
+ var r = testdb.stats();
- if (r["ok"])
- throw("db.$.cmd shouldn't give a.stats()");
- }
+ if (r["ok"])
+ throw ("db.$.cmd shouldn't give a.stats()");
+ }
});
run_test_bad_resource("empty_resource", granter, {});
@@ -202,26 +198,26 @@ function run_tests(granter, verifier) {
granter,
verifier,
[
- {resource: {db: "a", collection: "a"}, actions: ["find"]},
- {resource: {db: "", collection: ""}, actions: ["insert"]}
+ {resource: {db: "a", collection: "a"}, actions: ["find"]},
+ {resource: {db: "", collection: ""}, actions: ["insert"]}
],
{
- "a.a": function(testdb, testcol) {
- should_insert(testdb, testcol);
- should_find(testdb, testcol);
- },
- "a.b": function(testdb, testcol) {
- should_insert(testdb, testcol);
- should_fail_find(testdb, testcol);
- },
- "b.a": function(testdb, testcol) {
- should_insert(testdb, testcol);
- should_fail_find(testdb, testcol);
- },
- "b.b": function(testdb, testcol) {
- should_insert(testdb, testcol);
- should_fail_find(testdb, testcol);
- },
+ "a.a": function(testdb, testcol) {
+ should_insert(testdb, testcol);
+ should_find(testdb, testcol);
+ },
+ "a.b": function(testdb, testcol) {
+ should_insert(testdb, testcol);
+ should_fail_find(testdb, testcol);
+ },
+ "b.a": function(testdb, testcol) {
+ should_insert(testdb, testcol);
+ should_fail_find(testdb, testcol);
+ },
+ "b.b": function(testdb, testcol) {
+ should_insert(testdb, testcol);
+ should_fail_find(testdb, testcol);
+ },
});
}
diff --git a/jstests/auth/role_management_commands_edge_cases.js b/jstests/auth/role_management_commands_edge_cases.js
index 9dd774d5518..023f01df95e 100644
--- a/jstests/auth/role_management_commands_edge_cases.js
+++ b/jstests/auth/role_management_commands_edge_cases.js
@@ -92,10 +92,8 @@ function runTest(conn) {
db.createRole({
role: 'role13',
roles: [],
- privileges: [{
- resource: {db: "test", collection: "foo", cluster: true},
- actions: ['find']
- }]
+ privileges:
+ [{resource: {db: "test", collection: "foo", cluster: true}, actions: ['find']}]
});
});
assert.throws(function() {
@@ -116,8 +114,7 @@ function runTest(conn) {
db.createRole({
role: 'role16',
roles: [],
- privileges:
- [{resource: {db: "test", collection: "foo"}, actions: ['fakeAction']}]
+ privileges: [{resource: {db: "test", collection: "foo"}, actions: ['fakeAction']}]
});
});
@@ -233,7 +230,6 @@ function runTest(conn) {
assert.throws(function() {
db.revokeRolesFromRole("readWrite", ['read']);
});
-
})();
(function testGrantPrivilegesToRole() {
diff --git a/jstests/auth/role_management_commands_lib.js b/jstests/auth/role_management_commands_lib.js
index a4156a3be7e..a706899c6e7 100644
--- a/jstests/auth/role_management_commands_lib.js
+++ b/jstests/auth/role_management_commands_lib.js
@@ -194,8 +194,8 @@ function runAllRoleManagementCommandsTests(conn, writeConcern) {
adminUserAdmin.grantPrivilegesToRole(
'adminRole',
[
- {resource: {cluster: true}, actions: ['serverStatus']},
- {resource: {db: "", collection: ""}, actions: ['find']}
+ {resource: {cluster: true}, actions: ['serverStatus']},
+ {resource: {db: "", collection: ""}, actions: ['find']}
],
writeConcern);
assert.doesNotThrow(function() {
@@ -212,8 +212,8 @@ function runAllRoleManagementCommandsTests(conn, writeConcern) {
testUserAdmin.grantPrivilegesToRole(
'testRole2',
[
- {resource: {db: 'test', collection: ''}, actions: ['insert', 'update']},
- {resource: {db: 'test', collection: 'foo'}, actions: ['find']}
+ {resource: {db: 'test', collection: ''}, actions: ['insert', 'update']},
+ {resource: {db: 'test', collection: 'foo'}, actions: ['find']}
],
writeConcern);
assert.doesNotThrow(function() {
diff --git a/jstests/auth/role_management_commands_sharded_wc_1.js b/jstests/auth/role_management_commands_sharded_wc_1.js
index 400e85b0029..9e7e3482d76 100644
--- a/jstests/auth/role_management_commands_sharded_wc_1.js
+++ b/jstests/auth/role_management_commands_sharded_wc_1.js
@@ -1,18 +1,18 @@
// @tags: [requires_sharding]
(function() {
- 'use strict';
+'use strict';
- load('jstests/auth/role_management_commands_lib.js');
+load('jstests/auth/role_management_commands_lib.js');
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- var st = new ShardingTest({
- shards: 2,
- config: 3,
- keyFile: 'jstests/libs/key1',
- useHostname: false,
- other: {shardAsReplicaSet: false}
- });
- runAllRoleManagementCommandsTests(st.s, {w: 1});
- st.stop();
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+var st = new ShardingTest({
+ shards: 2,
+ config: 3,
+ keyFile: 'jstests/libs/key1',
+ useHostname: false,
+ other: {shardAsReplicaSet: false}
+});
+runAllRoleManagementCommandsTests(st.s, {w: 1});
+st.stop();
})();
diff --git a/jstests/auth/role_management_commands_sharded_wc_majority.js b/jstests/auth/role_management_commands_sharded_wc_majority.js
index 6bda9c5288a..155aa931feb 100644
--- a/jstests/auth/role_management_commands_sharded_wc_majority.js
+++ b/jstests/auth/role_management_commands_sharded_wc_majority.js
@@ -3,18 +3,18 @@
*/
(function() {
- 'use strict';
+'use strict';
- load('jstests/auth/role_management_commands_lib.js');
+load('jstests/auth/role_management_commands_lib.js');
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- var st = new ShardingTest({
- shards: 2,
- config: 3,
- keyFile: 'jstests/libs/key1',
- useHostname: false,
- other: {shardAsReplicaSet: false}
- });
- runAllRoleManagementCommandsTests(st.s, {w: 'majority', wtimeout: 60 * 1000});
- st.stop();
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+var st = new ShardingTest({
+ shards: 2,
+ config: 3,
+ keyFile: 'jstests/libs/key1',
+ useHostname: false,
+ other: {shardAsReplicaSet: false}
+});
+runAllRoleManagementCommandsTests(st.s, {w: 'majority', wtimeout: 60 * 1000});
+st.stop();
})();
diff --git a/jstests/auth/role_management_commands_standalone.js b/jstests/auth/role_management_commands_standalone.js
index d35f2c30a3f..13d428c8afd 100644
--- a/jstests/auth/role_management_commands_standalone.js
+++ b/jstests/auth/role_management_commands_standalone.js
@@ -1,9 +1,9 @@
(function() {
- 'use strict';
+'use strict';
- load('jstests/auth/role_management_commands_lib.js');
+load('jstests/auth/role_management_commands_lib.js');
- var conn = MongoRunner.runMongod({auth: '', useHostname: false});
- runAllRoleManagementCommandsTests(conn);
- MongoRunner.stopMongod(conn);
+var conn = MongoRunner.runMongod({auth: '', useHostname: false});
+runAllRoleManagementCommandsTests(conn);
+MongoRunner.stopMongod(conn);
})();
diff --git a/jstests/auth/sasl_mechanism_discovery.js b/jstests/auth/sasl_mechanism_discovery.js
index 0a2a05c2771..e64c8e3c545 100644
--- a/jstests/auth/sasl_mechanism_discovery.js
+++ b/jstests/auth/sasl_mechanism_discovery.js
@@ -1,80 +1,76 @@
// Tests that a client may discover a user's supported SASL mechanisms via isMaster.
// @tags: [requires_sharding]
(function() {
- "use strict";
+"use strict";
- function runTest(conn) {
- function checkMechs(userid, mechs) {
- const res =
- assert.commandWorked(db.runCommand({isMaster: 1, saslSupportedMechs: userid}));
- assert.eq(mechs.sort(), res.saslSupportedMechs.sort(), tojson(res));
- }
+function runTest(conn) {
+ function checkMechs(userid, mechs) {
+ const res = assert.commandWorked(db.runCommand({isMaster: 1, saslSupportedMechs: userid}));
+ assert.eq(mechs.sort(), res.saslSupportedMechs.sort(), tojson(res));
+ }
- var db = conn.getDB("admin");
- var externalDB = conn.getDB("$external");
+ var db = conn.getDB("admin");
+ var externalDB = conn.getDB("$external");
- assert.commandWorked(db.runCommand(
- {createUser: "userAdmin", pwd: "userAdmin", roles: ["userAdminAnyDatabase"]}));
- db.auth("userAdmin", "userAdmin");
+ assert.commandWorked(db.runCommand(
+ {createUser: "userAdmin", pwd: "userAdmin", roles: ["userAdminAnyDatabase"]}));
+ db.auth("userAdmin", "userAdmin");
- // Check that unknown users do not interrupt isMaster
- let res =
- assert.commandWorked(db.runCommand({isMaster: 1, saslSupportedMechs: "test.bogus"}));
- assert.eq(undefined, res.saslSupportedMechs);
+ // Check that unknown users do not interrupt isMaster
+ let res = assert.commandWorked(db.runCommand({isMaster: 1, saslSupportedMechs: "test.bogus"}));
+ assert.eq(undefined, res.saslSupportedMechs);
- // Check that invalid usernames produce the correct error code
- assert.commandFailedWithCode(db.runCommand({isMaster: 1, saslSupportedMechs: "bogus"}),
- ErrorCodes.BadValue);
+ // Check that invalid usernames produce the correct error code
+ assert.commandFailedWithCode(db.runCommand({isMaster: 1, saslSupportedMechs: "bogus"}),
+ ErrorCodes.BadValue);
- assert.commandWorked(db.runCommand({createUser: "user", pwd: "pwd", roles: []}));
- assert.commandWorked(externalDB.runCommand({createUser: "user", roles: []}));
+ assert.commandWorked(db.runCommand({createUser: "user", pwd: "pwd", roles: []}));
+ assert.commandWorked(externalDB.runCommand({createUser: "user", roles: []}));
- // Internal users should support scram methods.
- checkMechs("admin.user", ["SCRAM-SHA-256", "SCRAM-SHA-1"]);
+ // Internal users should support scram methods.
+ checkMechs("admin.user", ["SCRAM-SHA-256", "SCRAM-SHA-1"]);
- // External users on enterprise should support PLAIN, but not scram methods.
- if (assert.commandWorked(db.runCommand({buildInfo: 1})).modules.includes("enterprise")) {
- checkMechs("$external.user", ["PLAIN"]);
- } else {
- checkMechs("$external.user", []);
- }
+ // External users on enterprise should support PLAIN, but not scram methods.
+ if (assert.commandWorked(db.runCommand({buildInfo: 1})).modules.includes("enterprise")) {
+ checkMechs("$external.user", ["PLAIN"]);
+ } else {
+ checkMechs("$external.user", []);
+ }
- // Users with explicit mechs should only support those mechanisms
- assert.commandWorked(db.runCommand(
- {createUser: "256Only", pwd: "pwd", roles: [], mechanisms: ["SCRAM-SHA-256"]}));
- checkMechs("admin.256Only", ["SCRAM-SHA-256"]);
- assert.commandWorked(db.runCommand(
- {createUser: "1Only", pwd: "pwd", roles: [], mechanisms: ["SCRAM-SHA-1"]}));
- checkMechs("admin.1Only", ["SCRAM-SHA-1"]);
+ // Users with explicit mechs should only support those mechanisms
+ assert.commandWorked(db.runCommand(
+ {createUser: "256Only", pwd: "pwd", roles: [], mechanisms: ["SCRAM-SHA-256"]}));
+ checkMechs("admin.256Only", ["SCRAM-SHA-256"]);
+ assert.commandWorked(
+ db.runCommand({createUser: "1Only", pwd: "pwd", roles: [], mechanisms: ["SCRAM-SHA-1"]}));
+ checkMechs("admin.1Only", ["SCRAM-SHA-1"]);
- // Users with normalized and unnormalized names do not conflict
- assert.commandWorked(db.runCommand({createUser: "IX", pwd: "pwd", roles: []}));
- checkMechs("admin.IX", ["SCRAM-SHA-1", "SCRAM-SHA-256"]);
- assert.commandWorked(db.runCommand({createUser: "\u2168", pwd: "pwd", roles: []}));
- checkMechs("admin.\u2168", ["SCRAM-SHA-1", "SCRAM-SHA-256"]);
+ // Users with normalized and unnormalized names do not conflict
+ assert.commandWorked(db.runCommand({createUser: "IX", pwd: "pwd", roles: []}));
+ checkMechs("admin.IX", ["SCRAM-SHA-1", "SCRAM-SHA-256"]);
+ assert.commandWorked(db.runCommand({createUser: "\u2168", pwd: "pwd", roles: []}));
+ checkMechs("admin.\u2168", ["SCRAM-SHA-1", "SCRAM-SHA-256"]);
- // __system's mechanisms can be queried on local and admin if the server is in test mode
- checkMechs("local.__system", ["SCRAM-SHA-1", "SCRAM-SHA-256"]);
- checkMechs("admin.__system", ["SCRAM-SHA-1", "SCRAM-SHA-256"]);
- }
+ // __system's mechanisms can be queried on local and admin if the server is in test mode
+ checkMechs("local.__system", ["SCRAM-SHA-1", "SCRAM-SHA-256"]);
+ checkMechs("admin.__system", ["SCRAM-SHA-1", "SCRAM-SHA-256"]);
+}
- // Test standalone.
- var m = MongoRunner.runMongod({
- keyFile: 'jstests/libs/key1',
- setParameter: "authenticationMechanisms=SCRAM-SHA-1,SCRAM-SHA-256,PLAIN"
- });
- runTest(m);
- MongoRunner.stopMongod(m);
+// Test standalone.
+var m = MongoRunner.runMongod({
+ keyFile: 'jstests/libs/key1',
+ setParameter: "authenticationMechanisms=SCRAM-SHA-1,SCRAM-SHA-256,PLAIN"
+});
+runTest(m);
+MongoRunner.stopMongod(m);
- // Test mongos.
- var st = new ShardingTest({
- keyFile: 'jstests/libs/key1',
- shards: 0,
- other: {
- mongosOptions:
- {setParameter: "authenticationMechanisms=PLAIN,SCRAM-SHA-256,SCRAM-SHA-1"}
- }
- });
- runTest(st.s0);
- st.stop();
+// Test mongos.
+var st = new ShardingTest({
+ keyFile: 'jstests/libs/key1',
+ shards: 0,
+ other:
+ {mongosOptions: {setParameter: "authenticationMechanisms=PLAIN,SCRAM-SHA-256,SCRAM-SHA-1"}}
+});
+runTest(st.s0);
+st.stop();
})();
diff --git a/jstests/auth/scram-credentials-invalid.js b/jstests/auth/scram-credentials-invalid.js
index c5553c31f26..282c5c06cc9 100644
--- a/jstests/auth/scram-credentials-invalid.js
+++ b/jstests/auth/scram-credentials-invalid.js
@@ -2,43 +2,40 @@
// user with invalid SCRAM-SHA-1 credentials fails gracefully.
(function() {
- 'use strict';
-
- function runTest(mongod) {
- assert(mongod);
- const admin = mongod.getDB('admin');
- const test = mongod.getDB('test');
-
- admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
- assert(admin.auth('admin', 'pass'));
-
- test.createUser({user: 'user', pwd: 'pass', roles: jsTest.basicUserRoles});
-
- // Give the test user an invalid set of SCRAM-SHA-1 credentials.
- assert.eq(admin.system.users
- .update({_id: "test.user"}, {
- $set: {
- "credentials.SCRAM-SHA-1": {
- salt: "AAAA",
- storedKey: "AAAA",
- serverKey: "AAAA",
- iterationCount: 10000
- }
- }
- })
- .nModified,
- 1,
- "Should have updated one document for user@test");
- admin.logout();
-
- const error = assert.throws(function() {
- test._authOrThrow({user: 'user', pwd: 'pass'});
- });
-
- assert.eq(error, "Error: credential document SCRAM-SHA-1 failed validation");
- }
-
- const mongod = MongoRunner.runMongod({auth: "", useLogFiles: true});
- runTest(mongod);
- MongoRunner.stopMongod(mongod);
+'use strict';
+
+function runTest(mongod) {
+ assert(mongod);
+ const admin = mongod.getDB('admin');
+ const test = mongod.getDB('test');
+
+ admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
+ assert(admin.auth('admin', 'pass'));
+
+ test.createUser({user: 'user', pwd: 'pass', roles: jsTest.basicUserRoles});
+
+ // Give the test user an invalid set of SCRAM-SHA-1 credentials.
+ assert.eq(
+ admin.system.users
+ .update({_id: "test.user"}, {
+ $set: {
+ "credentials.SCRAM-SHA-1":
+ {salt: "AAAA", storedKey: "AAAA", serverKey: "AAAA", iterationCount: 10000}
+ }
+ })
+ .nModified,
+ 1,
+ "Should have updated one document for user@test");
+ admin.logout();
+
+ const error = assert.throws(function() {
+ test._authOrThrow({user: 'user', pwd: 'pass'});
+ });
+
+ assert.eq(error, "Error: credential document SCRAM-SHA-1 failed validation");
+}
+
+const mongod = MongoRunner.runMongod({auth: "", useLogFiles: true});
+runTest(mongod);
+MongoRunner.stopMongod(mongod);
})();
diff --git a/jstests/auth/shell.js b/jstests/auth/shell.js
index b3d391fd70e..0685798952c 100644
--- a/jstests/auth/shell.js
+++ b/jstests/auth/shell.js
@@ -1,19 +1,19 @@
// Authenticate to a mongod from the shell via command line.
(function() {
- 'use strict';
+'use strict';
- const port = allocatePort();
- const mongod = MongoRunner.runMongod({auth: '', port: port});
- const admin = mongod.getDB('admin');
+const port = allocatePort();
+const mongod = MongoRunner.runMongod({auth: '', port: port});
+const admin = mongod.getDB('admin');
- admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
+admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
- // Connect via shell round-trip in order to verify handling of mongodb:// uri with password.
- const uri = 'mongodb://admin:pass@localhost:' + port + '/admin';
- // Be sure to actually do something requiring authentication.
- const mongo = runMongoProgram('mongo', uri, '--eval', 'db.system.users.find({});');
- assert.eq(mongo, 0, "Failed connecting to mongod via shell+mongodb uri");
+// Connect via shell round-trip in order to verify handling of mongodb:// uri with password.
+const uri = 'mongodb://admin:pass@localhost:' + port + '/admin';
+// Be sure to actually do something requiring authentication.
+const mongo = runMongoProgram('mongo', uri, '--eval', 'db.system.users.find({});');
+assert.eq(mongo, 0, "Failed connecting to mongod via shell+mongodb uri");
- MongoRunner.stopMongod(mongod);
+MongoRunner.stopMongod(mongod);
})();
diff --git a/jstests/auth/system_auth_scram_mechs.js b/jstests/auth/system_auth_scram_mechs.js
index 7b6605a41c9..08934385d05 100644
--- a/jstests/auth/system_auth_scram_mechs.js
+++ b/jstests/auth/system_auth_scram_mechs.js
@@ -4,21 +4,21 @@
* @tags: [requires_replication]
*/
(function() {
- 'use strict';
+'use strict';
- const keyfile = 'jstests/libs/key1';
- const keyfileContents = cat(keyfile).replace(/[\011-\015\040]/g, '');
- const rs = new ReplSetTest({nodes: 3, keyFile: keyfile});
- rs.startSet();
- rs.initiate();
- const db = rs.getPrimary().getDB("admin");
+const keyfile = 'jstests/libs/key1';
+const keyfileContents = cat(keyfile).replace(/[\011-\015\040]/g, '');
+const rs = new ReplSetTest({nodes: 3, keyFile: keyfile});
+rs.startSet();
+rs.initiate();
+const db = rs.getPrimary().getDB("admin");
- jsTestLog("Testing scram-sha-256");
- assert.eq(db.auth({mechanism: 'SCRAM-SHA-256', user: '__system', pwd: keyfileContents}), 1);
- db.logout();
+jsTestLog("Testing scram-sha-256");
+assert.eq(db.auth({mechanism: 'SCRAM-SHA-256', user: '__system', pwd: keyfileContents}), 1);
+db.logout();
- jsTestLog("Testing scram-sha-1");
- assert.eq(db.auth({mechanism: 'SCRAM-SHA-1', user: '__system', pwd: keyfileContents}), 1);
+jsTestLog("Testing scram-sha-1");
+assert.eq(db.auth({mechanism: 'SCRAM-SHA-1', user: '__system', pwd: keyfileContents}), 1);
- rs.stopSet();
+rs.stopSet();
})();
diff --git a/jstests/auth/system_roles_collMod.js b/jstests/auth/system_roles_collMod.js
index c82a8d8b8b1..7b5f57567e0 100644
--- a/jstests/auth/system_roles_collMod.js
+++ b/jstests/auth/system_roles_collMod.js
@@ -1,24 +1,24 @@
// Verify custom roles still exist after noop collMod calls
(function() {
- 'use strict';
- print("START auth-system-roles-collMod.js");
- TestData.roleGraphInvalidationIsFatal = false;
- var conn = MongoRunner.runMongod({});
- var db = conn.getDB("test");
+'use strict';
+print("START auth-system-roles-collMod.js");
+TestData.roleGraphInvalidationIsFatal = false;
+var conn = MongoRunner.runMongod({});
+var db = conn.getDB("test");
- assert.commandWorked(db.runCommand(
- {createRole: "role1", roles: [{role: "readWrite", db: "test"}], privileges: []}));
- assert(db.runCommand({rolesInfo: "role1"}).roles[0].role === "role1");
+assert.commandWorked(
+ db.runCommand({createRole: "role1", roles: [{role: "readWrite", db: "test"}], privileges: []}));
+assert(db.runCommand({rolesInfo: "role1"}).roles[0].role === "role1");
- // RoleGraph not invalidated after empty collMod
- assert.commandWorked(db.adminCommand({collMod: "system.roles"}));
- assert(db.runCommand({rolesInfo: "role1"}).roles[0].role === "role1");
+// RoleGraph not invalidated after empty collMod
+assert.commandWorked(db.adminCommand({collMod: "system.roles"}));
+assert(db.runCommand({rolesInfo: "role1"}).roles[0].role === "role1");
- // RoleGraph invalidated after non-empty collMod
- assert.commandWorked(db.adminCommand({collMod: "system.roles", validationLevel: "off"}));
- assert(db.runCommand({rolesInfo: "role1"}).roles.length === 0);
+// RoleGraph invalidated after non-empty collMod
+assert.commandWorked(db.adminCommand({collMod: "system.roles", validationLevel: "off"}));
+assert(db.runCommand({rolesInfo: "role1"}).roles.length === 0);
- print("SUCCESS auth-system-roles-collMod.js");
- MongoRunner.stopMongod(conn);
+print("SUCCESS auth-system-roles-collMod.js");
+MongoRunner.stopMongod(conn);
})();
diff --git a/jstests/auth/system_user_exception.js b/jstests/auth/system_user_exception.js
index 5955d629135..67814119541 100644
--- a/jstests/auth/system_user_exception.js
+++ b/jstests/auth/system_user_exception.js
@@ -1,21 +1,19 @@
// Test the special handling of the __system user
// works when the SCRAM-SHA-1 pw auth mechanisms are disabled.
(function() {
- "use strict";
+"use strict";
- // Start mongod with no authentication mechanisms enabled
- var m = MongoRunner.runMongod(
- {keyFile: "jstests/libs/key1", setParameter: "authenticationMechanisms=PLAIN"});
+// Start mongod with no authentication mechanisms enabled
+var m = MongoRunner.runMongod(
+ {keyFile: "jstests/libs/key1", setParameter: "authenticationMechanisms=PLAIN"});
- // Verify that it's possible to use SCRAM-SHA-1 to authenticate as the __system@local user
- assert.eq(
- 1, m.getDB("local").auth({user: "__system", pwd: "foopdedoop", mechanism: "SCRAM-SHA-1"}));
+// Verify that it's possible to use SCRAM-SHA-1 to authenticate as the __system@local user
+assert.eq(1,
+ m.getDB("local").auth({user: "__system", pwd: "foopdedoop", mechanism: "SCRAM-SHA-1"}));
- // Verify that it is not possible to authenticate other users
- m.getDB("test").runCommand(
- {createUser: "guest", pwd: "guest", roles: jsTest.readOnlyUserRoles});
- assert.eq(0, m.getDB("test").auth({user: "guest", pwd: "guest", mechanism: "SCRAM-SHA-1"}));
-
- MongoRunner.stopMongod(m);
+// Verify that it is not possible to authenticate other users
+m.getDB("test").runCommand({createUser: "guest", pwd: "guest", roles: jsTest.readOnlyUserRoles});
+assert.eq(0, m.getDB("test").auth({user: "guest", pwd: "guest", mechanism: "SCRAM-SHA-1"}));
+MongoRunner.stopMongod(m);
})();
diff --git a/jstests/auth/system_user_privileges.js b/jstests/auth/system_user_privileges.js
index 164ba9bd2e4..40619ba307c 100644
--- a/jstests/auth/system_user_privileges.js
+++ b/jstests/auth/system_user_privileges.js
@@ -12,91 +12,91 @@
(function() {
- "use strict";
-
- // Runs the "count" command on a database in a way that returns the result document, for easier
- // inspection of the errmsg.
- function runCountCommand(conn, dbName, collectionName) {
- return conn.getDB(dbName).runCommand({count: collectionName});
- }
-
- // Asserts that on the given "conn", "dbName"."collectionName".count() fails as unauthorized.
- function assertCountUnauthorized(conn, dbName, collectionName) {
- assert.eq(runCountCommand(conn, dbName, collectionName).code,
- 13,
- "On " + dbName + "." + collectionName);
- }
-
- var conn = MongoRunner.runMongod({auth: ""});
-
- var admin = conn.getDB('admin');
- var test = conn.getDB('test');
- var local = conn.getDB('local');
-
- //
- // Preliminary set up.
- //
- admin.createUser({user: 'admin', pwd: 'a', roles: jsTest.adminUserRoles});
- admin.auth('admin', 'a');
-
- //
- // Add users named "__system" with no privileges on "test" and "admin", and make sure you can't
- // add one on "local"
- //
-
- test.createUser({user: '__system', pwd: 'a', roles: []});
- admin.createUser({user: '__system', pwd: 'a', roles: []});
- assert.throws(function() {
- local.createUser({user: '__system', pwd: 'a', roles: []});
- });
-
- //
- // Add some data to count.
- //
-
- admin.foo.insert({_id: 1});
- test.foo.insert({_id: 2});
- local.foo.insert({_id: 3});
-
- admin.logout();
- assertCountUnauthorized(conn, "admin", "foo");
- assertCountUnauthorized(conn, "local", "foo");
- assertCountUnauthorized(conn, "test", "foo");
-
- //
- // Validate that you cannot even log in as __system@local with the supplied password; you _must_
- // use the password from the keyfile.
- //
- assert(!local.auth('__system', 'a'));
- assertCountUnauthorized(conn, "admin", "foo");
- assertCountUnauthorized(conn, "local", "foo");
- assertCountUnauthorized(conn, "test", "foo");
-
- //
- // Validate that __system@test is not shadowed by the keyfile __system user.
- //
- test.auth('__system', 'a');
- assertCountUnauthorized(conn, "admin", "foo");
- assertCountUnauthorized(conn, "local", "foo");
- assertCountUnauthorized(conn, "test", "foo");
-
- test.logout();
- assertCountUnauthorized(conn, "admin", "foo");
- assertCountUnauthorized(conn, "local", "foo");
- assertCountUnauthorized(conn, "test", "foo");
-
- //
- // Validate that __system@admin is not shadowed by the keyfile __system user.
- //
- admin.auth('__system', 'a');
- assertCountUnauthorized(conn, "admin", "foo");
- assertCountUnauthorized(conn, "local", "foo");
- assertCountUnauthorized(conn, "test", "foo");
-
- admin.logout();
- assertCountUnauthorized(conn, "admin", "foo");
- assertCountUnauthorized(conn, "local", "foo");
- assertCountUnauthorized(conn, "test", "foo");
-
- MongoRunner.stopMongod(conn, null, {user: 'admin', pwd: 'a'});
+"use strict";
+
+// Runs the "count" command on a database in a way that returns the result document, for easier
+// inspection of the errmsg.
+function runCountCommand(conn, dbName, collectionName) {
+ return conn.getDB(dbName).runCommand({count: collectionName});
+}
+
+// Asserts that on the given "conn", "dbName"."collectionName".count() fails as unauthorized.
+function assertCountUnauthorized(conn, dbName, collectionName) {
+ assert.eq(runCountCommand(conn, dbName, collectionName).code,
+ 13,
+ "On " + dbName + "." + collectionName);
+}
+
+var conn = MongoRunner.runMongod({auth: ""});
+
+var admin = conn.getDB('admin');
+var test = conn.getDB('test');
+var local = conn.getDB('local');
+
+//
+// Preliminary set up.
+//
+admin.createUser({user: 'admin', pwd: 'a', roles: jsTest.adminUserRoles});
+admin.auth('admin', 'a');
+
+//
+// Add users named "__system" with no privileges on "test" and "admin", and make sure you can't
+// add one on "local"
+//
+
+test.createUser({user: '__system', pwd: 'a', roles: []});
+admin.createUser({user: '__system', pwd: 'a', roles: []});
+assert.throws(function() {
+ local.createUser({user: '__system', pwd: 'a', roles: []});
+});
+
+//
+// Add some data to count.
+//
+
+admin.foo.insert({_id: 1});
+test.foo.insert({_id: 2});
+local.foo.insert({_id: 3});
+
+admin.logout();
+assertCountUnauthorized(conn, "admin", "foo");
+assertCountUnauthorized(conn, "local", "foo");
+assertCountUnauthorized(conn, "test", "foo");
+
+//
+// Validate that you cannot even log in as __system@local with the supplied password; you _must_
+// use the password from the keyfile.
+//
+assert(!local.auth('__system', 'a'));
+assertCountUnauthorized(conn, "admin", "foo");
+assertCountUnauthorized(conn, "local", "foo");
+assertCountUnauthorized(conn, "test", "foo");
+
+//
+// Validate that __system@test is not shadowed by the keyfile __system user.
+//
+test.auth('__system', 'a');
+assertCountUnauthorized(conn, "admin", "foo");
+assertCountUnauthorized(conn, "local", "foo");
+assertCountUnauthorized(conn, "test", "foo");
+
+test.logout();
+assertCountUnauthorized(conn, "admin", "foo");
+assertCountUnauthorized(conn, "local", "foo");
+assertCountUnauthorized(conn, "test", "foo");
+
+//
+// Validate that __system@admin is not shadowed by the keyfile __system user.
+//
+admin.auth('__system', 'a');
+assertCountUnauthorized(conn, "admin", "foo");
+assertCountUnauthorized(conn, "local", "foo");
+assertCountUnauthorized(conn, "test", "foo");
+
+admin.logout();
+assertCountUnauthorized(conn, "admin", "foo");
+assertCountUnauthorized(conn, "local", "foo");
+assertCountUnauthorized(conn, "test", "foo");
+
+MongoRunner.stopMongod(conn, null, {user: 'admin', pwd: 'a'});
})();
diff --git a/jstests/auth/transactions.js b/jstests/auth/transactions.js
index 19e6526ab64..7037a78cd98 100644
--- a/jstests/auth/transactions.js
+++ b/jstests/auth/transactions.js
@@ -1,143 +1,141 @@
// Tests that users can only use transactions that they created.
// @tags: [uses_transactions]
(function() {
- "use strict";
-
- const rst = new ReplSetTest({nodes: 1, keyFile: "jstests/libs/key1"});
- rst.startSet();
- rst.initiate();
-
- const adminDB = rst.getPrimary().getDB("admin");
-
- // Create the admin user.
- assert.commandWorked(adminDB.runCommand({createUser: "admin", pwd: "admin", roles: ["root"]}));
- assert.eq(1, adminDB.auth("admin", "admin"));
-
- // Set up the test database.
- const dbName = "test";
- const collName = "transactions";
- const testDB = adminDB.getSiblingDB(dbName);
- testDB.dropDatabase();
- assert.commandWorked(testDB.runCommand({create: collName, writeConcern: {w: "majority"}}));
-
- // Create two users, "Alice" and "Mallory".
- assert.commandWorked(
- testDB.runCommand({createUser: "Alice", pwd: "pwd", roles: ["readWrite"]}));
- assert.commandWorked(
- testDB.runCommand({createUser: "Mallory", pwd: "pwd", roles: ["readWrite"]}));
- adminDB.logout();
-
- // Alice starts a transaction.
- assert.eq(1, testDB.auth("Alice", "pwd"));
- const lsid = assert.commandWorked(testDB.runCommand({startSession: 1})).id;
- assert.commandWorked(testDB.runCommand({
- insert: collName,
- documents: [{_id: "alice-1"}],
- lsid: lsid,
- txnNumber: NumberLong(0),
- stmtId: NumberInt(0),
- startTransaction: true,
- autocommit: false
- }));
- testDB.logout();
-
- // Mallory cannot continue the transaction. Using the same lsid for two different users creates
- // two distinct sessions on the server. Mallory's session does not have an open transaction.
- assert.eq(1, testDB.auth("Mallory", "pwd"));
- assert.commandFailedWithCode(testDB.runCommand({
- insert: collName,
- documents: [{_id: "mallory"}],
- lsid: lsid,
- txnNumber: NumberLong(0),
- stmtId: NumberInt(1),
- autocommit: false
- }),
- ErrorCodes.NoSuchTransaction);
-
- // Mallory cannot commit the transaction.
- assert.commandFailedWithCode(adminDB.runCommand({
- commitTransaction: 1,
- lsid: lsid,
- txnNumber: NumberLong(0),
- stmtId: NumberInt(1),
- autocommit: false,
- writeConcern: {w: "majority"}
- }),
- ErrorCodes.NoSuchTransaction);
-
- // Mallory cannot abort the transaction.
- assert.commandFailedWithCode(adminDB.runCommand({
- abortTransaction: 1,
- lsid: lsid,
- txnNumber: NumberLong(0),
- stmtId: NumberInt(1),
- autocommit: false,
- writeConcern: {w: "majority"}
- }),
- ErrorCodes.NoSuchTransaction);
- testDB.logout();
-
- // An unauthenticated user cannot continue the transaction.
- assert.commandFailedWithCode(testDB.runCommand({
- insert: collName,
- documents: [{_id: "unauthenticated"}],
- lsid: lsid,
- txnNumber: NumberLong(0),
- stmtId: NumberInt(1),
- autocommit: false
- }),
- ErrorCodes.Unauthorized);
-
- // An unauthenticated user cannot commit the transaction.
- assert.commandFailedWithCode(adminDB.runCommand({
- commitTransaction: 1,
- lsid: lsid,
- txnNumber: NumberLong(0),
- stmtId: NumberInt(1),
- autocommit: false,
- writeConcern: {w: "majority"}
- }),
- ErrorCodes.Unauthorized);
-
- // An unauthenticated user cannot abort the transaction.
- assert.commandFailedWithCode(adminDB.runCommand({
- abortTransaction: 1,
- lsid: lsid,
- txnNumber: NumberLong(0),
- stmtId: NumberInt(1),
- autocommit: false,
- writeConcern: {w: "majority"}
- }),
- ErrorCodes.Unauthorized);
-
- // Alice can continue the transaction.
- assert.eq(1, testDB.auth("Alice", "pwd"));
- assert.commandWorked(testDB.runCommand({
- insert: collName,
- documents: [{_id: "alice-2"}],
- lsid: lsid,
- txnNumber: NumberLong(0),
- stmtId: NumberInt(1),
- autocommit: false
- }));
-
- // Alice can commit the transaction.
- assert.commandWorked(adminDB.runCommand({
- commitTransaction: 1,
- lsid: lsid,
- txnNumber: NumberLong(0),
- stmtId: NumberInt(2),
- autocommit: false,
- writeConcern: {w: "majority"}
- }));
-
- // We do not see the writes from Mallory or the unauthenticated user.
- assert.eq(1, testDB[collName].find({_id: "alice-1"}).itcount());
- assert.eq(1, testDB[collName].find({_id: "alice-2"}).itcount());
- assert.eq(0, testDB[collName].find({_id: "mallory"}).itcount());
- assert.eq(0, testDB[collName].find({_id: "unauthenticated"}).itcount());
-
- assert.commandWorked(testDB.runCommand({endSessions: [lsid]}));
- testDB.logout();
- rst.stopSet();
+"use strict";
+
+const rst = new ReplSetTest({nodes: 1, keyFile: "jstests/libs/key1"});
+rst.startSet();
+rst.initiate();
+
+const adminDB = rst.getPrimary().getDB("admin");
+
+// Create the admin user.
+assert.commandWorked(adminDB.runCommand({createUser: "admin", pwd: "admin", roles: ["root"]}));
+assert.eq(1, adminDB.auth("admin", "admin"));
+
+// Set up the test database.
+const dbName = "test";
+const collName = "transactions";
+const testDB = adminDB.getSiblingDB(dbName);
+testDB.dropDatabase();
+assert.commandWorked(testDB.runCommand({create: collName, writeConcern: {w: "majority"}}));
+
+// Create two users, "Alice" and "Mallory".
+assert.commandWorked(testDB.runCommand({createUser: "Alice", pwd: "pwd", roles: ["readWrite"]}));
+assert.commandWorked(testDB.runCommand({createUser: "Mallory", pwd: "pwd", roles: ["readWrite"]}));
+adminDB.logout();
+
+// Alice starts a transaction.
+assert.eq(1, testDB.auth("Alice", "pwd"));
+const lsid = assert.commandWorked(testDB.runCommand({startSession: 1})).id;
+assert.commandWorked(testDB.runCommand({
+ insert: collName,
+ documents: [{_id: "alice-1"}],
+ lsid: lsid,
+ txnNumber: NumberLong(0),
+ stmtId: NumberInt(0),
+ startTransaction: true,
+ autocommit: false
+}));
+testDB.logout();
+
+// Mallory cannot continue the transaction. Using the same lsid for two different users creates
+// two distinct sessions on the server. Mallory's session does not have an open transaction.
+assert.eq(1, testDB.auth("Mallory", "pwd"));
+assert.commandFailedWithCode(testDB.runCommand({
+ insert: collName,
+ documents: [{_id: "mallory"}],
+ lsid: lsid,
+ txnNumber: NumberLong(0),
+ stmtId: NumberInt(1),
+ autocommit: false
+}),
+ ErrorCodes.NoSuchTransaction);
+
+// Mallory cannot commit the transaction.
+assert.commandFailedWithCode(adminDB.runCommand({
+ commitTransaction: 1,
+ lsid: lsid,
+ txnNumber: NumberLong(0),
+ stmtId: NumberInt(1),
+ autocommit: false,
+ writeConcern: {w: "majority"}
+}),
+ ErrorCodes.NoSuchTransaction);
+
+// Mallory cannot abort the transaction.
+assert.commandFailedWithCode(adminDB.runCommand({
+ abortTransaction: 1,
+ lsid: lsid,
+ txnNumber: NumberLong(0),
+ stmtId: NumberInt(1),
+ autocommit: false,
+ writeConcern: {w: "majority"}
+}),
+ ErrorCodes.NoSuchTransaction);
+testDB.logout();
+
+// An unauthenticated user cannot continue the transaction.
+assert.commandFailedWithCode(testDB.runCommand({
+ insert: collName,
+ documents: [{_id: "unauthenticated"}],
+ lsid: lsid,
+ txnNumber: NumberLong(0),
+ stmtId: NumberInt(1),
+ autocommit: false
+}),
+ ErrorCodes.Unauthorized);
+
+// An unauthenticated user cannot commit the transaction.
+assert.commandFailedWithCode(adminDB.runCommand({
+ commitTransaction: 1,
+ lsid: lsid,
+ txnNumber: NumberLong(0),
+ stmtId: NumberInt(1),
+ autocommit: false,
+ writeConcern: {w: "majority"}
+}),
+ ErrorCodes.Unauthorized);
+
+// An unauthenticated user cannot abort the transaction.
+assert.commandFailedWithCode(adminDB.runCommand({
+ abortTransaction: 1,
+ lsid: lsid,
+ txnNumber: NumberLong(0),
+ stmtId: NumberInt(1),
+ autocommit: false,
+ writeConcern: {w: "majority"}
+}),
+ ErrorCodes.Unauthorized);
+
+// Alice can continue the transaction.
+assert.eq(1, testDB.auth("Alice", "pwd"));
+assert.commandWorked(testDB.runCommand({
+ insert: collName,
+ documents: [{_id: "alice-2"}],
+ lsid: lsid,
+ txnNumber: NumberLong(0),
+ stmtId: NumberInt(1),
+ autocommit: false
+}));
+
+// Alice can commit the transaction.
+assert.commandWorked(adminDB.runCommand({
+ commitTransaction: 1,
+ lsid: lsid,
+ txnNumber: NumberLong(0),
+ stmtId: NumberInt(2),
+ autocommit: false,
+ writeConcern: {w: "majority"}
+}));
+
+// We do not see the writes from Mallory or the unauthenticated user.
+assert.eq(1, testDB[collName].find({_id: "alice-1"}).itcount());
+assert.eq(1, testDB[collName].find({_id: "alice-2"}).itcount());
+assert.eq(0, testDB[collName].find({_id: "mallory"}).itcount());
+assert.eq(0, testDB[collName].find({_id: "unauthenticated"}).itcount());
+
+assert.commandWorked(testDB.runCommand({endSessions: [lsid]}));
+testDB.logout();
+rst.stopSet();
}());
diff --git a/jstests/auth/upgrade_noauth_to_keyfile.js b/jstests/auth/upgrade_noauth_to_keyfile.js
index 9bf2ec115e6..41eef5612c8 100644
--- a/jstests/auth/upgrade_noauth_to_keyfile.js
+++ b/jstests/auth/upgrade_noauth_to_keyfile.js
@@ -13,46 +13,46 @@ load('jstests/multiVersion/libs/multi_rs.js');
TestData.skipGossipingClusterTime = true;
(function() {
- 'use strict';
- var keyFilePath = 'jstests/libs/key1';
+'use strict';
+var keyFilePath = 'jstests/libs/key1';
- // Disable auth explicitly
- var noAuthOptions = {noauth: ''};
+// Disable auth explicitly
+var noAuthOptions = {noauth: ''};
- // Undefine the flags we're replacing, otherwise upgradeSet will keep old values.
- var transitionToAuthOptions =
- {noauth: undefined, clusterAuthMode: 'keyFile', keyFile: keyFilePath, transitionToAuth: ''};
- var keyFileOptions = {
- clusterAuthMode: 'keyFile',
- keyFile: keyFilePath,
- transitionToAuth: undefined
- };
+// Undefine the flags we're replacing, otherwise upgradeSet will keep old values.
+var transitionToAuthOptions =
+ {noauth: undefined, clusterAuthMode: 'keyFile', keyFile: keyFilePath, transitionToAuth: ''};
+var keyFileOptions = {
+ clusterAuthMode: 'keyFile',
+ keyFile: keyFilePath,
+ transitionToAuth: undefined
+};
- var rst = new ReplSetTest({name: 'noauthSet', nodes: 3, nodeOptions: noAuthOptions});
- rst.startSet();
- rst.initiate();
+var rst = new ReplSetTest({name: 'noauthSet', nodes: 3, nodeOptions: noAuthOptions});
+rst.startSet();
+rst.initiate();
- var rstConn1 = rst.getPrimary();
+var rstConn1 = rst.getPrimary();
- // Create a user to login as when auth is enabled later
- rstConn1.getDB('admin').createUser({user: 'root', pwd: 'root', roles: ['root']});
+// Create a user to login as when auth is enabled later
+rstConn1.getDB('admin').createUser({user: 'root', pwd: 'root', roles: ['root']});
- rstConn1.getDB('test').a.insert({a: 1, str: 'TESTTESTTEST'});
- assert.eq(1, rstConn1.getDB('test').a.count(), 'Error interacting with replSet');
+rstConn1.getDB('test').a.insert({a: 1, str: 'TESTTESTTEST'});
+assert.eq(1, rstConn1.getDB('test').a.count(), 'Error interacting with replSet');
- print('=== UPGRADE noauth -> transitionToAuth/keyFile ===');
- rst.upgradeSet(transitionToAuthOptions);
- var rstConn2 = rst.getPrimary();
- rstConn2.getDB('test').a.insert({a: 1, str: 'TESTTESTTEST'});
- assert.eq(2, rstConn2.getDB('test').a.count(), 'Error interacting with replSet');
+print('=== UPGRADE noauth -> transitionToAuth/keyFile ===');
+rst.upgradeSet(transitionToAuthOptions);
+var rstConn2 = rst.getPrimary();
+rstConn2.getDB('test').a.insert({a: 1, str: 'TESTTESTTEST'});
+assert.eq(2, rstConn2.getDB('test').a.count(), 'Error interacting with replSet');
- print('=== UPGRADE transitionToAuth/keyFile -> keyFile ===');
- rst.upgradeSet(keyFileOptions, 'root', 'root');
+print('=== UPGRADE transitionToAuth/keyFile -> keyFile ===');
+rst.upgradeSet(keyFileOptions, 'root', 'root');
- // upgradeSet leaves its connections logged in as root
- var rstConn3 = rst.getPrimary();
- rstConn3.getDB('test').a.insert({a: 1, str: 'TESTTESTTEST'});
- assert.eq(3, rstConn3.getDB('test').a.count(), 'Error interacting with replSet');
+// upgradeSet leaves its connections logged in as root
+var rstConn3 = rst.getPrimary();
+rstConn3.getDB('test').a.insert({a: 1, str: 'TESTTESTTEST'});
+assert.eq(3, rstConn3.getDB('test').a.count(), 'Error interacting with replSet');
- rst.stopSet();
+rst.stopSet();
}());
diff --git a/jstests/auth/upgrade_noauth_to_keyfile_with_sharding.js b/jstests/auth/upgrade_noauth_to_keyfile_with_sharding.js
index 49d9e40c87c..148e9d1dbfc 100644
--- a/jstests/auth/upgrade_noauth_to_keyfile_with_sharding.js
+++ b/jstests/auth/upgrade_noauth_to_keyfile_with_sharding.js
@@ -5,29 +5,25 @@
load('jstests/ssl/libs/ssl_helpers.js');
(function() {
- 'use strict';
+'use strict';
- // Disable auth explicitly
- var noAuthOptions = {noauth: ''};
- var transitionToAuthOptions = {
- clusterAuthMode: 'keyFile',
- keyFile: KEYFILE,
- transitionToAuth: ''
- };
- var keyFileOptions = {clusterAuthMode: 'keyFile', keyFile: KEYFILE};
+// Disable auth explicitly
+var noAuthOptions = {noauth: ''};
+var transitionToAuthOptions = {clusterAuthMode: 'keyFile', keyFile: KEYFILE, transitionToAuth: ''};
+var keyFileOptions = {clusterAuthMode: 'keyFile', keyFile: KEYFILE};
- print('=== Testing no-auth/transitionToAuth cluster ===');
- mixedShardTest(noAuthOptions, transitionToAuthOptions, true);
- mixedShardTest(transitionToAuthOptions, noAuthOptions, true);
+print('=== Testing no-auth/transitionToAuth cluster ===');
+mixedShardTest(noAuthOptions, transitionToAuthOptions, true);
+mixedShardTest(transitionToAuthOptions, noAuthOptions, true);
- print('=== Testing transitionToAuth/transitionToAuth cluster ===');
- mixedShardTest(transitionToAuthOptions, transitionToAuthOptions, true);
+print('=== Testing transitionToAuth/transitionToAuth cluster ===');
+mixedShardTest(transitionToAuthOptions, transitionToAuthOptions, true);
- print('=== Testing transitionToAuth/keyFile cluster ===');
- mixedShardTest(keyFileOptions, transitionToAuthOptions, true);
- mixedShardTest(transitionToAuthOptions, keyFileOptions, true);
+print('=== Testing transitionToAuth/keyFile cluster ===');
+mixedShardTest(keyFileOptions, transitionToAuthOptions, true);
+mixedShardTest(transitionToAuthOptions, keyFileOptions, true);
- print('=== Testing no-auth/keyFile cluster fails ===');
- mixedShardTest(noAuthOptions, keyFileOptions, false);
- mixedShardTest(keyFileOptions, noAuthOptions, false);
+print('=== Testing no-auth/keyFile cluster fails ===');
+mixedShardTest(noAuthOptions, keyFileOptions, false);
+mixedShardTest(keyFileOptions, noAuthOptions, false);
}());
diff --git a/jstests/auth/user_cache_doc_source.js b/jstests/auth/user_cache_doc_source.js
index f56531fe580..3ffaee9b70e 100644
--- a/jstests/auth/user_cache_doc_source.js
+++ b/jstests/auth/user_cache_doc_source.js
@@ -1,47 +1,47 @@
// Tests the user cache document source
(function() {
- 'use strict';
-
- var mongod = MongoRunner.runMongod({auth: ""});
- var db = mongod.getDB("admin");
- db.createUser({user: "root", pwd: "root", roles: ["userAdminAnyDatabase"]});
- db.auth("root", "root");
- db.createUser({user: "readOnlyUser", pwd: "foobar", roles: ["readAnyDatabase"]});
- var readUserCache = function() {
- var ret = db.aggregate([{$listCachedAndActiveUsers: {}}]).toArray();
- print(tojson(ret));
- return ret;
- };
-
- const expectedOnlyRoot = [{username: "root", db: "admin", active: true}];
- assert.eq(expectedOnlyRoot, readUserCache());
-
- /* This is broken because of SERVER-36384
- var newConn = new Mongo(mongod.name);
- assert.eq(newConn.getDB("admin").auth("readOnlyUser", "foobar"), 1);
-
- const expectedBothActive = [
- { username: "root", db: "admin", active: true },
- { username: "readOnlyUser", db: "admin", active: true }
- ];
- assert.eq(expectedBothActive, readUserCache());
-
- newConn.close();
- */
-
- var awaitShell = startParallelShell(function() {
- assert.eq(db.getSisterDB("admin").auth("readOnlyUser", "foobar"), 1);
- }, mongod.port);
-
- const expectedReadOnlyInactive = [
- {username: "readOnlyUser", db: "admin", active: false},
- {username: "root", db: "admin", active: true}
- ];
- assert.soon(function() {
- return friendlyEqual(expectedReadOnlyInactive, readUserCache());
- });
-
- MongoRunner.stopMongod(mongod);
- awaitShell({checkExitSuccess: false});
+'use strict';
+
+var mongod = MongoRunner.runMongod({auth: ""});
+var db = mongod.getDB("admin");
+db.createUser({user: "root", pwd: "root", roles: ["userAdminAnyDatabase"]});
+db.auth("root", "root");
+db.createUser({user: "readOnlyUser", pwd: "foobar", roles: ["readAnyDatabase"]});
+var readUserCache = function() {
+ var ret = db.aggregate([{$listCachedAndActiveUsers: {}}]).toArray();
+ print(tojson(ret));
+ return ret;
+};
+
+const expectedOnlyRoot = [{username: "root", db: "admin", active: true}];
+assert.eq(expectedOnlyRoot, readUserCache());
+
+/* This is broken because of SERVER-36384
+var newConn = new Mongo(mongod.name);
+assert.eq(newConn.getDB("admin").auth("readOnlyUser", "foobar"), 1);
+
+const expectedBothActive = [
+ { username: "root", db: "admin", active: true },
+ { username: "readOnlyUser", db: "admin", active: true }
+];
+assert.eq(expectedBothActive, readUserCache());
+
+newConn.close();
+*/
+
+var awaitShell = startParallelShell(function() {
+ assert.eq(db.getSisterDB("admin").auth("readOnlyUser", "foobar"), 1);
+}, mongod.port);
+
+const expectedReadOnlyInactive = [
+ {username: "readOnlyUser", db: "admin", active: false},
+ {username: "root", db: "admin", active: true}
+];
+assert.soon(function() {
+ return friendlyEqual(expectedReadOnlyInactive, readUserCache());
+});
+
+MongoRunner.stopMongod(mongod);
+awaitShell({checkExitSuccess: false});
})();
diff --git a/jstests/auth/user_defined_roles.js b/jstests/auth/user_defined_roles.js
index 221c8c06e5a..a58d4ea52b6 100644
--- a/jstests/auth/user_defined_roles.js
+++ b/jstests/auth/user_defined_roles.js
@@ -100,10 +100,9 @@ function runTest(conn) {
testDB.updateUser('testUser', {customData: {zipCode: 10036}});
});
assert.eq(null, testDB.getUser('testUser').customData);
- testUserAdmin.grantPrivilegesToRole('testRole1',
- [{
- resource: {db: 'test', collection: ''},
- actions: ['changeOwnPassword', 'changeOwnCustomData']
+ testUserAdmin.grantPrivilegesToRole('testRole1', [{
+ resource: {db: 'test', collection: ''},
+ actions: ['changeOwnPassword', 'changeOwnCustomData']
}]);
testDB.changeUserPassword('testUser', 'password');
assert(!testDB.auth('testUser', 'pwd'));
diff --git a/jstests/auth/user_defined_roles_on_secondaries.js b/jstests/auth/user_defined_roles_on_secondaries.js
index 69f768c3c15..47746e9cd56 100644
--- a/jstests/auth/user_defined_roles_on_secondaries.js
+++ b/jstests/auth/user_defined_roles_on_secondaries.js
@@ -37,197 +37,195 @@
(function() {
- var name = 'user_defined_roles_on_secondaries';
- var m0, m1;
-
- function assertListContainsRole(list, role, msg) {
- var i;
- for (i = 0; i < list.length; ++i) {
- if (list[i].role == role.role && list[i].db == role.db)
- return;
- }
- doassert("Could not find value " + tojson(val) + " in " + tojson(list) +
- (msg ? ": " + msg : ""));
+var name = 'user_defined_roles_on_secondaries';
+var m0, m1;
+
+function assertListContainsRole(list, role, msg) {
+ var i;
+ for (i = 0; i < list.length; ++i) {
+ if (list[i].role == role.role && list[i].db == role.db)
+ return;
}
-
- //
- // Create a 1-node replicaset and add two roles, inheriting the built-in read role on db1.
- //
- // read
- // / \
- // r1 r2
- //
- var rstest = new ReplSetTest({name: name, nodes: 1, nodeOptions: {}});
-
- rstest.startSet();
- rstest.initiate();
-
- m0 = rstest.nodes[0];
-
- m0.getDB("db1").createRole({
- role: "r1",
- roles: ["read"],
- privileges: [{resource: {db: "db1", collection: "system.users"}, actions: ["find"]}]
- });
-
- m0.getDB("db1").createRole({
- role: "r2",
- roles: ["read"],
- privileges: [{resource: {db: "db1", collection: "log"}, actions: ["insert"]}]
- });
-
- //
- // Add a second node to the set, and add a third role, dependent on the first two.
- //
- // read
- // / \
- // r1 r2
- // \ /
- // r3
- //
- rstest.add();
- rstest.reInitiate();
-
- // This write will have to wait on the initial sync to complete before progressing.
- assert.soonNoExcept(() => {
- assert.writeOK(rstest.getPrimary().getDB("db1")["aCollection"].insert(
- {a: "afterSecondNodeAdded"}, {writeConcern: {w: 2, wtimeout: 60 * 1000}}));
- return true;
- });
-
- rstest.getPrimary().getDB("db1").createRole({
- role: "r3",
- roles: ["r1", "r2"],
- privileges: [{resource: {db: "db1", collection: "log"}, actions: ["update"]}]
- },
- {w: 2});
-
- // Verify that both members of the set see the same role graph.
- rstest.nodes.forEach(function(node) {
- var role = node.getDB("db1").getRole("r3");
- assert.eq(2, role.roles.length, tojson(node));
- assertListContainsRole(role.roles, {role: "r1", db: "db1"}, node);
- assertListContainsRole(role.roles, {role: "r2", db: "db1"}, node);
- assert.eq(3, role.inheritedRoles.length, tojson(node));
- assertListContainsRole(role.inheritedRoles, {role: "r1", db: "db1"}, node);
- assertListContainsRole(role.inheritedRoles, {role: "r2", db: "db1"}, node);
- assertListContainsRole(role.inheritedRoles, {role: "read", db: "db1"}, node);
- });
-
- // Verify that updating roles propagates.
- rstest.getPrimary().getDB("db1").revokeRolesFromRole("r1", ["read"], {w: 2});
- rstest.getPrimary().getDB("db1").grantRolesToRole("r1", ["dbAdmin"], {w: 2});
- rstest.nodes.forEach(function(node) {
- var role = node.getDB("db1").getRole("r1");
- assert.eq(1, role.roles.length, tojson(node));
- assertListContainsRole(role.roles, {role: "dbAdmin", db: "db1"});
- });
-
- // Verify that dropping roles propagates.
- rstest.getPrimary().getDB("db1").dropRole("r2", {w: 2});
- rstest.nodes.forEach(function(node) {
- assert.eq(null, node.getDB("db1").getRole("r2"));
- var role = node.getDB("db1").getRole("r3");
- assert.eq(1, role.roles.length, tojson(node));
- assertListContainsRole(role.roles, {role: "r1", db: "db1"}, node);
- assert.eq(2, role.inheritedRoles.length, tojson(node));
- assertListContainsRole(role.inheritedRoles, {role: "r1", db: "db1"}, node);
- assertListContainsRole(role.inheritedRoles, {role: "dbAdmin", db: "db1"}, node);
- });
-
- // Verify that applyOps commands propagate.
- // NOTE: This section of the test depends on the oplog and roles schemas.
- assert.commandWorked(rstest.getPrimary().getDB("admin").runCommand({
- applyOps: [
- {op: "c", ns: "admin.$cmd", o: {create: "system.roles"}},
- {
- op: "i",
- ns: "admin.system.roles",
- o: {
- _id: "db1.s1",
- role: "s1",
- db: "db1",
- roles: [{role: "read", db: "db1"}],
- privileges:
- [{resource: {db: "db1", collection: "system.users"}, actions: ["find"]}]
- }
- },
- {
- op: "i",
- ns: "admin.system.roles",
- o: {
- _id: "db1.s2",
- role: "s2",
- db: "db1",
- roles: [{role: "read", db: "db1"}],
- privileges: [{resource: {db: "db1", collection: "log"}, actions: ["insert"]}]
- }
- },
- {op: "c", ns: "admin.$cmd", o: {drop: "system.roles"}},
- {op: "c", ns: "admin.$cmd", o: {create: "system.roles"}},
- {
- op: "i",
- ns: "admin.system.roles",
- o: {
- _id: "db1.t1",
- role: "t1",
- db: "db1",
- roles: [{role: "read", db: "db1"}],
- privileges:
- [{resource: {db: "db1", collection: "system.users"}, actions: ["find"]}]
- }
- },
- {
- op: "i",
- ns: "admin.system.roles",
- o: {
- _id: "db1.t2",
- role: "t2",
- db: "db1",
- roles: [],
- privileges: [{resource: {db: "db1", collection: "log"}, actions: ["insert"]}]
- }
- },
- {
- op: "i",
- ns: "admin.system.roles",
- o: {
- _id: "db1.t3",
- role: "t3",
- db: "db1",
- roles: [{role: "t1", db: "db1"}, {role: "t2", db: "db1"}],
- privileges: []
- }
- },
- {
- op: "u",
- ns: "admin.system.roles",
- o: {$set: {roles: [{role: "readWrite", db: "db1"}]}},
- o2: {_id: "db1.t2"}
+ doassert("Could not find value " + tojson(val) + " in " + tojson(list) +
+ (msg ? ": " + msg : ""));
+}
+
+//
+// Create a 1-node replicaset and add two roles, inheriting the built-in read role on db1.
+//
+// read
+// / \
+// r1 r2
+//
+var rstest = new ReplSetTest({name: name, nodes: 1, nodeOptions: {}});
+
+rstest.startSet();
+rstest.initiate();
+
+m0 = rstest.nodes[0];
+
+m0.getDB("db1").createRole({
+ role: "r1",
+ roles: ["read"],
+ privileges: [{resource: {db: "db1", collection: "system.users"}, actions: ["find"]}]
+});
+
+m0.getDB("db1").createRole({
+ role: "r2",
+ roles: ["read"],
+ privileges: [{resource: {db: "db1", collection: "log"}, actions: ["insert"]}]
+});
+
+//
+// Add a second node to the set, and add a third role, dependent on the first two.
+//
+// read
+// / \
+// r1 r2
+// \ /
+// r3
+//
+rstest.add();
+rstest.reInitiate();
+
+// This write will have to wait on the initial sync to complete before progressing.
+assert.soonNoExcept(() => {
+ assert.writeOK(rstest.getPrimary().getDB("db1")["aCollection"].insert(
+ {a: "afterSecondNodeAdded"}, {writeConcern: {w: 2, wtimeout: 60 * 1000}}));
+ return true;
+});
+
+rstest.getPrimary().getDB("db1").createRole({
+ role: "r3",
+ roles: ["r1", "r2"],
+ privileges: [{resource: {db: "db1", collection: "log"}, actions: ["update"]}]
+},
+ {w: 2});
+
+// Verify that both members of the set see the same role graph.
+rstest.nodes.forEach(function(node) {
+ var role = node.getDB("db1").getRole("r3");
+ assert.eq(2, role.roles.length, tojson(node));
+ assertListContainsRole(role.roles, {role: "r1", db: "db1"}, node);
+ assertListContainsRole(role.roles, {role: "r2", db: "db1"}, node);
+ assert.eq(3, role.inheritedRoles.length, tojson(node));
+ assertListContainsRole(role.inheritedRoles, {role: "r1", db: "db1"}, node);
+ assertListContainsRole(role.inheritedRoles, {role: "r2", db: "db1"}, node);
+ assertListContainsRole(role.inheritedRoles, {role: "read", db: "db1"}, node);
+});
+
+// Verify that updating roles propagates.
+rstest.getPrimary().getDB("db1").revokeRolesFromRole("r1", ["read"], {w: 2});
+rstest.getPrimary().getDB("db1").grantRolesToRole("r1", ["dbAdmin"], {w: 2});
+rstest.nodes.forEach(function(node) {
+ var role = node.getDB("db1").getRole("r1");
+ assert.eq(1, role.roles.length, tojson(node));
+ assertListContainsRole(role.roles, {role: "dbAdmin", db: "db1"});
+});
+
+// Verify that dropping roles propagates.
+rstest.getPrimary().getDB("db1").dropRole("r2", {w: 2});
+rstest.nodes.forEach(function(node) {
+ assert.eq(null, node.getDB("db1").getRole("r2"));
+ var role = node.getDB("db1").getRole("r3");
+ assert.eq(1, role.roles.length, tojson(node));
+ assertListContainsRole(role.roles, {role: "r1", db: "db1"}, node);
+ assert.eq(2, role.inheritedRoles.length, tojson(node));
+ assertListContainsRole(role.inheritedRoles, {role: "r1", db: "db1"}, node);
+ assertListContainsRole(role.inheritedRoles, {role: "dbAdmin", db: "db1"}, node);
+});
+
+// Verify that applyOps commands propagate.
+// NOTE: This section of the test depends on the oplog and roles schemas.
+assert.commandWorked(rstest.getPrimary().getDB("admin").runCommand({
+ applyOps: [
+ {op: "c", ns: "admin.$cmd", o: {create: "system.roles"}},
+ {
+ op: "i",
+ ns: "admin.system.roles",
+ o: {
+ _id: "db1.s1",
+ role: "s1",
+ db: "db1",
+ roles: [{role: "read", db: "db1"}],
+ privileges: [{resource: {db: "db1", collection: "system.users"}, actions: ["find"]}]
+ }
+ },
+ {
+ op: "i",
+ ns: "admin.system.roles",
+ o: {
+ _id: "db1.s2",
+ role: "s2",
+ db: "db1",
+ roles: [{role: "read", db: "db1"}],
+ privileges: [{resource: {db: "db1", collection: "log"}, actions: ["insert"]}]
+ }
+ },
+ {op: "c", ns: "admin.$cmd", o: {drop: "system.roles"}},
+ {op: "c", ns: "admin.$cmd", o: {create: "system.roles"}},
+ {
+ op: "i",
+ ns: "admin.system.roles",
+ o: {
+ _id: "db1.t1",
+ role: "t1",
+ db: "db1",
+ roles: [{role: "read", db: "db1"}],
+ privileges: [{resource: {db: "db1", collection: "system.users"}, actions: ["find"]}]
}
- ]
- }));
-
- assert.commandWorked(rstest.getPrimary().getDB("admin").getLastErrorObj(2));
- rstest.nodes.forEach(function(node) {
- var role = node.getDB("db1").getRole("t1");
- assert.eq(1, role.roles.length, tojson(node));
- assertListContainsRole(role.roles, {role: "read", db: "db1"}, node);
-
- var role = node.getDB("db1").getRole("t2");
- assert.eq(1, role.roles.length, tojson(node));
- assertListContainsRole(role.roles, {role: "readWrite", db: "db1"}, node);
- });
-
- // Verify that irrelevant index creation doesn't impair graph resolution
- assert.commandWorked(rstest.getPrimary().getDB("admin").col.save({data: 5}));
- assert.commandWorked(rstest.getPrimary().getDB("admin").runCommand(
- {createIndexes: "col", indexes: [{key: {data: 1}, name: "testIndex"}]}));
- rstest.awaitReplication();
- rstest.nodes.forEach(function(node) {
- var role = node.getDB("db1").getRole("t3");
- assert.eq(4, role.inheritedRoles.length, tojson(node));
- });
-
- rstest.stopSet();
+ },
+ {
+ op: "i",
+ ns: "admin.system.roles",
+ o: {
+ _id: "db1.t2",
+ role: "t2",
+ db: "db1",
+ roles: [],
+ privileges: [{resource: {db: "db1", collection: "log"}, actions: ["insert"]}]
+ }
+ },
+ {
+ op: "i",
+ ns: "admin.system.roles",
+ o: {
+ _id: "db1.t3",
+ role: "t3",
+ db: "db1",
+ roles: [{role: "t1", db: "db1"}, {role: "t2", db: "db1"}],
+ privileges: []
+ }
+ },
+ {
+ op: "u",
+ ns: "admin.system.roles",
+ o: {$set: {roles: [{role: "readWrite", db: "db1"}]}},
+ o2: {_id: "db1.t2"}
+ }
+ ]
+}));
+
+assert.commandWorked(rstest.getPrimary().getDB("admin").getLastErrorObj(2));
+rstest.nodes.forEach(function(node) {
+ var role = node.getDB("db1").getRole("t1");
+ assert.eq(1, role.roles.length, tojson(node));
+ assertListContainsRole(role.roles, {role: "read", db: "db1"}, node);
+
+ var role = node.getDB("db1").getRole("t2");
+ assert.eq(1, role.roles.length, tojson(node));
+ assertListContainsRole(role.roles, {role: "readWrite", db: "db1"}, node);
+});
+
+// Verify that irrelevant index creation doesn't impair graph resolution
+assert.commandWorked(rstest.getPrimary().getDB("admin").col.save({data: 5}));
+assert.commandWorked(rstest.getPrimary().getDB("admin").runCommand(
+ {createIndexes: "col", indexes: [{key: {data: 1}, name: "testIndex"}]}));
+rstest.awaitReplication();
+rstest.nodes.forEach(function(node) {
+ var role = node.getDB("db1").getRole("t3");
+ assert.eq(4, role.inheritedRoles.length, tojson(node));
+});
+
+rstest.stopSet();
}());
diff --git a/jstests/auth/user_management_commands_edge_cases.js b/jstests/auth/user_management_commands_edge_cases.js
index f8447ddd7c8..d197d0105b2 100644
--- a/jstests/auth/user_management_commands_edge_cases.js
+++ b/jstests/auth/user_management_commands_edge_cases.js
@@ -257,7 +257,6 @@ function runTest(conn) {
assert.throws(function() {
db.getUser(['user1']);
});
-
})();
(function testDropUser() {
diff --git a/jstests/auth/user_management_commands_lib.js b/jstests/auth/user_management_commands_lib.js
index f05987c2b1d..3bea79ab955 100644
--- a/jstests/auth/user_management_commands_lib.js
+++ b/jstests/auth/user_management_commands_lib.js
@@ -118,11 +118,11 @@ function runAllUserManagementCommandsTests(conn, writeConcern) {
testUserAdmin.grantRolesToUser('spencer',
[
- 'readWrite',
- 'dbAdmin',
- {role: 'readWrite', db: 'test'},
- {role: 'testRole', db: 'test'},
- 'readWrite'
+ 'readWrite',
+ 'dbAdmin',
+ {role: 'readWrite', db: 'test'},
+ {role: 'testRole', db: 'test'},
+ 'readWrite'
],
writeConcern);
@@ -142,9 +142,9 @@ function runAllUserManagementCommandsTests(conn, writeConcern) {
testUserAdmin.revokeRolesFromUser(
'spencer',
[
- 'readWrite',
- {role: 'dbAdmin', db: 'test2'}, // role user doesnt have
- "testRole"
+ 'readWrite',
+ {role: 'dbAdmin', db: 'test2'}, // role user doesnt have
+ "testRole"
],
writeConcern);
@@ -169,7 +169,6 @@ function runAllUserManagementCommandsTests(conn, writeConcern) {
db.getRole('testRole');
});
assert.commandFailedWithCode(db.adminCommand('connPoolSync'), ErrorCodes.Unauthorized);
-
})();
(function testUsersInfo() {
diff --git a/jstests/auth/user_management_commands_mechanisms.js b/jstests/auth/user_management_commands_mechanisms.js
index f0d8a2dbd12..98c806f194b 100644
--- a/jstests/auth/user_management_commands_mechanisms.js
+++ b/jstests/auth/user_management_commands_mechanisms.js
@@ -2,227 +2,215 @@
// @tags: [requires_persistence]
(function() {
- 'use strict';
-
- let mongod = MongoRunner.runMongod(
- {auth: "", setParameter: "authenticationMechanisms=SCRAM-SHA-1,SCRAM-SHA-256,PLAIN"});
- assert(mongod);
- const admin = mongod.getDB('admin');
- const test = mongod.getDB('test');
-
- function checkUser(userid, passwd, haveSCRAMSHA1, haveSCRAMSHA256) {
- function checkCredentialRecord(creds, hashLen, saltLen, itCount) {
- assert.eq(creds.iterationCount, itCount);
- assert.eq(creds.salt.length, saltLen);
- assert.eq(creds.storedKey.length, hashLen);
- assert.eq(creds.serverKey.length, hashLen);
- }
- function checkLogin(mech, digestOK, nodigestOK) {
- assert(test.auth({user: userid, pwd: passwd, mechanism: mech}));
+'use strict';
+
+let mongod = MongoRunner.runMongod(
+ {auth: "", setParameter: "authenticationMechanisms=SCRAM-SHA-1,SCRAM-SHA-256,PLAIN"});
+assert(mongod);
+const admin = mongod.getDB('admin');
+const test = mongod.getDB('test');
+
+function checkUser(userid, passwd, haveSCRAMSHA1, haveSCRAMSHA256) {
+ function checkCredentialRecord(creds, hashLen, saltLen, itCount) {
+ assert.eq(creds.iterationCount, itCount);
+ assert.eq(creds.salt.length, saltLen);
+ assert.eq(creds.storedKey.length, hashLen);
+ assert.eq(creds.serverKey.length, hashLen);
+ }
+ function checkLogin(mech, digestOK, nodigestOK) {
+ assert(test.auth({user: userid, pwd: passwd, mechanism: mech}));
+ test.logout();
+ assert.eq(digestOK,
+ test.auth({user: userid, pwd: passwd, mechanism: mech, digestPassword: true}));
+ if (digestOK) {
test.logout();
- assert.eq(
- digestOK,
- test.auth({user: userid, pwd: passwd, mechanism: mech, digestPassword: true}));
- if (digestOK) {
- test.logout();
- }
- assert.eq(
- nodigestOK,
- test.auth({user: userid, pwd: passwd, mechanism: mech, digestPassword: false}));
- if (nodigestOK) {
- test.logout();
- }
}
-
- const user = admin.system.users.findOne({_id: ('test.' + userid)});
- assert.eq(user.credentials.hasOwnProperty('SCRAM-SHA-1'), haveSCRAMSHA1);
- assert.eq(user.credentials.hasOwnProperty('SCRAM-SHA-256'), haveSCRAMSHA256);
-
- // usersInfo contains correct mechanisms for the user
- const userInfo = assert.commandWorked(test.runCommand({usersInfo: userid}));
- assert(Array.isArray(userInfo.users[0].mechanisms));
- assert.eq(userInfo.users[0].mechanisms.includes('SCRAM-SHA-1'), haveSCRAMSHA1);
- assert.eq(userInfo.users[0].mechanisms.includes('SCRAM-SHA-256'), haveSCRAMSHA256);
-
- // usersInfo with showCredentials shows correct mechanisms and credentials
- const userInfoWithCredentials =
- assert.commandWorked(test.runCommand({usersInfo: userid, showCredentials: true}));
- print(tojson(userInfoWithCredentials));
- assert.eq(userInfoWithCredentials.users[0].credentials.hasOwnProperty('SCRAM-SHA-1'),
- haveSCRAMSHA1);
- assert.eq(userInfoWithCredentials.users[0].credentials.hasOwnProperty('SCRAM-SHA-256'),
- haveSCRAMSHA256);
- assert(Array.isArray(userInfoWithCredentials.users[0].mechanisms));
- assert.eq(userInfoWithCredentials.users[0].mechanisms.includes('SCRAM-SHA-1'),
- haveSCRAMSHA1);
- assert.eq(userInfoWithCredentials.users[0].mechanisms.includes('SCRAM-SHA-256'),
- haveSCRAMSHA256);
-
- if (haveSCRAMSHA1) {
- checkCredentialRecord(user.credentials['SCRAM-SHA-1'], 28, 24, 10000);
- checkLogin('SCRAM-SHA-1', true, false);
- checkLogin('PLAIN', false, true);
- }
- if (haveSCRAMSHA256) {
- checkCredentialRecord(user.credentials['SCRAM-SHA-256'], 44, 40, 15000);
- checkLogin('SCRAM-SHA-256', false, true);
- checkLogin('PLAIN', false, true);
+ assert.eq(nodigestOK,
+ test.auth({user: userid, pwd: passwd, mechanism: mech, digestPassword: false}));
+ if (nodigestOK) {
+ test.logout();
}
}
- admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
- assert(admin.auth('admin', 'pass'));
-
- // Unknown mechanism.
- assert.throws(function() {
- test.createUser({
- user: 'shalala',
- pwd: 'pass',
- roles: jsTest.basicUserRoles,
- mechanisms: ['SCRAM-SHA-1', 'SCRAM-SHA-LA-LA'],
- });
- });
-
- // By default, users are created with both SCRAM variants.
- test.createUser({user: 'user', pwd: 'pass', roles: jsTest.basicUserRoles});
- checkUser('user', 'pass', true, true);
+ const user = admin.system.users.findOne({_id: ('test.' + userid)});
+ assert.eq(user.credentials.hasOwnProperty('SCRAM-SHA-1'), haveSCRAMSHA1);
+ assert.eq(user.credentials.hasOwnProperty('SCRAM-SHA-256'), haveSCRAMSHA256);
+
+ // usersInfo contains correct mechanisms for the user
+ const userInfo = assert.commandWorked(test.runCommand({usersInfo: userid}));
+ assert(Array.isArray(userInfo.users[0].mechanisms));
+ assert.eq(userInfo.users[0].mechanisms.includes('SCRAM-SHA-1'), haveSCRAMSHA1);
+ assert.eq(userInfo.users[0].mechanisms.includes('SCRAM-SHA-256'), haveSCRAMSHA256);
+
+ // usersInfo with showCredentials shows correct mechanisms and credentials
+ const userInfoWithCredentials =
+ assert.commandWorked(test.runCommand({usersInfo: userid, showCredentials: true}));
+ print(tojson(userInfoWithCredentials));
+ assert.eq(userInfoWithCredentials.users[0].credentials.hasOwnProperty('SCRAM-SHA-1'),
+ haveSCRAMSHA1);
+ assert.eq(userInfoWithCredentials.users[0].credentials.hasOwnProperty('SCRAM-SHA-256'),
+ haveSCRAMSHA256);
+ assert(Array.isArray(userInfoWithCredentials.users[0].mechanisms));
+ assert.eq(userInfoWithCredentials.users[0].mechanisms.includes('SCRAM-SHA-1'), haveSCRAMSHA1);
+ assert.eq(userInfoWithCredentials.users[0].mechanisms.includes('SCRAM-SHA-256'),
+ haveSCRAMSHA256);
+
+ if (haveSCRAMSHA1) {
+ checkCredentialRecord(user.credentials['SCRAM-SHA-1'], 28, 24, 10000);
+ checkLogin('SCRAM-SHA-1', true, false);
+ checkLogin('PLAIN', false, true);
+ }
+ if (haveSCRAMSHA256) {
+ checkCredentialRecord(user.credentials['SCRAM-SHA-256'], 44, 40, 15000);
+ checkLogin('SCRAM-SHA-256', false, true);
+ checkLogin('PLAIN', false, true);
+ }
+}
- // Request SHA1 only.
- test.createUser(
- {user: 'sha1user', pwd: 'pass', roles: jsTest.basicUserRoles, mechanisms: ['SCRAM-SHA-1']});
- checkUser('sha1user', 'pass', true, false);
+admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
+assert(admin.auth('admin', 'pass'));
- // Request SHA256 only.
+// Unknown mechanism.
+assert.throws(function() {
test.createUser({
- user: 'sha256user',
+ user: 'shalala',
pwd: 'pass',
roles: jsTest.basicUserRoles,
- mechanisms: ['SCRAM-SHA-256']
+ mechanisms: ['SCRAM-SHA-1', 'SCRAM-SHA-LA-LA'],
});
- checkUser('sha256user', 'pass', false, true);
+});
- // Fail passing an empty mechanisms field.
- assert.throws(function() {
- test.createUser(
- {user: 'userNoMech', pwd: 'pass', roles: jsTest.basicUserRoles, mechanisms: []});
- });
+// By default, users are created with both SCRAM variants.
+test.createUser({user: 'user', pwd: 'pass', roles: jsTest.basicUserRoles});
+checkUser('user', 'pass', true, true);
- // Repeat above, but request client-side digesting.
- // Only the SCRAM-SHA-1 exclusive version should succeed.
+// Request SHA1 only.
+test.createUser(
+ {user: 'sha1user', pwd: 'pass', roles: jsTest.basicUserRoles, mechanisms: ['SCRAM-SHA-1']});
+checkUser('sha1user', 'pass', true, false);
- assert.throws(function() {
- test.createUser({
- user: 'user2',
- pwd: 'pass',
- roles: jsTest.basicUserRoles,
- passwordDisgestor: 'client'
- });
- });
+// Request SHA256 only.
+test.createUser(
+ {user: 'sha256user', pwd: 'pass', roles: jsTest.basicUserRoles, mechanisms: ['SCRAM-SHA-256']});
+checkUser('sha256user', 'pass', false, true);
+
+// Fail passing an empty mechanisms field.
+assert.throws(function() {
+ test.createUser(
+ {user: 'userNoMech', pwd: 'pass', roles: jsTest.basicUserRoles, mechanisms: []});
+});
+
+// Repeat above, but request client-side digesting.
+// Only the SCRAM-SHA-1 exclusive version should succeed.
+assert.throws(function() {
+ test.createUser(
+ {user: 'user2', pwd: 'pass', roles: jsTest.basicUserRoles, passwordDisgestor: 'client'});
+});
+
+test.createUser({
+ user: 'sha1user2',
+ pwd: 'pass',
+ roles: jsTest.basicUserRoles,
+ mechanisms: ['SCRAM-SHA-1'],
+ passwordDigestor: 'client'
+});
+checkUser('sha1user2', 'pass', true, false);
+
+assert.throws(function() {
test.createUser({
- user: 'sha1user2',
+ user: 'sha256user2',
pwd: 'pass',
roles: jsTest.basicUserRoles,
- mechanisms: ['SCRAM-SHA-1'],
+ mechanisms: ['SCRAM-SHA-256'],
passwordDigestor: 'client'
});
- checkUser('sha1user2', 'pass', true, false);
-
- assert.throws(function() {
- test.createUser({
- user: 'sha256user2',
- pwd: 'pass',
- roles: jsTest.basicUserRoles,
- mechanisms: ['SCRAM-SHA-256'],
- passwordDigestor: 'client'
- });
- });
-
- // Update original 1/256 user to just sha-1.
- test.updateUser('user', {pwd: 'pass1', mechanisms: ['SCRAM-SHA-1']});
- checkUser('user', 'pass1', true, false);
-
- // Then flip to 256-only
- test.updateUser('user', {pwd: 'pass256', mechanisms: ['SCRAM-SHA-256']});
- checkUser('user', 'pass256', false, true);
-
- // And back to (default) all.
- test.updateUser('user', {pwd: 'passAll'});
- checkUser('user', 'passAll', true, true);
-
- // Trim out mechanisms without changing password.
- test.updateUser('user', {mechanisms: ['SCRAM-SHA-256']});
- checkUser('user', 'passAll', false, true);
-
- // Fail when mechanisms is not a subset of the current user.
- assert.throws(function() {
- test.updateUser('user', {mechanisms: ['SCRAM-SHA-1']});
- });
-
- // Fail when passing an empty mechanisms field.
- assert.throws(function() {
- test.updateUser('user', {pwd: 'passEmpty', mechanisms: []});
- });
-
- // Succeed if we're using SHA-1 only.
- test.createUser(
- {user: "\u2168", pwd: 'pass', roles: jsTest.basicUserRoles, mechanisms: ['SCRAM-SHA-1']});
- checkUser("\u2168", 'pass', true, false);
-
- // Demonstrate that usersInfo returns all users with mechanisms lists
- const allUsersInfo = assert.commandWorked(test.runCommand({usersInfo: 1}));
- allUsersInfo.users.forEach(function(userObj) {
- assert(Array.isArray(userObj.mechanisms));
- });
-
- // Demonstrate that usersInfo can return all users with credentials
- const allUsersInfoWithCredentials =
- assert.commandWorked(test.runCommand({usersInfo: 1, showCredentials: true}));
- allUsersInfoWithCredentials.users.forEach(function(userObj) {
- assert(userObj.credentials !== undefined);
- assert(!Array.isArray(userObj.credentials));
- assert(userObj.mechanisms !== undefined);
- assert(Array.isArray(userObj.mechanisms));
- });
-
- // Demonstrate that usersInfo can find SCRAM-SHA-1 users
- const allSCRAMSHA1UsersInfo =
- assert.commandWorked(test.runCommand({usersInfo: 1, filter: {mechanisms: "SCRAM-SHA-1"}}));
- let foundUsers = [];
- allSCRAMSHA1UsersInfo.users.forEach(function(userObj) {
- foundUsers.push(userObj.user);
- });
- assert.eq(["sha1user", "sha1user2", "\u2168"], foundUsers);
-
- // Demonstrate that usersInfo can find SCRAM-SHA-256 users
- const allSCRAMSHA256UsersInfo = assert.commandWorked(
- test.runCommand({usersInfo: 1, filter: {mechanisms: "SCRAM-SHA-256"}}));
- foundUsers = [];
- allSCRAMSHA256UsersInfo.users.forEach(function(userObj) {
- foundUsers.push(userObj.user);
- });
- assert.eq(["sha256user", "user"], foundUsers);
-
- MongoRunner.stopMongod(mongod);
-
- // Ensure mechanisms can be enabled and disabled.
- mongod = MongoRunner.runMongod({
- auth: "",
- setParameter: "authenticationMechanisms=SCRAM-SHA-1",
- restart: mongod,
- noCleanData: true
- });
- assert(mongod.getDB("test").auth("sha1user", "pass"));
- assert(!mongod.getDB("test").auth("sha256user", "pass"));
- MongoRunner.stopMongod(mongod);
- mongod = MongoRunner.runMongod({
- auth: "",
- setParameter: "authenticationMechanisms=SCRAM-SHA-256",
- restart: mongod,
- noCleanData: true
- });
- assert(!mongod.getDB("test").auth("sha1user", "pass"));
- assert(mongod.getDB("test").auth("sha256user", "pass"));
- MongoRunner.stopMongod(mongod);
-
+});
+
+// Update original 1/256 user to just sha-1.
+test.updateUser('user', {pwd: 'pass1', mechanisms: ['SCRAM-SHA-1']});
+checkUser('user', 'pass1', true, false);
+
+// Then flip to 256-only
+test.updateUser('user', {pwd: 'pass256', mechanisms: ['SCRAM-SHA-256']});
+checkUser('user', 'pass256', false, true);
+
+// And back to (default) all.
+test.updateUser('user', {pwd: 'passAll'});
+checkUser('user', 'passAll', true, true);
+
+// Trim out mechanisms without changing password.
+test.updateUser('user', {mechanisms: ['SCRAM-SHA-256']});
+checkUser('user', 'passAll', false, true);
+
+// Fail when mechanisms is not a subset of the current user.
+assert.throws(function() {
+ test.updateUser('user', {mechanisms: ['SCRAM-SHA-1']});
+});
+
+// Fail when passing an empty mechanisms field.
+assert.throws(function() {
+ test.updateUser('user', {pwd: 'passEmpty', mechanisms: []});
+});
+
+// Succeed if we're using SHA-1 only.
+test.createUser(
+ {user: "\u2168", pwd: 'pass', roles: jsTest.basicUserRoles, mechanisms: ['SCRAM-SHA-1']});
+checkUser("\u2168", 'pass', true, false);
+
+// Demonstrate that usersInfo returns all users with mechanisms lists
+const allUsersInfo = assert.commandWorked(test.runCommand({usersInfo: 1}));
+allUsersInfo.users.forEach(function(userObj) {
+ assert(Array.isArray(userObj.mechanisms));
+});
+
+// Demonstrate that usersInfo can return all users with credentials
+const allUsersInfoWithCredentials =
+ assert.commandWorked(test.runCommand({usersInfo: 1, showCredentials: true}));
+allUsersInfoWithCredentials.users.forEach(function(userObj) {
+ assert(userObj.credentials !== undefined);
+ assert(!Array.isArray(userObj.credentials));
+ assert(userObj.mechanisms !== undefined);
+ assert(Array.isArray(userObj.mechanisms));
+});
+
+// Demonstrate that usersInfo can find SCRAM-SHA-1 users
+const allSCRAMSHA1UsersInfo =
+ assert.commandWorked(test.runCommand({usersInfo: 1, filter: {mechanisms: "SCRAM-SHA-1"}}));
+let foundUsers = [];
+allSCRAMSHA1UsersInfo.users.forEach(function(userObj) {
+ foundUsers.push(userObj.user);
+});
+assert.eq(["sha1user", "sha1user2", "\u2168"], foundUsers);
+
+// Demonstrate that usersInfo can find SCRAM-SHA-256 users
+const allSCRAMSHA256UsersInfo =
+ assert.commandWorked(test.runCommand({usersInfo: 1, filter: {mechanisms: "SCRAM-SHA-256"}}));
+foundUsers = [];
+allSCRAMSHA256UsersInfo.users.forEach(function(userObj) {
+ foundUsers.push(userObj.user);
+});
+assert.eq(["sha256user", "user"], foundUsers);
+
+MongoRunner.stopMongod(mongod);
+
+// Ensure mechanisms can be enabled and disabled.
+mongod = MongoRunner.runMongod({
+ auth: "",
+ setParameter: "authenticationMechanisms=SCRAM-SHA-1",
+ restart: mongod,
+ noCleanData: true
+});
+assert(mongod.getDB("test").auth("sha1user", "pass"));
+assert(!mongod.getDB("test").auth("sha256user", "pass"));
+MongoRunner.stopMongod(mongod);
+mongod = MongoRunner.runMongod({
+ auth: "",
+ setParameter: "authenticationMechanisms=SCRAM-SHA-256",
+ restart: mongod,
+ noCleanData: true
+});
+assert(!mongod.getDB("test").auth("sha1user", "pass"));
+assert(mongod.getDB("test").auth("sha256user", "pass"));
+MongoRunner.stopMongod(mongod);
})();
diff --git a/jstests/auth/user_management_commands_sharded_wc_1.js b/jstests/auth/user_management_commands_sharded_wc_1.js
index f5dd2222636..675efba731a 100644
--- a/jstests/auth/user_management_commands_sharded_wc_1.js
+++ b/jstests/auth/user_management_commands_sharded_wc_1.js
@@ -3,13 +3,13 @@
*/
(function() {
- 'use strict';
+'use strict';
- load('jstests/auth/user_management_commands_lib.js');
+load('jstests/auth/user_management_commands_lib.js');
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- var st = new ShardingTest(
- {shards: 2, config: 3, keyFile: 'jstests/libs/key1', other: {shardAsReplicaSet: false}});
- runAllUserManagementCommandsTests(st.s, {w: 1});
- st.stop();
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+var st = new ShardingTest(
+ {shards: 2, config: 3, keyFile: 'jstests/libs/key1', other: {shardAsReplicaSet: false}});
+runAllUserManagementCommandsTests(st.s, {w: 1});
+st.stop();
})();
diff --git a/jstests/auth/user_management_commands_sharded_wc_majority.js b/jstests/auth/user_management_commands_sharded_wc_majority.js
index e06f4b578c0..d9e0a75d543 100644
--- a/jstests/auth/user_management_commands_sharded_wc_majority.js
+++ b/jstests/auth/user_management_commands_sharded_wc_majority.js
@@ -1,13 +1,13 @@
// @tags: [requires_sharding]
(function() {
- 'use strict';
+'use strict';
- load('jstests/auth/user_management_commands_lib.js');
+load('jstests/auth/user_management_commands_lib.js');
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- var st = new ShardingTest(
- {shards: 2, config: 3, keyFile: 'jstests/libs/key1', other: {shardAsReplicaSet: false}});
- runAllUserManagementCommandsTests(st.s, {w: 'majority', wtimeout: 60 * 1000});
- st.stop();
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+var st = new ShardingTest(
+ {shards: 2, config: 3, keyFile: 'jstests/libs/key1', other: {shardAsReplicaSet: false}});
+runAllUserManagementCommandsTests(st.s, {w: 'majority', wtimeout: 60 * 1000});
+st.stop();
})();
diff --git a/jstests/auth/user_management_commands_standalone.js b/jstests/auth/user_management_commands_standalone.js
index 192f5968aa2..4f55c3dda81 100644
--- a/jstests/auth/user_management_commands_standalone.js
+++ b/jstests/auth/user_management_commands_standalone.js
@@ -1,9 +1,9 @@
(function() {
- 'use strict';
+'use strict';
- load('jstests/auth/user_management_commands_lib.js');
+load('jstests/auth/user_management_commands_lib.js');
- var conn = MongoRunner.runMongod({auth: '', useHostname: false});
- runAllUserManagementCommandsTests(conn);
- MongoRunner.stopMongod(conn);
+var conn = MongoRunner.runMongod({auth: '', useHostname: false});
+runAllUserManagementCommandsTests(conn);
+MongoRunner.stopMongod(conn);
})();
diff --git a/jstests/auth/user_special_chars.js b/jstests/auth/user_special_chars.js
index fc968bc30b7..85ef75b48af 100644
--- a/jstests/auth/user_special_chars.js
+++ b/jstests/auth/user_special_chars.js
@@ -2,66 +2,65 @@
// Test creating and authenticating users with special characters.
(function() {
- var conn = MongoRunner.runMongod({auth: ''});
+var conn = MongoRunner.runMongod({auth: ''});
- var adminDB = conn.getDB('admin');
- adminDB.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
+var adminDB = conn.getDB('admin');
+adminDB.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
- var testUserSpecialCharacters = function() {
+var testUserSpecialCharacters = function() {
+ // Create a user with special characters, make sure it can auth.
+ assert(adminDB.auth('admin', 'pass'));
+ adminDB.createUser(
+ {user: '~`!@#$%^&*()-_+={}[]||;:",.//><', pwd: 'pass', roles: jsTest.adminUserRoles});
+ assert(adminDB.logout());
- // Create a user with special characters, make sure it can auth.
- assert(adminDB.auth('admin', 'pass'));
- adminDB.createUser(
- {user: '~`!@#$%^&*()-_+={}[]||;:",.//><', pwd: 'pass', roles: jsTest.adminUserRoles});
- assert(adminDB.logout());
+ assert(adminDB.auth({user: '~`!@#$%^&*()-_+={}[]||;:",.//><', pwd: 'pass'}));
+ assert(adminDB.logout());
+};
+testUserSpecialCharacters();
- assert(adminDB.auth({user: '~`!@#$%^&*()-_+={}[]||;:",.//><', pwd: 'pass'}));
- assert(adminDB.logout());
- };
- testUserSpecialCharacters();
+var testUserAndDatabaseAtSymbolConflation = function() {
+ // Create a pair of users and databases such that their string representations are
+ // identical.
+ assert(adminDB.auth('admin', 'pass'));
- var testUserAndDatabaseAtSymbolConflation = function() {
- // Create a pair of users and databases such that their string representations are
- // identical.
- assert(adminDB.auth('admin', 'pass'));
+ var bcDB = conn.getDB('b@c');
+ bcDB.createUser({user: 'a', pwd: 'pass2', roles: [{role: 'readWrite', db: 'b@c'}]});
- var bcDB = conn.getDB('b@c');
- bcDB.createUser({user: 'a', pwd: 'pass2', roles: [{role: 'readWrite', db: 'b@c'}]});
+ var cDB = conn.getDB('c');
+ cDB.createUser({user: 'a@b', pwd: 'pass1', roles: [{role: 'readWrite', db: 'c'}]});
- var cDB = conn.getDB('c');
- cDB.createUser({user: 'a@b', pwd: 'pass1', roles: [{role: 'readWrite', db: 'c'}]});
+ assert(adminDB.logout());
- assert(adminDB.logout());
+ // Ensure they cannot authenticate to the wrong database.
+ assert(!bcDB.auth('a@b', 'pass1'));
+ assert(!bcDB.auth('a@b', 'pass2'));
+ assert(!cDB.auth('a', 'pass1'));
+ assert(!cDB.auth('a', 'pass2'));
- // Ensure they cannot authenticate to the wrong database.
- assert(!bcDB.auth('a@b', 'pass1'));
- assert(!bcDB.auth('a@b', 'pass2'));
- assert(!cDB.auth('a', 'pass1'));
- assert(!cDB.auth('a', 'pass2'));
+ // Ensure that they can both successfully authenticate to their correct database.
+ assert(cDB.auth('a@b', 'pass1'));
+ assert.writeOK(cDB.col.insert({data: 1}));
+ assert.writeError(bcDB.col.insert({data: 2}));
+ assert(cDB.logout());
- // Ensure that they can both successfully authenticate to their correct database.
- assert(cDB.auth('a@b', 'pass1'));
- assert.writeOK(cDB.col.insert({data: 1}));
- assert.writeError(bcDB.col.insert({data: 2}));
- assert(cDB.logout());
+ assert(bcDB.auth('a', 'pass2'));
+ assert.writeOK(bcDB.col.insert({data: 3}));
+ assert.writeError(cDB.col.insert({data: 4}));
+ assert(bcDB.logout());
- assert(bcDB.auth('a', 'pass2'));
- assert.writeOK(bcDB.col.insert({data: 3}));
- assert.writeError(cDB.col.insert({data: 4}));
- assert(bcDB.logout());
+ // Ensure that the user cache permits both users to log in at the same time
+ assert(cDB.auth('a@b', 'pass1'));
+ assert(bcDB.auth('a', 'pass2'));
+ assert(cDB.logout());
+ assert(bcDB.logout());
- // Ensure that the user cache permits both users to log in at the same time
- assert(cDB.auth('a@b', 'pass1'));
- assert(bcDB.auth('a', 'pass2'));
- assert(cDB.logout());
- assert(bcDB.logout());
+ assert(bcDB.auth('a', 'pass2'));
+ assert(cDB.auth('a@b', 'pass1'));
+ assert(cDB.logout());
+ assert(bcDB.logout());
+};
+testUserAndDatabaseAtSymbolConflation();
- assert(bcDB.auth('a', 'pass2'));
- assert(cDB.auth('a@b', 'pass1'));
- assert(cDB.logout());
- assert(bcDB.logout());
- };
- testUserAndDatabaseAtSymbolConflation();
-
- MongoRunner.stopMongod(conn);
+MongoRunner.stopMongod(conn);
})();
diff --git a/jstests/auth/usersInfo.js b/jstests/auth/usersInfo.js
index fdd4a1b0a5f..81b9b4ee870 100644
--- a/jstests/auth/usersInfo.js
+++ b/jstests/auth/usersInfo.js
@@ -1,47 +1,46 @@
// Test behavior and edge cases in usersInfo
(function() {
- 'use strict';
-
- function runTest(conn) {
- let db = conn.getDB("test");
- let emptyDB = conn.getDB("test2");
- let otherDB = conn.getDB("other");
-
- const userCount = 200;
- for (let i = 0; i < userCount; ++i) {
- assert.commandWorked(db.runCommand({createUser: "user" + i, pwd: "pwd", roles: []}));
- }
- assert.commandWorked(otherDB.runCommand({createUser: "otherUser", pwd: "pwd", roles: []}));
-
- // Check info for all users on the "test" database.
- const allTestInfo = assert.commandWorked(db.runCommand({usersInfo: 1}));
- assert.eq(userCount, allTestInfo.users.length);
-
- // Check we can find a particular user on the "test" database.
- assert.eq(1, assert.commandWorked(db.runCommand({usersInfo: "user12"})).users.length);
- assert.eq(1,
- assert.commandWorked(db.runCommand({usersInfo: {user: "user12", db: "test"}}))
- .users.length);
- assert.eq(0,
- assert.commandWorked(db.runCommand({usersInfo: {user: "user12", db: "test2"}}))
- .users.length);
- assert.eq(0, assert.commandWorked(emptyDB.runCommand({usersInfo: "user12"})).users.length);
-
- // No users are found on a database without users.
- assert.eq(0, assert.commandWorked(emptyDB.runCommand({usersInfo: 1})).users.length);
-
- // Check that we can find records for all users on all databases.
- const allInfo = assert.commandWorked(db.runCommand({usersInfo: {forAllDBs: true}}));
- assert.eq(userCount + 1, allInfo.users.length);
- }
+'use strict';
- const m = MongoRunner.runMongod();
- runTest(m);
- MongoRunner.stopMongod(m);
+function runTest(conn) {
+ let db = conn.getDB("test");
+ let emptyDB = conn.getDB("test2");
+ let otherDB = conn.getDB("other");
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- const st =
- new ShardingTest({shards: 1, mongos: 1, config: 1, other: {shardAsReplicaSet: false}});
- runTest(st.s0);
- st.stop();
+ const userCount = 200;
+ for (let i = 0; i < userCount; ++i) {
+ assert.commandWorked(db.runCommand({createUser: "user" + i, pwd: "pwd", roles: []}));
+ }
+ assert.commandWorked(otherDB.runCommand({createUser: "otherUser", pwd: "pwd", roles: []}));
+
+ // Check info for all users on the "test" database.
+ const allTestInfo = assert.commandWorked(db.runCommand({usersInfo: 1}));
+ assert.eq(userCount, allTestInfo.users.length);
+
+ // Check we can find a particular user on the "test" database.
+ assert.eq(1, assert.commandWorked(db.runCommand({usersInfo: "user12"})).users.length);
+ assert.eq(1,
+ assert.commandWorked(db.runCommand({usersInfo: {user: "user12", db: "test"}}))
+ .users.length);
+ assert.eq(0,
+ assert.commandWorked(db.runCommand({usersInfo: {user: "user12", db: "test2"}}))
+ .users.length);
+ assert.eq(0, assert.commandWorked(emptyDB.runCommand({usersInfo: "user12"})).users.length);
+
+ // No users are found on a database without users.
+ assert.eq(0, assert.commandWorked(emptyDB.runCommand({usersInfo: 1})).users.length);
+
+ // Check that we can find records for all users on all databases.
+ const allInfo = assert.commandWorked(db.runCommand({usersInfo: {forAllDBs: true}}));
+ assert.eq(userCount + 1, allInfo.users.length);
+}
+
+const m = MongoRunner.runMongod();
+runTest(m);
+MongoRunner.stopMongod(m);
+
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+const st = new ShardingTest({shards: 1, mongos: 1, config: 1, other: {shardAsReplicaSet: false}});
+runTest(st.s0);
+st.stop();
}());
diff --git a/jstests/auth/validate_auth_schema_on_startup.js b/jstests/auth/validate_auth_schema_on_startup.js
index 764308a3644..e4c6c50fdcc 100644
--- a/jstests/auth/validate_auth_schema_on_startup.js
+++ b/jstests/auth/validate_auth_schema_on_startup.js
@@ -6,47 +6,46 @@
*/
(function() {
- const dbpath = MongoRunner.dataPath + "validateAuthSchemaOnStartup/";
- resetDbpath(dbpath);
- const dbName = "validateAuthSchemaOnStartup";
- const authSchemaColl = "system.version";
+const dbpath = MongoRunner.dataPath + "validateAuthSchemaOnStartup/";
+resetDbpath(dbpath);
+const dbName = "validateAuthSchemaOnStartup";
+const authSchemaColl = "system.version";
- let mongod = MongoRunner.runMongod({dbpath: dbpath, auth: ""});
- let adminDB = mongod.getDB('admin');
+let mongod = MongoRunner.runMongod({dbpath: dbpath, auth: ""});
+let adminDB = mongod.getDB('admin');
- // Create a user.
- adminDB.createUser(
- {user: "root", pwd: "root", roles: [{role: 'userAdminAnyDatabase', db: 'admin'}]});
- assert(adminDB.auth("root", "root"));
+// Create a user.
+adminDB.createUser(
+ {user: "root", pwd: "root", roles: [{role: 'userAdminAnyDatabase', db: 'admin'}]});
+assert(adminDB.auth("root", "root"));
- MongoRunner.stopMongod(mongod);
+MongoRunner.stopMongod(mongod);
- // Start without auth to corrupt the authSchema document.
- mongod = MongoRunner.runMongod({dbpath: dbpath, noCleanData: true});
- adminDB = mongod.getDB('admin');
+// Start without auth to corrupt the authSchema document.
+mongod = MongoRunner.runMongod({dbpath: dbpath, noCleanData: true});
+adminDB = mongod.getDB('admin');
- let currentVersion = adminDB[authSchemaColl].findOne({_id: 'authSchema'}).currentVersion;
+let currentVersion = adminDB[authSchemaColl].findOne({_id: 'authSchema'}).currentVersion;
- // Invalidate the authSchema document.
- assert.commandWorked(
- adminDB[authSchemaColl].update({_id: 'authSchema'}, {currentVersion: 'asdf'}));
- MongoRunner.stopMongod(mongod);
+// Invalidate the authSchema document.
+assert.commandWorked(adminDB[authSchemaColl].update({_id: 'authSchema'}, {currentVersion: 'asdf'}));
+MongoRunner.stopMongod(mongod);
- // Confirm start up fails, even without --auth.
- assert.eq(null, MongoRunner.runMongod({dbpath: dbpath, noCleanData: true}));
+// Confirm start up fails, even without --auth.
+assert.eq(null, MongoRunner.runMongod({dbpath: dbpath, noCleanData: true}));
- // Confirm startup works with the flag to disable validation so the document can be repaired.
- mongod = MongoRunner.runMongod(
- {dbpath: dbpath, noCleanData: true, setParameter: "startupAuthSchemaValidation=false"});
- adminDB = mongod.getDB('admin');
- assert.commandWorked(
- adminDB[authSchemaColl].update({_id: 'authSchema'}, {currentVersion: currentVersion}));
- MongoRunner.stopMongod(mongod);
+// Confirm startup works with the flag to disable validation so the document can be repaired.
+mongod = MongoRunner.runMongod(
+ {dbpath: dbpath, noCleanData: true, setParameter: "startupAuthSchemaValidation=false"});
+adminDB = mongod.getDB('admin');
+assert.commandWorked(
+ adminDB[authSchemaColl].update({_id: 'authSchema'}, {currentVersion: currentVersion}));
+MongoRunner.stopMongod(mongod);
- // Confirm everything is normal again.
- mongod = MongoRunner.runMongod({dbpath: dbpath, noCleanData: true, auth: ""});
- adminDB = mongod.getDB('admin');
- assert(adminDB.auth("root", "root"));
+// Confirm everything is normal again.
+mongod = MongoRunner.runMongod({dbpath: dbpath, noCleanData: true, auth: ""});
+adminDB = mongod.getDB('admin');
+assert(adminDB.auth("root", "root"));
- MongoRunner.stopMongod(mongod);
+MongoRunner.stopMongod(mongod);
})();
diff --git a/jstests/auth/views_authz.js b/jstests/auth/views_authz.js
index 080a4b2bfcd..6223312249c 100644
--- a/jstests/auth/views_authz.js
+++ b/jstests/auth/views_authz.js
@@ -4,155 +4,142 @@
* @tags: [requires_sharding]
*/
(function() {
- "use strict";
+"use strict";
- // TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
- TestData.disableImplicitSessions = true;
+// TODO SERVER-35447: Multiple users cannot be authenticated on one connection within a session.
+TestData.disableImplicitSessions = true;
- function runTest(conn) {
- // Create the admin user.
- let adminDB = conn.getDB("admin");
- assert.commandWorked(
- adminDB.runCommand({createUser: "admin", pwd: "admin", roles: ["root"]}));
- assert.eq(1, adminDB.auth("admin", "admin"));
+function runTest(conn) {
+ // Create the admin user.
+ let adminDB = conn.getDB("admin");
+ assert.commandWorked(adminDB.runCommand({createUser: "admin", pwd: "admin", roles: ["root"]}));
+ assert.eq(1, adminDB.auth("admin", "admin"));
- const viewsDBName = "views_authz";
- let viewsDB = adminDB.getSiblingDB(viewsDBName);
- viewsDB.dropAllUsers();
- viewsDB.logout();
+ const viewsDBName = "views_authz";
+ let viewsDB = adminDB.getSiblingDB(viewsDBName);
+ viewsDB.dropAllUsers();
+ viewsDB.logout();
- // Create a user who can read, create and modify a view 'view' and a read a namespace
- // 'permitted' but does not have access to 'forbidden'.
- assert.commandWorked(viewsDB.runCommand({
- createRole: "readWriteView",
- privileges: [
- {
- resource: {db: viewsDBName, collection: "view"},
- actions: ["find", "createCollection", "collMod"]
- },
- {resource: {db: viewsDBName, collection: "view2"}, actions: ["find"]},
- {resource: {db: viewsDBName, collection: "permitted"}, actions: ["find"]}
- ],
- roles: []
- }));
- assert.commandWorked(
- viewsDB.runCommand({createUser: "viewUser", pwd: "pwd", roles: ["readWriteView"]}));
+ // Create a user who can read, create and modify a view 'view' and a read a namespace
+ // 'permitted' but does not have access to 'forbidden'.
+ assert.commandWorked(viewsDB.runCommand({
+ createRole: "readWriteView",
+ privileges: [
+ {
+ resource: {db: viewsDBName, collection: "view"},
+ actions: ["find", "createCollection", "collMod"]
+ },
+ {resource: {db: viewsDBName, collection: "view2"}, actions: ["find"]},
+ {resource: {db: viewsDBName, collection: "permitted"}, actions: ["find"]}
+ ],
+ roles: []
+ }));
+ assert.commandWorked(
+ viewsDB.runCommand({createUser: "viewUser", pwd: "pwd", roles: ["readWriteView"]}));
- adminDB.logout();
- assert.eq(1, viewsDB.auth("viewUser", "pwd"));
+ adminDB.logout();
+ assert.eq(1, viewsDB.auth("viewUser", "pwd"));
- const lookupStage = {
- $lookup: {from: "forbidden", localField: "x", foreignField: "x", as: "y"}
- };
- const graphLookupStage = {
- $graphLookup: {
- from: "forbidden",
- startWith: [],
- connectFromField: "x",
- connectToField: "x",
- as: "y"
- }
- };
+ const lookupStage = {$lookup: {from: "forbidden", localField: "x", foreignField: "x", as: "y"}};
+ const graphLookupStage = {
+ $graphLookup:
+ {from: "forbidden", startWith: [], connectFromField: "x", connectToField: "x", as: "y"}
+ };
- // You cannot create a view if you have both the 'createCollection' and 'find' actions on
- // that view but not the 'find' action on all of the dependent namespaces.
- assert.commandFailedWithCode(viewsDB.createView("view", "forbidden", []),
- ErrorCodes.Unauthorized,
- "created a readable view on an unreadable collection");
- assert.commandFailedWithCode(
- viewsDB.createView("view", "permitted", [lookupStage]),
- ErrorCodes.Unauthorized,
- "created a readable view on an unreadable collection via $lookup");
- assert.commandFailedWithCode(
- viewsDB.createView("view", "permitted", [graphLookupStage]),
- ErrorCodes.Unauthorized,
- "created a readable view on an unreadable collection via $graphLookup");
- assert.commandFailedWithCode(
- viewsDB.createView("view", "permitted", [{$facet: {a: [lookupStage]}}]),
- ErrorCodes.Unauthorized,
- "created a readable view on an unreadable collection via $lookup in a $facet");
- assert.commandFailedWithCode(
- viewsDB.createView("view", "permitted", [{$facet: {b: [graphLookupStage]}}]),
- ErrorCodes.Unauthorized,
- "created a readable view on an unreadable collection via $graphLookup in a $facet");
+ // You cannot create a view if you have both the 'createCollection' and 'find' actions on
+ // that view but not the 'find' action on all of the dependent namespaces.
+ assert.commandFailedWithCode(viewsDB.createView("view", "forbidden", []),
+ ErrorCodes.Unauthorized,
+ "created a readable view on an unreadable collection");
+ assert.commandFailedWithCode(viewsDB.createView("view", "permitted", [lookupStage]),
+ ErrorCodes.Unauthorized,
+ "created a readable view on an unreadable collection via $lookup");
+ assert.commandFailedWithCode(
+ viewsDB.createView("view", "permitted", [graphLookupStage]),
+ ErrorCodes.Unauthorized,
+ "created a readable view on an unreadable collection via $graphLookup");
+ assert.commandFailedWithCode(
+ viewsDB.createView("view", "permitted", [{$facet: {a: [lookupStage]}}]),
+ ErrorCodes.Unauthorized,
+ "created a readable view on an unreadable collection via $lookup in a $facet");
+ assert.commandFailedWithCode(
+ viewsDB.createView("view", "permitted", [{$facet: {b: [graphLookupStage]}}]),
+ ErrorCodes.Unauthorized,
+ "created a readable view on an unreadable collection via $graphLookup in a $facet");
- assert.commandWorked(viewsDB.createView("view", "permitted", [{$match: {x: 1}}]));
+ assert.commandWorked(viewsDB.createView("view", "permitted", [{$match: {x: 1}}]));
- // You cannot modify a view if you have both the 'collMod' and 'find' actions on that view
- // but not the 'find' action on all of the dependent namespaces.
- assert.commandFailedWithCode(
- viewsDB.runCommand({collMod: "view", viewOn: "forbidden", pipeline: [{$match: {}}]}),
- ErrorCodes.Unauthorized,
- "modified a view to read an unreadable collection");
- assert.commandFailedWithCode(
- viewsDB.runCommand({collMod: "view", viewOn: "permitted", pipeline: [lookupStage]}),
- ErrorCodes.Unauthorized,
- "modified a view to read an unreadable collection via $lookup");
- assert.commandFailedWithCode(
- viewsDB.runCommand(
- {collMod: "view", viewOn: "permitted", pipeline: [graphLookupStage]}),
- ErrorCodes.Unauthorized,
- "modified a view to read an unreadable collection via $graphLookup");
- assert.commandFailedWithCode(
- viewsDB.runCommand(
- {collMod: "view", viewOn: "permitted", pipeline: [{$facet: {a: [lookupStage]}}]}),
- ErrorCodes.Unauthorized,
- "modified a view to read an unreadable collection via $lookup in a $facet");
- assert.commandFailedWithCode(
- viewsDB.runCommand({
- collMod: "view",
- viewOn: "permitted",
- pipeline: [{$facet: {b: [graphLookupStage]}}]
- }),
- ErrorCodes.Unauthorized,
- "modified a view to read an unreadable collection via $graphLookup in a $facet");
+ // You cannot modify a view if you have both the 'collMod' and 'find' actions on that view
+ // but not the 'find' action on all of the dependent namespaces.
+ assert.commandFailedWithCode(
+ viewsDB.runCommand({collMod: "view", viewOn: "forbidden", pipeline: [{$match: {}}]}),
+ ErrorCodes.Unauthorized,
+ "modified a view to read an unreadable collection");
+ assert.commandFailedWithCode(
+ viewsDB.runCommand({collMod: "view", viewOn: "permitted", pipeline: [lookupStage]}),
+ ErrorCodes.Unauthorized,
+ "modified a view to read an unreadable collection via $lookup");
+ assert.commandFailedWithCode(
+ viewsDB.runCommand({collMod: "view", viewOn: "permitted", pipeline: [graphLookupStage]}),
+ ErrorCodes.Unauthorized,
+ "modified a view to read an unreadable collection via $graphLookup");
+ assert.commandFailedWithCode(
+ viewsDB.runCommand(
+ {collMod: "view", viewOn: "permitted", pipeline: [{$facet: {a: [lookupStage]}}]}),
+ ErrorCodes.Unauthorized,
+ "modified a view to read an unreadable collection via $lookup in a $facet");
+ assert.commandFailedWithCode(
+ viewsDB.runCommand(
+ {collMod: "view", viewOn: "permitted", pipeline: [{$facet: {b: [graphLookupStage]}}]}),
+ ErrorCodes.Unauthorized,
+ "modified a view to read an unreadable collection via $graphLookup in a $facet");
- // When auth is enabled, users must specify both "viewOn" and "pipeline" when running
- // collMod on a view; specifying only one or the other is not allowed. Without both the
- // "viewOn" and "pipeline" specified, authorization checks cannot determine if the users
- // have the necessary privileges.
- assert.commandFailedWithCode(viewsDB.runCommand({collMod: "view", pipeline: []}),
- ErrorCodes.InvalidOptions,
- "modified a view without having to specify 'viewOn'");
- assert.commandFailedWithCode(viewsDB.runCommand({collMod: "view", viewOn: "other"}),
- ErrorCodes.InvalidOptions,
- "modified a view without having to specify 'pipeline'");
+ // When auth is enabled, users must specify both "viewOn" and "pipeline" when running
+ // collMod on a view; specifying only one or the other is not allowed. Without both the
+ // "viewOn" and "pipeline" specified, authorization checks cannot determine if the users
+ // have the necessary privileges.
+ assert.commandFailedWithCode(viewsDB.runCommand({collMod: "view", pipeline: []}),
+ ErrorCodes.InvalidOptions,
+ "modified a view without having to specify 'viewOn'");
+ assert.commandFailedWithCode(viewsDB.runCommand({collMod: "view", viewOn: "other"}),
+ ErrorCodes.InvalidOptions,
+ "modified a view without having to specify 'pipeline'");
- // Create a view on a forbidden collection and populate it.
- assert.eq(1, adminDB.auth("admin", "admin"));
- assert.commandWorked(viewsDB.createView("view2", "forbidden", []));
- for (let i = 0; i < 10; i++) {
- assert.writeOK(viewsDB.forbidden.insert({x: 1}));
- }
- adminDB.logout();
-
- // Performing a find on a readable view returns a cursor that allows us to perform a getMore
- // even if the underlying collection is unreadable.
- assert.commandFailedWithCode(viewsDB.runCommand({find: "forbidden"}),
- ErrorCodes.Unauthorized,
- "successfully performed a find on an unreadable namespace");
- let res = viewsDB.runCommand({find: "view2", batchSize: 1});
- assert.commandWorked(res, "could not perform a find on a readable view");
- assert.eq(res.cursor.ns,
- "views_authz.view2",
- "performing find on a view does not return a cursor on the view namespace");
- assert.commandWorked(viewsDB.runCommand({getMore: res.cursor.id, collection: "view2"}),
- "could not perform getMore on a readable view");
+ // Create a view on a forbidden collection and populate it.
+ assert.eq(1, adminDB.auth("admin", "admin"));
+ assert.commandWorked(viewsDB.createView("view2", "forbidden", []));
+ for (let i = 0; i < 10; i++) {
+ assert.writeOK(viewsDB.forbidden.insert({x: 1}));
}
+ adminDB.logout();
+
+ // Performing a find on a readable view returns a cursor that allows us to perform a getMore
+ // even if the underlying collection is unreadable.
+ assert.commandFailedWithCode(viewsDB.runCommand({find: "forbidden"}),
+ ErrorCodes.Unauthorized,
+ "successfully performed a find on an unreadable namespace");
+ let res = viewsDB.runCommand({find: "view2", batchSize: 1});
+ assert.commandWorked(res, "could not perform a find on a readable view");
+ assert.eq(res.cursor.ns,
+ "views_authz.view2",
+ "performing find on a view does not return a cursor on the view namespace");
+ assert.commandWorked(viewsDB.runCommand({getMore: res.cursor.id, collection: "view2"}),
+ "could not perform getMore on a readable view");
+}
- // Run the test on a standalone.
- let mongod = MongoRunner.runMongod({auth: "", bind_ip: "127.0.0.1"});
- runTest(mongod);
- MongoRunner.stopMongod(mongod);
+// Run the test on a standalone.
+let mongod = MongoRunner.runMongod({auth: "", bind_ip: "127.0.0.1"});
+runTest(mongod);
+MongoRunner.stopMongod(mongod);
- // Run the test on a sharded cluster.
- // TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
- let cluster = new ShardingTest({
- shards: 1,
- mongos: 1,
- keyFile: "jstests/libs/key1",
- other: {shardOptions: {auth: ""}, shardAsReplicaSet: false}
- });
- runTest(cluster);
- cluster.stop();
+// Run the test on a sharded cluster.
+// TODO: Remove 'shardAsReplicaSet: false' when SERVER-32672 is fixed.
+let cluster = new ShardingTest({
+ shards: 1,
+ mongos: 1,
+ keyFile: "jstests/libs/key1",
+ other: {shardOptions: {auth: ""}, shardAsReplicaSet: false}
+});
+runTest(cluster);
+cluster.stop();
}());