Status V2UserDocumentParser::initializeUserIndirectRolesFromUserDocument(const BSONObj& privDoc, User* user) const { BSONElement indirectRolesElement = privDoc[INHERITED_ROLES_FIELD_NAME]; if (indirectRolesElement.type() != Array) { return Status(ErrorCodes::UnsupportedFormat, "User document needs 'inheritedRoles' field to be an array"); } std::vector<RoleName> indirectRoles; for (BSONObjIterator it(indirectRolesElement.Obj()); it.more(); it.next()) { if ((*it).type() != Object) { return Status(ErrorCodes::UnsupportedFormat, "User document needs values in 'inheritedRoles'" " array to be a sub-documents"); } BSONObj indirectRoleObject = (*it).Obj(); RoleName indirectRole; Status status = parseRoleName(indirectRoleObject, &indirectRole); if (!status.isOK()) { return status; } indirectRoles.push_back(indirectRole); } user->setIndirectRoles(makeRoleNameIteratorForContainer(indirectRoles)); return Status::OK(); }
Status AuthzManagerExternalStateMock::getUserDescription( const UserName& userName, BSONObj* result) { BSONObj privDoc; Status status = getPrivilegeDocument(userName, 2, &privDoc); if (!status.isOK()) return status; unordered_set<RoleName> indirectRoles; PrivilegeVector allPrivileges; for (BSONObjIterator iter(privDoc["roles"].Obj()); iter.more(); iter.next()) { if (!(*iter)["hasRole"].trueValue()) continue; RoleName roleName((*iter)[AuthorizationManager::ROLE_NAME_FIELD_NAME].str(), (*iter)[AuthorizationManager::ROLE_SOURCE_FIELD_NAME].str()); indirectRoles.insert(roleName); for (RoleNameIterator subordinates = _roleGraph.getIndirectSubordinates( roleName); subordinates.more(); subordinates.next()) { indirectRoles.insert(subordinates.get()); } const PrivilegeVector& rolePrivileges(_roleGraph.getAllPrivileges(roleName)); for (PrivilegeVector::const_iterator priv = rolePrivileges.begin(), end = rolePrivileges.end(); priv != end; ++priv) { Privilege::addPrivilegeToPrivilegeVector(&allPrivileges, *priv); } } mutablebson::Document userDoc(privDoc, mutablebson::Document::kInPlaceDisabled); mutablebson::Element indirectRolesElement = userDoc.makeElementArray("indirectRoles"); mutablebson::Element privilegesElement = userDoc.makeElementArray("privileges"); mutablebson::Element warningsElement = userDoc.makeElementArray("warnings"); fassert(17180, userDoc.root().pushBack(privilegesElement)); fassert(17181, userDoc.root().pushBack(indirectRolesElement)); addRoleNameObjectsToArrayElement(indirectRolesElement, makeRoleNameIteratorForContainer(indirectRoles)); addPrivilegeObjectsOrWarningsToArrayElement( privilegesElement, warningsElement, allPrivileges); if (warningsElement.hasChildren()) { fassert(17182, userDoc.root().pushBack(warningsElement)); } *result = userDoc.getObject(); return Status::OK(); }
Status AuthzManagerExternalStateLocal::getUserDescription( const UserName& userName, BSONObj* result) { BSONObj userDoc; Status status = _getUserDocument(userName, &userDoc); if (!status.isOK()) return status; BSONElement directRolesElement; status = bsonExtractTypedField(userDoc, "roles", Array, &directRolesElement); if (!status.isOK()) return status; std::vector<RoleName> directRoles; status = V2UserDocumentParser::parseRoleVector(BSONArray(directRolesElement.Obj()), &directRoles); if (!status.isOK()) return status; unordered_set<RoleName> indirectRoles; PrivilegeVector allPrivileges; bool isRoleGraphInconsistent; { boost::lock_guard<boost::mutex> lk(_roleGraphMutex); isRoleGraphInconsistent = _roleGraphState == roleGraphStateConsistent; for (size_t i = 0; i < directRoles.size(); ++i) { const RoleName& role(directRoles[i]); indirectRoles.insert(role); if (isRoleGraphInconsistent) { for (RoleNameIterator subordinates = _roleGraph.getIndirectSubordinates(role); subordinates.more(); subordinates.next()) { indirectRoles.insert(subordinates.get()); } } const PrivilegeVector& rolePrivileges( isRoleGraphInconsistent ? _roleGraph.getAllPrivileges(role) : _roleGraph.getDirectPrivileges(role)); for (PrivilegeVector::const_iterator priv = rolePrivileges.begin(), end = rolePrivileges.end(); priv != end; ++priv) { Privilege::addPrivilegeToPrivilegeVector(&allPrivileges, *priv); } } } mutablebson::Document resultDoc(userDoc, mutablebson::Document::kInPlaceDisabled); mutablebson::Element inheritedRolesElement = resultDoc.makeElementArray("inheritedRoles"); mutablebson::Element privilegesElement = resultDoc.makeElementArray("inheritedPrivileges"); mutablebson::Element warningsElement = resultDoc.makeElementArray("warnings"); fassert(17159, resultDoc.root().pushBack(inheritedRolesElement)); fassert(17158, resultDoc.root().pushBack(privilegesElement)); if (!isRoleGraphInconsistent) { fassert(17160, warningsElement.appendString( "", "Role graph inconsistent, only direct privileges available.")); } addRoleNameObjectsToArrayElement(inheritedRolesElement, makeRoleNameIteratorForContainer(indirectRoles)); addPrivilegeObjectsOrWarningsToArrayElement( privilegesElement, warningsElement, allPrivileges); if (warningsElement.hasChildren()) { fassert(17161, resultDoc.root().pushBack(warningsElement)); } *result = resultDoc.getObject(); return Status::OK(); }
RoleNameIterator User::getIndirectRoles() const { return makeRoleNameIteratorForContainer(_indirectRoles); }
RoleNameIterator User::getRoles() const { return makeRoleNameIteratorForContainer(_roles); }