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.h | |
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.h')
-rw-r--r-- | src/mongo/db/auth/role_graph.h | 528 |
1 files changed, 263 insertions, 265 deletions
diff --git a/src/mongo/db/auth/role_graph.h b/src/mongo/db/auth/role_graph.h index bec12b6d1e2..50a0c47a857 100644 --- a/src/mongo/db/auth/role_graph.h +++ b/src/mongo/db/auth/role_graph.h @@ -41,273 +41,271 @@ namespace mongo { +/** + * A graph of role and privilege relationships. + * + * This structure is used to store an in-memory representation of the admin.system.roledata + * collection, specifically the graph of which roles are members of other roles and what + * privileges each role has, both directly and transitively through membership in other roles. + * There are some restrictions on calls to getAllPrivileges(), specifically, one must call + * recomputePrivilegeData() before calling getAllPrivileges() if any of the mutation methods + * have been called on the instance since the later of its construction or the last call to + * recomputePrivilegeData() on the object. + */ +class RoleGraph { +public: + /** + * Adds to "privileges" the privileges associated with the named built-in role, and returns + * true. Returns false if "role" does not name a built-in role, and does not modify + * "privileges". Addition of new privileges is done as with + * Privilege::addPrivilegeToPrivilegeVector. + */ + static bool addPrivilegesForBuiltinRole(const RoleName& role, PrivilegeVector* privileges); + + RoleGraph(); + RoleGraph(const RoleGraph& other); + ~RoleGraph(); + + // Built-in roles for backwards compatibility with 2.2 and prior + static const std::string BUILTIN_ROLE_V0_READ; + static const std::string BUILTIN_ROLE_V0_READ_WRITE; + static const std::string BUILTIN_ROLE_V0_ADMIN_READ; + static const std::string BUILTIN_ROLE_V0_ADMIN_READ_WRITE; + + // Swaps the contents of this RoleGraph with those of "other" + void swap(RoleGraph& other); + + /** + * Adds to "privileges" the necessary privileges to do absolutely anything on the system. + */ + static void generateUniversalPrivileges(PrivilegeVector* privileges); + + /** + * 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 + * this node in the graph. + */ + RoleNameIterator getDirectMembers(const RoleName& role); + + /** + * Returns an iterator over the RoleNames of the "subordinates" of the given role. + * Subordinate roles are the roles that this role has been granted directly (roles + * that have been granted transitively through another role are not included). These are + * the "children" of this node in the graph. + */ + RoleNameIterator getDirectSubordinates(const RoleName& role); + + /** + * Returns an iterator that can be used to get a full list of roles that this role inherits + * privileges from. This includes its direct subordinate roles as well as the subordinates + * of its subordinates, and so on. + */ + RoleNameIterator getIndirectSubordinates(const RoleName& role); + + /** + * Returns an iterator that can be used to get a full list of roles (in lexicographical + * order) that are defined on the given database. + */ + RoleNameIterator getRolesForDatabase(const std::string& dbname); + + /** + * Returns a vector of the privileges that the given role has been directly granted. + * Privileges that have been granted transitively through this role's subordinate roles are + * not included. + */ + const PrivilegeVector& getDirectPrivileges(const RoleName& role); + /** - * A graph of role and privilege relationships. + * Returns a vector of all privileges that the given role contains. This includes both the + * privileges that have been granted to this role directly, as well as any privileges + * inherited from the role's subordinate roles. + */ + const PrivilegeVector& getAllPrivileges(const RoleName& role); + + /** + * Returns whether or not the given role exists in the role graph. Will implicitly + * add the role to the graph if it is a built-in role and isn't already in the graph. + */ + bool roleExists(const RoleName& role); + + /** + * Returns whether the given role corresponds to a built-in role. + */ + static bool isBuiltinRole(const RoleName& role); + + // Mutation functions + + /** + * Puts an entry into the RoleGraph for the given RoleName. + * Returns DuplicateKey if the role already exists. + */ + Status createRole(const RoleName& role); + + /** + * Deletes the given role by first removing it from the members/subordinates arrays for + * all other roles, and then by removing its own entries in the 4 member maps. + * Returns RoleNotFound if the role doesn't exist. + * Returns InvalidRoleModification if "role" is a built-in role. + */ + Status deleteRole(const RoleName& role); + + /** + * Grants "role" to "recipient". This leaves "recipient" as a member of "role" and "role" + * as a subordinate of "recipient". + * Returns RoleNotFound if either of "role" or "recipient" doesn't exist in + * the RoleGraph. + * Returns InvalidRoleModification if "recipient" is a built-in role. + */ + Status addRoleToRole(const RoleName& recipient, const RoleName& role); + + /** + * Revokes "role" from "recipient". + * Returns RoleNotFound if either of "role" or "recipient" doesn't exist in + * the RoleGraph. Returns RolesNotRelated if "recipient" is not currently a + * member of "role". + * Returns InvalidRoleModification if "role" is a built-in role. + */ + Status removeRoleFromRole(const RoleName& recipient, const RoleName& role); + + /** + * Removes all roles held by "victim". + * Returns RoleNotFound if "victim" doesn't exist in the role graph. + * Returns InvalidRoleModification if "victim" is a built-in role. + */ + Status removeAllRolesFromRole(const RoleName& victim); + + /** + * Grants "privilegeToAdd" to "role". + * Returns RoleNotFound if "role" doesn't exist in the role graph. + * Returns InvalidRoleModification if "role" is a built-in role. + */ + Status addPrivilegeToRole(const RoleName& role, const Privilege& privilegeToAdd); + + /** + * Grants Privileges from "privilegesToAdd" to "role". + * Returns RoleNotFound if "role" doesn't exist in the role graph. + * Returns InvalidRoleModification if "role" is a built-in role. + */ + Status addPrivilegesToRole(const RoleName& role, const PrivilegeVector& privilegesToAdd); + + /** + * Removes "privilegeToRemove" from "role". + * Returns RoleNotFound if "role" doesn't exist in the role graph. + * Returns PrivilegeNotFound if "role" doesn't contain the full privilege being removed. + * Returns InvalidRoleModification if "role" is a built-in role. + */ + Status removePrivilegeFromRole(const RoleName& role, const Privilege& privilegeToRemove); + + /** + * Removes all privileges in the "privilegesToRemove" vector from "role". + * Returns RoleNotFound if "role" doesn't exist in the role graph. + * Returns InvalidRoleModification if "role" is a built-in role. + * Returns PrivilegeNotFound if "role" is missing any of the privileges being removed. If + * PrivilegeNotFound is returned then the graph may be in an inconsistent state and needs to + * be abandoned. + */ + Status removePrivilegesFromRole(const RoleName& role, + const PrivilegeVector& privilegesToRemove); + + /** + * Removes all privileges from "role". + * Returns RoleNotFound if "role" doesn't exist in the role graph. + * Returns InvalidRoleModification if "role" is a built-in role. + */ + Status removeAllPrivilegesFromRole(const RoleName& role); + + /** + * Updates the RoleGraph by adding the role named "roleName", with the given role + * memberships and privileges. If the name "roleName" already exists, it is replaced. Any + * subordinate roles mentioned in role.roles are created, if needed, with empty privilege + * and subordinate role lists. + * + * Should _only_ fail if the role to replace is a builtin role, in which + * case it will return ErrorCodes::InvalidRoleModification. + */ + Status replaceRole(const RoleName& roleName, + const std::vector<RoleName>& roles, + const PrivilegeVector& privileges); + + /** + * Adds the role described in "doc" the role graph. + */ + Status addRoleFromDocument(const BSONObj& doc); + + /** + * Applies to the RoleGraph the oplog operation described by the parameters. * - * This structure is used to store an in-memory representation of the admin.system.roledata - * collection, specifically the graph of which roles are members of other roles and what - * privileges each role has, both directly and transitively through membership in other roles. - * There are some restrictions on calls to getAllPrivileges(), specifically, one must call - * recomputePrivilegeData() before calling getAllPrivileges() if any of the mutation methods - * have been called on the instance since the later of its construction or the last call to - * recomputePrivilegeData() on the object. + * Returns Status::OK() on success, ErrorCodes::OplogOperationUnsupported if the oplog + * operation is not supported, and other codes (typically BadValue) if the oplog operation + * is ill-described. */ - class RoleGraph { - public: - /** - * Adds to "privileges" the privileges associated with the named built-in role, and returns - * true. Returns false if "role" does not name a built-in role, and does not modify - * "privileges". Addition of new privileges is done as with - * Privilege::addPrivilegeToPrivilegeVector. - */ - static bool addPrivilegesForBuiltinRole(const RoleName& role, PrivilegeVector* privileges); - - RoleGraph(); - RoleGraph(const RoleGraph& other); - ~RoleGraph(); - - // Built-in roles for backwards compatibility with 2.2 and prior - static const std::string BUILTIN_ROLE_V0_READ; - static const std::string BUILTIN_ROLE_V0_READ_WRITE; - static const std::string BUILTIN_ROLE_V0_ADMIN_READ; - static const std::string BUILTIN_ROLE_V0_ADMIN_READ_WRITE; - - // Swaps the contents of this RoleGraph with those of "other" - void swap(RoleGraph& other); - - /** - * Adds to "privileges" the necessary privileges to do absolutely anything on the system. - */ - static void generateUniversalPrivileges(PrivilegeVector* privileges); - - /** - * 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 - * this node in the graph. - */ - RoleNameIterator getDirectMembers(const RoleName& role); - - /** - * Returns an iterator over the RoleNames of the "subordinates" of the given role. - * Subordinate roles are the roles that this role has been granted directly (roles - * that have been granted transitively through another role are not included). These are - * the "children" of this node in the graph. - */ - RoleNameIterator getDirectSubordinates(const RoleName& role); - - /** - * Returns an iterator that can be used to get a full list of roles that this role inherits - * privileges from. This includes its direct subordinate roles as well as the subordinates - * of its subordinates, and so on. - */ - RoleNameIterator getIndirectSubordinates(const RoleName& role); - - /** - * Returns an iterator that can be used to get a full list of roles (in lexicographical - * order) that are defined on the given database. - */ - RoleNameIterator getRolesForDatabase(const std::string& dbname); - - /** - * Returns a vector of the privileges that the given role has been directly granted. - * Privileges that have been granted transitively through this role's subordinate roles are - * not included. - */ - const PrivilegeVector& getDirectPrivileges(const RoleName& role); - - /** - * Returns a vector of all privileges that the given role contains. This includes both the - * privileges that have been granted to this role directly, as well as any privileges - * inherited from the role's subordinate roles. - */ - const PrivilegeVector& getAllPrivileges(const RoleName& role); - - /** - * Returns whether or not the given role exists in the role graph. Will implicitly - * add the role to the graph if it is a built-in role and isn't already in the graph. - */ - bool roleExists(const RoleName& role); - - /** - * Returns whether the given role corresponds to a built-in role. - */ - static bool isBuiltinRole(const RoleName& role); - - // Mutation functions - - /** - * Puts an entry into the RoleGraph for the given RoleName. - * Returns DuplicateKey if the role already exists. - */ - Status createRole(const RoleName& role); - - /** - * Deletes the given role by first removing it from the members/subordinates arrays for - * all other roles, and then by removing its own entries in the 4 member maps. - * Returns RoleNotFound if the role doesn't exist. - * Returns InvalidRoleModification if "role" is a built-in role. - */ - Status deleteRole(const RoleName& role); - - /** - * Grants "role" to "recipient". This leaves "recipient" as a member of "role" and "role" - * as a subordinate of "recipient". - * Returns RoleNotFound if either of "role" or "recipient" doesn't exist in - * the RoleGraph. - * Returns InvalidRoleModification if "recipient" is a built-in role. - */ - Status addRoleToRole(const RoleName& recipient, const RoleName& role); - - /** - * Revokes "role" from "recipient". - * Returns RoleNotFound if either of "role" or "recipient" doesn't exist in - * the RoleGraph. Returns RolesNotRelated if "recipient" is not currently a - * member of "role". - * Returns InvalidRoleModification if "role" is a built-in role. - */ - Status removeRoleFromRole(const RoleName& recipient, const RoleName& role); - - /** - * Removes all roles held by "victim". - * Returns RoleNotFound if "victim" doesn't exist in the role graph. - * Returns InvalidRoleModification if "victim" is a built-in role. - */ - Status removeAllRolesFromRole(const RoleName& victim); - - /** - * Grants "privilegeToAdd" to "role". - * Returns RoleNotFound if "role" doesn't exist in the role graph. - * Returns InvalidRoleModification if "role" is a built-in role. - */ - Status addPrivilegeToRole(const RoleName& role, const Privilege& privilegeToAdd); - - /** - * Grants Privileges from "privilegesToAdd" to "role". - * Returns RoleNotFound if "role" doesn't exist in the role graph. - * Returns InvalidRoleModification if "role" is a built-in role. - */ - Status addPrivilegesToRole(const RoleName& role, const PrivilegeVector& privilegesToAdd); - - /** - * Removes "privilegeToRemove" from "role". - * Returns RoleNotFound if "role" doesn't exist in the role graph. - * Returns PrivilegeNotFound if "role" doesn't contain the full privilege being removed. - * Returns InvalidRoleModification if "role" is a built-in role. - */ - Status removePrivilegeFromRole(const RoleName& role, - const Privilege& privilegeToRemove); - - /** - * Removes all privileges in the "privilegesToRemove" vector from "role". - * Returns RoleNotFound if "role" doesn't exist in the role graph. - * Returns InvalidRoleModification if "role" is a built-in role. - * Returns PrivilegeNotFound if "role" is missing any of the privileges being removed. If - * PrivilegeNotFound is returned then the graph may be in an inconsistent state and needs to - * be abandoned. - */ - Status removePrivilegesFromRole(const RoleName& role, - const PrivilegeVector& privilegesToRemove); - - /** - * Removes all privileges from "role". - * Returns RoleNotFound if "role" doesn't exist in the role graph. - * Returns InvalidRoleModification if "role" is a built-in role. - */ - Status removeAllPrivilegesFromRole(const RoleName& role); - - /** - * Updates the RoleGraph by adding the role named "roleName", with the given role - * memberships and privileges. If the name "roleName" already exists, it is replaced. Any - * subordinate roles mentioned in role.roles are created, if needed, with empty privilege - * and subordinate role lists. - * - * Should _only_ fail if the role to replace is a builtin role, in which - * case it will return ErrorCodes::InvalidRoleModification. - */ - Status replaceRole(const RoleName& roleName, - const std::vector<RoleName>& roles, - const PrivilegeVector& privileges); - - /** - * Adds the role described in "doc" the role graph. - */ - Status addRoleFromDocument(const BSONObj& doc); - - /** - * Applies to the RoleGraph the oplog operation described by the parameters. - * - * Returns Status::OK() on success, ErrorCodes::OplogOperationUnsupported if the oplog - * operation is not supported, and other codes (typically BadValue) if the oplog operation - * is ill-described. - */ - Status handleLogOp( - const char* op, - const NamespaceString& ns, - const BSONObj& o, - const BSONObj* o2); - - /** - * Recomputes the indirect (getAllPrivileges) data for this graph. - * - * Must be called between calls to any of the mutation functions and calls - * to getAllPrivileges(). - * - * Returns Status::OK() on success. If a cycle is detected, returns - * ErrorCodes::GraphContainsCycle, and the status message reveals the cycle. - */ - Status recomputePrivilegeData(); - - private: - // Helper method doing a topological DFS to compute the indirect privilege - // data and look for cycles - Status _recomputePrivilegeDataHelper(const RoleName& currentRole, - unordered_set<RoleName>& visitedRoles); - - /** - * If the role name given is not a built-in role, or it is but it's already in the role - * graph, then this does nothing. If it *is* a built-in role and this is the first time - * this function has been called for this role, it will add the role into the role graph. - */ - void _createBuiltinRoleIfNeeded(const RoleName& role); - - /** - * Adds the built-in roles for the given database name to the role graph if they aren't - * already present. - */ - void _createBuiltinRolesForDBIfNeeded(const std::string& dbname); - - /** - * Returns whether or not the given role exists strictly within the role graph. - */ - bool _roleExistsDontCreateBuiltin(const RoleName& role); - - /** - * Just creates the role in the role graph, without checking whether or not the role already - * exists. - */ - void _createRoleDontCheckIfRoleExists(const RoleName& role); - - /** - * Grants "privilegeToAdd" to "role". - * Doesn't do any checking as to whether the role exists or is a built-in role. - */ - void _addPrivilegeToRoleNoChecks(const RoleName& role, const Privilege& privilegeToAdd); - - - // Represents all the outgoing edges to other roles from any given role. - typedef unordered_map<RoleName, std::vector<RoleName> > EdgeSet; - // Maps a role name to a list of privileges associated with that role. - typedef unordered_map<RoleName, PrivilegeVector> RolePrivilegeMap; - - EdgeSet _roleToSubordinates; - unordered_map<RoleName, unordered_set<RoleName> > _roleToIndirectSubordinates; - EdgeSet _roleToMembers; - RolePrivilegeMap _directPrivilegesForRole; - RolePrivilegeMap _allPrivilegesForRole; - std::set<RoleName> _allRoles; - }; - - void swap(RoleGraph& lhs, RoleGraph& rhs); + Status handleLogOp(const char* op, + const NamespaceString& ns, + const BSONObj& o, + const BSONObj* o2); + + /** + * Recomputes the indirect (getAllPrivileges) data for this graph. + * + * Must be called between calls to any of the mutation functions and calls + * to getAllPrivileges(). + * + * Returns Status::OK() on success. If a cycle is detected, returns + * ErrorCodes::GraphContainsCycle, and the status message reveals the cycle. + */ + Status recomputePrivilegeData(); + +private: + // Helper method doing a topological DFS to compute the indirect privilege + // data and look for cycles + Status _recomputePrivilegeDataHelper(const RoleName& currentRole, + unordered_set<RoleName>& visitedRoles); + + /** + * If the role name given is not a built-in role, or it is but it's already in the role + * graph, then this does nothing. If it *is* a built-in role and this is the first time + * this function has been called for this role, it will add the role into the role graph. + */ + void _createBuiltinRoleIfNeeded(const RoleName& role); + + /** + * Adds the built-in roles for the given database name to the role graph if they aren't + * already present. + */ + void _createBuiltinRolesForDBIfNeeded(const std::string& dbname); + + /** + * Returns whether or not the given role exists strictly within the role graph. + */ + bool _roleExistsDontCreateBuiltin(const RoleName& role); + + /** + * Just creates the role in the role graph, without checking whether or not the role already + * exists. + */ + void _createRoleDontCheckIfRoleExists(const RoleName& role); + + /** + * Grants "privilegeToAdd" to "role". + * Doesn't do any checking as to whether the role exists or is a built-in role. + */ + void _addPrivilegeToRoleNoChecks(const RoleName& role, const Privilege& privilegeToAdd); + + + // Represents all the outgoing edges to other roles from any given role. + typedef unordered_map<RoleName, std::vector<RoleName>> EdgeSet; + // Maps a role name to a list of privileges associated with that role. + typedef unordered_map<RoleName, PrivilegeVector> RolePrivilegeMap; + + EdgeSet _roleToSubordinates; + unordered_map<RoleName, unordered_set<RoleName>> _roleToIndirectSubordinates; + EdgeSet _roleToMembers; + RolePrivilegeMap _directPrivilegesForRole; + RolePrivilegeMap _allPrivilegesForRole; + std::set<RoleName> _allRoles; +}; + +void swap(RoleGraph& lhs, RoleGraph& rhs); } // namespace mongo |