summaryrefslogtreecommitdiff
path: root/src/mongo/db/auth
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@10gen.com>2013-09-06 14:12:13 -0400
committerSpencer T Brody <spencer@10gen.com>2013-09-09 11:43:45 -0400
commiteb46cc62a0d6e08e2cabc0862490d76f2833e8b1 (patch)
tree780c981e5ec88f919775bc8d3225c58fc820b503 /src/mongo/db/auth
parent667648a2d9e97ca0ecf995e89eba75fd3e70a08c (diff)
downloadmongo-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.cpp2
-rw-r--r--src/mongo/db/auth/authorization_manager_test.cpp10
-rw-r--r--src/mongo/db/auth/privilege_document_parser.cpp3
-rw-r--r--src/mongo/db/auth/privilege_document_parser_test.cpp16
-rw-r--r--src/mongo/db/auth/user.cpp19
-rw-r--r--src/mongo/db/auth/user.h23
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;