diff options
author | Spencer Jackson <spencer.jackson@mongodb.com> | 2020-01-15 16:30:37 +0000 |
---|---|---|
committer | Spencer Jackson <spencer.jackson@mongodb.com> | 2020-01-15 15:42:20 -0500 |
commit | a10d0a22d5d009d27664967181042933ec1bef36 (patch) | |
tree | 729a3622da26c8adc76207a7366a3440bd85f32c | |
parent | d0e18b320827819ee08efb7f8d65e9abd5f28d4f (diff) | |
download | mongo-a10d0a22d5d009d27664967181042933ec1bef36.tar.gz |
SERVER-45472 Ensure RoleGraph can serialize authentication restrictions to BSON
(cherry picked from commit 521e56b407ac72bc69a97a24d1253f51a5b6e81b)
-rw-r--r-- | jstests/auth/authentication_restrictions_role.js | 8 | ||||
-rw-r--r-- | src/mongo/db/auth/role_graph.cpp | 9 | ||||
-rw-r--r-- | src/mongo/db/auth/role_graph_test.cpp | 36 |
3 files changed, 52 insertions, 1 deletions
diff --git a/jstests/auth/authentication_restrictions_role.js b/jstests/auth/authentication_restrictions_role.js index 70256fba7f5..9e7ed765c2f 100644 --- a/jstests/auth/authentication_restrictions_role.js +++ b/jstests/auth/authentication_restrictions_role.js @@ -42,6 +42,14 @@ function testRestrictionCreationAndEnforcement( assert.commandWorked(admin.runCommand({createRole: "role3", roles: [], privileges: []})); print("=== Role creation tests"); + print("When a role is updated, it retains authenticationRestrictions"); + assert.commandWorked(admin.runCommand({updateRole: "role2", roles: ["root"]})); + const role2Info = assert.commandWorked( + admin.runCommand({rolesInfo: "role2", showAuthenticationRestrictions: true})); + printjson(role2Info); + assert.eq(JSON.stringify([[{clientSource: ["127.0.0.1/32"]}]]), + JSON.stringify(role2Info.roles[0].authenticationRestrictions)); + print( "When a client creates roles with empty authenticationRestrictions, the operation succeeds, though it has no effect"); assert.commandWorked(admin.runCommand( diff --git a/src/mongo/db/auth/role_graph.cpp b/src/mongo/db/auth/role_graph.cpp index b05a29fff4d..99c92d8d4b6 100644 --- a/src/mongo/db/auth/role_graph.cpp +++ b/src/mongo/db/auth/role_graph.cpp @@ -575,6 +575,15 @@ Status RoleGraph::getBSONForRole(RoleGraph* graph, uassertStatusOK(rolesArrayElement.pushBack(roleObj)); } + // Build authentication restrictions + auto restrictions = graph->getDirectAuthenticationRestrictions(roleName); + mutablebson::Element authenticationRestrictionsElement = + result.getDocument().makeElementArray("authenticationRestrictions"); + uassertStatusOK(result.pushBack(authenticationRestrictionsElement)); + if (restrictions) { + uassertStatusOK(authenticationRestrictionsElement.setValueArray(restrictions->toBSON())); + } + return Status::OK(); } catch (...) { return exceptionToStatus(); diff --git a/src/mongo/db/auth/role_graph_test.cpp b/src/mongo/db/auth/role_graph_test.cpp index 765d3d3c61c..694a6b1884b 100644 --- a/src/mongo/db/auth/role_graph_test.cpp +++ b/src/mongo/db/auth/role_graph_test.cpp @@ -34,6 +34,7 @@ #include <algorithm> #include "mongo/bson/mutable/document.h" +#include "mongo/db/auth/address_restriction.h" #include "mongo/db/auth/role_graph.h" #include "mongo/unittest/unittest.h" #include "mongo/util/sequence_util.h" @@ -47,16 +48,21 @@ TEST(RoleParsingTest, BuildRoleBSON) { RoleName roleA("roleA", "dbA"); RoleName roleB("roleB", "dbB"); RoleName roleC("roleC", "dbC"); + RoleName roleD("roleD", "dbD"); ActionSet actions; actions.addAction(ActionType::find); actions.addAction(ActionType::insert); + SharedRestrictionDocument restrictions = uassertStatusOK(parseAuthenticationRestriction( + BSON_ARRAY(BSON("clientSource" << BSON_ARRAY("127.0.0.1"))))); ASSERT_OK(graph.createRole(roleA)); ASSERT_OK(graph.createRole(roleB)); ASSERT_OK(graph.createRole(roleC)); + ASSERT_OK(graph.createRole(roleD)); ASSERT_OK(graph.addRoleToRole(roleA, roleC)); ASSERT_OK(graph.addRoleToRole(roleA, roleB)); + ASSERT_OK(graph.addRoleToRole(roleA, roleD)); ASSERT_OK(graph.addRoleToRole(roleB, roleC)); ASSERT_OK(graph.addPrivilegeToRole( @@ -65,6 +71,7 @@ TEST(RoleParsingTest, BuildRoleBSON) { roleB, Privilege(ResourcePattern::forExactNamespace(NamespaceString("dbB.foo")), actions))); ASSERT_OK( graph.addPrivilegeToRole(roleC, Privilege(ResourcePattern::forClusterResource(), actions))); + ASSERT_OK(graph.replaceRestrictionsForRole(roleD, restrictions)); ASSERT_OK(graph.recomputePrivilegeData()); @@ -77,6 +84,8 @@ TEST(RoleParsingTest, BuildRoleBSON) { ASSERT_EQUALS("roleA", roleDoc["role"].String()); ASSERT_EQUALS("dbA", roleDoc["db"].String()); + ASSERT_TRUE(roleDoc["authenticationRestrictions"].Array().empty()); + std::vector<BSONElement> privs = roleDoc["privileges"].Array(); ASSERT_EQUALS(1U, privs.size()); ASSERT_EQUALS("", privs[0].Obj()["resource"].Obj()["db"].String()); @@ -88,7 +97,7 @@ TEST(RoleParsingTest, BuildRoleBSON) { ASSERT_EQUALS("insert", actionElements[1].String()); std::vector<BSONElement> roles = roleDoc["roles"].Array(); - ASSERT_EQUALS(2U, roles.size()); + ASSERT_EQUALS(3U, roles.size()); ASSERT_EQUALS("roleC", roles[0].Obj()["role"].String()); ASSERT_EQUALS("dbC", roles[0].Obj()["db"].String()); ASSERT_EQUALS("roleB", roles[1].Obj()["role"].String()); @@ -103,6 +112,8 @@ TEST(RoleParsingTest, BuildRoleBSON) { ASSERT_EQUALS("roleB", roleDoc["role"].String()); ASSERT_EQUALS("dbB", roleDoc["db"].String()); + ASSERT_TRUE(roleDoc["authenticationRestrictions"].Array().empty()); + privs = roleDoc["privileges"].Array(); ASSERT_EQUALS(1U, privs.size()); ASSERT_EQUALS("dbB", privs[0].Obj()["resource"].Obj()["db"].String()); @@ -127,6 +138,8 @@ TEST(RoleParsingTest, BuildRoleBSON) { ASSERT_EQUALS("roleC", roleDoc["role"].String()); ASSERT_EQUALS("dbC", roleDoc["db"].String()); + ASSERT_TRUE(roleDoc["authenticationRestrictions"].Array().empty()); + privs = roleDoc["privileges"].Array(); ASSERT_EQUALS(1U, privs.size()); ASSERT(privs[0].Obj()["resource"].Obj()["cluster"].Bool()); @@ -139,6 +152,27 @@ TEST(RoleParsingTest, BuildRoleBSON) { roles = roleDoc["roles"].Array(); ASSERT_EQUALS(0U, roles.size()); + + // Role D + doc.reset(); + ASSERT_OK(RoleGraph::getBSONForRole(&graph, roleD, doc.root())); + roleDoc = doc.getObject(); + + ASSERT_EQUALS("dbD.roleD", roleDoc["_id"].String()); + ASSERT_EQUALS("roleD", roleDoc["role"].String()); + ASSERT_EQUALS("dbD", roleDoc["db"].String()); + + ASSERT_FALSE(roleDoc["authenticationRestrictions"].Array().empty()); + auto restrictionObj = BSONArray(roleDoc["authenticationRestrictions"].Obj()); + SharedRestrictionDocument parsedRestrictions = + uassertStatusOK(parseAuthenticationRestriction(restrictionObj)); + ASSERT_EQ(restrictions->toString(), parsedRestrictions->toString()); + + privs = roleDoc["privileges"].Array(); + ASSERT_TRUE(privs.empty()); + + roles = roleDoc["roles"].Array(); + ASSERT_EQUALS(0U, roles.size()); } // Tests adding and removing roles from other roles, the RoleNameIterator, and the |