diff options
-rw-r--r-- | src/mongo/client/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/auth/SConscript | 48 | ||||
-rw-r--r-- | src/mongo/db/auth/authorization_manager.h | 21 | ||||
-rw-r--r-- | src/mongo/db/auth/authorization_manager_impl.cpp | 51 | ||||
-rw-r--r-- | src/mongo/db/auth/authorization_manager_test.cpp | 103 | ||||
-rw-r--r-- | src/mongo/db/auth/privilege.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/auth/privilege.h | 8 | ||||
-rw-r--r-- | src/mongo/db/auth/role_graph.cpp | 44 | ||||
-rw-r--r-- | src/mongo/db/auth/role_graph.h | 14 | ||||
-rw-r--r-- | src/mongo/db/auth/role_graph_test.cpp | 100 | ||||
-rw-r--r-- | src/mongo/db/auth/role_graph_update.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/drop_database_test.cpp | 13 | ||||
-rw-r--r-- | src/mongo/db/catalog/rename_collection_test.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/commands/SConscript | 5 | ||||
-rw-r--r-- | src/mongo/db/commands/user_management_commands.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/repl/storage_interface_impl_test.cpp | 18 | ||||
-rw-r--r-- | src/mongo/db/storage/wiredtiger/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/s/commands/SConscript | 1 |
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', |