mirror of https://github.com/mongodb/mongo
177 lines
5.0 KiB
JavaScript
177 lines
5.0 KiB
JavaScript
// Tests that $$USER_ROLES is able to be used in an "update" and "findAndModify" commands.
|
|
// @tags: [requires_fcv_70]
|
|
|
|
import {ShardingTest} from "jstests/libs/shardingtest.js";
|
|
|
|
const dbName = "test";
|
|
const collName = "coll";
|
|
|
|
function initialize(db) {
|
|
let engDoc = {
|
|
_id: 0,
|
|
allowedRoles: ["eng-app-prod", "eng-app-stg", "read"],
|
|
allowedRole: "read",
|
|
comment: "only for engineering team",
|
|
teamMembers: ["John", "Ashley", "Gina"],
|
|
yearlyEduBudget: 15000,
|
|
yearlyTnEBudget: 2000,
|
|
salesWins: 1000,
|
|
};
|
|
|
|
let salesDoc = {
|
|
_id: 1,
|
|
allowedRoles: ["sales-person"],
|
|
allowedRole: "observe",
|
|
comment: "only for sales team",
|
|
salesWins: 1000,
|
|
};
|
|
|
|
let testUpdate = {_id: 2, allowedRole: "test", teamMembersRights: ["testUpdate"]};
|
|
|
|
let testFindAndModify = {
|
|
_id: 3,
|
|
allowedRole: "write",
|
|
teamMembersRights: ["testFindAndModify"],
|
|
};
|
|
|
|
let coll = db.getCollection(collName);
|
|
assert.commandWorked(coll.insertMany([engDoc, salesDoc, testUpdate, testFindAndModify]));
|
|
}
|
|
|
|
// Test accessing $$USER_ROLES in the query portion of "update" command.
|
|
function runUpdateQuery(db) {
|
|
let coll = db.getCollection(collName);
|
|
|
|
let pre = coll.findOne({$expr: {$eq: [{$setIntersection: ["$allowedRoles", "$$USER_ROLES.role"]}, []]}});
|
|
let preSalesWins = pre.salesWins;
|
|
|
|
assert.commandWorked(
|
|
coll.update(
|
|
{$expr: {$eq: [{$setIntersection: ["$allowedRoles", "$$USER_ROLES.role"]}, []]}},
|
|
{$inc: {salesWins: 1000}},
|
|
{multi: true},
|
|
),
|
|
);
|
|
|
|
let post = coll.findOne({$expr: {$eq: [{$setIntersection: ["$allowedRoles", "$$USER_ROLES.role"]}, []]}});
|
|
let postSalesWins = post.salesWins;
|
|
|
|
assert.eq(postSalesWins, preSalesWins + 1000);
|
|
}
|
|
|
|
// Test accessing $$USER_ROLES in the update portion of "update" command.
|
|
function runUpdateUpdate(db) {
|
|
let coll = db.getCollection(collName);
|
|
|
|
assert.commandWorked(coll.update({_id: 2}, [{$set: {"teamMembersRights": "$$USER_ROLES.role"}}]));
|
|
|
|
let post = coll.findOne({_id: 2});
|
|
|
|
let expectedResult = {
|
|
_id: 2,
|
|
allowedRole: "test",
|
|
teamMembersRights: ["readWriteAnyDatabase", "read"],
|
|
};
|
|
|
|
assert.eq(post, expectedResult);
|
|
}
|
|
|
|
// Test accessing $$USER_ROLES in the query portion of "findAndModify" command.
|
|
function runFindAndModifyQuery(db) {
|
|
let coll = db.getCollection(collName);
|
|
|
|
let pre = coll.findOne({$expr: {allowedRole: "$$USER_ROLES.role"}});
|
|
let preSalesWins = pre.salesWins;
|
|
|
|
db.coll.findAndModify({
|
|
query: {allowedRole: "read", $expr: {allowedRole: "$$USER_ROLES.role"}},
|
|
update: {$inc: {salesWins: 1000}},
|
|
});
|
|
|
|
let post = coll.findOne({$expr: {allowedRole: "$$USER_ROLES.role"}});
|
|
let postSalesWins = post.salesWins;
|
|
|
|
assert.eq(postSalesWins, preSalesWins + 1000);
|
|
}
|
|
|
|
// Test accessing $$USER_ROLES in the update portion of "findAndModify" command.
|
|
function runFindAndModifyUpdate(db) {
|
|
let coll = db.getCollection(collName);
|
|
|
|
coll.findAndModify({
|
|
query: {allowedRole: "write"},
|
|
update: [{$set: {"teamMembersRights": "$$USER_ROLES.role"}}],
|
|
});
|
|
|
|
let post = coll.findOne({_id: 3});
|
|
|
|
let expectedResult = {
|
|
_id: 3,
|
|
allowedRole: "write",
|
|
teamMembersRights: ["readWriteAnyDatabase", "read"],
|
|
};
|
|
|
|
assert.eq(post, expectedResult);
|
|
}
|
|
|
|
function runTest(conn, st = null) {
|
|
// Create a user on the admin database.
|
|
let admin = conn.getDB("admin");
|
|
assert.commandWorked(admin.runCommand({createUser: "admin", pwd: "admin", roles: ["root"]}));
|
|
admin.auth("admin", "admin");
|
|
|
|
if (st) {
|
|
// Shard the collection that will be used in the update and findAndModify commands.
|
|
assert.commandWorked(conn.getDB("admin").runCommand({enableSharding: dbName}));
|
|
st.shardColl(conn.getDB(dbName).getCollection(collName), {allowedRole: 1});
|
|
}
|
|
|
|
const db = conn.getDB(dbName);
|
|
|
|
// Create a user that has roles on more than one database. The readWriteAnyDatabase is
|
|
// necessary for the inserts that follow to work.
|
|
assert.commandWorked(
|
|
db.runCommand({
|
|
createUser: "user",
|
|
pwd: "pwd",
|
|
roles: [
|
|
{role: "readWriteAnyDatabase", db: "admin"},
|
|
{role: "read", db: dbName},
|
|
],
|
|
}),
|
|
);
|
|
|
|
// Logout of the admin user so that we can log into the other user so we can access those
|
|
// roles with $$USER_ROLES below.
|
|
admin.logout();
|
|
db.auth("user", "pwd");
|
|
|
|
initialize(db);
|
|
|
|
runUpdateQuery(db);
|
|
|
|
runUpdateUpdate(db);
|
|
|
|
runFindAndModifyQuery(db);
|
|
|
|
runFindAndModifyUpdate(db);
|
|
|
|
db.logout();
|
|
}
|
|
|
|
jsTest.log("Test standalone");
|
|
const mongod = MongoRunner.runMongod({auth: ""});
|
|
runTest(mongod);
|
|
MongoRunner.stopMongod(mongod);
|
|
|
|
jsTest.log("Test sharded cluster");
|
|
const st = new ShardingTest({
|
|
mongos: 1,
|
|
config: 1,
|
|
shards: 2,
|
|
keyFile: "jstests/libs/key1",
|
|
});
|
|
|
|
runTest(st.s, st);
|
|
st.stop();
|