Status V2UserDocumentParser::initializeUserPrivilegesFromUserDocument(const BSONObj& doc, User* user) const { BSONElement privilegesElement = doc[PRIVILEGES_FIELD_NAME]; if (privilegesElement.eoo()) return Status::OK(); if (privilegesElement.type() != Array) { return Status(ErrorCodes::UnsupportedFormat, "User document 'inheritedPrivileges' element must be Array if present."); } PrivilegeVector privileges; std::string errmsg; for (BSONObjIterator it(privilegesElement.Obj()); it.more(); it.next()) { if ((*it).type() != Object) { warning() << "Wrong type of element in inheritedPrivileges array for " << user->getName() << ": " << *it; continue; } Privilege privilege; ParsedPrivilege pp; if (!pp.parseBSON((*it).Obj(), &errmsg) || !ParsedPrivilege::parsedPrivilegeToPrivilege(pp, &privilege, &errmsg)) { warning() << "Could not parse privilege element in user document for " << user->getName() << ": " << errmsg; continue; } privileges.push_back(privilege); } user->setPrivileges(privileges); return Status::OK(); }
/* * Validates that the given privilege BSONArray is valid. * If parsedPrivileges is not NULL, adds to it the privileges parsed out of the input BSONArray. */ Status _parseAndValidatePrivilegeArray(const BSONArray& privileges, PrivilegeVector* parsedPrivileges) { for (BSONObjIterator it(privileges); it.more(); it.next()) { BSONElement element = *it; if (element.type() != Object) { return Status(ErrorCodes::FailedToParse, "Elements in privilege arrays must be objects"); } ParsedPrivilege parsedPrivilege; std::string errmsg; if (!parsedPrivilege.parseBSON(element.Obj(), &errmsg)) { return Status(ErrorCodes::FailedToParse, errmsg); } if (!parsedPrivilege.isValid(&errmsg)) { return Status(ErrorCodes::FailedToParse, errmsg); } Privilege privilege; if (!ParsedPrivilege::parsedPrivilegeToPrivilege(parsedPrivilege, &privilege, &errmsg)) { return Status(ErrorCodes::FailedToParse, errmsg); } if (parsedPrivileges) { parsedPrivileges->push_back(privilege); } } return Status::OK(); }
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()); } return Status::OK(); }
Status ParsedPrivilege::parsedPrivilegeToPrivilege(const ParsedPrivilege& parsedPrivilege, Privilege* result, std::vector<std::string>* unrecognizedActions) { std::string errmsg; if (!parsedPrivilege.isValid(&errmsg)) { return Status(ErrorCodes::FailedToParse, errmsg); } // Build actions ActionSet actions; const vector<std::string>& parsedActions = parsedPrivilege.getActions(); Status status = ActionSet::parseActionSetFromStringVector(parsedActions, &actions, unrecognizedActions); if (!status.isOK()) { return status; } // Build resource ResourcePattern resource; const ParsedResource& parsedResource = parsedPrivilege.getResource(); if (parsedResource.isAnyResourceSet() && parsedResource.getAnyResource()) { resource = ResourcePattern::forAnyResource(); } else if (parsedResource.isClusterSet() && parsedResource.getCluster()) { resource = ResourcePattern::forClusterResource(); } else { if (parsedResource.isDbSet() && !parsedResource.getDb().empty()) { if (parsedResource.isCollectionSet() && !parsedResource.getCollection().empty()) { resource = ResourcePattern::forExactNamespace( NamespaceString(parsedResource.getDb(), parsedResource.getCollection())); } else { resource = ResourcePattern::forDatabaseName(parsedResource.getDb()); } } else { if (parsedResource.isCollectionSet() && !parsedResource.getCollection().empty()) { resource = ResourcePattern::forCollectionName(parsedResource.getCollection()); } else { resource = ResourcePattern::forAnyNormalResource(); } } } *result = Privilege(resource, actions); return Status::OK(); }
bool ParsedPrivilege::parsedPrivilegeToPrivilege(const ParsedPrivilege& parsedPrivilege, Privilege* result, std::string* errmsg) { if (!parsedPrivilege.isValid(errmsg)) { return false; } // Build actions ActionSet actions; const vector<std::string>& parsedActions = parsedPrivilege.getActions(); Status status = ActionSet::parseActionSetFromStringVector(parsedActions, &actions); if (!status.isOK()) { *errmsg = status.reason(); return false; } // Build resource ResourcePattern resource; const ParsedResource& parsedResource = parsedPrivilege.getResource(); if (parsedResource.isAnyResourceSet() && parsedResource.getAnyResource()) { resource = ResourcePattern::forAnyResource(); } else if (parsedResource.isClusterSet() && parsedResource.getCluster()) { resource = ResourcePattern::forClusterResource(); } else { if (parsedResource.isDbSet() && !parsedResource.getDb().empty()) { if (parsedResource.isCollectionSet() && !parsedResource.getCollection().empty()) { resource = ResourcePattern::forExactNamespace( NamespaceString(parsedResource.getDb(), parsedResource.getCollection())); } else { resource = ResourcePattern::forDatabaseName(parsedResource.getDb()); } } else { if (parsedResource.isCollectionSet() && !parsedResource.getCollection().empty()) { resource = ResourcePattern::forCollectionName(parsedResource.getCollection()); } else { resource = ResourcePattern::forAnyNormalResource(); } } } *result = Privilege(resource, actions); return true; }
Status V2UserDocumentParser::initializeUserPrivilegesFromUserDocument(const BSONObj& doc, User* user) const { BSONElement privilegesElement = doc[PRIVILEGES_FIELD_NAME]; if (privilegesElement.eoo()) return Status::OK(); if (privilegesElement.type() != Array) { return Status(ErrorCodes::UnsupportedFormat, "User document 'inheritedPrivileges' element must be Array if present."); } PrivilegeVector privileges; std::string errmsg; for (BSONObjIterator it(privilegesElement.Obj()); it.more(); it.next()) { if ((*it).type() != Object) { warning() << "Wrong type of element in inheritedPrivileges array for " << user->getName() << ": " << *it; continue; } Privilege privilege; ParsedPrivilege pp; if (!pp.parseBSON((*it).Obj(), &errmsg)) { warning() << "Could not parse privilege element in user document for " << user->getName() << ": " << errmsg; continue; } std::vector<std::string> unrecognizedActions; Status status = ParsedPrivilege::parsedPrivilegeToPrivilege(pp, &privilege, &unrecognizedActions); if (!status.isOK()) { warning() << "Could not parse privilege element in user document for " << user->getName() << causedBy(status); continue; } if (unrecognizedActions.size()) { std::string unrecognizedActionsString; joinStringDelim(unrecognizedActions, &unrecognizedActionsString, ','); warning() << "Encountered unrecognized actions \" " << unrecognizedActionsString << "\" while parsing user document for " << user->getName(); } privileges.push_back(privilege); } user->setPrivileges(privileges); return Status::OK(); }
/* * Validates that the given privilege BSONArray is valid. * If parsedPrivileges is not NULL, adds to it the privileges parsed out of the input BSONArray. */ Status parseAndValidatePrivilegeArray(const BSONArray& privileges, PrivilegeVector* parsedPrivileges) { for (BSONObjIterator it(privileges); it.more(); it.next()) { BSONElement element = *it; if (element.type() != Object) { return Status(ErrorCodes::FailedToParse, "Elements in privilege arrays must be objects"); } ParsedPrivilege parsedPrivilege; std::string errmsg; if (!parsedPrivilege.parseBSON(element.Obj(), &errmsg)) { return Status(ErrorCodes::FailedToParse, errmsg); } if (!parsedPrivilege.isValid(&errmsg)) { return Status(ErrorCodes::FailedToParse, errmsg); } Privilege privilege; std::vector<std::string> unrecognizedActions; Status status = ParsedPrivilege::parsedPrivilegeToPrivilege( parsedPrivilege, &privilege, &unrecognizedActions); if (!status.isOK()) { return status; } if (unrecognizedActions.size()) { std::string unrecognizedActionsString; joinStringDelim(unrecognizedActions, &unrecognizedActionsString, ','); return Status(ErrorCodes::FailedToParse, str::stream() << "Unrecognized action privilege strings: " << unrecognizedActionsString); } parsedPrivileges->push_back(privilege); } return Status::OK(); }