diff options
author | Spencer T Brody <spencer@10gen.com> | 2013-09-06 14:12:13 -0400 |
---|---|---|
committer | Spencer T Brody <spencer@10gen.com> | 2013-09-09 11:43:45 -0400 |
commit | eb46cc62a0d6e08e2cabc0862490d76f2833e8b1 (patch) | |
tree | 780c981e5ec88f919775bc8d3225c58fc820b503 /src/mongo/db/auth | |
parent | 667648a2d9e97ca0ecf995e89eba75fd3e70a08c (diff) | |
download | mongo-eb46cc62a0d6e08e2cabc0862490d76f2833e8b1.tar.gz |
SERVER-9518 Store delegatable roles list in User object in memory
Diffstat (limited to 'src/mongo/db/auth')
-rw-r--r-- | src/mongo/db/auth/authorization_manager.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/auth/authorization_manager_test.cpp | 10 | ||||
-rw-r--r-- | src/mongo/db/auth/privilege_document_parser.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/auth/privilege_document_parser_test.cpp | 16 | ||||
-rw-r--r-- | src/mongo/db/auth/user.cpp | 19 | ||||
-rw-r--r-- | src/mongo/db/auth/user.h | 23 |
6 files changed, 68 insertions, 5 deletions
diff --git a/src/mongo/db/auth/authorization_manager.cpp b/src/mongo/db/auth/authorization_manager.cpp index 07faa831d24..b9b59d003ce 100644 --- a/src/mongo/db/auth/authorization_manager.cpp +++ b/src/mongo/db/auth/authorization_manager.cpp @@ -771,7 +771,7 @@ namespace { BSONObjBuilder roleBuilder(rolesArray.subobjStart()); roleBuilder.append("name", roleName.getRole()); roleBuilder.append("source", roleName.getDB()); - roleBuilder.appendBool("canDelegate", false); + roleBuilder.appendBool("canDelegate", user.canDelegateRole(roleName)); roleBuilder.appendBool("hasRole", true); roleBuilder.doneFast(); } diff --git a/src/mongo/db/auth/authorization_manager_test.cpp b/src/mongo/db/auth/authorization_manager_test.cpp index a053c9c7cc7..b5d86841923 100644 --- a/src/mongo/db/auth/authorization_manager_test.cpp +++ b/src/mongo/db/auth/authorization_manager_test.cpp @@ -562,7 +562,7 @@ namespace { "credentials" << BSON("MONGODB-CR" << "password") << "roles" << BSON_ARRAY(BSON("name" << "clusterAdmin" << "source" << "admin" << - "canDelegate" << false << + "canDelegate" << true << "hasRole" << true))))); User* v2read; @@ -576,6 +576,7 @@ namespace { ASSERT_EQUALS("test", roleName.getDB()); ASSERT_EQUALS("read", roleName.getRole()); ASSERT_FALSE(it.more()); + ASSERT(!v2read->canDelegateRole(roleName)); ActionSet actions = v2read->getActionsForResource("test"); ASSERT(actions.contains(ActionType::find)); ASSERT_FALSE(actions.contains(ActionType::insert)); @@ -597,6 +598,13 @@ namespace { ASSERT_EQUALS("admin", roleName.getDB()); ASSERT_EQUALS("clusterAdmin", roleName.getRole()); ASSERT_FALSE(it.more()); + it = v2cluster->getDelegatableRoles(); + ASSERT(it.more()); + roleName = it.next(); + ASSERT_EQUALS("admin", roleName.getDB()); + ASSERT_EQUALS("clusterAdmin", roleName.getRole()); + ASSERT_FALSE(it.more()); + ASSERT(v2cluster->canDelegateRole(roleName)); actions = v2cluster->getActionsForResource("*"); ASSERT(actions.contains(ActionType::listDatabases)); ASSERT(actions.contains(ActionType::dropDatabase)); diff --git a/src/mongo/db/auth/privilege_document_parser.cpp b/src/mongo/db/auth/privilege_document_parser.cpp index 2bdd50f0d4b..78b75697b64 100644 --- a/src/mongo/db/auth/privilege_document_parser.cpp +++ b/src/mongo/db/auth/privilege_document_parser.cpp @@ -428,7 +428,8 @@ namespace { user->addRole(RoleName(roleNameElement.String(), roleSourceElement.String())); } if (canDelegateElement.Bool()) { - // TODO(spencer): record the fact that this user can delegate this role + user->addDelegatableRole(RoleName(roleNameElement.String(), + roleSourceElement.String())); } } return Status::OK(); diff --git a/src/mongo/db/auth/privilege_document_parser_test.cpp b/src/mongo/db/auth/privilege_document_parser_test.cpp index 505993b2842..2f004e59c41 100644 --- a/src/mongo/db/auth/privilege_document_parser_test.cpp +++ b/src/mongo/db/auth/privilege_document_parser_test.cpp @@ -269,6 +269,10 @@ namespace { "test")); RoleNameIterator nameIt = user->getRoles(); ASSERT(!nameIt.more()); + nameIt = user->getDelegatableRoles(); + ASSERT(nameIt.more()); + ASSERT(nameIt.next() == RoleName("roleA", "dbA")); + ASSERT(!nameIt.more()); // Valid role names are extracted successfully ASSERT_OK(v2parser.initializeUserRolesFromPrivilegeDocument( @@ -283,6 +287,10 @@ namespace { ASSERT(nameIt.more()); ASSERT(nameIt.next() == RoleName("roleA", "dbA")); ASSERT(!nameIt.more()); + nameIt = user->getDelegatableRoles(); + ASSERT(nameIt.more()); + ASSERT(nameIt.next() == RoleName("roleA", "dbA")); + ASSERT(!nameIt.more()); // Multiple roles OK ASSERT_OK(v2parser.initializeUserRolesFromPrivilegeDocument( @@ -294,7 +302,7 @@ namespace { "hasRole" << true) << BSON("name" << "roleB" << "source" << "dbB" << - "canDelegate" << true << + "canDelegate" << false << "hasRole" << true))), "test")); nameIt = user->getRoles(); @@ -310,6 +318,12 @@ namespace { ASSERT(false); } ASSERT(!nameIt.more()); + nameIt = user->getDelegatableRoles(); + ASSERT(nameIt.more()); + ASSERT(nameIt.next() == RoleName("roleA", "dbA")); + ASSERT(!nameIt.more()); + ASSERT(user->canDelegateRole(RoleName("roleA", "dbA"))); + ASSERT(!user->canDelegateRole(RoleName("roleB", "dbB"))); } } // namespace diff --git a/src/mongo/db/auth/user.cpp b/src/mongo/db/auth/user.cpp index 5040675446f..e5a39e43c58 100644 --- a/src/mongo/db/auth/user.cpp +++ b/src/mongo/db/auth/user.cpp @@ -39,6 +39,15 @@ namespace mongo { return RoleNameIterator(new RoleNameSetIterator(_roles.begin(), _roles.end())); } + const RoleNameIterator User::getDelegatableRoles() const { + return RoleNameIterator(new RoleNameSetIterator(_delegatableRoles.begin(), + _delegatableRoles.end())); + } + + bool User::canDelegateRole(const RoleName& role) const { + return _delegatableRoles.count(role); + } + const User::CredentialData& User::getCredentials() const { return _credentials; } @@ -82,6 +91,16 @@ namespace mongo { } } + void User::addDelegatableRole(const RoleName& role) { + _delegatableRoles.insert(role); + } + + void User::addDelegatableRoles(const std::vector<RoleName>& roles) { + for (std::vector<RoleName>::const_iterator it = roles.begin(); it != roles.end(); ++it) { + _delegatableRoles.insert(*it); + } + } + void User::addPrivilege(const Privilege& privilegeToAdd) { ResourcePrivilegeMap::iterator it = _privileges.find(privilegeToAdd.getResource()); if (it == _privileges.end()) { diff --git a/src/mongo/db/auth/user.h b/src/mongo/db/auth/user.h index 0e164797d33..f2d3cfbb385 100644 --- a/src/mongo/db/auth/user.h +++ b/src/mongo/db/auth/user.h @@ -63,6 +63,16 @@ namespace mongo { const RoleNameIterator getRoles() const; /** + * Returns an iterator that can be used to get the list of roles this user can delegate. + */ + const RoleNameIterator getDelegatableRoles() const; + + /** + * Returns whether or not this user is allowed to delegate the given role. + */ + bool canDelegateRole(const RoleName& role) const; + + /** * Returns the CredentialData for this user. */ const CredentialData& getCredentials() const; @@ -109,6 +119,16 @@ namespace mongo { void addRoles(const std::vector<RoleName>& roles); /** + * Adds the given role name to the list of roles that this user is allowed to delegate. + */ + void addDelegatableRole(const RoleName& role); + + /** + * Adds the given role names to the list of roles that this user is allowed to delegate. + */ + void addDelegatableRoles(const std::vector<RoleName>& roles); + + /** * Adds the given privilege to the list of privileges this user is authorized for. */ void addPrivilege(const Privilege& privilege); @@ -153,7 +173,8 @@ namespace mongo { // Maps resource name to privilege on that resource ResourcePrivilegeMap _privileges; - unordered_set<RoleName> _roles; + unordered_set<RoleName> _roles; // Roles the user actually has privileges from + unordered_set<RoleName> _delegatableRoles; // Roles the user is allowed to delegate CredentialData _credentials; |