diff options
6 files changed, 107 insertions, 2 deletions
diff --git a/jstests/serverless/native_tenant_data_isolation_basic_dollar_tenant.js b/jstests/serverless/native_tenant_data_isolation_basic_dollar_tenant.js index 4f07a6b018c..62b90907f74 100644 --- a/jstests/serverless/native_tenant_data_isolation_basic_dollar_tenant.js +++ b/jstests/serverless/native_tenant_data_isolation_basic_dollar_tenant.js @@ -211,5 +211,54 @@ const testColl = testDb.getCollection(kCollName); {insert: kCollName, documents: [{_id: 0, a: 1, b: 1}], '$tenant': kTenant})); } +// Test createIndexes, listIndexes and dropIndexes command. +{ + var sortIndexesByName = function(indexes) { + return indexes.sort(function(a, b) { + return a.name > b.name; + }); + }; + + var getIndexesKeyAndName = function(indexes) { + return sortIndexesByName(indexes).map(function(index) { + return {key: index.key, name: index.name}; + }); + }; + + let res = assert.commandWorked(testDb.runCommand({ + createIndexes: kCollName, + indexes: [{key: {a: 1}, name: "indexA"}, {key: {b: 1}, name: "indexB"}], + '$tenant': kTenant + })); + assert.eq(3, res.numIndexesAfter); + + res = assert.commandWorked(testDb.runCommand({listIndexes: kCollName, '$tenant': kTenant})); + assert.eq(3, res.cursor.firstBatch.length); + assert(arrayEq( + [ + {key: {"_id": 1}, name: "_id_"}, + {key: {a: 1}, name: "indexA"}, + {key: {b: 1}, name: "indexB"} + ], + getIndexesKeyAndName(res.cursor.firstBatch))); + + // These indexes should not be accessed with a different tenant. + assert.commandFailedWithCode( + testDb.runCommand({listIndexes: kCollName, '$tenant': kOtherTenant}), + ErrorCodes.NamespaceNotFound); + assert.commandFailedWithCode( + testDb.runCommand( + {dropIndexes: kCollName, index: ["indexA", "indexB"], '$tenant': kOtherTenant}), + ErrorCodes.NamespaceNotFound); + + // Drop those new created indexes. + res = assert.commandWorked(testDb.runCommand( + {dropIndexes: kCollName, index: ["indexA", "indexB"], '$tenant': kTenant})); + + res = assert.commandWorked(testDb.runCommand({listIndexes: kCollName, '$tenant': kTenant})); + assert.eq(1, res.cursor.firstBatch.length); + assert(arrayEq([{key: {"_id": 1}, name: "_id_"}], getIndexesKeyAndName(res.cursor.firstBatch))); +} + MongoRunner.stopMongod(mongod); })(); diff --git a/jstests/serverless/native_tenant_data_isolation_basic_security_token.js b/jstests/serverless/native_tenant_data_isolation_basic_security_token.js index 11079552f8b..e6893484868 100644 --- a/jstests/serverless/native_tenant_data_isolation_basic_security_token.js +++ b/jstests/serverless/native_tenant_data_isolation_basic_security_token.js @@ -144,6 +144,46 @@ const tokenDB = tokenConn.getDB(kDbName); assert.commandWorked( tokenDB.runCommand({insert: kCollName, documents: [{_id: 0, a: 1, b: 1}]})); } + + // Test createIndexes, listIndexes and dropIndexes command. + { + var sortIndexesByName = function(indexes) { + return indexes.sort(function(a, b) { + return a.name > b.name; + }); + }; + + var getIndexesKeyAndName = function(indexes) { + return sortIndexesByName(indexes).map(function(index) { + return {key: index.key, name: index.name}; + }); + }; + + let res = assert.commandWorked(tokenDB.runCommand({ + createIndexes: kCollName, + indexes: [{key: {a: 1}, name: "indexA"}, {key: {b: 1}, name: "indexB"}] + })); + assert.eq(3, res.numIndexesAfter); + + res = assert.commandWorked(tokenDB.runCommand({listIndexes: kCollName})); + assert.eq(3, res.cursor.firstBatch.length); + assert(arrayEq( + [ + {key: {"_id": 1}, name: "_id_"}, + {key: {a: 1}, name: "indexA"}, + {key: {b: 1}, name: "indexB"} + ], + getIndexesKeyAndName(res.cursor.firstBatch))); + + // Drop those new created indexes. + res = assert.commandWorked( + tokenDB.runCommand({dropIndexes: kCollName, index: ["indexA", "indexB"]})); + + res = assert.commandWorked(tokenDB.runCommand({listIndexes: kCollName})); + assert.eq(1, res.cursor.firstBatch.length); + assert(arrayEq([{key: {"_id": 1}, name: "_id_"}], + getIndexesKeyAndName(res.cursor.firstBatch))); + } } // Test commands using a security token for a different tenant and check that this tenant cannot @@ -189,6 +229,12 @@ const tokenDB = tokenConn.getDB(kDbName); adminDb.runCommand({renameCollection: fromName, to: toName, dropTarget: true}), ErrorCodes.NamespaceNotFound); + assert.commandFailedWithCode(tokenDB2.runCommand({listIndexes: kCollName}), + ErrorCodes.NamespaceNotFound); + assert.commandFailedWithCode( + tokenDB2.runCommand({dropIndexes: kCollName, index: ["indexA", "indexB"]}), + ErrorCodes.NamespaceNotFound); + // Attempt to drop the database, then check it was not dropped. assert.commandWorked(tokenDB2.runCommand({dropDatabase: 1})); diff --git a/src/mongo/db/catalog/drop_indexes.cpp b/src/mongo/db/catalog/drop_indexes.cpp index 8ee4b3cc43f..25d50406adc 100644 --- a/src/mongo/db/catalog/drop_indexes.cpp +++ b/src/mongo/db/catalog/drop_indexes.cpp @@ -403,7 +403,7 @@ DropIndexesReply dropIndexes(OperationContext* opCtx, uassertStatusOK(checkView(opCtx, nss, collection->getCollection())); const UUID collectionUUID = (*collection)->uuid(); - const NamespaceStringOrUUID dbAndUUID = {nss.db().toString(), collectionUUID}; + const NamespaceStringOrUUID dbAndUUID = {nss.dbName(), collectionUUID}; uassertStatusOK(checkReplState(opCtx, dbAndUUID, collection->getCollection())); if (!serverGlobalParams.quiet.load()) { LOGV2(51806, diff --git a/src/mongo/db/commands/create_indexes_cmd.cpp b/src/mongo/db/commands/create_indexes_cmd.cpp index 233d60bba58..f6da49a5444 100644 --- a/src/mongo/db/commands/create_indexes_cmd.cpp +++ b/src/mongo/db/commands/create_indexes_cmd.cpp @@ -482,7 +482,7 @@ CreateIndexesReply runCreateIndexesWithCoordinator(OperationContext* opCtx, boost::optional<UUID> collectionUUID; CreateIndexesReply reply; { - AutoGetDb autoDb(opCtx, ns.db(), MODE_IX); + AutoGetDb autoDb(opCtx, ns.dbName(), MODE_IX); assertNoMovePrimaryInProgress(opCtx, ns); if (!repl::ReplicationCoordinator::get(opCtx)->canAcceptWritesFor(opCtx, ns)) { @@ -706,6 +706,9 @@ CreateIndexesReply runCreateIndexesWithCoordinator(OperationContext* opCtx, */ class CmdCreateIndexes : public CreateIndexesCmdVersion1Gen<CmdCreateIndexes> { public: + bool allowedWithSecurityToken() const final { + return true; + } class Invocation final : public InvocationBase { public: using InvocationBase::InvocationBase; diff --git a/src/mongo/db/commands/drop_indexes.cpp b/src/mongo/db/commands/drop_indexes.cpp index ae15287286e..86d66718499 100644 --- a/src/mongo/db/commands/drop_indexes.cpp +++ b/src/mongo/db/commands/drop_indexes.cpp @@ -79,6 +79,9 @@ public: std::string help() const override { return "drop indexes for a collection"; } + bool allowedWithSecurityToken() const final { + return true; + } class Invocation final : public InvocationBaseGen { public: using InvocationBaseGen::InvocationBaseGen; diff --git a/src/mongo/db/commands/list_indexes.cpp b/src/mongo/db/commands/list_indexes.cpp index 4312a142906..c61c6781e50 100644 --- a/src/mongo/db/commands/list_indexes.cpp +++ b/src/mongo/db/commands/list_indexes.cpp @@ -215,6 +215,10 @@ public: return "list indexes for a collection"; } + bool allowedWithSecurityToken() const final { + return true; + } + class Invocation final : public InvocationBaseGen { public: using InvocationBaseGen::InvocationBaseGen; |