diff options
| author | Ratan Gupta <ratagupt@linux.vnet.ibm.com> | 2019-04-03 10:39:08 +0530 |
|---|---|---|
| committer | Ed Tanous <ed.tanous@intel.com> | 2019-07-11 01:29:29 +0000 |
| commit | 6f3595683739a6528e98b38cc82afbc60f9fda34 (patch) | |
| tree | 36d0636a6d7e6d890fc540fa3e3fd7ab48631318 | |
| parent | f5c9f8bda365b90c978a95738b66419ad21df27f (diff) | |
| download | bmcweb-6f3595683739a6528e98b38cc82afbc60f9fda34.tar.gz bmcweb-6f3595683739a6528e98b38cc82afbc60f9fda34.zip | |
Redfish(Authorization): Map the user role with the Redfish privileges
This commit gets the role of the user from the session object and
map it with the redfish privileges and then allow/reject the asked
operation depending on the userprivileges and the entity privileges.
Change-Id: I40be06c28e80b47fe76891cacf863f8495bace88
Signed-off-by: Ratan Gupta <ratagupt@linux.vnet.ibm.com>
| -rw-r--r-- | crow/include/crow/http_request.h | 4 | ||||
| -rw-r--r-- | crow/include/crow/routing.h | 17 | ||||
| -rw-r--r-- | include/token_authorization_middleware.hpp | 53 | ||||
| -rw-r--r-- | redfish-core/include/privileges.hpp | 23 |
4 files changed, 64 insertions, 33 deletions
diff --git a/crow/include/crow/http_request.h b/crow/include/crow/http_request.h index 0ba0266..ef0bb28 100644 --- a/crow/include/crow/http_request.h +++ b/crow/include/crow/http_request.h @@ -1,5 +1,7 @@ #pragma once +#include "sessions.hpp" + #include <boost/asio/io_context.hpp> #include <boost/beast/http.hpp> #include <boost/beast/websocket.hpp> @@ -22,6 +24,8 @@ struct Request void* middlewareContext{}; boost::asio::io_context* ioService{}; + std::shared_ptr<crow::persistent_data::UserSession> session; + Request(boost::beast::http::request<boost::beast::http::string_body>& req) : req(req), body(req.body()) { diff --git a/crow/include/crow/routing.h b/crow/include/crow/routing.h index d1c33b5..c97c874 100644 --- a/crow/include/crow/routing.h +++ b/crow/include/crow/routing.h @@ -1,6 +1,7 @@ #pragma once #include "privileges.hpp" +#include "sessions.hpp" #include <boost/container/flat_map.hpp> #include <boost/container/small_vector.hpp> @@ -1229,11 +1230,17 @@ class Router << (uint32_t)req.method() << " / " << rules[ruleIndex]->getMethods(); - // TODO: load user privileges from configuration as soon as its - // available now we are granting all privileges to everyone. - redfish::Privileges userPrivileges{"Login", "ConfigureManager", - "ConfigureSelf", "ConfigureUsers", - "ConfigureComponents"}; + redfish::Privileges userPrivileges; + if (req.session != nullptr) + { + // Get the user role from the session. + const std::string& userRole = req.session->userRole; + + BMCWEB_LOG_DEBUG << "USER ROLE=" << userRole; + + // Get the user privileges from the role + userPrivileges = redfish::getUserPrivileges(userRole); + } if (!rules[ruleIndex]->checkPrivileges(userPrivileges)) { diff --git a/include/token_authorization_middleware.hpp b/include/token_authorization_middleware.hpp index 697e400..ee34d00 100644 --- a/include/token_authorization_middleware.hpp +++ b/include/token_authorization_middleware.hpp @@ -22,7 +22,6 @@ class Middleware public: struct Context { - std::shared_ptr<crow::persistent_data::UserSession> session; }; void beforeHandle(crow::Request& req, Response& res, Context& ctx) @@ -32,12 +31,12 @@ class Middleware return; } - ctx.session = performXtokenAuth(req); - if (ctx.session == nullptr) + req.session = performXtokenAuth(req); + if (req.session == nullptr) { - ctx.session = performCookieAuth(req); + req.session = performCookieAuth(req); } - if (ctx.session == nullptr) + if (req.session == nullptr) { std::string_view authHeader = req.getHeaderValue("Authorization"); if (!authHeader.empty()) @@ -45,16 +44,16 @@ class Middleware // Reject any kind of auth other than basic or token if (boost::starts_with(authHeader, "Token ")) { - ctx.session = performTokenAuth(authHeader); + req.session = performTokenAuth(authHeader); } else if (boost::starts_with(authHeader, "Basic ")) { - ctx.session = performBasicAuth(authHeader); + req.session = performBasicAuth(authHeader); } } } - if (ctx.session == nullptr) + if (req.session == nullptr) { BMCWEB_LOG_WARNING << "[AuthMiddleware] authorization failed"; @@ -93,12 +92,12 @@ class Middleware // middleware, but because it is upstream, it doesn't have access to the // session information. Should the data middleware persist the current // user session? - if (ctx.session != nullptr && - ctx.session->persistence == + if (req.session != nullptr && + req.session->persistence == crow::persistent_data::PersistenceType::SINGLE_REQUEST) { persistent_data::SessionStore::getInstance().removeSession( - ctx.session); + req.session); } } @@ -431,24 +430,22 @@ template <typename... Middlewares> void requestRoutes(Crow<Middlewares...>& app) }); BMCWEB_ROUTE(app, "/logout") - .methods( - "POST"_method)([&](const crow::Request& req, crow::Response& res) { - auto& session = - app.template getContext<token_authorization::Middleware>(req) - .session; - if (session != nullptr) - { - res.jsonValue = { - {"data", "User '" + session->username + "' logged out"}, - {"message", "200 OK"}, - {"status", "ok"}}; + .methods("POST"_method)( + [&](const crow::Request& req, crow::Response& res) { + auto& session = req.session; + if (session != nullptr) + { + res.jsonValue = { + {"data", "User '" + session->username + "' logged out"}, + {"message", "200 OK"}, + {"status", "ok"}}; - persistent_data::SessionStore::getInstance().removeSession( - session); - } - res.end(); - return; - }); + persistent_data::SessionStore::getInstance().removeSession( + session); + } + res.end(); + return; + }); } } // namespace token_authorization } // namespace crow diff --git a/redfish-core/include/privileges.hpp b/redfish-core/include/privileges.hpp index ca44551..ec6e6a5 100644 --- a/redfish-core/include/privileges.hpp +++ b/redfish-core/include/privileges.hpp @@ -177,6 +177,29 @@ class Privileges std::bitset<maxPrivilegeCount> privilegeBitset = 0; }; +inline const Privileges& getUserPrivileges(const std::string& userRole) +{ + // Redfish privilege : Administrator + if (userRole == "priv-admin") + { + static Privileges admin{"Login", "ConfigureManager", "ConfigureSelf", + "ConfigureUsers", "ConfigureComponents"}; + return admin; + } + else if (userRole == "priv-operator") + { + // Redfish privilege : Operator + static Privileges op{"Login", "ConfigureSelf", "ConfigureComponents"}; + return op; + } + else + { + // Redfish privilege : Readonly + static Privileges readOnly{"Login", "ConfigureSelf"}; + return readOnly; + } +} + using OperationMap = boost::container::flat_map<boost::beast::http::verb, std::vector<Privileges>>; |

