Redfish privileges
Redfish privilege authorization subsystem controlled by the
privilege_registy.json configuration file.
PropertyOverrides, SubordinateOverrides and ResourceURIOverrides
are not yet implemented.
Change-Id: I4d5670d557f4da172460ada3512e015830dab667
Signed-off-by: Borawski.Lukasz <lukasz.borawski@intel.com>
Signed-off-by: Ed Tanous <ed.tanous@intel.com>
diff --git a/redfish-core/include/node.hpp b/redfish-core/include/node.hpp
index 70b85222..6a58cb2 100644
--- a/redfish-core/include/node.hpp
+++ b/redfish-core/include/node.hpp
@@ -28,13 +28,12 @@
class Node {
public:
template <typename CrowApp, typename... Params>
- Node(CrowApp& app, PrivilegeProvider& provider, std::string odataType,
- std::string odataId, Params... params)
- : odataType(odataType), odataId(odataId) {
- // privileges for the node as defined in the privileges_registry.json
- entityPrivileges = provider.getPrivileges(odataId, odataType);
-
- app.route_dynamic(std::move(odataId))
+ Node(CrowApp& app, const PrivilegeProvider& privilegeProvider,
+ const std::string& entityType, const std::string& entityUrl,
+ Params... params)
+ : entityPrivileges(privilegeProvider.getPrivilegesRequiredByEntity(
+ entityUrl, entityType)) {
+ app.route_dynamic(entityUrl.c_str())
.methods("GET"_method, "PATCH"_method, "POST"_method,
"DELETE"_method)([&](const crow::request& req,
crow::response& res, Params... params) {
@@ -43,15 +42,41 @@
});
}
+ virtual ~Node() = default;
+
+ protected:
+ // Node is designed to be an abstract class, so doGet is pure virtual
+ virtual void doGet(crow::response& res, const crow::request& req,
+ const std::vector<std::string>& params) = 0;
+
+ virtual void doPatch(crow::response& res, const crow::request& req,
+ const std::vector<std::string>& params) {
+ res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
+ res.end();
+ }
+
+ virtual void doPost(crow::response& res, const crow::request& req,
+ const std::vector<std::string>& params) {
+ res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
+ res.end();
+ }
+
+ virtual void doDelete(crow::response& res, const crow::request& req,
+ const std::vector<std::string>& params) {
+ res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
+ res.end();
+ }
+
+ private:
template <typename CrowApp>
void dispatchRequest(CrowApp& app, const crow::request& req,
crow::response& res,
const std::vector<std::string>& params) {
- // drop requests without required privileges
auto ctx =
app.template get_context<crow::TokenAuthorization::Middleware>(req);
- if (!entityPrivileges.isMethodAllowed(req.method, ctx.session->username)) {
+ if (!entityPrivileges.isMethodAllowedForUser(req.method,
+ ctx.session->username)) {
res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
res.end();
return;
@@ -81,33 +106,7 @@
return;
}
- protected:
- const std::string odataType;
- const std::string odataId;
-
- // Node is designed to be an abstract class, so doGet is pure virutal
- virtual void doGet(crow::response& res, const crow::request& req,
- const std::vector<std::string>& params) = 0;
-
- virtual void doPatch(crow::response& res, const crow::request& req,
- const std::vector<std::string>& params) {
- res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
- res.end();
- }
-
- virtual void doPost(crow::response& res, const crow::request& req,
- const std::vector<std::string>& params) {
- res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
- res.end();
- }
-
- virtual void doDelete(crow::response& res, const crow::request& req,
- const std::vector<std::string>& params) {
- res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
- res.end();
- }
-
- EntityPrivileges entityPrivileges;
+ const EntityPrivileges entityPrivileges;
};
template <typename CrowApp>
diff --git a/redfish-core/include/privileges.hpp b/redfish-core/include/privileges.hpp
index 290c0eb..2441104 100644
--- a/redfish-core/include/privileges.hpp
+++ b/redfish-core/include/privileges.hpp
@@ -15,51 +15,228 @@
*/
#pragma once
+#include <bitset>
+#include <cstdint>
+#include "crow.h"
+#include <boost/container/flat_map.hpp>
+#include <boost/optional.hpp>
+
namespace redfish {
+class PrivilegeProvider;
+
+enum class PrivilegeType { BASE, OEM };
+
+/** @brief Max number of privileges per type */
+constexpr const size_t MAX_PRIVILEGE_COUNT = 32;
+using privilegeBitset = std::bitset<MAX_PRIVILEGE_COUNT>;
+
/**
- * @brief Class used to store privileges for a given user.
+ * @brief Redfish privileges
+ *
+ * Entity privileges and user privileges are represented by this class.
+ *
+ * Each incoming connection requires a comparison between privileges held
+ * by the user issuing a request and the target entity's privileges.
+ *
+ * To ensure best runtime performance of this comparison, privileges
+ * are represented as bitsets. Each bit in the bitset corresponds to a
+ * unique privilege name.
+ *
+ * Privilege names are read from the privilege_registry.json file and
+ * stored in flat maps.
+ *
+ * A bit is set if the privilege is required (entity domain) or granted
+ * (user domain) and false otherwise.
+ *
+ * Bitset index to privilege name mapping depends on the order in which
+ * privileges are defined in PrivilegesUsed and OEMPrivilegesUsed arrays
+ * in the privilege_registry.json.
*/
-class UserPrivileges {
- // TODO: Temporary stub, implementation will come with next patch-sets
+class Privileges {
+ public:
+ /**
+ * @brief Retrieves the base privileges bitset
+ *
+ * @return Bitset representation of base Redfish privileges
+ */
+ privilegeBitset getBasePrivilegeBitset() const { return basePrivilegeBitset; }
+
+ /**
+ * @brief Retrieves the OEM privileges bitset
+ *
+ * @return Bitset representation of OEM Redfish privileges
+ */
+ privilegeBitset getOEMPrivilegeBitset() const { return oemPrivilegeBitset; }
+
+ /**
+ * @brief Sets given privilege in the bitset
+ *
+ * @param[in] privilege Privilege to be set
+ *
+ * @return None
+ */
+ void setSinglePrivilege(const std::string& privilege) {
+ auto index = getBitsetIndexForPrivilege(privilege, PrivilegeType::BASE);
+ if (index) {
+ basePrivilegeBitset.set(*index);
+ return;
+ }
+
+ index = getBitsetIndexForPrivilege(privilege, PrivilegeType::OEM);
+ if (index) {
+ oemPrivilegeBitset.set(*index);
+ }
+ }
+
+ /**
+ * @brief Retrieves names of all active privileges for a given type
+ *
+ * @param[in] type Base or OEM
+ *
+ * @return Vector of active privileges
+ */
+ std::vector<std::string> getActivePrivilegeNames(
+ const PrivilegeType type) const {
+ std::vector<std::string> activePrivileges;
+
+ if (type == PrivilegeType::BASE) {
+ for (const auto& pair : basePrivNameToIndexMap) {
+ if (basePrivilegeBitset.test(pair.second)) {
+ activePrivileges.emplace_back(pair.first);
+ }
+ }
+ } else {
+ for (const auto& pair : oemPrivNameToIndexMap) {
+ if (oemPrivilegeBitset.test(pair.second)) {
+ activePrivileges.emplace_back(pair.first);
+ }
+ }
+ }
+
+ return activePrivileges;
+ }
+
private:
- uint32_t redfishPrivileges;
- uint32_t oemPrivileges;
+ boost::optional<size_t> getBitsetIndexForPrivilege(
+ const std::string& privilege, const PrivilegeType type) const {
+ if (type == PrivilegeType::BASE) {
+ const auto pair = basePrivNameToIndexMap.find(privilege);
+ if (pair != basePrivNameToIndexMap.end()) {
+ return pair->second;
+ }
+ } else {
+ const auto pair = oemPrivNameToIndexMap.find(privilege);
+ if (pair != oemPrivNameToIndexMap.end()) {
+ return pair->second;
+ }
+ }
+
+ return boost::none;
+ }
+
+ privilegeBitset basePrivilegeBitset;
+ privilegeBitset oemPrivilegeBitset;
+
+ static boost::container::flat_map<std::string, size_t> basePrivNameToIndexMap;
+ static boost::container::flat_map<std::string, size_t> oemPrivNameToIndexMap;
+
+ friend class PrivilegeProvider;
};
/**
- * @brief Class used to store privileges for a given Redfish entity.
+ * @brief Class used to store privileges for Redfish entities
*/
class EntityPrivileges {
- // TODO: Temporary stub, implementation will come with next patch-sets
public:
- bool isMethodAllowed(const crow::HTTPMethod& method,
- const std::string& username) const {
- return true;
+ /**
+ * @brief Checks if a user is allowed to call an HTTP method
+ *
+ * @param[in] method HTTP method
+ * @param[in] user Username
+ *
+ * @return True if method allowed, false otherwise
+ */
+ bool isMethodAllowedForUser(const crow::HTTPMethod method,
+ const std::string& user) const;
+
+ /**
+ * @brief Checks if given privileges allow to call an HTTP method
+ *
+ * @param[in] method HTTP method
+ * @param[in] user Privileges
+ *
+ * @return True if method allowed, false otherwise
+ */
+ bool isMethodAllowedWithPrivileges(const crow::HTTPMethod method,
+ const Privileges& userPrivileges) const;
+
+ /**
+ * @brief Sets required privileges for a method on a given entity
+ *
+ * @param[in] method HTTP method
+ * @param[in] privileges Required privileges
+ *
+ * @return None
+ */
+ void addPrivilegesRequiredByMethod(const crow::HTTPMethod method,
+ const Privileges& privileges) {
+ methodToPrivilegeMap[method].push_back(privileges);
}
+
+ private:
+ bool verifyPrivileges(const privilegeBitset userPrivilegeBitset,
+ const privilegeBitset requiredPrivilegeBitset) const;
+
+ boost::container::flat_map<crow::HTTPMethod, std::vector<Privileges>>
+ methodToPrivilegeMap;
};
/**
* @brief Class used to:
- * - read the PrivilegeRegistry file,
- * - provide EntityPrivileges objects to callers.
+ * - read the privilege_registry.json file
+ * - provide EntityPrivileges objects to callers
*
- * To save runtime memory object of this class should
- * exist only for the time required to install all Nodes.
+ * To save runtime memory, object of this class should
+ * exist only for the time required to install all Nodes
*/
class PrivilegeProvider {
- // TODO: Temporary stub, implementation will come with next patch-sets
public:
- PrivilegeProvider() {
- // load privilege_registry.json to memory
+ PrivilegeProvider(const std::string& privilegeRegistryPath) {
+ // TODO: read this path from the configuration once its available
+ std::ifstream privilegeRegistryFile{privilegeRegistryPath};
+
+ if (privilegeRegistryFile.is_open()) {
+ if (!loadPrivilegesFromFile(privilegeRegistryFile)) {
+ privilegeRegistryJson.clear();
+ CROW_LOG_ERROR << "Couldn't parse privilege_registry.json";
+ }
+ } else {
+ CROW_LOG_ERROR << "Couldn't open privilege_registry.json";
+ }
}
- EntityPrivileges getPrivileges(const std::string& entity_url,
- const std::string& entity_type) const {
- // return an entity privilege object based on the privilege_registry.json,
- // currently returning default constructed object
- return EntityPrivileges();
- }
+ /**
+ * @brief Gets required privileges for a certain entity type
+ *
+ * @param[in] entityUrl Entity url
+ * @param[in] entityType Entity type
+ *
+ * @return EntityPrivilege object
+ */
+ EntityPrivileges getPrivilegesRequiredByEntity(
+ const std::string& entityUrl, const std::string& entityType) const;
+
+ private:
+ bool loadPrivilegesFromFile(std::ifstream& privilegeRegistryFile);
+ bool privilegeRegistryHasRequiredFields() const;
+ bool parseOperationMap(const nlohmann::json& operationMap,
+ EntityPrivileges& entityPrivileges) const;
+ bool fillPrivilegeMap(const nlohmann::json& privilegesUsed,
+ boost::container::flat_map<std::string, size_t>&
+ privilegeToIndexMap) const;
+
+ nlohmann::json privilegeRegistryJson;
};
} // namespace redfish
diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index 0598636..b67c857 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -34,7 +34,8 @@
*/
template <typename CrowApp>
RedfishService(CrowApp& app) {
- auto privilegeProvider = PrivilegeProvider();
+ auto privilegeProvider =
+ PrivilegeProvider("/etc/redfish.conf.d/privilege_registry.json");
nodes.emplace_back(
std::make_unique<SessionCollection>(app, privilegeProvider));
diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp
index 0835fa1..11cde72 100644
--- a/redfish-core/lib/redfish_sessions.hpp
+++ b/redfish-core/lib/redfish_sessions.hpp
@@ -28,7 +28,7 @@
Sessions(CrowApp& app, PrivilegeProvider& provider)
: Node(app, provider, "#Session.v1_0_2.Session",
"/redfish/v1/SessionService/Sessions/<str>", std::string()) {
- nodeJson["@odata.type"] = Node::odataType;
+ nodeJson["@odata.type"] = "#Session.v1_0_2.Session";
nodeJson["@odata.context"] = "/redfish/v1/$metadata#Session.Session";
nodeJson["Name"] = "User Session";
nodeJson["Description"] = "Manager User Session";
@@ -95,8 +95,8 @@
: Node(app, provider, "#SessionCollection.SessionCollection",
"/redfish/v1/SessionService/Sessions/"),
memberSession(app, provider) {
- nodeJson["@odata.type"] = Node::odataType;
- nodeJson["@odata.id"] = Node::odataId;
+ nodeJson["@odata.type"] = "#SessionCollection.SessionCollection";
+ nodeJson["@odata.id"] = "/redfish/v1/SessionService/Sessions/";
nodeJson["@odata.context"] =
"/redfish/v1/$metadata#SessionCollection.SessionCollection";
nodeJson["Name"] = "Session Collection";
diff --git a/redfish-core/lib/service_root.hpp b/redfish-core/lib/service_root.hpp
index 55015e4..cdb0000 100644
--- a/redfish-core/lib/service_root.hpp
+++ b/redfish-core/lib/service_root.hpp
@@ -24,8 +24,8 @@
template <typename CrowApp, typename PrivilegeProvider>
ServiceRoot(CrowApp& app, PrivilegeProvider& provider)
: Node(app, provider, "#ServiceRoot.v1_1_1.ServiceRoot", "/redfish/v1/") {
- nodeJson["@odata.type"] = Node::odataType;
- nodeJson["@odata.id"] = Node::odataId;
+ nodeJson["@odata.type"] = "#ServiceRoot.v1_1_1.ServiceRoot";
+ nodeJson["@odata.id"] = "/redfish/v1";
nodeJson["@odata.context"] =
"/redfish/v1/$metadata#ServiceRoot.ServiceRoot";
nodeJson["Id"] = "RootService";
diff --git a/redfish-core/privilege_registry.json b/redfish-core/privilege_registry.json
new file mode 100644
index 0000000..cfd5cdd
--- /dev/null
+++ b/redfish-core/privilege_registry.json
@@ -0,0 +1,4117 @@
+{
+ "@Redfish.Copyright": "Copyright 2015-2017 Distributed Management Task Force, Inc. (DMTF). All rights reserved.",
+ "@odata.type": "#PrivilegeRegistry.v1_0_0.PrivilegeRegistry",
+ "Id": "Redfish_1.0.2_PrivilegeRegistry",
+ "Name": "Privilege Mapping array collection",
+ "PrivilegesUsed": [
+ "Login",
+ "ConfigureManager",
+ "ConfigureUsers",
+ "ConfigureComponents",
+ "ConfigureSelf"
+ ],
+ "OEMPrivilegesUsed": [
+ "OEMRoot"
+ ],
+ "Mappings": [
+ {
+ "Entity": "Manager",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "ManagerCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "ComputerSystem",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "ComputerSystemCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "EthernetInterface",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "SubordinateOverrides": [
+ {
+ "Targets": [
+ "Manager",
+ "EthernetInterfaceCollection"
+ ],
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "EthernetInterfaceCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "ManagerAccount",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ },
+ {
+ "Privilege": [
+ "ConfigureUsers"
+ ]
+ },
+ {
+ "Privilege": [
+ "ConfigureSelf"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureUsers"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureUsers"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureUsers"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureUsers"
+ ]
+ }
+ ]
+ },
+ "PropertyOverrides": [
+ {
+ "Targets": [
+ "Password"
+ ],
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ },
+ {
+ "Privilege": [
+ "ConfigureSelf"
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "Entity": "ManagerAccountCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "ConfigureUsers"
+ ]
+ },
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureUsers"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureUsers"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureUsers"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureUsers"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "AccountService",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "ConfigureUsers"
+ ]
+ },
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureUsers"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureUsers"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureUsers"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureUsers"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Chassis",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "ChassisCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "LogService",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "SubordinateOverrides": [
+ {
+ "Targets": [
+ "ComputerSystem",
+ "LogServiceCollection"
+ ],
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Targets": [
+ "Chassis",
+ "LogServiceCollection"
+ ],
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "LogServiceCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "SubordinateOverrides": [
+ {
+ "Targets": [
+ "ComputerSystem"
+ ],
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Targets": [
+ "Chassis"
+ ],
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "LogEntry",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "SubordinateOverrides": [
+ {
+ "Targets": [
+ "ComputerSystem",
+ "LogServiceCollection",
+ "LogService",
+ "LogEntryCollection"
+ ],
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Targets": [
+ "Chassis",
+ "LogServiceCollection",
+ "LogService",
+ "LogEntryCollection"
+ ],
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "LogEntryCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "SubordinateOverrides": [
+ {
+ "Targets": [
+ "ComputerSystem",
+ "LogServiceCollection",
+ "LogService"
+ ],
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Targets": [
+ "Chassis",
+ "LogServiceCollection",
+ "LogService"
+ ],
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Power",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Processor",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "ProcessorCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Role",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "RoleCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "SerialInterface",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "SerialInterfaceCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "SessionService",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Session",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "SessionCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": []
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Task",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "TaskCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "TaskService",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Thermal",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "VirtualMedia",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "VirtualMediaCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "VLanNetworkInterface",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "VLanNetworkInterfaceCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "BIOS",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Drive",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "EventService",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "EventDestination",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "EventDestinationCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Fabric",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "FabricCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "ManagerNetworkProtocol",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Memory",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "MemoryCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "MemoryChunks",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "MemoryChunksCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "MemoryDomain",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "MemoryDomainCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "MemoryMetrics",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "PCIeDevice",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "PCIeFunction",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Port",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "PortCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "SecureBoot",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "SoftwareInventory",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "SoftwareInventoryCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Storage",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "StorageCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Switch",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "SwitchCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "UpdateService",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Volume",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "VolumeCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Zone",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "ZoneCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Endpoint",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "EndpointCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "JSONSchemaFile",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "JSONSchemaFileCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "MessageRegistry",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "MessageRegistryCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "MessageRegistryFile",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "MessageRegistryFileCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "PhysicalContext",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "Redundancy",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "ServiceRoot",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": []
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureManager"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "SimpleStorage",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "Entity": "SimpleStorageCollection",
+ "OperationMap": {
+ "GET": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "HEAD": [
+ {
+ "Privilege": [
+ "Login"
+ ]
+ }
+ ],
+ "PATCH": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "POST": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "PUT": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ],
+ "DELETE": [
+ {
+ "Privilege": [
+ "ConfigureComponents"
+ ]
+ }
+ ]
+ }
+ }
+ ]
+}
diff --git a/redfish-core/src/privileges.cpp b/redfish-core/src/privileges.cpp
new file mode 100644
index 0000000..5fbce23
--- /dev/null
+++ b/redfish-core/src/privileges.cpp
@@ -0,0 +1,202 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#include "privileges.hpp"
+
+namespace redfish {
+
+boost::container::flat_map<std::string, size_t>
+ Privileges::basePrivNameToIndexMap;
+boost::container::flat_map<std::string, size_t>
+ Privileges::oemPrivNameToIndexMap;
+
+bool EntityPrivileges::isMethodAllowedForUser(const crow::HTTPMethod method,
+ const std::string& user) const {
+ // TODO: load user privileges from configuration as soon as its available
+ // now we are granting only Login.
+ auto userPrivileges = Privileges();
+ userPrivileges.setSinglePrivilege("Login");
+
+ return isMethodAllowedWithPrivileges(method, userPrivileges);
+}
+
+bool EntityPrivileges::isMethodAllowedWithPrivileges(
+ const crow::HTTPMethod method, const Privileges& userPrivileges) const {
+ if (methodToPrivilegeMap.find(method) == methodToPrivilegeMap.end()) {
+ return false;
+ }
+
+ for (auto& requiredPrivileges : methodToPrivilegeMap.at(method)) {
+ // Check if user has required base privileges
+ if (!verifyPrivileges(userPrivileges.getBasePrivilegeBitset(),
+ requiredPrivileges.getBasePrivilegeBitset())) {
+ continue;
+ }
+
+ // Check if user has required OEM privileges
+ if (!verifyPrivileges(userPrivileges.getOEMPrivilegeBitset(),
+ requiredPrivileges.getOEMPrivilegeBitset())) {
+ continue;
+ }
+
+ return true;
+ }
+ return false;
+}
+
+bool EntityPrivileges::verifyPrivileges(
+ const privilegeBitset userPrivilegeBitset,
+ const privilegeBitset requiredPrivilegeBitset) const {
+ return (userPrivilegeBitset & requiredPrivilegeBitset) ==
+ requiredPrivilegeBitset;
+}
+
+EntityPrivileges PrivilegeProvider::getPrivilegesRequiredByEntity(
+ const std::string& entityUrl, const std::string& entityType) const {
+ if (privilegeRegistryJson.empty()) {
+ return EntityPrivileges();
+ }
+
+ // type from @odata.type e.g: ServiceRoot from #ServiceRoot.v1_1_1.ServiceRoot
+ auto entity = entityType.substr(entityType.find_last_of(".") + strlen("."));
+
+ for (auto mapping : privilegeRegistryJson.at("Mappings")) {
+ const auto& entityJson = mapping.find("Entity");
+ const auto& operationMapJson = mapping.find("OperationMap");
+ const auto& propertyOverridesJson = mapping.find("PropertyOverrides");
+ const auto& subordinateOverridesJson = mapping.find("SubordinateOverrides");
+ const auto& resourceURIOverridesJson = mapping.find("ResourceURIOverrides");
+
+ if (entityJson == mapping.end() || operationMapJson == mapping.end()) {
+ return EntityPrivileges();
+ }
+
+ if (entityJson->is_string() && entity == entityJson.value()) {
+ auto entityPrivileges = EntityPrivileges();
+
+ if (!parseOperationMap(operationMapJson.value(), entityPrivileges)) {
+ return EntityPrivileges();
+ }
+
+ if (propertyOverridesJson != mapping.end()) {
+ // TODO: implementation comes in next patch-sets
+ }
+ if (subordinateOverridesJson != mapping.end()) {
+ // TODO: implementation comes in next patch-sets
+ }
+ if (resourceURIOverridesJson != mapping.end()) {
+ // TODO: implementation comes in next patch-sets
+ }
+
+ return entityPrivileges;
+ }
+ }
+ return EntityPrivileges();
+}
+
+bool PrivilegeProvider::parseOperationMap(
+ const nlohmann::json& operationMap,
+ EntityPrivileges& entityPrivileges) const {
+ for (auto it = operationMap.begin(); it != operationMap.end(); ++it) {
+ const std::string& method = it.key();
+ const nlohmann::json& privilegesForMethod = it.value();
+
+ for (const auto& privilegeOr : privilegesForMethod) {
+ const auto& privilegeJson = privilegeOr.find("Privilege");
+
+ if (privilegeJson == privilegeOr.end()) {
+ return false;
+ }
+ auto privileges = Privileges();
+
+ for (auto& privilegeAnd : privilegeJson.value()) {
+ if (!privilegeAnd.is_string()) {
+ return false;
+ }
+ privileges.setSinglePrivilege(privilegeAnd);
+ }
+ entityPrivileges.addPrivilegesRequiredByMethod(operator"" _method(
+ method.c_str(),
+ method.size()),
+ privileges);
+ }
+ }
+ return true;
+}
+
+bool PrivilegeProvider::loadPrivilegesFromFile(
+ std::ifstream& privilegeRegistryFile) {
+ privilegeRegistryJson =
+ nlohmann::json::parse(privilegeRegistryFile, nullptr, false);
+
+ if (!privilegeRegistryHasRequiredFields()) {
+ return false;
+ }
+
+ const nlohmann::json& basePrivilegesUsed =
+ privilegeRegistryJson.at("PrivilegesUsed");
+ if (basePrivilegesUsed.size() == 0) {
+ return false;
+ }
+ if (!fillPrivilegeMap(basePrivilegesUsed,
+ Privileges::basePrivNameToIndexMap)) {
+ return false;
+ }
+
+ const nlohmann::json& oemPrivilegesUsed =
+ privilegeRegistryJson.at("OEMPrivilegesUsed");
+ if (!fillPrivilegeMap(oemPrivilegesUsed, Privileges::oemPrivNameToIndexMap)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool PrivilegeProvider::privilegeRegistryHasRequiredFields() const {
+ if (privilegeRegistryJson.is_discarded() ||
+ privilegeRegistryJson.find("@Redfish.Copyright") ==
+ privilegeRegistryJson.end() ||
+ privilegeRegistryJson.find("@odata.type") ==
+ privilegeRegistryJson.end() ||
+ privilegeRegistryJson.find("Id") == privilegeRegistryJson.end() ||
+ privilegeRegistryJson.find("Name") == privilegeRegistryJson.end() ||
+ privilegeRegistryJson.find("Mappings") == privilegeRegistryJson.end() ||
+ privilegeRegistryJson.find("PrivilegesUsed") ==
+ privilegeRegistryJson.end() ||
+ privilegeRegistryJson.find("OEMPrivilegesUsed") ==
+ privilegeRegistryJson.end()) {
+ return false;
+ }
+ return true;
+}
+
+bool PrivilegeProvider::fillPrivilegeMap(
+ const nlohmann::json& privilegesUsed,
+ boost::container::flat_map<std::string, size_t>& privilegeToIndexMap)
+ const {
+ privilegeToIndexMap.clear();
+ for (auto& privilege : privilegesUsed) {
+ if (privilegeToIndexMap.size() < MAX_PRIVILEGE_COUNT) {
+ if (!privilege.is_string()) {
+ return false;
+ }
+ privilegeToIndexMap.insert(std::pair<std::string, size_t>(
+ privilege.get<std::string>(), privilegeToIndexMap.size()));
+ }
+ }
+ return true;
+}
+
+} // namespace redfish
diff --git a/redfish-core/ut/privileges_test.cpp b/redfish-core/ut/privileges_test.cpp
new file mode 100644
index 0000000..9d0d156
--- /dev/null
+++ b/redfish-core/ut/privileges_test.cpp
@@ -0,0 +1,526 @@
+#include "privileges.hpp"
+#include <fstream>
+#include <string>
+#include "nlohmann/json.hpp"
+#include "gmock/gmock.h"
+
+using namespace redfish;
+
+class PrivilegeTest : public testing::Test {
+ protected:
+ nlohmann::json privilegeRegistryMockJson;
+
+ std::vector<std::string> expectedBasePrivileges{
+ "Login", "ConfigureManager", "ConfigureUsers", "ConfigureComponents",
+ "ConfigureSelf"};
+
+ std::vector<std::string> expectedOEMPrivileges{"OEMRoot", "OEMDummy"};
+
+ PrivilegeTest() {
+ crow::logger::setLogLevel(crow::LogLevel::CRITICAL);
+
+ std::ofstream privilegeRegistryMockOfstream("privilege_registry_mock.json");
+ privilegeRegistryMockJson = nlohmann::json::parse(
+ "{\
+ \"@Redfish.Copyright\": \"Dummy copyright\",\
+ \"@odata.type\": \"#PrivilegeRegistry.v1_0_0.PrivilegeRegistry\",\
+ \"Id\": \"Dummy id\",\
+ \"Name\": \"Dummy name\",\
+ \"PrivilegesUsed\": [\
+ \"Login\",\
+ \"ConfigureManager\",\
+ \"ConfigureUsers\",\
+ \"ConfigureComponents\",\
+ \"ConfigureSelf\"],\
+ \"OEMPrivilegesUsed\": [\
+ \"OEMRoot\",\
+ \"OEMDummy\"],\
+ \"Mappings\": [\
+ {\
+ \"Entity\": \"TestEntity\",\
+ \"OperationMap\": {\
+ \"GET\": [\
+ {\
+ \"Privilege\": [\
+ \"Login\"\
+ ]\
+ }\
+ ],\
+ \"PATCH\": [\
+ {\
+ \"Privilege\": [\
+ \"ConfigureManager\"\
+ ]\
+ },\
+ {\
+ \"Privilege\": [\
+ \"ConfigureUser\",\
+ \"ConfigureDummy\",\
+ \"OEMRoot\"\
+ ]\
+ }\
+ ],\
+ \"POST\": [\
+ {\
+ \"Privilege\": [\
+ \"ConfigureManager\",\
+ \"OEMDummy\"\
+ ]\
+ }\
+ ],\
+ \"DELETE\": [\
+ {\
+ \"Privilege\": [\
+ \"ConfigureManager\"\
+ ]\
+ }\
+ ]\
+ }\
+ },\
+ {\
+ \"Entity\": \"EntityWithNonStringPrivilege\",\
+ \"OperationMap\": {\
+ \"GET\": [\
+ {\
+ \"Privilege\": [\"Login\"]\
+ }\
+ ],\
+ \"POST\": [\
+ {\
+ \"Privilege\": [1]\
+ }\
+ ]\
+ }\
+ }\
+ ]\
+ }");
+ privilegeRegistryMockOfstream << std::setw(4) << privilegeRegistryMockJson
+ << std::endl;
+ privilegeRegistryMockOfstream.close();
+ }
+
+ virtual ~PrivilegeTest() { std::remove("privilege_registry_mock.json"); }
+
+ void removeFieldFromRegistry(const std::string& field) {
+ std::ifstream in("privilege_registry_mock.json");
+ nlohmann::json tempJson = nlohmann::json::parse(in);
+ in.close();
+
+ tempJson.erase(field);
+
+ std::ofstream out("privilege_registry_mock.json");
+ out << std::setw(4) << tempJson << std::endl;
+ out.close();
+ }
+
+ void removeFieldFromMappings(const std::string& field) {
+ std::ifstream in("privilege_registry_mock.json");
+ nlohmann::json tempJson = nlohmann::json::parse(in);
+ in.close();
+
+ tempJson.at("Mappings")[0].erase(field);
+
+ std::ofstream out("privilege_registry_mock.json");
+ out << std::setw(4) << tempJson << std::endl;
+ out.close();
+ }
+
+ void clearArryInJson(const std::string& key) {
+ std::ifstream in("privilege_registry_mock.json");
+ nlohmann::json tempJson = nlohmann::json::parse(in);
+ in.close();
+
+ tempJson[key].clear();
+
+ std::ofstream out("privilege_registry_mock.json");
+ out << std::setw(4) << tempJson << std::endl;
+ out.close();
+ }
+
+ template <typename T>
+ void fillPrivilegeArray(const std::string& key,
+ const std::vector<T>& values) {
+ std::ifstream in("privilege_registry_mock.json");
+ nlohmann::json tempJson = nlohmann::json::parse(in);
+ in.close();
+
+ tempJson[key].clear();
+ for (const auto& value : values) {
+ tempJson[key].push_back(value);
+ }
+
+ std::ofstream out("privilege_registry_mock.json");
+ out << std::setw(4) << tempJson << std::endl;
+ out.close();
+ }
+
+ template <typename T>
+ void addRequiredPrivilege(const T& value) {
+ std::ifstream in("privilege_registry_mock.json");
+ nlohmann::json tempJson = nlohmann::json::parse(in);
+ in.close();
+
+ tempJson["Mappings"][0]["OperationMap"]["GET"][0]["Privilege"].push_back(
+ value);
+
+ std::ofstream out("privilege_registry_mock.json");
+ out << std::setw(4) << tempJson << std::endl;
+ out.close();
+ }
+
+ bool isPrivilegeRegistryParsed(const EntityPrivileges& entityPrivileges) {
+ auto userPrivileges = Privileges();
+ userPrivileges.setSinglePrivilege("Login");
+ // given the privileges_registry_mock.json, GET should be allowed with Login
+ // if the file got parsed successfully
+ return entityPrivileges.isMethodAllowedWithPrivileges(crow::HTTPMethod::GET,
+ userPrivileges);
+ }
+};
+
+TEST_F(PrivilegeTest, PrivilegeRegistryJsonSuccessfullParse) {
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+ auto entityPrivileges =
+ privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
+ EXPECT_TRUE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeRegistryJsonNotFound) {
+ std::remove("privilege_registry_mock.json");
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+ auto entityPrivileges =
+ privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
+ EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeRegistryMissingCopyright) {
+ removeFieldFromRegistry("@Redfish.Copyright");
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+ auto entityPrivileges =
+ privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
+ EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeRegistryMissingOdataType) {
+ removeFieldFromRegistry("@odata.type");
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+ auto entityPrivileges =
+ privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
+ EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeRegistryMissingId) {
+ removeFieldFromRegistry("Id");
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+ auto entityPrivileges =
+ privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
+ EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeRegistryMissingName) {
+ removeFieldFromRegistry("Name");
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+ auto entityPrivileges =
+ privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
+ EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeRegistryMissingMappings) {
+ removeFieldFromRegistry("Mappings");
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+ auto entityPrivileges =
+ privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
+ EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeRegistryMissingPrivilegesUsed) {
+ removeFieldFromRegistry("PrivilegesUsed");
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+ auto entityPrivileges =
+ privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
+ EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeRegistryMissingOEMPrivilegesUsed) {
+ removeFieldFromRegistry("OEMPrivilegesUsed");
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+ auto entityPrivileges =
+ privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
+ EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeRegistryMissingOperationMap) {
+ removeFieldFromMappings("OperationMap");
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+
+ auto entityPrivileges =
+ privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
+ EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeRegistryPrivilegesUsedMayNotBeEmpty) {
+ clearArryInJson("PrivilegesUsed");
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+ auto entityPrivileges =
+ privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
+ EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeRegistryOEMPrivilegesUsedMayByEmpty) {
+ clearArryInJson("OEMPrivilegesUsed");
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+ auto entityPrivileges =
+ privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
+ EXPECT_TRUE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeValuesMayOnlyBeStrings) {
+ std::vector<int> privilegesUsed = {1, 3, 4};
+ fillPrivilegeArray("PrivilegesUsed", privilegesUsed);
+
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+ auto entityPrivileges =
+ privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
+ EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, OnlyMaxNoOfBasePrivilegesGetsLoaded) {
+ const std::string excessivePrivilege("ExcessivePrivilege");
+ std::vector<std::string> privilegesUsed;
+
+ for (int i = 0; i < MAX_PRIVILEGE_COUNT; i++) {
+ privilegesUsed.push_back(std::to_string(i));
+ }
+ privilegesUsed.push_back(excessivePrivilege);
+
+ fillPrivilegeArray("PrivilegesUsed", privilegesUsed);
+ addRequiredPrivilege(excessivePrivilege);
+
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+
+ Privileges privileges;
+ privileges.setSinglePrivilege(excessivePrivilege);
+
+ EXPECT_EQ(privileges.getBasePrivilegeBitset(), 0);
+}
+
+TEST_F(PrivilegeTest, OnlyMaxNoOfOEMPrivilegesGetsLoaded) {
+ const std::string excessivePrivilege("ExcessivePrivilege");
+ std::vector<std::string> privilegesUsed;
+
+ for (int i = 0; i < MAX_PRIVILEGE_COUNT; i++) {
+ privilegesUsed.push_back(std::to_string(i));
+ }
+ privilegesUsed.push_back(excessivePrivilege);
+
+ fillPrivilegeArray("OEMPrivilegesUsed", privilegesUsed);
+ addRequiredPrivilege(excessivePrivilege);
+
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+
+ Privileges privileges;
+ privileges.setSinglePrivilege(excessivePrivilege);
+
+ EXPECT_EQ(privileges.getOEMPrivilegeBitset(), 0);
+}
+
+TEST_F(PrivilegeTest, LoadEntityPrivilegesForExistingEntity) {
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+ auto entityPrivileges =
+ privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.TestEntity");
+ EXPECT_TRUE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, LoadEntityPrivilegesForNonExistingEntity) {
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+ auto entityPrivileges =
+ privilegeProvider.getPrivilegesRequiredByEntity("", "foo.bar.NotExists");
+ EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, LoadEntityPrivilegesForEntityWithNonStringPrivilege) {
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+ auto entityPrivileges = privilegeProvider.getPrivilegesRequiredByEntity(
+ "", "foo.bar.EntityWithNonStringPrivilege");
+ EXPECT_FALSE(isPrivilegeRegistryParsed(entityPrivileges));
+}
+
+TEST_F(PrivilegeTest, DefaultEntityPrivilegesDenyAccess) {
+ auto entityPrivileges = EntityPrivileges();
+
+ auto res =
+ entityPrivileges.isMethodAllowedForUser(crow::HTTPMethod::GET, "user");
+ EXPECT_FALSE(res);
+}
+
+TEST_F(PrivilegeTest, PrivilegeCheckForSingleCaseSuccess) {
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+
+ auto entityPrivileges = EntityPrivileges();
+ auto userPrivileges = Privileges();
+ auto requiredPrivileges = Privileges();
+
+ userPrivileges.setSinglePrivilege("Login");
+ requiredPrivileges.setSinglePrivilege("Login");
+ entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
+ requiredPrivileges);
+ EXPECT_TRUE(entityPrivileges.isMethodAllowedWithPrivileges(
+ crow::HTTPMethod::GET, userPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeCheckForSingleCaseFailure) {
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+
+ auto entityPrivileges = EntityPrivileges();
+ auto userPrivileges = Privileges();
+ auto requiredPrivileges = Privileges();
+
+ userPrivileges.setSinglePrivilege("Login");
+ requiredPrivileges.setSinglePrivilege("ConfigureManager");
+ entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
+ requiredPrivileges);
+ EXPECT_FALSE(entityPrivileges.isMethodAllowedWithPrivileges(
+ crow::HTTPMethod::GET, userPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeCheckForANDCaseSuccess) {
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+
+ auto entityPrivileges = EntityPrivileges();
+ auto userPrivileges = Privileges();
+ auto requiredPrivileges = Privileges();
+
+ userPrivileges.setSinglePrivilege("Login");
+ userPrivileges.setSinglePrivilege("ConfigureManager");
+ userPrivileges.setSinglePrivilege("OEMRoot");
+ requiredPrivileges.setSinglePrivilege("Login");
+ requiredPrivileges.setSinglePrivilege("ConfigureManager");
+ requiredPrivileges.setSinglePrivilege("OEMRoot");
+ entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
+ requiredPrivileges);
+ EXPECT_TRUE(entityPrivileges.isMethodAllowedWithPrivileges(
+ crow::HTTPMethod::GET, userPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeCheckForANDCaseFailure) {
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+
+ auto entityPrivileges = EntityPrivileges();
+ auto userPrivileges = Privileges();
+ auto requiredPrivileges = Privileges();
+
+ userPrivileges.setSinglePrivilege("Login");
+ userPrivileges.setSinglePrivilege("ConfigureUsers");
+ requiredPrivileges.setSinglePrivilege("Login");
+ requiredPrivileges.setSinglePrivilege("OEMDummy");
+ requiredPrivileges.setSinglePrivilege("ConfigureUsers");
+ entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
+ requiredPrivileges);
+ EXPECT_FALSE(entityPrivileges.isMethodAllowedWithPrivileges(
+ crow::HTTPMethod::GET, userPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeCheckForORCaseSuccess) {
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+
+ auto entityPrivileges = EntityPrivileges();
+ auto userPrivileges = Privileges();
+ auto requiredPrivileges = Privileges();
+
+ userPrivileges.setSinglePrivilege("OEMRoot");
+ requiredPrivileges.setSinglePrivilege("Login");
+ entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
+ requiredPrivileges);
+ requiredPrivileges = Privileges();
+ requiredPrivileges.setSinglePrivilege("OEMRoot");
+ entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
+ requiredPrivileges);
+ EXPECT_TRUE(entityPrivileges.isMethodAllowedWithPrivileges(
+ crow::HTTPMethod::GET, userPrivileges));
+}
+
+TEST_F(PrivilegeTest, PrivilegeCheckForORCaseFailure) {
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+
+ auto entityPrivileges = EntityPrivileges();
+ auto userPrivileges = Privileges();
+ auto requiredPrivileges = Privileges();
+
+ userPrivileges.setSinglePrivilege("ConfigureComponents");
+ requiredPrivileges.setSinglePrivilege("Login");
+ entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
+ requiredPrivileges);
+ requiredPrivileges = Privileges();
+ requiredPrivileges.setSinglePrivilege("ConfigureManager");
+ entityPrivileges.addPrivilegesRequiredByMethod(crow::HTTPMethod::GET,
+ requiredPrivileges);
+ EXPECT_FALSE(entityPrivileges.isMethodAllowedWithPrivileges(
+ crow::HTTPMethod::GET, userPrivileges));
+}
+
+TEST_F(PrivilegeTest, DefaultPrivilegeBitsetsAreEmpty) {
+ Privileges privileges;
+ EXPECT_TRUE(privileges.getBasePrivilegeBitset() == 0);
+ EXPECT_TRUE(privileges.getOEMPrivilegeBitset() == 0);
+}
+
+TEST_F(PrivilegeTest, UniqueBitsAssignedForAllPrivilegeNames) {
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+
+ Privileges privileges;
+
+ for (const auto& privilege : expectedBasePrivileges) {
+ privileges.setSinglePrivilege(privilege);
+ }
+
+ for (const auto& privilege : expectedOEMPrivileges) {
+ privileges.setSinglePrivilege(privilege);
+ }
+
+ EXPECT_EQ(privileges.getBasePrivilegeBitset().count(),
+ expectedBasePrivileges.size());
+ EXPECT_EQ(privileges.getOEMPrivilegeBitset().count(),
+ expectedOEMPrivileges.size());
+}
+
+TEST_F(PrivilegeTest, GetActiveBasePrivilegeNames) {
+ Privileges privileges;
+
+ EXPECT_EQ(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
+ std::vector<std::string>());
+
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+
+ for (const auto& privilege : expectedBasePrivileges) {
+ privileges.setSinglePrivilege(privilege);
+ }
+
+ std::vector<std::string> activePrivileges =
+ privileges.getActivePrivilegeNames(PrivilegeType::BASE);
+
+ std::sort(expectedBasePrivileges.begin(), expectedBasePrivileges.end());
+ std::sort(activePrivileges.begin(), activePrivileges.end());
+
+ EXPECT_EQ(activePrivileges, expectedBasePrivileges);
+}
+
+TEST_F(PrivilegeTest, GetActiveOEMPrivilegeNames) {
+ Privileges privileges;
+
+ EXPECT_EQ(privileges.getActivePrivilegeNames(PrivilegeType::OEM),
+ std::vector<std::string>());
+
+ PrivilegeProvider privilegeProvider("privilege_registry_mock.json");
+
+ for (const auto& privilege : expectedOEMPrivileges) {
+ privileges.setSinglePrivilege(privilege);
+ }
+
+ std::vector<std::string> activePrivileges =
+ privileges.getActivePrivilegeNames(PrivilegeType::OEM);
+
+ std::sort(expectedOEMPrivileges.begin(), expectedOEMPrivileges.end());
+ std::sort(activePrivileges.begin(), activePrivileges.end());
+
+ EXPECT_EQ(activePrivileges, expectedOEMPrivileges);
+}