diff options
-rw-r--r-- | jstests/auth/lib/commands_lib.js | 16 | ||||
-rw-r--r-- | jstests/auth/restore_role_create_collection_via_apply_ops.js | 61 | ||||
-rw-r--r-- | src/mongo/db/auth/role_graph_builtin_roles.cpp | 8 |
3 files changed, 77 insertions, 8 deletions
diff --git a/jstests/auth/lib/commands_lib.js b/jstests/auth/lib/commands_lib.js index 4169036623f..a04e3cc033d 100644 --- a/jstests/auth/lib/commands_lib.js +++ b/jstests/auth/lib/commands_lib.js @@ -324,7 +324,8 @@ var authCommandsLib = { roles: { dbAdminAnyDatabase: 1, root: 1, - __system: 1 + __system: 1, + restore: 1, }, privileges: [ {resource: {db: firstDbName, collection: "x"}, actions: ["createCollection"]}, @@ -354,7 +355,7 @@ var authCommandsLib = { testcases: [ { runOnDb: adminDbName, - roles: {__system: 1, root: 1}, + roles: {__system: 1, root: 1, restore: 1}, privileges: [ {resource: {db: firstDbName, collection: "x"}, actions: ["createCollection"]}, {resource: {cluster: true}, actions: ["useUUID", "forceUUID", "applyOps"]}, @@ -413,7 +414,8 @@ var authCommandsLib = { roles: { dbAdminAnyDatabase: 1, root: 1, - __system: 1 + __system: 1, + restore: 1, }, privileges: [ {resource: {db: firstDbName, collection: "x"}, actions: ["dropCollection"]}, @@ -452,7 +454,7 @@ var authCommandsLib = { testcases: [ { runOnDb: adminDbName, - roles: {__system: 1, root: 1}, + roles: {__system: 1, root: 1, restore: 1}, privileges: [ {resource: {db: firstDbName, collection: "x"}, actions: ["dropCollection"]}, {resource: {cluster: true}, actions: ["useUUID", "applyOps"]}, @@ -580,7 +582,7 @@ var authCommandsLib = { testcases: [ { runOnDb: adminDbName, - roles: {__system: 1, root: 1}, + roles: {__system: 1, root: 1, restore: 1}, privileges: [ {resource: {db: firstDbName, collection: "x"}, actions: ["insert"]}, {resource: {cluster: true}, actions: ["applyOps"]}, @@ -616,7 +618,7 @@ var authCommandsLib = { testcases: [ { runOnDb: adminDbName, - roles: {__system: 1, root: 1}, + roles: {__system: 1, root: 1, restore: 1}, privileges: [ {resource: {db: firstDbName, collection: "x"}, actions: ["insert"]}, {resource: {cluster: true}, actions: ["useUUID", "applyOps"]}, @@ -656,7 +658,7 @@ var authCommandsLib = { // failure. expectFail: true, runOnDb: adminDbName, - roles: {__system: 1, root: 1}, + roles: {__system: 1, root: 1, restore: 1}, privileges: [ {resource: {db: firstDbName, collection: "x"}, actions: ["insert"]}, {resource: {cluster: true}, actions: ["useUUID", "applyOps"]}, diff --git a/jstests/auth/restore_role_create_collection_via_apply_ops.js b/jstests/auth/restore_role_create_collection_via_apply_ops.js new file mode 100644 index 00000000000..be30be7db47 --- /dev/null +++ b/jstests/auth/restore_role_create_collection_via_apply_ops.js @@ -0,0 +1,61 @@ +// Verify that mongorestore can create a collection via applyOps + +(function() { +'use strict'; + +function makeCreateOp(collName, uuid = undefined) { + const op = { + op: 'c', + ns: 'test.$cmd', + o: { + create: collName, + idIndex: { + key: {_id: 1}, + v: 2, + name: "_id_", + ns: "test." + collName, + }, + }, + }; + if (uuid) { + op.ui = uuid; + } + return op; +} + +function assertHasCollection(db, collName, expectUUID = undefined) { + const colls = db.getCollectionInfos({name: collName}); + assert.eq(colls.length, 1, colls); + if (expectUUID !== undefined) { + assert.eq(colls[0].info.uuid, expectUUID, colls); + } +} + +function runTest(conn) { + const admin = conn.getDB('admin'); + const test = conn.getDB('test'); + assert.commandWorked(admin.runCommand({createUser: 'admin', pwd: 'admin', roles: ['root']})); + assert(admin.auth('admin', 'admin')); + + assert.commandWorked( + admin.runCommand({createUser: 'restore1', pwd: 'pwd', roles: ['restore']})); + admin.logout(); + + assert(admin.auth('restore1', 'pwd')); + + // Simple create collection op. + assert.commandWorked(admin.runCommand({applyOps: [makeCreateOp('test1')]})); + assertHasCollection(test, 'test1'); + + // Create collection with UUID. + const kSpecificUUID = UUID(); + assert.commandWorked(admin.runCommand({applyOps: [makeCreateOp('test2', kSpecificUUID)]})); + assertHasCollection(test, 'test2', kSpecificUUID); + + admin.logout(); +} + +const standalone = MongoRunner.runMongod({auth: ''}); +runTest(standalone); +MongoRunner.stopMongod(standalone); +})();
\ No newline at end of file diff --git a/src/mongo/db/auth/role_graph_builtin_roles.cpp b/src/mongo/db/auth/role_graph_builtin_roles.cpp index b001cb2dc70..042c5efc9ed 100644 --- a/src/mongo/db/auth/role_graph_builtin_roles.cpp +++ b/src/mongo/db/auth/role_graph_builtin_roles.cpp @@ -672,7 +672,13 @@ void addRestorePrivileges(PrivilegeVector* privileges) { Privilege::addPrivilegeToPrivilegeVector( privileges, Privilege(ResourcePattern::forClusterResource(), - {ActionType::forceUUID, ActionType::useUUID})); + { + // Need to be able to force UUID consistency in sharded restores + ActionType::forceUUID, + ActionType::useUUID, + // Needed for `mongorestore --preserveUUID` + ActionType::applyOps, + })); } void addRootRolePrivileges(PrivilegeVector* privileges) { |