diff options
4 files changed, 34 insertions, 7 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 be387787627..4f07a6b018c 100644 --- a/jstests/serverless/native_tenant_data_isolation_basic_dollar_tenant.js +++ b/jstests/serverless/native_tenant_data_isolation_basic_dollar_tenant.js @@ -49,7 +49,7 @@ const testColl = testDb.getCollection(kCollName); assert.eq(0, collsWithDiffTenant.cursor.firstBatch.length); } -// Test insert, find, getMore, and explain commands. +// Test insert, agg, find, getMore, and explain commands. { const kTenantDocs = [{w: 0}, {x: 1}, {y: 2}, {z: 3}]; const kOtherTenantDocs = [{i: 1}, {j: 2}, {k: 3}]; @@ -88,6 +88,26 @@ const testColl = testDb.getCollection(kCollName); {getMore: cmdRes2.cursor.id, collection: kCollName, '$tenant': kOtherTenant}), ErrorCodes.Unauthorized); + // Test that aggregate only finds a tenant's own document. + const aggRes = assert.commandWorked(testDb.runCommand({ + aggregate: kCollName, + pipeline: [{$match: {w: 0}}, {$project: {_id: 0}}], + cursor: {}, + '$tenant': kTenant + })); + assert.eq(1, aggRes.cursor.firstBatch.length, tojson(aggRes.cursor.firstBatch)); + assert.eq(kTenantDocs[0], aggRes.cursor.firstBatch[0]); + + const aggRes2 = assert.commandWorked(testDb.runCommand({ + aggregate: kCollName, + pipeline: [{$match: {i: 1}}, {$project: {_id: 0}}], + cursor: {}, + '$tenant': kOtherTenant + })); + assert.eq(1, aggRes2.cursor.firstBatch.length, tojson(aggRes2.cursor.firstBatch)); + assert.eq(kOtherTenantDocs[0], aggRes2.cursor.firstBatch[0]); + + // Test that explain works correctly. const kTenantExplainRes = assert.commandWorked(testDb.runCommand( {explain: {find: kCollName}, verbosity: 'executionStats', '$tenant': kTenant})); assert.eq( 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 3eead1b2286..11079552f8b 100644 --- a/jstests/serverless/native_tenant_data_isolation_basic_security_token.js +++ b/jstests/serverless/native_tenant_data_isolation_basic_security_token.js @@ -58,6 +58,13 @@ const tokenDB = tokenConn.getDB(kDbName); tokenDB.runCommand({getMore: findRes.cursor.id, collection: kCollName})); } + // Test the aggregate command. + { + const aggRes = assert.commandWorked( + tokenDB.runCommand({aggregate: kCollName, pipeline: [{$match: {a: 1}}], cursor: {}})); + assert(arrayEq([{_id: 0, a: 1, b: 1}], aggRes.cursor.firstBatch), tojson(aggRes)); + } + // Find and modify the document. { const fad1 = assert.commandWorked( diff --git a/src/mongo/db/pipeline/aggregation_request_helper.cpp b/src/mongo/db/pipeline/aggregation_request_helper.cpp index ae494215682..1af17053607 100644 --- a/src/mongo/db/pipeline/aggregation_request_helper.cpp +++ b/src/mongo/db/pipeline/aggregation_request_helper.cpp @@ -107,10 +107,10 @@ AggregateCommandRequest parseFromBSON(OperationContext* opCtx, cmdObjChanged = true; } - // TODO SERVER-68721: pass in tenantId from nss to IDLParserContext AggregateCommandRequest request(nss); - request = AggregateCommandRequest::parse(IDLParserContext("aggregate", apiStrict), - cmdObjChanged ? cmdObjBob.obj() : cmdObj); + request = + AggregateCommandRequest::parse(IDLParserContext("aggregate", apiStrict, nss.tenantId()), + cmdObjChanged ? cmdObjBob.obj() : cmdObj); if (explainVerbosity) { uassert(ErrorCodes::FailedToParse, diff --git a/src/mongo/db/query/query_request_helper.cpp b/src/mongo/db/query/query_request_helper.cpp index 54b3c9dcf7f..bbfa90f4bec 100644 --- a/src/mongo/db/query/query_request_helper.cpp +++ b/src/mongo/db/query/query_request_helper.cpp @@ -152,9 +152,9 @@ void refreshNSS(const NamespaceString& nss, FindCommandRequest* findCommand) { std::unique_ptr<FindCommandRequest> makeFromFindCommand(const BSONObj& cmdObj, boost::optional<NamespaceString> nss, bool apiStrict) { - // TODO SERVER-68721: Pass tenantId from nss to the IDLParserContext - auto findCommand = std::make_unique<FindCommandRequest>( - FindCommandRequest::parse(IDLParserContext("FindCommandRequest", apiStrict), cmdObj)); + auto findCommand = std::make_unique<FindCommandRequest>(FindCommandRequest::parse( + IDLParserContext("FindCommandRequest", apiStrict, nss ? nss->tenantId() : boost::none), + cmdObj)); // If there is an explicit namespace specified overwite it. if (nss) { |