summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/client/SConscript1
-rw-r--r--src/mongo/db/SConscript1
-rw-r--r--src/mongo/db/auth/SConscript48
-rw-r--r--src/mongo/db/auth/authorization_manager.h21
-rw-r--r--src/mongo/db/auth/authorization_manager_impl.cpp51
-rw-r--r--src/mongo/db/auth/authorization_manager_test.cpp103
-rw-r--r--src/mongo/db/auth/privilege.cpp15
-rw-r--r--src/mongo/db/auth/privilege.h8
-rw-r--r--src/mongo/db/auth/role_graph.cpp44
-rw-r--r--src/mongo/db/auth/role_graph.h14
-rw-r--r--src/mongo/db/auth/role_graph_test.cpp100
-rw-r--r--src/mongo/db/auth/role_graph_update.cpp2
-rw-r--r--src/mongo/db/catalog/drop_database_test.cpp13
-rw-r--r--src/mongo/db/catalog/rename_collection_test.cpp6
-rw-r--r--src/mongo/db/commands/SConscript5
-rw-r--r--src/mongo/db/commands/user_management_commands.cpp4
-rw-r--r--src/mongo/db/repl/storage_interface_impl_test.cpp18
-rw-r--r--src/mongo/db/storage/wiredtiger/SConscript1
-rw-r--r--src/mongo/s/commands/SConscript1
19 files changed, 259 insertions, 197 deletions
diff --git a/src/mongo/client/SConscript b/src/mongo/client/SConscript
index 208e1ac5462..009e20c5eb2 100644
--- a/src/mongo/client/SConscript
+++ b/src/mongo/client/SConscript
@@ -224,6 +224,7 @@ env.Library(
'$BUILD_DIR/mongo/rpc/command_status',
'$BUILD_DIR/mongo/rpc/rpc',
'$BUILD_DIR/mongo/transport/transport_layer_common',
+ '$BUILD_DIR/mongo/util/net/ssl_manager',
'authentication',
],
LIBDEPS_PRIVATE=[
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index 1d71169e527..6864920421b 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -633,6 +633,7 @@ env.Library(
],
LIBDEPS_PRIVATE=[
'commands/server_status',
+ 'update/update_driver',
]
)
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript
index 38348507286..04db6b74cee 100644
--- a/src/mongo/db/auth/SConscript
+++ b/src/mongo/db/auth/SConscript
@@ -89,16 +89,53 @@ env.Library(
)
env.Library(
+ target="role_graph",
+ source=[
+ 'role_graph.cpp',
+ 'role_graph_builtin_roles.cpp',
+ ],
+ LIBDEPS=[
+ 'auth',
+ 'authprivilege',
+ '$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/bson/mutable/mutable_bson',
+ ],
+)
+
+env.Library(
+ target='user_document_parser',
+ source=[
+ 'user_document_parser.cpp',
+ ],
+ LIBDEPS=[
+ 'auth',
+ 'user',
+ 'role_graph_update',
+ '$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/bson/mutable/mutable_bson',
+ '$BUILD_DIR/mongo/bson/util/bson_extract',
+ ],
+)
+
+env.Library(
+ target='role_graph_update',
+ source=[
+ 'role_graph_update.cpp',
+ ],
+ LIBDEPS=[
+ 'auth',
+ 'role_graph',
+ '$BUILD_DIR/mongo/db/update/update_driver',
+ ],
+)
+
+env.Library(
target='auth_impl_internal',
source=[
'authorization_manager_impl.cpp',
'authorization_session_impl.cpp',
'authz_manager_external_state.cpp',
'authz_session_external_state.cpp',
- 'role_graph.cpp',
- 'role_graph_update.cpp',
- 'role_graph_builtin_roles.cpp',
- 'user_document_parser.cpp',
'user_set.cpp',
],
LIBDEPS=[
@@ -107,8 +144,10 @@ env.Library(
'auth_rolename',
'authentication_restriction',
'authprivilege',
+ 'role_graph',
'sasl_options',
'user',
+ 'user_document_parser',
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/base/secure_allocator',
'$BUILD_DIR/mongo/bson/mutable/mutable_bson',
@@ -139,6 +178,7 @@ env.Library(
'auth',
'address_restriction',
'$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/bson/mutable/mutable_bson',
'$BUILD_DIR/mongo/db/common',
]
)
diff --git a/src/mongo/db/auth/authorization_manager.h b/src/mongo/db/auth/authorization_manager.h
index 5d9506a9f18..a8e1bc65e05 100644
--- a/src/mongo/db/auth/authorization_manager.h
+++ b/src/mongo/db/auth/authorization_manager.h
@@ -158,27 +158,6 @@ public:
*/
static const int schemaVersion28SCRAM = 5;
- // TODO: Make the following functions no longer static.
-
- /**
- * Takes a vector of privileges and fills the output param "resultArray" with a BSON array
- * representation of the privileges.
- */
- static Status getBSONForPrivileges(const PrivilegeVector& privileges,
- mutablebson::Element resultArray);
-
- /**
- * Takes a role name and a role graph and fills the output param "result" with a BSON
- * representation of the role object.
- * This function does no locking - it is up to the caller to synchronize access to the
- * role graph.
- * Note: The passed in RoleGraph can't be marked const because some of its accessors can
- * actually modify it internally (to set up built-in roles).
- */
- static Status getBSONForRole(/*const*/ RoleGraph* graph,
- const RoleName& roleName,
- mutablebson::Element result);
-
/**
* Returns a new AuthorizationSession for use with this AuthorizationManager.
*/
diff --git a/src/mongo/db/auth/authorization_manager_impl.cpp b/src/mongo/db/auth/authorization_manager_impl.cpp
index bc8970484fa..b64e7ebcbda 100644
--- a/src/mongo/db/auth/authorization_manager_impl.cpp
+++ b/src/mongo/db/auth/authorization_manager_impl.cpp
@@ -340,57 +340,6 @@ bool AuthorizationManagerImpl::hasAnyPrivilegeDocuments(OperationContext* opCtx)
return _privilegeDocsExist;
}
-Status AuthorizationManager::getBSONForPrivileges(const PrivilegeVector& privileges,
- mutablebson::Element resultArray) {
- for (PrivilegeVector::const_iterator it = privileges.begin(); it != privileges.end(); ++it) {
- std::string errmsg;
- ParsedPrivilege privilege;
- if (!ParsedPrivilege::privilegeToParsedPrivilege(*it, &privilege, &errmsg)) {
- return Status(ErrorCodes::BadValue, errmsg);
- }
- resultArray.appendObject("privileges", privilege.toBSON()).transitional_ignore();
- }
- return Status::OK();
-}
-
-Status AuthorizationManager::getBSONForRole(RoleGraph* graph,
- const RoleName& roleName,
- mutablebson::Element result) {
- if (!graph->roleExists(roleName)) {
- return Status(ErrorCodes::RoleNotFound,
- mongoutils::str::stream() << roleName.getFullName()
- << "does not name an existing role");
- }
- std::string id = mongoutils::str::stream() << roleName.getDB() << "." << roleName.getRole();
- result.appendString("_id", id).transitional_ignore();
- result.appendString(ROLE_NAME_FIELD_NAME, roleName.getRole()).transitional_ignore();
- result.appendString(ROLE_DB_FIELD_NAME, roleName.getDB()).transitional_ignore();
-
- // Build privileges array
- mutablebson::Element privilegesArrayElement =
- result.getDocument().makeElementArray("privileges");
- result.pushBack(privilegesArrayElement).transitional_ignore();
- const PrivilegeVector& privileges = graph->getDirectPrivileges(roleName);
- Status status = getBSONForPrivileges(privileges, privilegesArrayElement);
- if (!status.isOK()) {
- return status;
- }
-
- // Build roles array
- mutablebson::Element rolesArrayElement = result.getDocument().makeElementArray("roles");
- result.pushBack(rolesArrayElement).transitional_ignore();
- for (RoleNameIterator roles = graph->getDirectSubordinates(roleName); roles.more();
- roles.next()) {
- const RoleName& subRole = roles.get();
- mutablebson::Element roleObj = result.getDocument().makeElementObject("");
- roleObj.appendString(ROLE_NAME_FIELD_NAME, subRole.getRole()).transitional_ignore();
- roleObj.appendString(ROLE_DB_FIELD_NAME, subRole.getDB()).transitional_ignore();
- rolesArrayElement.pushBack(roleObj).transitional_ignore();
- }
-
- return Status::OK();
-}
-
Status AuthorizationManagerImpl::_initializeUserFromPrivilegeDocument(User* user,
const BSONObj& privDoc) {
V2UserDocumentParser parser;
diff --git a/src/mongo/db/auth/authorization_manager_test.cpp b/src/mongo/db/auth/authorization_manager_test.cpp
index 75d078bfbc7..cfb62e5ff50 100644
--- a/src/mongo/db/auth/authorization_manager_test.cpp
+++ b/src/mongo/db/auth/authorization_manager_test.cpp
@@ -73,105 +73,6 @@ void setX509PeerInfo(const transport::SessionHandle& session, SSLPeerInfo info)
using std::vector;
-TEST(RoleParsingTest, BuildRoleBSON) {
- RoleGraph graph;
- RoleName roleA("roleA", "dbA");
- RoleName roleB("roleB", "dbB");
- RoleName roleC("roleC", "dbC");
- ActionSet actions;
- actions.addAction(ActionType::find);
- actions.addAction(ActionType::insert);
-
- ASSERT_OK(graph.createRole(roleA));
- ASSERT_OK(graph.createRole(roleB));
- ASSERT_OK(graph.createRole(roleC));
-
- ASSERT_OK(graph.addRoleToRole(roleA, roleC));
- ASSERT_OK(graph.addRoleToRole(roleA, roleB));
- ASSERT_OK(graph.addRoleToRole(roleB, roleC));
-
- ASSERT_OK(graph.addPrivilegeToRole(
- roleA, Privilege(ResourcePattern::forAnyNormalResource(), actions)));
- ASSERT_OK(graph.addPrivilegeToRole(
- roleB, Privilege(ResourcePattern::forExactNamespace(NamespaceString("dbB.foo")), actions)));
- ASSERT_OK(
- graph.addPrivilegeToRole(roleC, Privilege(ResourcePattern::forClusterResource(), actions)));
- ASSERT_OK(graph.recomputePrivilegeData());
-
-
- // Role A
- mutablebson::Document doc;
- ASSERT_OK(AuthorizationManager::getBSONForRole(&graph, roleA, doc.root()));
- BSONObj roleDoc = doc.getObject();
-
- ASSERT_EQUALS("dbA.roleA", roleDoc["_id"].String());
- ASSERT_EQUALS("roleA", roleDoc["role"].String());
- ASSERT_EQUALS("dbA", roleDoc["db"].String());
-
- vector<BSONElement> privs = roleDoc["privileges"].Array();
- ASSERT_EQUALS(1U, privs.size());
- ASSERT_EQUALS("", privs[0].Obj()["resource"].Obj()["db"].String());
- ASSERT_EQUALS("", privs[0].Obj()["resource"].Obj()["collection"].String());
- ASSERT(privs[0].Obj()["resource"].Obj()["cluster"].eoo());
- vector<BSONElement> actionElements = privs[0].Obj()["actions"].Array();
- ASSERT_EQUALS(2U, actionElements.size());
- ASSERT_EQUALS("find", actionElements[0].String());
- ASSERT_EQUALS("insert", actionElements[1].String());
-
- vector<BSONElement> roles = roleDoc["roles"].Array();
- ASSERT_EQUALS(2U, 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());
- ASSERT_EQUALS("dbB", roles[1].Obj()["db"].String());
-
- // Role B
- doc.reset();
- ASSERT_OK(AuthorizationManager::getBSONForRole(&graph, roleB, doc.root()));
- roleDoc = doc.getObject();
-
- ASSERT_EQUALS("dbB.roleB", roleDoc["_id"].String());
- ASSERT_EQUALS("roleB", roleDoc["role"].String());
- ASSERT_EQUALS("dbB", roleDoc["db"].String());
-
- privs = roleDoc["privileges"].Array();
- ASSERT_EQUALS(1U, privs.size());
- ASSERT_EQUALS("dbB", privs[0].Obj()["resource"].Obj()["db"].String());
- ASSERT_EQUALS("foo", privs[0].Obj()["resource"].Obj()["collection"].String());
- ASSERT(privs[0].Obj()["resource"].Obj()["cluster"].eoo());
- actionElements = privs[0].Obj()["actions"].Array();
- ASSERT_EQUALS(2U, actionElements.size());
- ASSERT_EQUALS("find", actionElements[0].String());
- ASSERT_EQUALS("insert", actionElements[1].String());
-
- roles = roleDoc["roles"].Array();
- ASSERT_EQUALS(1U, roles.size());
- ASSERT_EQUALS("roleC", roles[0].Obj()["role"].String());
- ASSERT_EQUALS("dbC", roles[0].Obj()["db"].String());
-
- // Role C
- doc.reset();
- ASSERT_OK(AuthorizationManager::getBSONForRole(&graph, roleC, doc.root()));
- roleDoc = doc.getObject();
-
- ASSERT_EQUALS("dbC.roleC", roleDoc["_id"].String());
- ASSERT_EQUALS("roleC", roleDoc["role"].String());
- ASSERT_EQUALS("dbC", roleDoc["db"].String());
-
- privs = roleDoc["privileges"].Array();
- ASSERT_EQUALS(1U, privs.size());
- ASSERT(privs[0].Obj()["resource"].Obj()["cluster"].Bool());
- ASSERT(privs[0].Obj()["resource"].Obj()["db"].eoo());
- ASSERT(privs[0].Obj()["resource"].Obj()["collection"].eoo());
- actionElements = privs[0].Obj()["actions"].Array();
- ASSERT_EQUALS(2U, actionElements.size());
- ASSERT_EQUALS("find", actionElements[0].String());
- ASSERT_EQUALS("insert", actionElements[1].String());
-
- roles = roleDoc["roles"].Array();
- ASSERT_EQUALS(0U, roles.size());
-}
-
class AuthorizationManagerTest : public ::mongo::unittest::Test {
public:
virtual ~AuthorizationManagerTest() {
@@ -180,9 +81,9 @@ public:
}
void setUp() override {
- auto localExternalState = stdx::make_unique<AuthzManagerExternalStateMock>();
+ auto localExternalState = std::make_unique<AuthzManagerExternalStateMock>();
externalState = localExternalState.get();
- authzManager = stdx::make_unique<AuthorizationManagerImpl>(
+ authzManager = std::make_unique<AuthorizationManagerImpl>(
std::move(localExternalState),
AuthorizationManagerImpl::InstallMockForTestingOrAuthImpl{});
externalState->setAuthorizationManager(authzManager.get());
diff --git a/src/mongo/db/auth/privilege.cpp b/src/mongo/db/auth/privilege.cpp
index 93c75cce9d8..708db497462 100644
--- a/src/mongo/db/auth/privilege.cpp
+++ b/src/mongo/db/auth/privilege.cpp
@@ -82,4 +82,19 @@ BSONObj Privilege::toBSON() const {
return pp.toBSON();
}
+Status Privilege::getBSONForPrivileges(const PrivilegeVector& privileges,
+ mutablebson::Element resultArray) try {
+ for (auto& currPriv : privileges) {
+ std::string errmsg;
+ ParsedPrivilege privilege;
+ if (!ParsedPrivilege::privilegeToParsedPrivilege(currPriv, &privilege, &errmsg)) {
+ return Status(ErrorCodes::BadValue, errmsg);
+ }
+ uassertStatusOK(resultArray.appendObject("privileges", privilege.toBSON()));
+ }
+ return Status::OK();
+} catch (...) {
+ return exceptionToStatus();
+}
+
} // namespace mongo
diff --git a/src/mongo/db/auth/privilege.h b/src/mongo/db/auth/privilege.h
index 43f5fb48d9c..0b52cfd2ecc 100644
--- a/src/mongo/db/auth/privilege.h
+++ b/src/mongo/db/auth/privilege.h
@@ -29,6 +29,7 @@
#include <vector>
+#include "mongo/bson/mutable/element.h"
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/resource_pattern.h"
@@ -55,6 +56,13 @@ public:
static void addPrivilegesToPrivilegeVector(PrivilegeVector* privileges,
const PrivilegeVector& privilegesToAdd);
+ /**
+ * Takes a vector of privileges and fills the output param "resultArray" with a BSON array
+ * representation of the privileges.
+ */
+ static Status getBSONForPrivileges(const PrivilegeVector& privileges,
+ mutablebson::Element resultArray);
+
Privilege(){};
Privilege(const ResourcePattern& resource, const ActionType& action);
diff --git a/src/mongo/db/auth/role_graph.cpp b/src/mongo/db/auth/role_graph.cpp
index d9ec88e072a..5081f55677a 100644
--- a/src/mongo/db/auth/role_graph.cpp
+++ b/src/mongo/db/auth/role_graph.cpp
@@ -32,6 +32,8 @@
#include <set>
#include <vector>
+#include "mongo/bson/mutable/document.h"
+#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/auth/role_name.h"
#include "mongo/stdx/unordered_set.h"
@@ -549,4 +551,46 @@ RoleNameIterator RoleGraph::getRolesForDatabase(const std::string& dbname) {
return makeRoleNameIterator(lower, upper);
}
+
+Status RoleGraph::getBSONForRole(RoleGraph* graph,
+ const RoleName& roleName,
+ mutablebson::Element result) try {
+ if (!graph->roleExists(roleName)) {
+ return Status(ErrorCodes::RoleNotFound,
+ mongoutils::str::stream() << roleName.getFullName()
+ << "does not name an existing role");
+ }
+ std::string id = mongoutils::str::stream() << roleName.getDB() << "." << roleName.getRole();
+ uassertStatusOK(result.appendString("_id", id));
+ uassertStatusOK(
+ result.appendString(AuthorizationManager::ROLE_NAME_FIELD_NAME, roleName.getRole()));
+ uassertStatusOK(
+ result.appendString(AuthorizationManager::ROLE_DB_FIELD_NAME, roleName.getDB()));
+
+ // Build privileges array
+ mutablebson::Element privilegesArrayElement =
+ result.getDocument().makeElementArray("privileges");
+ uassertStatusOK(result.pushBack(privilegesArrayElement));
+ const PrivilegeVector& privileges = graph->getDirectPrivileges(roleName);
+ uassertStatusOK(Privilege::getBSONForPrivileges(privileges, privilegesArrayElement));
+
+ // Build roles array
+ mutablebson::Element rolesArrayElement = result.getDocument().makeElementArray("roles");
+ uassertStatusOK(result.pushBack(rolesArrayElement));
+ for (RoleNameIterator roles = graph->getDirectSubordinates(roleName); roles.more();
+ roles.next()) {
+ const RoleName& subRole = roles.get();
+ mutablebson::Element roleObj = result.getDocument().makeElementObject("");
+ uassertStatusOK(
+ roleObj.appendString(AuthorizationManager::ROLE_NAME_FIELD_NAME, subRole.getRole()));
+ uassertStatusOK(
+ roleObj.appendString(AuthorizationManager::ROLE_DB_FIELD_NAME, subRole.getDB()));
+ uassertStatusOK(rolesArrayElement.pushBack(roleObj));
+ }
+
+ return Status::OK();
+} catch (...) {
+ return exceptionToStatus();
+}
+
} // namespace mongo
diff --git a/src/mongo/db/auth/role_graph.h b/src/mongo/db/auth/role_graph.h
index 1b8678609a7..0bcd28ccda8 100644
--- a/src/mongo/db/auth/role_graph.h
+++ b/src/mongo/db/auth/role_graph.h
@@ -33,6 +33,7 @@
#include <vector>
#include "mongo/base/status.h"
+#include "mongo/bson/mutable/element.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/auth/restriction_set.h"
#include "mongo/db/auth/role_name.h"
@@ -86,6 +87,19 @@ public:
static void generateUniversalPrivileges(PrivilegeVector* privileges);
/**
+ * Takes a role name and a role graph and fills the output param "result" with a BSON
+ * representation of the role object.
+ * This function does no locking - it is up to the caller to synchronize access to the
+ * role graph.
+ * Note: The passed in RoleGraph can't be marked const because some of its accessors can
+ * actually modify it internally (to set up built-in roles).
+ */
+ static Status getBSONForRole(/*const*/ RoleGraph* graph,
+ const RoleName& roleName,
+ mutablebson::Element result);
+
+
+ /**
* Returns an iterator over the RoleNames of the "members" of the given role.
* Members of a role are roles that have been granted this role directly (roles that are
* members transitively through another role are not included). These are the "parents" of
diff --git a/src/mongo/db/auth/role_graph_test.cpp b/src/mongo/db/auth/role_graph_test.cpp
index 5e7e2a3bb80..7b826dd3cdf 100644
--- a/src/mongo/db/auth/role_graph_test.cpp
+++ b/src/mongo/db/auth/role_graph_test.cpp
@@ -32,6 +32,7 @@
#include <algorithm>
+#include "mongo/bson/mutable/document.h"
#include "mongo/db/auth/role_graph.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/mongoutils/str.h"
@@ -40,6 +41,105 @@
namespace mongo {
namespace {
+TEST(RoleParsingTest, BuildRoleBSON) {
+ RoleGraph graph;
+ RoleName roleA("roleA", "dbA");
+ RoleName roleB("roleB", "dbB");
+ RoleName roleC("roleC", "dbC");
+ ActionSet actions;
+ actions.addAction(ActionType::find);
+ actions.addAction(ActionType::insert);
+
+ ASSERT_OK(graph.createRole(roleA));
+ ASSERT_OK(graph.createRole(roleB));
+ ASSERT_OK(graph.createRole(roleC));
+
+ ASSERT_OK(graph.addRoleToRole(roleA, roleC));
+ ASSERT_OK(graph.addRoleToRole(roleA, roleB));
+ ASSERT_OK(graph.addRoleToRole(roleB, roleC));
+
+ ASSERT_OK(graph.addPrivilegeToRole(
+ roleA, Privilege(ResourcePattern::forAnyNormalResource(), actions)));
+ ASSERT_OK(graph.addPrivilegeToRole(
+ roleB, Privilege(ResourcePattern::forExactNamespace(NamespaceString("dbB.foo")), actions)));
+ ASSERT_OK(
+ graph.addPrivilegeToRole(roleC, Privilege(ResourcePattern::forClusterResource(), actions)));
+ ASSERT_OK(graph.recomputePrivilegeData());
+
+
+ // Role A
+ mutablebson::Document doc;
+ ASSERT_OK(RoleGraph::getBSONForRole(&graph, roleA, doc.root()));
+ BSONObj roleDoc = doc.getObject();
+
+ ASSERT_EQUALS("dbA.roleA", roleDoc["_id"].String());
+ ASSERT_EQUALS("roleA", roleDoc["role"].String());
+ ASSERT_EQUALS("dbA", roleDoc["db"].String());
+
+ std::vector<BSONElement> privs = roleDoc["privileges"].Array();
+ ASSERT_EQUALS(1U, privs.size());
+ ASSERT_EQUALS("", privs[0].Obj()["resource"].Obj()["db"].String());
+ ASSERT_EQUALS("", privs[0].Obj()["resource"].Obj()["collection"].String());
+ ASSERT(privs[0].Obj()["resource"].Obj()["cluster"].eoo());
+ std::vector<BSONElement> actionElements = privs[0].Obj()["actions"].Array();
+ ASSERT_EQUALS(2U, actionElements.size());
+ ASSERT_EQUALS("find", actionElements[0].String());
+ ASSERT_EQUALS("insert", actionElements[1].String());
+
+ std::vector<BSONElement> roles = roleDoc["roles"].Array();
+ ASSERT_EQUALS(2U, 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());
+ ASSERT_EQUALS("dbB", roles[1].Obj()["db"].String());
+
+ // Role B
+ doc.reset();
+ ASSERT_OK(RoleGraph::getBSONForRole(&graph, roleB, doc.root()));
+ roleDoc = doc.getObject();
+
+ ASSERT_EQUALS("dbB.roleB", roleDoc["_id"].String());
+ ASSERT_EQUALS("roleB", roleDoc["role"].String());
+ ASSERT_EQUALS("dbB", roleDoc["db"].String());
+
+ privs = roleDoc["privileges"].Array();
+ ASSERT_EQUALS(1U, privs.size());
+ ASSERT_EQUALS("dbB", privs[0].Obj()["resource"].Obj()["db"].String());
+ ASSERT_EQUALS("foo", privs[0].Obj()["resource"].Obj()["collection"].String());
+ ASSERT(privs[0].Obj()["resource"].Obj()["cluster"].eoo());
+ actionElements = privs[0].Obj()["actions"].Array();
+ ASSERT_EQUALS(2U, actionElements.size());
+ ASSERT_EQUALS("find", actionElements[0].String());
+ ASSERT_EQUALS("insert", actionElements[1].String());
+
+ roles = roleDoc["roles"].Array();
+ ASSERT_EQUALS(1U, roles.size());
+ ASSERT_EQUALS("roleC", roles[0].Obj()["role"].String());
+ ASSERT_EQUALS("dbC", roles[0].Obj()["db"].String());
+
+ // Role C
+ doc.reset();
+ ASSERT_OK(RoleGraph::getBSONForRole(&graph, roleC, doc.root()));
+ roleDoc = doc.getObject();
+
+ ASSERT_EQUALS("dbC.roleC", roleDoc["_id"].String());
+ ASSERT_EQUALS("roleC", roleDoc["role"].String());
+ ASSERT_EQUALS("dbC", roleDoc["db"].String());
+
+ privs = roleDoc["privileges"].Array();
+ ASSERT_EQUALS(1U, privs.size());
+ ASSERT(privs[0].Obj()["resource"].Obj()["cluster"].Bool());
+ ASSERT(privs[0].Obj()["resource"].Obj()["db"].eoo());
+ ASSERT(privs[0].Obj()["resource"].Obj()["collection"].eoo());
+ actionElements = privs[0].Obj()["actions"].Array();
+ ASSERT_EQUALS(2U, actionElements.size());
+ ASSERT_EQUALS("find", actionElements[0].String());
+ ASSERT_EQUALS("insert", actionElements[1].String());
+
+ roles = roleDoc["roles"].Array();
+ ASSERT_EQUALS(0U, roles.size());
+}
+
// Tests adding and removing roles from other roles, the RoleNameIterator, and the
// getDirectMembers and getDirectSubordinates methods
TEST(RoleGraphTest, AddRemoveRoles) {
diff --git a/src/mongo/db/auth/role_graph_update.cpp b/src/mongo/db/auth/role_graph_update.cpp
index dc90439f134..cf0f7644a09 100644
--- a/src/mongo/db/auth/role_graph_update.cpp
+++ b/src/mongo/db/auth/role_graph_update.cpp
@@ -213,7 +213,7 @@ Status handleOplogUpdate(OperationContext* opCtx,
return status;
mutablebson::Document roleDocument;
- status = AuthorizationManager::getBSONForRole(roleGraph, roleToUpdate, roleDocument.root());
+ status = RoleGraph::getBSONForRole(roleGraph, roleToUpdate, roleDocument.root());
if (status == ErrorCodes::RoleNotFound) {
// The query pattern will only contain _id, no other immutable fields are present
const FieldRef idFieldRef("_id");
diff --git a/src/mongo/db/catalog/drop_database_test.cpp b/src/mongo/db/catalog/drop_database_test.cpp
index 2c7e6d3e37c..adecc862da4 100644
--- a/src/mongo/db/catalog/drop_database_test.cpp
+++ b/src/mongo/db/catalog/drop_database_test.cpp
@@ -424,9 +424,10 @@ TEST_F(DropDatabaseTest,
auto status = dropDatabase(_opCtx.get(), _nss.db().toString());
ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, status);
- ASSERT_EQUALS(status.reason(),
- str::stream() << "Could not drop database " << _nss.db()
- << " because it does not exist after dropping 1 collection(s).");
+ ASSERT_EQUALS(
+ status.reason(),
+ std::string(str::stream() << "Could not drop database " << _nss.db()
+ << " because it does not exist after dropping 1 collection(s)."));
ASSERT_FALSE(AutoGetDb(_opCtx.get(), _nss.db(), MODE_X).getDb());
}
@@ -448,9 +449,9 @@ TEST_F(DropDatabaseTest,
auto status = dropDatabase(_opCtx.get(), _nss.db().toString());
ASSERT_EQUALS(ErrorCodes::PrimarySteppedDown, status);
ASSERT_EQUALS(status.reason(),
- str::stream() << "Could not drop database " << _nss.db()
- << " because we transitioned from PRIMARY to SECONDARY"
- << " while waiting for 1 pending collection drop(s).");
+ std::string(str::stream() << "Could not drop database " << _nss.db()
+ << " because we transitioned from PRIMARY to SECONDARY"
+ << " while waiting for 1 pending collection drop(s)."));
// Check drop-pending flag in Database after dropDatabase() fails.
AutoGetDb autoDb(_opCtx.get(), _nss.db(), MODE_X);
diff --git a/src/mongo/db/catalog/rename_collection_test.cpp b/src/mongo/db/catalog/rename_collection_test.cpp
index f72f686aaa5..ede724e4968 100644
--- a/src/mongo/db/catalog/rename_collection_test.cpp
+++ b/src/mongo/db/catalog/rename_collection_test.cpp
@@ -911,15 +911,15 @@ void _checkOplogEntries(const std::vector<std::string>& actualOplogEntries,
std::string expectedOplogEntriesStr;
joinStringDelim(expectedOplogEntries, &expectedOplogEntriesStr, ',');
ASSERT_EQUALS(expectedOplogEntries.size(), actualOplogEntries.size())
- << str::stream()
+
<< "Incorrect number of oplog entries written to oplog. Actual: " << actualOplogEntriesStr
<< ". Expected: " << expectedOplogEntriesStr;
std::vector<std::string>::size_type i = 0;
for (const auto& actualOplogEntry : actualOplogEntries) {
const auto& expectedOplogEntry = expectedOplogEntries[i++];
ASSERT_EQUALS(expectedOplogEntry, actualOplogEntry)
- << str::stream() << "Mismatch in oplog entry at index " << i
- << ". Actual: " << actualOplogEntriesStr << ". Expected: " << expectedOplogEntriesStr;
+ << "Mismatch in oplog entry at index " << i << ". Actual: " << actualOplogEntriesStr
+ << ". Expected: " << expectedOplogEntriesStr;
}
}
diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript
index 27cdc331cfb..ba1bdc9f7db 100644
--- a/src/mongo/db/commands/SConscript
+++ b/src/mongo/db/commands/SConscript
@@ -126,6 +126,7 @@ env.Library(
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/audit',
'$BUILD_DIR/mongo/db/auth/sasl_options',
+ '$BUILD_DIR/mongo/db/auth/user_document_parser',
'$BUILD_DIR/mongo/db/commands',
'$BUILD_DIR/mongo/db/commands/test_commands_enabled',
'$BUILD_DIR/mongo/db/common',
@@ -294,6 +295,10 @@ env.Library(
'$BUILD_DIR/mongo/client/clientdriver',
'$BUILD_DIR/mongo/db/auth/auth',
'$BUILD_DIR/mongo/db/auth/authprivilege',
+ '$BUILD_DIR/mongo/db/auth/role_graph',
+ '$BUILD_DIR/mongo/db/auth/sasl_options',
+ '$BUILD_DIR/mongo/db/auth/user',
+ '$BUILD_DIR/mongo/db/auth/user_document_parser',
'$BUILD_DIR/mongo/db/background',
'$BUILD_DIR/mongo/db/catalog/catalog_helpers',
'$BUILD_DIR/mongo/db/catalog/catalog_impl',
diff --git a/src/mongo/db/commands/user_management_commands.cpp b/src/mongo/db/commands/user_management_commands.cpp
index f2c4f3ad6cf..e0f205b18fd 100644
--- a/src/mongo/db/commands/user_management_commands.cpp
+++ b/src/mongo/db/commands/user_management_commands.cpp
@@ -1696,7 +1696,7 @@ public:
mutablebson::Element privilegesElement = updateObj.makeElementArray("privileges");
status = setElement.pushBack(privilegesElement);
uassertStatusOK(status);
- status = authzManager->getBSONForPrivileges(privileges, privilegesElement);
+ status = Privilege::getBSONForPrivileges(privileges, privilegesElement);
uassertStatusOK(status);
BSONObjBuilder updateBSONBuilder;
@@ -1798,7 +1798,7 @@ public:
mutablebson::Element privilegesElement = updateObj.makeElementArray("privileges");
status = setElement.pushBack(privilegesElement);
uassertStatusOK(status);
- status = authzManager->getBSONForPrivileges(privileges, privilegesElement);
+ status = Privilege::getBSONForPrivileges(privileges, privilegesElement);
uassertStatusOK(status);
audit::logRevokePrivilegesFromRole(Client::getCurrent(), roleName, privilegesToRemove);
diff --git a/src/mongo/db/repl/storage_interface_impl_test.cpp b/src/mongo/db/repl/storage_interface_impl_test.cpp
index ae6fb27827b..9a681f74d88 100644
--- a/src/mongo/db/repl/storage_interface_impl_test.cpp
+++ b/src/mongo/db/repl/storage_interface_impl_test.cpp
@@ -2287,10 +2287,11 @@ TEST_F(StorageInterfaceImplTest, DeleteByFilterReturnsNamespaceNotFoundWhenDatab
auto filter = BSON("x" << 1);
auto status = storage.deleteByFilter(opCtx, nss, filter);
ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, status);
- ASSERT_EQUALS(str::stream() << "Database [nosuchdb] not found. Unable to delete documents in "
- << nss.ns()
- << " using filter "
- << filter,
+ ASSERT_EQUALS(std::string(str::stream()
+ << "Database [nosuchdb] not found. Unable to delete documents in "
+ << nss.ns()
+ << " using filter "
+ << filter),
status.reason());
}
@@ -2383,12 +2384,13 @@ TEST_F(StorageInterfaceImplTest, DeleteByFilterReturnsNamespaceNotFoundWhenColle
auto filter = BSON("x" << 1);
auto status = storage.deleteByFilter(opCtx, wrongColl, filter);
ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, status);
- ASSERT_EQUALS(
- str::stream() << "Collection [mydb.wrongColl] not found. Unable to delete documents in "
+ ASSERT_EQUALS(std::string(
+ str::stream()
+ << "Collection [mydb.wrongColl] not found. Unable to delete documents in "
<< wrongColl.ns()
<< " using filter "
- << filter,
- status.reason());
+ << filter),
+ status.reason());
}
TEST_F(StorageInterfaceImplTest, DeleteByFilterReturnsSuccessIfCollectionIsEmpty) {
diff --git a/src/mongo/db/storage/wiredtiger/SConscript b/src/mongo/db/storage/wiredtiger/SConscript
index 25b49ee34fe..3d28c1b6b30 100644
--- a/src/mongo/db/storage/wiredtiger/SConscript
+++ b/src/mongo/db/storage/wiredtiger/SConscript
@@ -103,6 +103,7 @@ if wiredtiger:
'$BUILD_DIR/mongo/db/commands/server_status',
'$BUILD_DIR/mongo/db/concurrency/lock_manager',
'$BUILD_DIR/mongo/db/storage/storage_engine_common',
+ '$BUILD_DIR/mongo/util/options_parser/options_parser',
],
)
diff --git a/src/mongo/s/commands/SConscript b/src/mongo/s/commands/SConscript
index 45358239bfa..4ed4c82deed 100644
--- a/src/mongo/s/commands/SConscript
+++ b/src/mongo/s/commands/SConscript
@@ -96,6 +96,7 @@ env.Library(
],
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/auth/auth',
+ '$BUILD_DIR/mongo/db/auth/role_graph',
'$BUILD_DIR/mongo/db/auth/saslauth',
'$BUILD_DIR/mongo/db/commands/core',
'$BUILD_DIR/mongo/db/commands/current_op_common',