diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2015-06-20 00:22:50 -0400 |
---|---|---|
committer | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2015-06-20 10:56:02 -0400 |
commit | 9c2ed42daa8fbbef4a919c21ec564e2db55e8d60 (patch) | |
tree | 3814f79c10d7b490948d8cb7b112ac1dd41ceff1 /src/mongo/db/auth/role_graph_update.cpp | |
parent | 01965cf52bce6976637ecb8f4a622aeb05ab256a (diff) | |
download | mongo-9c2ed42daa8fbbef4a919c21ec564e2db55e8d60.tar.gz |
SERVER-18579: Clang-Format - reformat code, no comment reflow
Diffstat (limited to 'src/mongo/db/auth/role_graph_update.cpp')
-rw-r--r-- | src/mongo/db/auth/role_graph_update.cpp | 458 |
1 files changed, 223 insertions, 235 deletions
diff --git a/src/mongo/db/auth/role_graph_update.cpp b/src/mongo/db/auth/role_graph_update.cpp index 71e9370ec61..62df4a33a4b 100644 --- a/src/mongo/db/auth/role_graph_update.cpp +++ b/src/mongo/db/auth/role_graph_update.cpp @@ -40,278 +40,266 @@ namespace mongo { namespace { - /** - * Structure representing information parsed out of a role document. - */ - struct RoleInfo { - RoleName name; - std::vector<RoleName> roles; - PrivilegeVector privileges; - }; +/** + * Structure representing information parsed out of a role document. + */ +struct RoleInfo { + RoleName name; + std::vector<RoleName> roles; + PrivilegeVector privileges; +}; - /** - * Parses the role name out of a BSON document. - */ - Status parseRoleNameFromDocument(const BSONObj& doc, RoleName* name) { - BSONElement nameElement; - BSONElement sourceElement; - Status status = bsonExtractTypedField( - doc, AuthorizationManager::ROLE_NAME_FIELD_NAME, String, &nameElement); - if (!status.isOK()) - return status; - status = bsonExtractTypedField( - doc, AuthorizationManager::ROLE_DB_FIELD_NAME, String, &sourceElement); - if (!status.isOK()) - return status; - *name = RoleName(nameElement.valueStringData(), sourceElement.valueStringData()); +/** + * Parses the role name out of a BSON document. + */ +Status parseRoleNameFromDocument(const BSONObj& doc, RoleName* name) { + BSONElement nameElement; + BSONElement sourceElement; + Status status = bsonExtractTypedField( + doc, AuthorizationManager::ROLE_NAME_FIELD_NAME, String, &nameElement); + if (!status.isOK()) return status; - } + status = bsonExtractTypedField( + doc, AuthorizationManager::ROLE_DB_FIELD_NAME, String, &sourceElement); + if (!status.isOK()) + return status; + *name = RoleName(nameElement.valueStringData(), sourceElement.valueStringData()); + return status; +} - /** - * Checks whether the given "roleName" corresponds with the given _id field. - * In admin.system.roles, documents with role name "role@db" must have _id - * "db.role". - * - * Returns Status::OK if the two values are compatible. - */ - Status checkIdMatchesRoleName(const BSONElement& idElement, const RoleName& roleName) { - if (idElement.type() != String) { - return Status(ErrorCodes::TypeMismatch, - "Role document _id fields must be strings."); - } - StringData idField = idElement.valueStringData(); - size_t firstDot = idField.find('.'); - if (firstDot == std::string::npos || - idField.substr(0, firstDot) != roleName.getDB() || - idField.substr(firstDot + 1) != roleName.getRole()) { - return Status(ErrorCodes::FailedToParse, mongoutils::str::stream() << - "Role document _id fields must be encoded as the string " - "dbname.rolename. Found " << idField << " for " << - roleName.getFullName()); - } - return Status::OK(); +/** + * Checks whether the given "roleName" corresponds with the given _id field. + * In admin.system.roles, documents with role name "role@db" must have _id + * "db.role". + * + * Returns Status::OK if the two values are compatible. + */ +Status checkIdMatchesRoleName(const BSONElement& idElement, const RoleName& roleName) { + if (idElement.type() != String) { + return Status(ErrorCodes::TypeMismatch, "Role document _id fields must be strings."); + } + StringData idField = idElement.valueStringData(); + size_t firstDot = idField.find('.'); + if (firstDot == std::string::npos || idField.substr(0, firstDot) != roleName.getDB() || + idField.substr(firstDot + 1) != roleName.getRole()) { + return Status(ErrorCodes::FailedToParse, + mongoutils::str::stream() + << "Role document _id fields must be encoded as the string " + "dbname.rolename. Found " << idField << " for " + << roleName.getFullName()); } + return Status::OK(); +} - /** - * Parses "idElement" to extract the role name, according to the "dbname.role" convention - * used for admin.system.roles documents. - */ - Status getRoleNameFromIdField(const BSONElement& idElement, RoleName* roleName) { - if (idElement.type() != String) { - return Status(ErrorCodes::TypeMismatch, - "Role document _id fields must be strings."); - } - StringData idField = idElement.valueStringData(); - size_t dotPos = idField.find('.'); - if (dotPos == std::string::npos) { - return Status(ErrorCodes::BadValue, - "Role document _id fields must have the form dbname.rolename"); - } - *roleName = RoleName(idField.substr(dotPos + 1), idField.substr(0, dotPos)); - return Status::OK(); +/** + * Parses "idElement" to extract the role name, according to the "dbname.role" convention + * used for admin.system.roles documents. + */ +Status getRoleNameFromIdField(const BSONElement& idElement, RoleName* roleName) { + if (idElement.type() != String) { + return Status(ErrorCodes::TypeMismatch, "Role document _id fields must be strings."); } + StringData idField = idElement.valueStringData(); + size_t dotPos = idField.find('.'); + if (dotPos == std::string::npos) { + return Status(ErrorCodes::BadValue, + "Role document _id fields must have the form dbname.rolename"); + } + *roleName = RoleName(idField.substr(dotPos + 1), idField.substr(0, dotPos)); + return Status::OK(); +} - /** - * Parses information about a role from a BSON document. - */ - Status parseRoleFromDocument(const BSONObj& doc, RoleInfo* role) { - BSONElement rolesElement; - Status status = parseRoleNameFromDocument(doc, &role->name); - if (!status.isOK()) - return status; - status = checkIdMatchesRoleName(doc["_id"], role->name); - if (!status.isOK()) - return status; - status = bsonExtractTypedField(doc, "roles", Array, &rolesElement); - if (!status.isOK()) - return status; - BSONForEach(singleRoleElement, rolesElement.Obj()) { - if (singleRoleElement.type() != Object) { - return Status(ErrorCodes::TypeMismatch, - "Elements of roles array must be objects."); - } - RoleName possessedRoleName; - status = parseRoleNameFromDocument(singleRoleElement.Obj(), &possessedRoleName); - if (!status.isOK()) - return status; - role->roles.push_back(possessedRoleName); +/** + * Parses information about a role from a BSON document. + */ +Status parseRoleFromDocument(const BSONObj& doc, RoleInfo* role) { + BSONElement rolesElement; + Status status = parseRoleNameFromDocument(doc, &role->name); + if (!status.isOK()) + return status; + status = checkIdMatchesRoleName(doc["_id"], role->name); + if (!status.isOK()) + return status; + status = bsonExtractTypedField(doc, "roles", Array, &rolesElement); + if (!status.isOK()) + return status; + BSONForEach(singleRoleElement, rolesElement.Obj()) { + if (singleRoleElement.type() != Object) { + return Status(ErrorCodes::TypeMismatch, "Elements of roles array must be objects."); } - - BSONElement privilegesElement; - status = bsonExtractTypedField(doc, "privileges", Array, &privilegesElement); + RoleName possessedRoleName; + status = parseRoleNameFromDocument(singleRoleElement.Obj(), &possessedRoleName); if (!status.isOK()) return status; - status = auth::parseAndValidatePrivilegeArray(BSONArray(privilegesElement.Obj()), - &role->privileges); - return status; + role->roles.push_back(possessedRoleName); } - /** - * Updates roleGraph for an insert-type oplog operation on admin.system.roles. - */ - Status handleOplogInsert(RoleGraph* roleGraph, const BSONObj& insertedObj) { - RoleInfo role; - Status status = parseRoleFromDocument(insertedObj, &role); - if (!status.isOK()) - return status; - status = roleGraph->replaceRole(role.name, role.roles, role.privileges); + BSONElement privilegesElement; + status = bsonExtractTypedField(doc, "privileges", Array, &privilegesElement); + if (!status.isOK()) return status; - } + status = + auth::parseAndValidatePrivilegeArray(BSONArray(privilegesElement.Obj()), &role->privileges); + return status; +} - /** - * Updates roleGraph for an update-type oplog operation on admin.system.roles. - * - * Treats all updates as upserts. - */ - Status handleOplogUpdate(RoleGraph* roleGraph, - const BSONObj& updatePattern, - const BSONObj& queryPattern) { - RoleName roleToUpdate; - Status status = getRoleNameFromIdField(queryPattern["_id"], &roleToUpdate); - if (!status.isOK()) - return status; +/** + * Updates roleGraph for an insert-type oplog operation on admin.system.roles. + */ +Status handleOplogInsert(RoleGraph* roleGraph, const BSONObj& insertedObj) { + RoleInfo role; + Status status = parseRoleFromDocument(insertedObj, &role); + if (!status.isOK()) + return status; + status = roleGraph->replaceRole(role.name, role.roles, role.privileges); + return status; +} - UpdateDriver::Options updateOptions; - UpdateDriver driver(updateOptions); - status = driver.parse(updatePattern); - if (!status.isOK()) - return status; +/** + * Updates roleGraph for an update-type oplog operation on admin.system.roles. + * + * Treats all updates as upserts. + */ +Status handleOplogUpdate(RoleGraph* roleGraph, + const BSONObj& updatePattern, + const BSONObj& queryPattern) { + RoleName roleToUpdate; + Status status = getRoleNameFromIdField(queryPattern["_id"], &roleToUpdate); + if (!status.isOK()) + return status; - mutablebson::Document roleDocument; - status = AuthorizationManager::getBSONForRole( - roleGraph, roleToUpdate, roleDocument.root()); - if (status == ErrorCodes::RoleNotFound) { - // The query pattern will only contain _id, no other immutable fields are present - status = driver.populateDocumentWithQueryFields(queryPattern, NULL, roleDocument); - } - if (!status.isOK()) - return status; + UpdateDriver::Options updateOptions; + UpdateDriver driver(updateOptions); + status = driver.parse(updatePattern); + if (!status.isOK()) + return status; - status = driver.update(StringData(), &roleDocument); - if (!status.isOK()) - return status; + mutablebson::Document roleDocument; + status = AuthorizationManager::getBSONForRole(roleGraph, roleToUpdate, roleDocument.root()); + if (status == ErrorCodes::RoleNotFound) { + // The query pattern will only contain _id, no other immutable fields are present + status = driver.populateDocumentWithQueryFields(queryPattern, NULL, roleDocument); + } + if (!status.isOK()) + return status; - // Now use the updated document to totally replace the role in the graph! - RoleInfo role; - status = parseRoleFromDocument(roleDocument.getObject(), &role); - if (!status.isOK()) - return status; - status = roleGraph->replaceRole(role.name, role.roles, role.privileges); + status = driver.update(StringData(), &roleDocument); + if (!status.isOK()) + return status; + // Now use the updated document to totally replace the role in the graph! + RoleInfo role; + status = parseRoleFromDocument(roleDocument.getObject(), &role); + if (!status.isOK()) return status; - } + status = roleGraph->replaceRole(role.name, role.roles, role.privileges); - /** - * Updates roleGraph for a delete-type oplog operation on admin.system.roles. - */ - Status handleOplogDelete( - RoleGraph* roleGraph, - const BSONObj& deletePattern) { + return status; +} - RoleName roleToDelete; - Status status = getRoleNameFromIdField(deletePattern["_id"], &roleToDelete); - if (!status.isOK()) - return status; - status = roleGraph->deleteRole(roleToDelete); - if (ErrorCodes::RoleNotFound == status) { - // Double-delete can happen in oplog application. - status = Status::OK(); - } +/** + * Updates roleGraph for a delete-type oplog operation on admin.system.roles. + */ +Status handleOplogDelete(RoleGraph* roleGraph, const BSONObj& deletePattern) { + RoleName roleToDelete; + Status status = getRoleNameFromIdField(deletePattern["_id"], &roleToDelete); + if (!status.isOK()) return status; + status = roleGraph->deleteRole(roleToDelete); + if (ErrorCodes::RoleNotFound == status) { + // Double-delete can happen in oplog application. + status = Status::OK(); } + return status; +} - /** - * Updates roleGraph for command-type oplog operations on the admin database. - */ - Status handleOplogCommand(RoleGraph* roleGraph, const BSONObj& cmdObj) { - const NamespaceString& rolesCollectionNamespace = - AuthorizationManager::rolesCollectionNamespace; - const StringData cmdName(cmdObj.firstElement().fieldNameStringData()); - if (cmdName == "applyOps") { - // Operations applied by applyOps will be passed into RoleGraph::handleOplog() by the - // implementation of applyOps itself. - return Status::OK(); - } - if (cmdName == "create") { - return Status::OK(); - } - if (cmdName == "drop") { - if (cmdObj.firstElement().str() == rolesCollectionNamespace.coll()) { - *roleGraph = RoleGraph(); - } - return Status::OK(); - } - if (cmdName == "dropDatabase") { +/** + * Updates roleGraph for command-type oplog operations on the admin database. + */ +Status handleOplogCommand(RoleGraph* roleGraph, const BSONObj& cmdObj) { + const NamespaceString& rolesCollectionNamespace = + AuthorizationManager::rolesCollectionNamespace; + const StringData cmdName(cmdObj.firstElement().fieldNameStringData()); + if (cmdName == "applyOps") { + // Operations applied by applyOps will be passed into RoleGraph::handleOplog() by the + // implementation of applyOps itself. + return Status::OK(); + } + if (cmdName == "create") { + return Status::OK(); + } + if (cmdName == "drop") { + if (cmdObj.firstElement().str() == rolesCollectionNamespace.coll()) { *roleGraph = RoleGraph(); - return Status::OK(); } - if (cmdName == "renameCollection") { - if (cmdObj.firstElement().str() == rolesCollectionNamespace.ns()) { - *roleGraph = RoleGraph(); - return Status::OK(); - } - if (cmdObj["to"].str() == rolesCollectionNamespace.ns()) { - *roleGraph = RoleGraph(); - return Status(ErrorCodes::OplogOperationUnsupported, - "Renaming into admin.system.roles produces inconsistent state; " - "must resynchronize role graph."); - } - return Status::OK(); - } - if (cmdName == "dropIndexes" || cmdName == "deleteIndexes") { + return Status::OK(); + } + if (cmdName == "dropDatabase") { + *roleGraph = RoleGraph(); + return Status::OK(); + } + if (cmdName == "renameCollection") { + if (cmdObj.firstElement().str() == rolesCollectionNamespace.ns()) { + *roleGraph = RoleGraph(); return Status::OK(); } - if ((cmdName == "collMod" || cmdName == "emptycapped") && - cmdObj.firstElement().str() != rolesCollectionNamespace.coll()) { - - // We don't care about these if they're not on the roles collection. - return Status::OK(); + if (cmdObj["to"].str() == rolesCollectionNamespace.ns()) { + *roleGraph = RoleGraph(); + return Status(ErrorCodes::OplogOperationUnsupported, + "Renaming into admin.system.roles produces inconsistent state; " + "must resynchronize role graph."); } - // No other commands expected. Warn. - return Status(ErrorCodes::OplogOperationUnsupported, "Unsupported oplog operation"); + return Status::OK(); } + if (cmdName == "dropIndexes" || cmdName == "deleteIndexes") { + return Status::OK(); + } + if ((cmdName == "collMod" || cmdName == "emptycapped") && + cmdObj.firstElement().str() != rolesCollectionNamespace.coll()) { + // We don't care about these if they're not on the roles collection. + return Status::OK(); + } + // No other commands expected. Warn. + return Status(ErrorCodes::OplogOperationUnsupported, "Unsupported oplog operation"); +} } // namespace - Status RoleGraph::addRoleFromDocument(const BSONObj& doc) { - RoleInfo role; - Status status = parseRoleFromDocument(doc, &role); - if (!status.isOK()) - return status; - status = replaceRole(role.name, role.roles, role.privileges); +Status RoleGraph::addRoleFromDocument(const BSONObj& doc) { + RoleInfo role; + Status status = parseRoleFromDocument(doc, &role); + if (!status.isOK()) return status; - } + status = replaceRole(role.name, role.roles, role.privileges); + return status; +} - Status RoleGraph::handleLogOp( - const char* op, - const NamespaceString& ns, - const BSONObj& o, - const BSONObj* o2) { - - if (op == StringData("db", StringData::LiteralTag())) - return Status::OK(); - if (op[0] == '\0' || op[1] != '\0') { - return Status(ErrorCodes::BadValue, - mongoutils::str::stream() << "Unrecognized \"op\" field value \"" << - op << '"'); - } +Status RoleGraph::handleLogOp(const char* op, + const NamespaceString& ns, + const BSONObj& o, + const BSONObj* o2) { + if (op == StringData("db", StringData::LiteralTag())) + return Status::OK(); + if (op[0] == '\0' || op[1] != '\0') { + return Status(ErrorCodes::BadValue, + mongoutils::str::stream() << "Unrecognized \"op\" field value \"" << op + << '"'); + } - if (ns.db() != AuthorizationManager::rolesCollectionNamespace.db()) - return Status::OK(); + if (ns.db() != AuthorizationManager::rolesCollectionNamespace.db()) + return Status::OK(); - if (ns.isCommand()) { - if (*op == 'c') { - return handleOplogCommand(this, o); - } - else { - return Status(ErrorCodes::BadValue, - "Non-command oplog entry on admin.$cmd namespace"); - } + if (ns.isCommand()) { + if (*op == 'c') { + return handleOplogCommand(this, o); + } else { + return Status(ErrorCodes::BadValue, "Non-command oplog entry on admin.$cmd namespace"); } + } - if (ns.coll() != AuthorizationManager::rolesCollectionNamespace.coll()) - return Status::OK(); + if (ns.coll() != AuthorizationManager::rolesCollectionNamespace.coll()) + return Status::OK(); - switch (*op) { + switch (*op) { case 'i': return handleOplogInsert(this, o); case 'u': @@ -329,9 +317,9 @@ namespace { "Namespace admin.system.roles is not a valid target for commands"); default: return Status(ErrorCodes::BadValue, - mongoutils::str::stream() << "Unrecognized \"op\" field value \"" << - op << '"'); - } + mongoutils::str::stream() << "Unrecognized \"op\" field value \"" << op + << '"'); } +} } // namespace mongo |