diff options
author | Kyle Suarez <kyle.suarez@mongodb.com> | 2016-08-01 14:33:15 -0400 |
---|---|---|
committer | Kyle Suarez <kyle.suarez@mongodb.com> | 2016-08-11 11:07:41 -0400 |
commit | eb15955c67b8a13455b91a6848f8750447fb0f44 (patch) | |
tree | 8a347bd0a5d33ce1fd4ab67ed1e17ce4c09c78e0 /jstests/auth/views_authz.js | |
parent | b4b3cda7501f1d4a292f3b02e13631fae8d4de7f (diff) | |
download | mongo-eb15955c67b8a13455b91a6848f8750447fb0f44.tar.gz |
SERVER-24724 authz for views
Adds special authorization logic to prevent a user from reading
normally-inaccessible collections via a view.
Diffstat (limited to 'jstests/auth/views_authz.js')
-rw-r--r-- | jstests/auth/views_authz.js | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/jstests/auth/views_authz.js b/jstests/auth/views_authz.js new file mode 100644 index 00000000000..e187dff9c90 --- /dev/null +++ b/jstests/auth/views_authz.js @@ -0,0 +1,86 @@ +/** + * Tests authorization special cases with views. These are special exceptions that prohibit certain + * operations on views even if the user has an explicit privilege on that view. + */ +(function() { + "use strict"; + + let mongod = MongoRunner.runMongod({auth: "", bind_ip: "127.0.0.1"}); + + // Create the admin user. + let adminDB = mongod.getDB("admin"); + assert.commandWorked(adminDB.runCommand({createUser: "admin", pwd: "admin", roles: ["root"]})); + assert.eq(1, adminDB.auth("admin", "admin")); + + const viewsDBName = "views_authz"; + let viewsDB = adminDB.getSiblingDB(viewsDBName); + viewsDB.dropAllUsers(); + viewsDB.logout(); + + // Create a user who can read, create and modify a view 'view' and a read a namespace + // 'permitted' but does not have access to 'forbidden'. + assert.commandWorked(viewsDB.runCommand({ + createRole: "readWriteView", + privileges: [ + { + resource: {db: viewsDBName, collection: "view"}, + actions: ["find", "createCollection", "collMod"] + }, + {resource: {db: viewsDBName, collection: "permitted"}, actions: ["find"]} + ], + roles: [] + })); + assert.commandWorked( + viewsDB.runCommand({createUser: "viewUser", pwd: "pwd", roles: ["readWriteView"]})); + + adminDB.logout(); + assert.eq(1, viewsDB.auth("viewUser", "pwd")); + + const lookupStage = {$lookup: {from: "forbidden", localField: "x", foreignField: "x", as: "y"}}; + const graphLookupStage = { + $graphLookup: { + from: "forbidden", + startWith: [], + connectFromField: "x", + connectToField: "x", + as: "y" + } + }; + + // You cannot create a view if you have both the 'createCollection' and 'find' actions on that + // view but not the 'find' action on all of the dependent namespaces. + assert.commandFailedWithCode(viewsDB.createView("view", "forbidden", []), + ErrorCodes.Unauthorized); + assert.commandFailedWithCode(viewsDB.createView("view", "permitted", [lookupStage]), + ErrorCodes.Unauthorized); + assert.commandFailedWithCode(viewsDB.createView("view", "permitted", [graphLookupStage]), + ErrorCodes.Unauthorized); + assert.commandFailedWithCode( + viewsDB.createView("view", "permitted", [{$facet: {a: [lookupStage]}}]), + ErrorCodes.Unauthorized); + assert.commandFailedWithCode( + viewsDB.createView("view", "permitted", [{$facet: {b: [graphLookupStage]}}]), + ErrorCodes.Unauthorized); + + assert.commandWorked(viewsDB.createView("view", "permitted", [{$match: {x: 1}}])); + + // You cannot modify a view if you have both the 'collMod' and 'find' actions on that view but + // not the 'find' action on all of the dependent namespaces. + assert.commandFailedWithCode( + viewsDB.runCommand({collMod: "view", viewOn: "forbidden", pipeline: [{$match: {}}]}), + ErrorCodes.Unauthorized); + assert.commandFailedWithCode( + viewsDB.runCommand({collMod: "view", viewOn: "permitted", pipeline: [lookupStage]}), + ErrorCodes.Unauthorized); + assert.commandFailedWithCode( + viewsDB.runCommand({collMod: "view", viewOn: "permitted", pipeline: [graphLookupStage]}), + ErrorCodes.Unauthorized); + assert.commandFailedWithCode( + viewsDB.runCommand( + {collMod: "view", viewOn: "permitted", pipeline: [{$facet: {a: [lookupStage]}}]}), + ErrorCodes.Unauthorized); + assert.commandFailedWithCode( + viewsDB.runCommand( + {collMod: "view", viewOn: "permitted", pipeline: [{$facet: {b: [graphLookupStage]}}]}), + ErrorCodes.Unauthorized); +}()); |