xref: /openbmc/bmcweb/features/redfish/lib/redfish_sessions.hpp (revision be2f124cec67c51dae320e856b83da9e846a148c)
12b7981f6SKowalski, Kamil /*
26be832e2SEd Tanous Copyright (c) 2018 Intel Corporation
36be832e2SEd Tanous 
46be832e2SEd Tanous Licensed under the Apache License, Version 2.0 (the "License");
56be832e2SEd Tanous you may not use this file except in compliance with the License.
66be832e2SEd Tanous You may obtain a copy of the License at
76be832e2SEd Tanous 
86be832e2SEd Tanous       http://www.apache.org/licenses/LICENSE-2.0
96be832e2SEd Tanous 
106be832e2SEd Tanous Unless required by applicable law or agreed to in writing, software
116be832e2SEd Tanous distributed under the License is distributed on an "AS IS" BASIS,
126be832e2SEd Tanous WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136be832e2SEd Tanous See the License for the specific language governing permissions and
146be832e2SEd Tanous limitations under the License.
152b7981f6SKowalski, Kamil */
162b7981f6SKowalski, Kamil #pragma once
1743a095abSBorawski.Lukasz 
18ce22f609SPaul Fertser #include "account_service.hpp"
193ccb3adbSEd Tanous #include "app.hpp"
2029aab242SPaul Fertser #include "cookies.hpp"
21f4c4dcf4SKowalski, Kamil #include "error_messages.hpp"
223ccb3adbSEd Tanous #include "http/utility.hpp"
2352cc112dSEd Tanous #include "persistent_data.hpp"
243ccb3adbSEd Tanous #include "query.hpp"
253ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
263ccb3adbSEd Tanous #include "utils/json_utils.hpp"
277e860f15SJohn Edward Broadbent 
28ef4c65b7SEd Tanous #include <boost/url/format.hpp>
29ef4c65b7SEd Tanous 
3089cda63dSEd Tanous #include <string>
3189cda63dSEd Tanous #include <vector>
3289cda63dSEd Tanous 
331abe55efSEd Tanous namespace redfish
341abe55efSEd Tanous {
352b7981f6SKowalski, Kamil 
364f48d5f6SEd Tanous inline void fillSessionObject(crow::Response& res,
37faa34ccfSEd Tanous                               const persistent_data::UserSession& session)
381abe55efSEd Tanous {
39faa34ccfSEd Tanous     res.jsonValue["Id"] = session.uniqueId;
40faa34ccfSEd Tanous     res.jsonValue["UserName"] = session.username;
41ce22f609SPaul Fertser     nlohmann::json::array_t roles;
42ce22f609SPaul Fertser     roles.emplace_back(redfish::getRoleIdFromPrivilege(session.userRole));
43ce22f609SPaul Fertser     res.jsonValue["Roles"] = std::move(roles);
44ef4c65b7SEd Tanous     res.jsonValue["@odata.id"] = boost::urls::format(
45ef4c65b7SEd Tanous         "/redfish/v1/SessionService/Sessions/{}", session.uniqueId);
46ce22f609SPaul Fertser     res.jsonValue["@odata.type"] = "#Session.v1_7_0.Session";
47faa34ccfSEd Tanous     res.jsonValue["Name"] = "User Session";
48faa34ccfSEd Tanous     res.jsonValue["Description"] = "Manager User Session";
49faa34ccfSEd Tanous     res.jsonValue["ClientOriginIPAddress"] = session.clientIp;
50bb759e3aSEd Tanous     if (session.clientId)
51bb759e3aSEd Tanous     {
52bb759e3aSEd Tanous         res.jsonValue["Context"] = *session.clientId;
53bb759e3aSEd Tanous     }
542b7981f6SKowalski, Kamil }
552b7981f6SKowalski, Kamil 
56724340d7SEd Tanous inline void
57a1e0871dSEd Tanous     handleSessionHead(crow::App& app, const crow::Request& req,
58faa34ccfSEd Tanous                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
59a1e0871dSEd Tanous                       const std::string& /*sessionId*/)
60724340d7SEd Tanous {
613ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
6245ca1b86SEd Tanous     {
6345ca1b86SEd Tanous         return;
6445ca1b86SEd Tanous     }
65a1e0871dSEd Tanous     asyncResp->res.addHeader(
66a1e0871dSEd Tanous         boost::beast::http::field::link,
67a1e0871dSEd Tanous         "</redfish/v1/JsonSchemas/Session/Session.json>; rel=describedby");
68a1e0871dSEd Tanous }
69a1e0871dSEd Tanous 
70a1e0871dSEd Tanous inline void
71a1e0871dSEd Tanous     handleSessionGet(crow::App& app, const crow::Request& req,
72a1e0871dSEd Tanous                      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
73a1e0871dSEd Tanous                      const std::string& sessionId)
74a1e0871dSEd Tanous {
7565ffbcb3SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
7665ffbcb3SEd Tanous     {
7765ffbcb3SEd Tanous         return;
7865ffbcb3SEd Tanous     }
7965ffbcb3SEd Tanous     asyncResp->res.addHeader(
8065ffbcb3SEd Tanous         boost::beast::http::field::link,
8165ffbcb3SEd Tanous         "</redfish/v1/JsonSchemas/Session/Session.json>; rel=describedby");
82a1e0871dSEd Tanous 
83faa34ccfSEd Tanous     // Note that control also reaches here via doPost and doDelete.
84724340d7SEd Tanous     auto session =
85724340d7SEd Tanous         persistent_data::SessionStore::getInstance().getSessionByUid(sessionId);
862b7981f6SKowalski, Kamil 
871abe55efSEd Tanous     if (session == nullptr)
881abe55efSEd Tanous     {
89724340d7SEd Tanous         messages::resourceNotFound(asyncResp->res, "Session", sessionId);
90faa34ccfSEd Tanous         return;
91faa34ccfSEd Tanous     }
92faa34ccfSEd Tanous 
93faa34ccfSEd Tanous     fillSessionObject(asyncResp->res, *session);
94724340d7SEd Tanous }
95faa34ccfSEd Tanous 
96724340d7SEd Tanous inline void
9745ca1b86SEd Tanous     handleSessionDelete(crow::App& app, const crow::Request& req,
98faa34ccfSEd Tanous                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
99724340d7SEd Tanous                         const std::string& sessionId)
100724340d7SEd Tanous {
1013ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
10245ca1b86SEd Tanous     {
10345ca1b86SEd Tanous         return;
10445ca1b86SEd Tanous     }
105724340d7SEd Tanous     auto session =
106724340d7SEd Tanous         persistent_data::SessionStore::getInstance().getSessionByUid(sessionId);
107faa34ccfSEd Tanous 
108faa34ccfSEd Tanous     if (session == nullptr)
109faa34ccfSEd Tanous     {
110724340d7SEd Tanous         messages::resourceNotFound(asyncResp->res, "Session", sessionId);
1112b7981f6SKowalski, Kamil         return;
1122b7981f6SKowalski, Kamil     }
1132b7981f6SKowalski, Kamil 
114900f9497SJoseph Reynolds     // Perform a proper ConfigureSelf authority check.  If a
115900f9497SJoseph Reynolds     // session is being used to DELETE some other user's session,
116900f9497SJoseph Reynolds     // then the ConfigureSelf privilege does not apply.  In that
117900f9497SJoseph Reynolds     // case, perform the authority check again without the user's
118900f9497SJoseph Reynolds     // ConfigureSelf privilege.
1190fd29865Swukaihua-fii-na     if (req.session != nullptr && !session->username.empty() &&
1200fd29865Swukaihua-fii-na         session->username != req.session->username)
121900f9497SJoseph Reynolds     {
1226c51eab1SEd Tanous         Privileges effectiveUserPrivileges =
1233e72c202SNinad Palsule             redfish::getUserPrivileges(*req.session);
1246c51eab1SEd Tanous 
125724340d7SEd Tanous         if (!effectiveUserPrivileges.isSupersetOf({"ConfigureUsers"}))
126900f9497SJoseph Reynolds         {
1278d1b46d7Szhanghch05             messages::insufficientPrivilege(asyncResp->res);
128900f9497SJoseph Reynolds             return;
129900f9497SJoseph Reynolds         }
130900f9497SJoseph Reynolds     }
131900f9497SJoseph Reynolds 
1328812e8beSPaul Fertser     if (req.session != nullptr && req.session->uniqueId == sessionId &&
1338812e8beSPaul Fertser         session->cookieAuth)
13429aab242SPaul Fertser     {
13529aab242SPaul Fertser         bmcweb::clearSessionCookies(asyncResp->res);
13629aab242SPaul Fertser     }
13729aab242SPaul Fertser 
138724340d7SEd Tanous     persistent_data::SessionStore::getInstance().removeSession(session);
1395cc148afSEd Tanous     messages::success(asyncResp->res);
140724340d7SEd Tanous }
141f4c4dcf4SKowalski, Kamil 
142724340d7SEd Tanous inline nlohmann::json getSessionCollectionMembers()
143724340d7SEd Tanous {
14489cda63dSEd Tanous     std::vector<std::string> sessionIds =
14589cda63dSEd Tanous         persistent_data::SessionStore::getInstance().getAllUniqueIds();
146724340d7SEd Tanous     nlohmann::json ret = nlohmann::json::array();
14789cda63dSEd Tanous     for (const std::string& uid : sessionIds)
1481abe55efSEd Tanous     {
1491476687dSEd Tanous         nlohmann::json::object_t session;
150ef4c65b7SEd Tanous         session["@odata.id"] =
15189cda63dSEd Tanous             boost::urls::format("/redfish/v1/SessionService/Sessions/{}", uid);
152b2ba3072SPatrick Williams         ret.emplace_back(std::move(session));
1532b7981f6SKowalski, Kamil     }
154724340d7SEd Tanous     return ret;
155724340d7SEd Tanous }
156724340d7SEd Tanous 
157a1e0871dSEd Tanous inline void handleSessionCollectionHead(
15845ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
159724340d7SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
160724340d7SEd Tanous {
1613ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
16245ca1b86SEd Tanous     {
16345ca1b86SEd Tanous         return;
16445ca1b86SEd Tanous     }
165a1e0871dSEd Tanous     asyncResp->res.addHeader(
166a1e0871dSEd Tanous         boost::beast::http::field::link,
167a1e0871dSEd Tanous         "</redfish/v1/JsonSchemas/SessionCollection.json>; rel=describedby");
168a1e0871dSEd Tanous }
169a1e0871dSEd Tanous 
170a1e0871dSEd Tanous inline void handleSessionCollectionGet(
171a1e0871dSEd Tanous     crow::App& app, const crow::Request& req,
172a1e0871dSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
173a1e0871dSEd Tanous {
17401a89a1fSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
17501a89a1fSEd Tanous     {
17601a89a1fSEd Tanous         return;
17701a89a1fSEd Tanous     }
17801a89a1fSEd Tanous     asyncResp->res.addHeader(
17901a89a1fSEd Tanous         boost::beast::http::field::link,
18001a89a1fSEd Tanous         "</redfish/v1/JsonSchemas/SessionCollection.json>; rel=describedby");
18101a89a1fSEd Tanous 
182724340d7SEd Tanous     asyncResp->res.jsonValue["Members"] = getSessionCollectionMembers();
183faa34ccfSEd Tanous     asyncResp->res.jsonValue["Members@odata.count"] =
184724340d7SEd Tanous         asyncResp->res.jsonValue["Members"].size();
1858d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
1868d1b46d7Szhanghch05         "#SessionCollection.SessionCollection";
1878d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.id"] =
1887a859ffeSGunnar Mills         "/redfish/v1/SessionService/Sessions";
1898d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Session Collection";
1908d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Session Collection";
191724340d7SEd Tanous }
1922b7981f6SKowalski, Kamil 
193724340d7SEd Tanous inline void handleSessionCollectionMembersGet(
19445ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
195724340d7SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
196724340d7SEd Tanous {
1973ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
19845ca1b86SEd Tanous     {
19945ca1b86SEd Tanous         return;
20045ca1b86SEd Tanous     }
201724340d7SEd Tanous     asyncResp->res.jsonValue = getSessionCollectionMembers();
202724340d7SEd Tanous }
203724340d7SEd Tanous 
204*be2f124cSJishnu CM inline void processAfterSessionCreation(
205*be2f124cSJishnu CM     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
206*be2f124cSJishnu CM     const crow::Request& req, const std::string& username,
207*be2f124cSJishnu CM     std::shared_ptr<persistent_data::UserSession>& session)
208*be2f124cSJishnu CM {
209*be2f124cSJishnu CM     // When session is created by webui-vue give it session cookies as a
210*be2f124cSJishnu CM     // non-standard Redfish extension. This is needed for authentication for
211*be2f124cSJishnu CM     // WebSockets-based functionality.
212*be2f124cSJishnu CM     if (!req.getHeaderValue("X-Requested-With").empty())
213*be2f124cSJishnu CM     {
214*be2f124cSJishnu CM         bmcweb::setSessionCookies(asyncResp->res, *session);
215*be2f124cSJishnu CM     }
216*be2f124cSJishnu CM     else
217*be2f124cSJishnu CM     {
218*be2f124cSJishnu CM         asyncResp->res.addHeader("X-Auth-Token", session->sessionToken);
219*be2f124cSJishnu CM     }
220*be2f124cSJishnu CM 
221*be2f124cSJishnu CM     asyncResp->res.addHeader(
222*be2f124cSJishnu CM         "Location", "/redfish/v1/SessionService/Sessions/" + session->uniqueId);
223*be2f124cSJishnu CM     asyncResp->res.result(boost::beast::http::status::created);
224*be2f124cSJishnu CM     if (session->isConfigureSelfOnly)
225*be2f124cSJishnu CM     {
226*be2f124cSJishnu CM         messages::passwordChangeRequired(
227*be2f124cSJishnu CM             asyncResp->res,
228*be2f124cSJishnu CM             boost::urls::format("/redfish/v1/AccountService/Accounts/{}",
229*be2f124cSJishnu CM                                 session->username));
230*be2f124cSJishnu CM     }
231*be2f124cSJishnu CM 
232*be2f124cSJishnu CM     crow::getUserInfo(asyncResp, username, session, [asyncResp, session]() {
233*be2f124cSJishnu CM         fillSessionObject(asyncResp->res, *session);
234*be2f124cSJishnu CM     });
235*be2f124cSJishnu CM }
236*be2f124cSJishnu CM 
2374ee8e211SEd Tanous inline void handleSessionCollectionPost(
23845ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
239724340d7SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
240724340d7SEd Tanous {
2413ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
24245ca1b86SEd Tanous     {
24345ca1b86SEd Tanous         return;
24445ca1b86SEd Tanous     }
2459712f8acSEd Tanous     std::string username;
2469712f8acSEd Tanous     std::string password;
247bb759e3aSEd Tanous     std::optional<std::string> clientId;
2482ccce1f3SRavi Teja     std::optional<std::string> token;
249afc474aeSMyung Bae     if (!json_util::readJsonPatch( //
250afc474aeSMyung Bae             req, asyncResp->res, //
251afc474aeSMyung Bae             "Context", clientId, //
252afc474aeSMyung Bae             "Password", password, //
253afc474aeSMyung Bae             "Token", token, //
254afc474aeSMyung Bae             "UserName", username //
255afc474aeSMyung Bae             ))
2561abe55efSEd Tanous     {
2572b7981f6SKowalski, Kamil         return;
2582b7981f6SKowalski, Kamil     }
259820ce598SEd Tanous     if (password.empty() || username.empty() ||
2608d1b46d7Szhanghch05         asyncResp->res.result() != boost::beast::http::status::ok)
2611abe55efSEd Tanous     {
2621abe55efSEd Tanous         if (username.empty())
2631abe55efSEd Tanous         {
2648d1b46d7Szhanghch05             messages::propertyMissing(asyncResp->res, "UserName");
265f4c4dcf4SKowalski, Kamil         }
266f4c4dcf4SKowalski, Kamil 
2671abe55efSEd Tanous         if (password.empty())
2681abe55efSEd Tanous         {
2698d1b46d7Szhanghch05             messages::propertyMissing(asyncResp->res, "Password");
270820ce598SEd Tanous         }
271820ce598SEd Tanous 
272820ce598SEd Tanous         return;
273f4c4dcf4SKowalski, Kamil     }
2742b7981f6SKowalski, Kamil 
2752ccce1f3SRavi Teja     int pamrc = pamAuthenticateUser(username, password, token);
2763bf4e632SJoseph Reynolds     bool isConfigureSelfOnly = pamrc == PAM_NEW_AUTHTOK_REQD;
2773bf4e632SJoseph Reynolds     if ((pamrc != PAM_SUCCESS) && !isConfigureSelfOnly)
2781abe55efSEd Tanous     {
27939662a3bSEd Tanous         messages::resourceAtUriUnauthorized(asyncResp->res, req.url(),
280f12894f8SJason M. Bills                                             "Invalid username or password");
281820ce598SEd Tanous         return;
2822b7981f6SKowalski, Kamil     }
2836f115bbbSManojkiran Eda 
284820ce598SEd Tanous     // User is authenticated - create session
28552cc112dSEd Tanous     std::shared_ptr<persistent_data::UserSession> session =
286724340d7SEd Tanous         persistent_data::SessionStore::getInstance().generateUserSession(
28741d61c82SJiaqing Zhao             username, req.ipAddress, clientId,
28889cda63dSEd Tanous             persistent_data::SessionType::Session, isConfigureSelfOnly);
28902e53aefSBrad Bishop     if (session == nullptr)
29002e53aefSBrad Bishop     {
29102e53aefSBrad Bishop         messages::internalError(asyncResp->res);
29202e53aefSBrad Bishop         return;
29302e53aefSBrad Bishop     }
294*be2f124cSJishnu CM     processAfterSessionCreation(asyncResp, req, username, session);
29529aab242SPaul Fertser }
29629aab242SPaul Fertser 
297a1e0871dSEd Tanous inline void handleSessionServiceHead(
298a1e0871dSEd Tanous     crow::App& app, const crow::Request& req,
299a1e0871dSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
300a1e0871dSEd Tanous {
301a1e0871dSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
302a1e0871dSEd Tanous     {
303a1e0871dSEd Tanous         return;
304a1e0871dSEd Tanous     }
305a1e0871dSEd Tanous     asyncResp->res.addHeader(
306a1e0871dSEd Tanous         boost::beast::http::field::link,
307a1e0871dSEd Tanous         "</redfish/v1/JsonSchemas/SessionService/SessionService.json>; rel=describedby");
308a1e0871dSEd Tanous }
309724340d7SEd Tanous inline void
31045ca1b86SEd Tanous     handleSessionServiceGet(crow::App& app, const crow::Request& req,
311724340d7SEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3122b7981f6SKowalski, Kamil 
313724340d7SEd Tanous {
31478e3900fSGunnar Mills     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
31578e3900fSGunnar Mills     {
31678e3900fSGunnar Mills         return;
31778e3900fSGunnar Mills     }
31878e3900fSGunnar Mills     asyncResp->res.addHeader(
31978e3900fSGunnar Mills         boost::beast::http::field::link,
32078e3900fSGunnar Mills         "</redfish/v1/JsonSchemas/SessionService/SessionService.json>; rel=describedby");
32178e3900fSGunnar Mills 
3228d1b46d7Szhanghch05     asyncResp->res.jsonValue["@odata.type"] =
3238d1b46d7Szhanghch05         "#SessionService.v1_0_2.SessionService";
3247a859ffeSGunnar Mills     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/SessionService";
3258d1b46d7Szhanghch05     asyncResp->res.jsonValue["Name"] = "Session Service";
3268d1b46d7Szhanghch05     asyncResp->res.jsonValue["Id"] = "SessionService";
3278d1b46d7Szhanghch05     asyncResp->res.jsonValue["Description"] = "Session Service";
3288d1b46d7Szhanghch05     asyncResp->res.jsonValue["SessionTimeout"] =
329724340d7SEd Tanous         persistent_data::SessionStore::getInstance().getTimeoutInSeconds();
3308d1b46d7Szhanghch05     asyncResp->res.jsonValue["ServiceEnabled"] = true;
3310f74e643SEd Tanous 
3321476687dSEd Tanous     asyncResp->res.jsonValue["Sessions"]["@odata.id"] =
3331476687dSEd Tanous         "/redfish/v1/SessionService/Sessions";
334724340d7SEd Tanous }
335f2a4a606SManojkiran Eda 
336724340d7SEd Tanous inline void handleSessionServicePatch(
33745ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
338724340d7SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
339724340d7SEd Tanous {
3403ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
34145ca1b86SEd Tanous     {
34245ca1b86SEd Tanous         return;
34345ca1b86SEd Tanous     }
344f2a4a606SManojkiran Eda     std::optional<int64_t> sessionTimeout;
345afc474aeSMyung Bae     if (!json_util::readJsonPatch( //
346afc474aeSMyung Bae             req, asyncResp->res, //
347afc474aeSMyung Bae             "SessionTimeout", sessionTimeout //
348afc474aeSMyung Bae             ))
349f2a4a606SManojkiran Eda     {
350f2a4a606SManojkiran Eda         return;
351f2a4a606SManojkiran Eda     }
352f2a4a606SManojkiran Eda 
353f2a4a606SManojkiran Eda     if (sessionTimeout)
354f2a4a606SManojkiran Eda     {
3558ece0e45SEd Tanous         // The minimum & maximum allowed values for session timeout
356faa34ccfSEd Tanous         // are 30 seconds and 86400 seconds respectively as per the
357faa34ccfSEd Tanous         // session service schema mentioned at
358f2a4a606SManojkiran Eda         // https://redfish.dmtf.org/schemas/v1/SessionService.v1_1_7.json
359f2a4a606SManojkiran Eda 
360f2a4a606SManojkiran Eda         if (*sessionTimeout <= 86400 && *sessionTimeout >= 30)
361f2a4a606SManojkiran Eda         {
362724340d7SEd Tanous             std::chrono::seconds sessionTimeoutInseconds(*sessionTimeout);
363724340d7SEd Tanous             persistent_data::SessionStore::getInstance().updateSessionTimeout(
364724340d7SEd Tanous                 sessionTimeoutInseconds);
365724340d7SEd Tanous             messages::propertyValueModified(asyncResp->res, "SessionTimeOut",
366f2a4a606SManojkiran Eda                                             std::to_string(*sessionTimeout));
367f2a4a606SManojkiran Eda         }
368f2a4a606SManojkiran Eda         else
369f2a4a606SManojkiran Eda         {
370e2616cc5SEd Tanous             messages::propertyValueNotInList(asyncResp->res, *sessionTimeout,
3718d1b46d7Szhanghch05                                              "SessionTimeOut");
372f2a4a606SManojkiran Eda         }
373f2a4a606SManojkiran Eda     }
374724340d7SEd Tanous }
375724340d7SEd Tanous 
376724340d7SEd Tanous inline void requestRoutesSession(App& app)
377724340d7SEd Tanous {
378724340d7SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/<str>/")
379a1e0871dSEd Tanous         .privileges(redfish::privileges::headSession)
380a1e0871dSEd Tanous         .methods(boost::beast::http::verb::head)(
381a1e0871dSEd Tanous             std::bind_front(handleSessionHead, std::ref(app)));
382a1e0871dSEd Tanous 
383a1e0871dSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/<str>/")
384724340d7SEd Tanous         .privileges(redfish::privileges::getSession)
38545ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(
38645ca1b86SEd Tanous             std::bind_front(handleSessionGet, std::ref(app)));
387724340d7SEd Tanous 
388724340d7SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/<str>/")
389724340d7SEd Tanous         .privileges(redfish::privileges::deleteSession)
39045ca1b86SEd Tanous         .methods(boost::beast::http::verb::delete_)(
39145ca1b86SEd Tanous             std::bind_front(handleSessionDelete, std::ref(app)));
392724340d7SEd Tanous 
393724340d7SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/")
394a1e0871dSEd Tanous         .privileges(redfish::privileges::headSessionCollection)
395a1e0871dSEd Tanous         .methods(boost::beast::http::verb::head)(
396a1e0871dSEd Tanous             std::bind_front(handleSessionCollectionHead, std::ref(app)));
397a1e0871dSEd Tanous 
398a1e0871dSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/")
399724340d7SEd Tanous         .privileges(redfish::privileges::getSessionCollection)
40045ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(
40145ca1b86SEd Tanous             std::bind_front(handleSessionCollectionGet, std::ref(app)));
402724340d7SEd Tanous 
403e76cd868SEd Tanous     // Note, the next two routes technically don't match the privilege
404724340d7SEd Tanous     // registry given the way login mechanisms work.  The base privilege
405724340d7SEd Tanous     // registry lists this endpoint as requiring login privilege, but because
406724340d7SEd Tanous     // this is the endpoint responsible for giving the login privilege, and it
407724340d7SEd Tanous     // is itself its own route, it needs to not require Login
408724340d7SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/")
409724340d7SEd Tanous         .privileges({})
41045ca1b86SEd Tanous         .methods(boost::beast::http::verb::post)(
41145ca1b86SEd Tanous             std::bind_front(handleSessionCollectionPost, std::ref(app)));
412724340d7SEd Tanous 
413e76cd868SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/Members/")
414e76cd868SEd Tanous         .privileges({})
41545ca1b86SEd Tanous         .methods(boost::beast::http::verb::post)(
41645ca1b86SEd Tanous             std::bind_front(handleSessionCollectionPost, std::ref(app)));
417e76cd868SEd Tanous 
418724340d7SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/")
419a1e0871dSEd Tanous         .privileges(redfish::privileges::headSessionService)
420a1e0871dSEd Tanous         .methods(boost::beast::http::verb::head)(
421a1e0871dSEd Tanous             std::bind_front(handleSessionServiceHead, std::ref(app)));
422a1e0871dSEd Tanous 
423a1e0871dSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/")
424724340d7SEd Tanous         .privileges(redfish::privileges::getSessionService)
42545ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(
42645ca1b86SEd Tanous             std::bind_front(handleSessionServiceGet, std::ref(app)));
427724340d7SEd Tanous 
428724340d7SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/")
429724340d7SEd Tanous         .privileges(redfish::privileges::patchSessionService)
43045ca1b86SEd Tanous         .methods(boost::beast::http::verb::patch)(
43145ca1b86SEd Tanous             std::bind_front(handleSessionServicePatch, std::ref(app)));
432f2a4a606SManojkiran Eda }
4335d27b854SBorawski.Lukasz 
4342b7981f6SKowalski, Kamil } // namespace redfish
435