diff options
author | Spencer Jackson <spencer.jackson@mongodb.com> | 2016-09-26 12:54:12 -0400 |
---|---|---|
committer | Spencer Jackson <spencer.jackson@mongodb.com> | 2016-09-30 13:43:42 -0400 |
commit | 1ac511f1673d9663454651c2763aec32387c077f (patch) | |
tree | d8b367422ab62a89f928e585b8c4ba4ba9e906a1 /jstests | |
parent | 67c441cf094920674fc76668d5b0d225503a9c8a (diff) | |
download | mongo-1ac511f1673d9663454651c2763aec32387c077f.tar.gz |
SERVER-25994: Make applyOps work without universal privileges
Diffstat (limited to 'jstests')
-rw-r--r-- | jstests/auth/lib/commands_lib.js | 239 | ||||
-rw-r--r-- | jstests/core/apply_ops1.js | 145 |
2 files changed, 374 insertions, 10 deletions
diff --git a/jstests/auth/lib/commands_lib.js b/jstests/auth/lib/commands_lib.js index ae08ff755cc..daea8325abb 100644 --- a/jstests/auth/lib/commands_lib.js +++ b/jstests/auth/lib/commands_lib.js @@ -198,25 +198,250 @@ var authCommandsLib = { roles: Object.extend({readWriteAnyDatabase: 1}, roles_clusterManager) }] }, + { - testname: "applyOps", - command: {applyOps: "x"}, + testname: "applyOps_empty", + command: {applyOps: []}, + skipSharded: true, testcases: [ { + roles: {__system: 1}, runOnDb: adminDbName, + }, + { roles: {__system: 1}, - privileges: [{resource: {anyResource: true}, actions: ["anyAction"]}], - expectFail: true + runOnDb: firstDbName, + } + ] + }, + { + testname: "applyOps_precondition", + command: { + applyOps: [{ + "ts": Timestamp(1473353037, 1), + "h": NumberLong(0), + "v": 2, + "op": "n", + "ns": "", + "o": {} + }], + preCondition: [{ns: firstDbName + ".x", q: {x: 5}, res: []}] + }, + skipSharded: true, + setup: function(db) { + db.getSisterDB(firstDbName).x.save({}); + }, + teardown: function(db) { + db.getSisterDB(firstDbName).x.drop(); + }, + testcases: [ + { + runOnDb: adminDbName, + privileges: [ + {resource: {db: firstDbName, collection: "x"}, actions: ["find"]}, + { + resource: {cluster: true}, + actions: ["appendOplogNote"], + removeWhenTestingAuthzFailure: false + }, + ], + }, + ] + }, + { + testname: "applyOps_noop", + command: { + applyOps: [{ + "ts": Timestamp(1473353037, 1), + "h": NumberLong(0), + "v": 2, + "op": "n", + "ns": "", + "o": {} + }] + }, + skipSharded: true, + testcases: [ + { + runOnDb: adminDbName, + privileges: [ + {resource: {cluster: true}, actions: ["appendOplogNote"]}, + ], }, { runOnDb: firstDbName, - roles: {__system: 1}, - privileges: [{resource: {anyResource: true}, actions: ["anyAction"]}], - expectFail: true + privileges: [ + {resource: {cluster: true}, actions: ["appendOplogNote"]}, + ], + expectFailure: true } ] }, { + testname: "applyOps_c_renameCollection_twoDbs", + command: { + applyOps: [{ + "ts": Timestamp(1474051004, 1), + "h": NumberLong(0), + "v": 2, + "op": "c", + "ns": "test.$cmd", + "o": { + "renameCollection": firstDbName + ".x", + "to": secondDbName + ".y", + "stayTemp": false, + "dropTarget": false + } + }] + }, + skipSharded: true, + setup: function(db) { + db.getSisterDB(firstDbName).x.save({}); + db.getSisterDB(adminDbName).runCommand({movePrimary: firstDbName, to: shard0name}); + db.getSisterDB(adminDbName).runCommand({movePrimary: secondDbName, to: shard0name}); + }, + teardown: function(db) { + db.getSisterDB(firstDbName).x.drop(); + db.getSisterDB(secondDbName).y.drop(); + }, + testcases: [ + { + runOnDb: adminDbName, + roles: {readWriteAnyDatabase: 1, root: 1, __system: 1}, + privileges: [ + { + resource: {db: firstDbName, collection: "x"}, + actions: ["find", "dropCollection"] + }, + { + resource: {db: secondDbName, collection: "y"}, + actions: ["insert", "createIndex"] + } + ] + }, + ] + }, + { + testname: "applyOps_insert", + command: { + applyOps: [{ + "ts": Timestamp(1474051453, 1), + "h": NumberLong(0), + "v": 2, + "op": "i", + "ns": firstDbName + ".x", + "o": {"_id": ObjectId("57dc3d7da4fce4358afa85b8"), "data": 5} + }] + }, + skipSharded: true, + setup: function(db) { + db.getSisterDB(firstDbName).x.save({}); + }, + teardown: function(db) { + db.getSisterDB(firstDbName).x.drop(); + }, + testcases: [ + { + runOnDb: adminDbName, + roles: roles_write, + privileges: [ + {resource: {db: firstDbName, collection: "x"}, actions: ["insert"]}, + ], + }, + ] + }, + { + testname: "applyOps_upsert", + command: { + applyOps: [{ + "ts": Timestamp(1474053682, 1), + "h": NumberLong(0), + "v": 2, + "op": "u", + "ns": firstDbName + ".x", + "o2": {"_id": 1}, + "o": {"_id": 1, "data": 8} + }] + }, + skipSharded: true, + setup: function(db) { + db.getSisterDB(firstDbName).x.save({_id: 1, data: 1}); + }, + teardown: function(db) { + db.getSisterDB(firstDbName).x.drop(); + }, + testcases: [ + { + runOnDb: adminDbName, + roles: Object.merge(roles_write, {restore: 0}, true), + privileges: [ + {resource: {db: firstDbName, collection: "x"}, actions: ["update", "insert"]}, + ], + }, + ] + }, + { + testname: "applyOps_update", + command: { + applyOps: [{ + "ts": Timestamp(1474053682, 1), + "h": NumberLong(0), + "v": 2, + "op": "u", + "ns": firstDbName + ".x", + "o2": {"_id": 1}, + "o": {"_id": 1, "data": 8} + }], + alwaysUpsert: false + }, + skipSharded: true, + setup: function(db) { + db.getSisterDB(firstDbName).x.save({_id: 1, data: 1}); + }, + teardown: function(db) { + db.getSisterDB(firstDbName).x.drop(); + }, + testcases: [ + { + runOnDb: adminDbName, + roles: Object.merge(roles_write, {restore: 0}, true), + privileges: [ + {resource: {db: firstDbName, collection: "x"}, actions: ["update"]}, + ], + }, + ] + }, + { + testname: "applyOps_delete", + command: { + applyOps: [{ + "ts": Timestamp(1474056194, 1), + "h": NumberLong(0), + "v": 2, + "op": "d", + "ns": firstDbName + ".x", + "o": {"_id": 1} + }] + }, + skipSharded: true, + setup: function(db) { + db.getSisterDB(firstDbName).x.save({_id: 1, data: 1}); + }, + teardown: function(db) { + db.getSisterDB(firstDbName).x.drop(); + }, + testcases: [ + { + runOnDb: adminDbName, + roles: Object.merge(roles_write, {restore: 0}, true), + privileges: [ + {resource: {db: firstDbName, collection: "x"}, actions: ["remove"]}, + ], + }, + ] + }, + + { testname: "aggregate_readonly", command: {aggregate: "foo", pipeline: []}, testcases: [ diff --git a/jstests/core/apply_ops1.js b/jstests/core/apply_ops1.js index 1e6b545a210..8ce15b1df22 100644 --- a/jstests/core/apply_ops1.js +++ b/jstests/core/apply_ops1.js @@ -66,6 +66,144 @@ db.adminCommand({applyOps: [{op: 'c', ns: ''}]}), 'applyOps should fail on non-"n" operation type with empty "ns" field value'); + // Excessively nested applyOps commands gracefully fail. + assert.commandFailed(db.adminCommand({ + "applyOps": [{ + "ts": {"$timestamp": {"t": 1, "i": 100}}, + "h": 0, + "v": 2, + "op": "c", + "ns": "test.$cmd", + "o": { + "applyOps": [{ + "ts": {"$timestamp": {"t": 1, "i": 100}}, + "h": 0, + "v": 2, + "op": "c", + "ns": "test.$cmd", + "o": { + "applyOps": [{ + "ts": {"$timestamp": {"t": 1, "i": 100}}, + "h": 0, + "v": 2, + "op": "c", + "ns": "test.$cmd", + "o": { + "applyOps": [{ + "ts": {"$timestamp": {"t": 1, "i": 100}}, + "h": 0, + "v": 2, + "op": "c", + "ns": "test.$cmd", + "o": { + "applyOps": [{ + "ts": {"$timestamp": {"t": 1, "i": 100}}, + "h": 0, + "v": 2, + "op": "c", + "ns": "test.$cmd", + "o": { + "applyOps": [{ + "ts": {"$timestamp": {"t": 1, "i": 100}}, + "h": 0, + "v": 2, + "op": "c", + "ns": "test.$cmd", + "o": { + "applyOps": [{ + "ts": + {"$timestamp": {"t": 1, "i": 100}}, + "h": 0, + "v": 2, + "op": "c", + "ns": "test.$cmd", + "o": { + "applyOps": [{ + "ts": { + "$timestamp": + {"t": 1, "i": 100} + }, + "h": 0, + "v": 2, + "op": "c", + "ns": "test.$cmd", + "o": { + "applyOps": [{ + "ts": { + "$timestamp": { + "t": 1, + "i": 100 + } + }, + "h": 0, + "v": 2, + "op": "c", + "ns": "test.$cmd", + "o": { + "applyOps": [{ + "ts": { + "$timestamp": + { + "t": + 1, + "i": + 100 + } + }, + "h": 0, + "v": 2, + "op": "c", + "ns": + "test.$cmd", + "o": { + "applyOps": [ + { + "ts": { + "$timestamp": { + "t": + 1, + "i": + 100 + } + }, + "h": + 0, + "v": + 2, + "op": + "c", + "ns": + "test.$cmd", + "o": { + "applyOps": + [ + ] + } + } + ] + } + }] + } + }] + } + }] + } + }] + } + }] + } + }] + } + }] + } + }] + } + }] + } + }] + }), + "Excessively nested applyOps should be rejected"); + // Missing 'o' field value in an operation of type 'i' on 'system.indexes' collection. assert.commandFailedWithCode( db.adminCommand({applyOps: [{op: 'i', ns: db.getName() + '.system.indexes'}]}), @@ -153,7 +291,8 @@ "Applying an insert operation on a non-existent collection should fail"); assert.commandWorked(db.createCollection(t.getName())); - var a = db.adminCommand({applyOps: [{"op": "i", "ns": t.getFullName(), "o": {_id: 5, x: 17}}]}); + var a = assert.commandWorked( + db.adminCommand({applyOps: [{"op": "i", "ns": t.getFullName(), "o": {_id: 5, x: 17}}]})); assert.eq(1, t.find().count(), "Valid insert failed"); assert.eq(true, a.results[0], "Bad result value for valid insert"); @@ -169,12 +308,12 @@ assert.commandFailed(db.adminCommand({applyOps: [{op: 'i', ns: t.getFullName(), o: []}]}), 'applyOps should fail on insert of object with empty array element'); - var res = db.runCommand({ + var res = assert.commandWorked(db.runCommand({ applyOps: [ {op: "u", ns: t.getFullName(), o2: {_id: 5}, o: {$inc: {x: 1}}}, {op: "u", ns: t.getFullName(), o2: {_id: 5}, o: {$inc: {x: 1}}} ] - }); + })); o.x++; o.x++; |