diff options
author | Spencer Jackson <spencer.jackson@mongodb.com> | 2018-06-19 20:15:56 -0400 |
---|---|---|
committer | Spencer Jackson <spencer.jackson@mongodb.com> | 2018-06-20 18:13:39 -0400 |
commit | 7230641bb09b1ceb04c3135cf83a5044c4838906 (patch) | |
tree | 2c50cdd0463fc5bbe54f18669f6c89e0bf6719f3 | |
parent | 16e476893838f5d3003a8de7e07a111d3cd3434f (diff) | |
download | mongo-7230641bb09b1ceb04c3135cf83a5044c4838906.tar.gz |
SERVER-35698 Uncap usersInfo output past 101 resultsr4.0.0-rc7
(cherry picked from commit 4132ecabfdc1de9b1fcc2df3188c089ad9c22e27)
-rw-r--r-- | jstests/auth/usersInfo.js | 47 | ||||
-rw-r--r-- | src/mongo/client/dbclientcursor.cpp | 15 | ||||
-rw-r--r-- | src/mongo/client/dbclientcursor.h | 10 | ||||
-rw-r--r-- | src/mongo/db/commands/user_management_commands.cpp | 22 |
4 files changed, 79 insertions, 15 deletions
diff --git a/jstests/auth/usersInfo.js b/jstests/auth/usersInfo.js new file mode 100644 index 00000000000..fdd4a1b0a5f --- /dev/null +++ b/jstests/auth/usersInfo.js @@ -0,0 +1,47 @@ +// 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); + } + + 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/src/mongo/client/dbclientcursor.cpp b/src/mongo/client/dbclientcursor.cpp index 0efe1e2a32c..2736023861a 100644 --- a/src/mongo/client/dbclientcursor.cpp +++ b/src/mongo/client/dbclientcursor.cpp @@ -466,13 +466,15 @@ DBClientCursor::DBClientCursor(DBClientBase* client, nToSkip, fieldsToReturn, queryOptions, - batchSize) {} + batchSize, + {}) {} DBClientCursor::DBClientCursor(DBClientBase* client, const std::string& ns, long long cursorId, int nToReturn, - int queryOptions) + int queryOptions, + std::vector<BSONObj> initialBatch) : DBClientCursor(client, ns, BSONObj(), // query @@ -481,7 +483,8 @@ DBClientCursor::DBClientCursor(DBClientBase* client, 0, // nToSkip nullptr, // fieldsToReturn queryOptions, - 0) {} // batchSize + 0, + std::move(initialBatch)) {} // batchSize DBClientCursor::DBClientCursor(DBClientBase* client, const std::string& ns, @@ -491,8 +494,10 @@ DBClientCursor::DBClientCursor(DBClientBase* client, int nToSkip, const BSONObj* fieldsToReturn, int queryOptions, - int batchSize) - : _client(client), + int batchSize, + std::vector<BSONObj> initialBatch) + : batch{std::move(initialBatch)}, + _client(client), _originalHost(_client->getServerAddress()), ns(ns), _isCommand(nsIsFull(ns) ? nsToCollectionSubstring(ns) == "$cmd" : false), diff --git a/src/mongo/client/dbclientcursor.h b/src/mongo/client/dbclientcursor.h index 0601a3bf6ef..876d3f30db7 100644 --- a/src/mongo/client/dbclientcursor.h +++ b/src/mongo/client/dbclientcursor.h @@ -152,7 +152,8 @@ public: const std::string& ns, long long cursorId, int nToReturn, - int options); + int options, + std::vector<BSONObj> initialBatch = {}); virtual ~DBClientCursor(); @@ -224,11 +225,16 @@ private: int nToSkip, const BSONObj* fieldsToReturn, int queryOptions, - int bs); + int bs, + std::vector<BSONObj> initialBatch); int nextBatchSize(); struct Batch { + // TODO remove constructors after c++17 toolchain upgrade + Batch() = default; + Batch(std::vector<BSONObj> initial, size_t initialPos = 0) + : objs(std::move(initial)), pos(initialPos) {} std::vector<BSONObj> objs; size_t pos = 0; }; diff --git a/src/mongo/db/commands/user_management_commands.cpp b/src/mongo/db/commands/user_management_commands.cpp index e0f205b18fd..d1e53b2cb03 100644 --- a/src/mongo/db/commands/user_management_commands.cpp +++ b/src/mongo/db/commands/user_management_commands.cpp @@ -1379,21 +1379,27 @@ public: pipeline.push_back(BSON("$match" << *args.filter)); } + DBDirectClient client(opCtx); + BSONObjBuilder responseBuilder; AggregationRequest aggRequest(AuthorizationManager::usersCollectionNamespace, std::move(pipeline)); - Status status = runAggregate(opCtx, + uassertStatusOK(runAggregate(opCtx, AuthorizationManager::usersCollectionNamespace, aggRequest, aggRequest.serializeToCommandObj().toBson(), - responseBuilder); - uassertStatusOK(status); - + responseBuilder)); CommandHelpers::appendSimpleCommandStatus(responseBuilder, true); - auto swResponse = CursorResponse::parseFromBSON(responseBuilder.obj()); - uassertStatusOK(swResponse.getStatus()); - for (const BSONObj& obj : swResponse.getValue().getBatch()) { - usersArrayBuilder.append(obj); + auto response = CursorResponse::parseFromBSONThrowing(responseBuilder.obj()); + DBClientCursor cursor(&client, + response.getNSS().toString(), + response.getCursorId(), + 0, + 0, + response.releaseBatch()); + + while (cursor.more()) { + usersArrayBuilder.append(cursor.next()); } } result.append("users", usersArrayBuilder.arr()); |