blob: 48d53bfd94c4365ea4f9c033871f6d956b6a6154 [file] [log] [blame]
Kowalski, Kamil2b7981f2018-01-31 13:24:59 +01001/*
Ed Tanous6be832e2024-09-10 11:44:48 -07002Copyright (c) 2018 Intel Corporation
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
Kowalski, Kamil2b7981f2018-01-31 13:24:59 +010015*/
16#pragma once
Borawski.Lukasz43a095a2018-02-19 15:39:01 +010017
Paul Fertserce22f602024-06-03 20:53:16 +000018#include "account_service.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080019#include "app.hpp"
Paul Fertser29aab242024-06-12 19:28:47 +000020#include "cookies.hpp"
Kowalski, Kamilf4c4dcf2018-01-29 14:55:35 +010021#include "error_messages.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080022#include "http/utility.hpp"
Ed Tanous52cc1122020-07-18 13:51:21 -070023#include "persistent_data.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080024#include "query.hpp"
25#include "registries/privilege_registry.hpp"
26#include "utils/json_utils.hpp"
John Edward Broadbent7e860f12021-04-08 15:57:16 -070027
Ed Tanousef4c65b2023-04-24 15:28:50 -070028#include <boost/url/format.hpp>
29
Ed Tanous89cda632024-04-16 08:45:54 -070030#include <string>
31#include <vector>
32
Ed Tanous1abe55e2018-09-05 08:30:59 -070033namespace redfish
34{
Kowalski, Kamil2b7981f2018-01-31 13:24:59 +010035
Ed Tanous4f48d5f2021-06-21 08:27:45 -070036inline void fillSessionObject(crow::Response& res,
37 const persistent_data::UserSession& session)
Ed Tanous1abe55e2018-09-05 08:30:59 -070038{
Ed Tanousfaa34cc2021-06-03 13:27:02 -070039 res.jsonValue["Id"] = session.uniqueId;
40 res.jsonValue["UserName"] = session.username;
Paul Fertserce22f602024-06-03 20:53:16 +000041 nlohmann::json::array_t roles;
42 roles.emplace_back(redfish::getRoleIdFromPrivilege(session.userRole));
43 res.jsonValue["Roles"] = std::move(roles);
Ed Tanousef4c65b2023-04-24 15:28:50 -070044 res.jsonValue["@odata.id"] = boost::urls::format(
45 "/redfish/v1/SessionService/Sessions/{}", session.uniqueId);
Paul Fertserce22f602024-06-03 20:53:16 +000046 res.jsonValue["@odata.type"] = "#Session.v1_7_0.Session";
Ed Tanousfaa34cc2021-06-03 13:27:02 -070047 res.jsonValue["Name"] = "User Session";
48 res.jsonValue["Description"] = "Manager User Session";
49 res.jsonValue["ClientOriginIPAddress"] = session.clientIp;
Ed Tanousbb759e32022-08-02 17:07:54 -070050 if (session.clientId)
51 {
52 res.jsonValue["Context"] = *session.clientId;
53 }
Ed Tanousfaa34cc2021-06-03 13:27:02 -070054}
Kowalski, Kamil2b7981f2018-01-31 13:24:59 +010055
Ed Tanous724340d2022-03-14 09:10:07 -070056inline void
Ed Tanousa1e08712022-07-07 16:10:39 -070057 handleSessionHead(crow::App& app, const crow::Request& req,
58 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
59 const std::string& /*sessionId*/)
Ed Tanous724340d2022-03-14 09:10:07 -070060{
Carson Labrado3ba00072022-06-06 19:40:56 +000061 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -070062 {
63 return;
64 }
Ed Tanousa1e08712022-07-07 16:10:39 -070065 asyncResp->res.addHeader(
66 boost::beast::http::field::link,
67 "</redfish/v1/JsonSchemas/Session/Session.json>; rel=describedby");
68}
69
70inline void
71 handleSessionGet(crow::App& app, const crow::Request& req,
72 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
73 const std::string& sessionId)
74{
Ed Tanous65ffbcb2023-05-16 08:54:11 -070075 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
76 {
77 return;
78 }
79 asyncResp->res.addHeader(
80 boost::beast::http::field::link,
81 "</redfish/v1/JsonSchemas/Session/Session.json>; rel=describedby");
Ed Tanousa1e08712022-07-07 16:10:39 -070082
Ed Tanous724340d2022-03-14 09:10:07 -070083 // Note that control also reaches here via doPost and doDelete.
84 auto session =
85 persistent_data::SessionStore::getInstance().getSessionByUid(sessionId);
86
87 if (session == nullptr)
88 {
89 messages::resourceNotFound(asyncResp->res, "Session", sessionId);
90 return;
91 }
92
93 fillSessionObject(asyncResp->res, *session);
94}
95
96inline void
Ed Tanous45ca1b82022-03-25 13:07:27 -070097 handleSessionDelete(crow::App& app, const crow::Request& req,
Ed Tanous724340d2022-03-14 09:10:07 -070098 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
99 const std::string& sessionId)
100{
Carson Labrado3ba00072022-06-06 19:40:56 +0000101 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -0700102 {
103 return;
104 }
Ed Tanous724340d2022-03-14 09:10:07 -0700105 auto session =
106 persistent_data::SessionStore::getInstance().getSessionByUid(sessionId);
107
108 if (session == nullptr)
109 {
110 messages::resourceNotFound(asyncResp->res, "Session", sessionId);
111 return;
112 }
113
114 // Perform a proper ConfigureSelf authority check. If a
115 // session is being used to DELETE some other user's session,
116 // then the ConfigureSelf privilege does not apply. In that
117 // case, perform the authority check again without the user's
118 // ConfigureSelf privilege.
wukaihua-fii-na0fd29862022-05-18 09:19:16 +0800119 if (req.session != nullptr && !session->username.empty() &&
120 session->username != req.session->username)
Ed Tanous724340d2022-03-14 09:10:07 -0700121 {
122 Privileges effectiveUserPrivileges =
Ninad Palsule3e72c202023-03-27 17:19:55 -0500123 redfish::getUserPrivileges(*req.session);
Ed Tanous724340d2022-03-14 09:10:07 -0700124
125 if (!effectiveUserPrivileges.isSupersetOf({"ConfigureUsers"}))
126 {
127 messages::insufficientPrivilege(asyncResp->res);
128 return;
129 }
130 }
131
Paul Fertser8812e8b2024-09-18 12:16:37 +0000132 if (req.session != nullptr && req.session->uniqueId == sessionId &&
133 session->cookieAuth)
Paul Fertser29aab242024-06-12 19:28:47 +0000134 {
135 bmcweb::clearSessionCookies(asyncResp->res);
136 }
137
Ed Tanous724340d2022-03-14 09:10:07 -0700138 persistent_data::SessionStore::getInstance().removeSession(session);
139 messages::success(asyncResp->res);
140}
141
142inline nlohmann::json getSessionCollectionMembers()
143{
Ed Tanous89cda632024-04-16 08:45:54 -0700144 std::vector<std::string> sessionIds =
145 persistent_data::SessionStore::getInstance().getAllUniqueIds();
Ed Tanous724340d2022-03-14 09:10:07 -0700146 nlohmann::json ret = nlohmann::json::array();
Ed Tanous89cda632024-04-16 08:45:54 -0700147 for (const std::string& uid : sessionIds)
Ed Tanous724340d2022-03-14 09:10:07 -0700148 {
Ed Tanous14766872022-03-15 10:44:42 -0700149 nlohmann::json::object_t session;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700150 session["@odata.id"] =
Ed Tanous89cda632024-04-16 08:45:54 -0700151 boost::urls::format("/redfish/v1/SessionService/Sessions/{}", uid);
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500152 ret.emplace_back(std::move(session));
Ed Tanous724340d2022-03-14 09:10:07 -0700153 }
154 return ret;
155}
156
Ed Tanousa1e08712022-07-07 16:10:39 -0700157inline void handleSessionCollectionHead(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700158 crow::App& app, const crow::Request& req,
Ed Tanous724340d2022-03-14 09:10:07 -0700159 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
160{
Carson Labrado3ba00072022-06-06 19:40:56 +0000161 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -0700162 {
163 return;
164 }
Ed Tanousa1e08712022-07-07 16:10:39 -0700165 asyncResp->res.addHeader(
166 boost::beast::http::field::link,
167 "</redfish/v1/JsonSchemas/SessionCollection.json>; rel=describedby");
168}
169
170inline void handleSessionCollectionGet(
171 crow::App& app, const crow::Request& req,
172 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
173{
Ed Tanous01a89a12022-08-05 09:18:54 -0700174 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
175 {
176 return;
177 }
178 asyncResp->res.addHeader(
179 boost::beast::http::field::link,
180 "</redfish/v1/JsonSchemas/SessionCollection.json>; rel=describedby");
181
Ed Tanous724340d2022-03-14 09:10:07 -0700182 asyncResp->res.jsonValue["Members"] = getSessionCollectionMembers();
183 asyncResp->res.jsonValue["Members@odata.count"] =
184 asyncResp->res.jsonValue["Members"].size();
185 asyncResp->res.jsonValue["@odata.type"] =
186 "#SessionCollection.SessionCollection";
187 asyncResp->res.jsonValue["@odata.id"] =
Gunnar Mills7a859ff2024-03-04 23:04:45 -0700188 "/redfish/v1/SessionService/Sessions";
Ed Tanous724340d2022-03-14 09:10:07 -0700189 asyncResp->res.jsonValue["Name"] = "Session Collection";
190 asyncResp->res.jsonValue["Description"] = "Session Collection";
191}
192
193inline void handleSessionCollectionMembersGet(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700194 crow::App& app, const crow::Request& req,
Ed Tanous724340d2022-03-14 09:10:07 -0700195 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
196{
Carson Labrado3ba00072022-06-06 19:40:56 +0000197 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -0700198 {
199 return;
200 }
Ed Tanous724340d2022-03-14 09:10:07 -0700201 asyncResp->res.jsonValue = getSessionCollectionMembers();
202}
203
Ed Tanous4ee8e212022-05-28 09:42:51 -0700204inline void handleSessionCollectionPost(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700205 crow::App& app, const crow::Request& req,
Ed Tanous724340d2022-03-14 09:10:07 -0700206 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
207{
Carson Labrado3ba00072022-06-06 19:40:56 +0000208 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -0700209 {
210 return;
211 }
Ed Tanous724340d2022-03-14 09:10:07 -0700212 std::string username;
213 std::string password;
Ed Tanousbb759e32022-08-02 17:07:54 -0700214 std::optional<std::string> clientId;
Ravi Teja2ccce1f2024-08-10 04:05:36 -0500215 std::optional<std::string> token;
Ed Tanous724340d2022-03-14 09:10:07 -0700216 if (!json_util::readJsonPatch(req, asyncResp->res, "UserName", username,
Ravi Teja2ccce1f2024-08-10 04:05:36 -0500217 "Password", password, "Token", token,
218 "Context", clientId))
Ed Tanous724340d2022-03-14 09:10:07 -0700219 {
220 return;
221 }
Ed Tanous724340d2022-03-14 09:10:07 -0700222 if (password.empty() || username.empty() ||
223 asyncResp->res.result() != boost::beast::http::status::ok)
224 {
225 if (username.empty())
226 {
227 messages::propertyMissing(asyncResp->res, "UserName");
228 }
229
230 if (password.empty())
231 {
232 messages::propertyMissing(asyncResp->res, "Password");
233 }
234
235 return;
236 }
237
Ravi Teja2ccce1f2024-08-10 04:05:36 -0500238 int pamrc = pamAuthenticateUser(username, password, token);
Ed Tanous724340d2022-03-14 09:10:07 -0700239 bool isConfigureSelfOnly = pamrc == PAM_NEW_AUTHTOK_REQD;
240 if ((pamrc != PAM_SUCCESS) && !isConfigureSelfOnly)
241 {
Ed Tanous39662a32023-02-06 15:09:46 -0800242 messages::resourceAtUriUnauthorized(asyncResp->res, req.url(),
Ed Tanous724340d2022-03-14 09:10:07 -0700243 "Invalid username or password");
244 return;
245 }
Ed Tanous724340d2022-03-14 09:10:07 -0700246
247 // User is authenticated - create session
248 std::shared_ptr<persistent_data::UserSession> session =
249 persistent_data::SessionStore::getInstance().generateUserSession(
250 username, req.ipAddress, clientId,
Ed Tanous89cda632024-04-16 08:45:54 -0700251 persistent_data::SessionType::Session, isConfigureSelfOnly);
Brad Bishop02e53ae2022-07-29 14:38:40 -0400252 if (session == nullptr)
253 {
254 messages::internalError(asyncResp->res);
255 return;
256 }
257
Paul Fertser29aab242024-06-12 19:28:47 +0000258 // When session is created by webui-vue give it session cookies as a
259 // non-standard Redfish extension. This is needed for authentication for
260 // WebSockets-based functionality.
261 if (!req.getHeaderValue("X-Requested-With").empty())
262 {
263 bmcweb::setSessionCookies(asyncResp->res, *session);
264 }
265 else
266 {
267 asyncResp->res.addHeader("X-Auth-Token", session->sessionToken);
268 }
269
Ed Tanous724340d2022-03-14 09:10:07 -0700270 asyncResp->res.addHeader(
271 "Location", "/redfish/v1/SessionService/Sessions/" + session->uniqueId);
272 asyncResp->res.result(boost::beast::http::status::created);
273 if (session->isConfigureSelfOnly)
274 {
275 messages::passwordChangeRequired(
276 asyncResp->res,
Ed Tanousef4c65b2023-04-24 15:28:50 -0700277 boost::urls::format("/redfish/v1/AccountService/Accounts/{}",
278 session->username));
Ed Tanous724340d2022-03-14 09:10:07 -0700279 }
280
Paul Fertser478c5a52024-06-26 22:27:59 +0000281 crow::getUserInfo(asyncResp, username, session, [asyncResp, session]() {
282 fillSessionObject(asyncResp->res, *session);
283 });
Ed Tanous724340d2022-03-14 09:10:07 -0700284}
Ed Tanousa1e08712022-07-07 16:10:39 -0700285inline void handleSessionServiceHead(
286 crow::App& app, const crow::Request& req,
287 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
288{
Ed Tanousa1e08712022-07-07 16:10:39 -0700289 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
290 {
291 return;
292 }
293 asyncResp->res.addHeader(
294 boost::beast::http::field::link,
295 "</redfish/v1/JsonSchemas/SessionService/SessionService.json>; rel=describedby");
296}
Ed Tanous724340d2022-03-14 09:10:07 -0700297inline void
Ed Tanous45ca1b82022-03-25 13:07:27 -0700298 handleSessionServiceGet(crow::App& app, const crow::Request& req,
Ed Tanous724340d2022-03-14 09:10:07 -0700299 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
300
301{
Gunnar Mills78e39002023-05-17 11:52:44 -0500302 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
303 {
304 return;
305 }
306 asyncResp->res.addHeader(
307 boost::beast::http::field::link,
308 "</redfish/v1/JsonSchemas/SessionService/SessionService.json>; rel=describedby");
309
Ed Tanous724340d2022-03-14 09:10:07 -0700310 asyncResp->res.jsonValue["@odata.type"] =
311 "#SessionService.v1_0_2.SessionService";
Gunnar Mills7a859ff2024-03-04 23:04:45 -0700312 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/SessionService";
Ed Tanous724340d2022-03-14 09:10:07 -0700313 asyncResp->res.jsonValue["Name"] = "Session Service";
314 asyncResp->res.jsonValue["Id"] = "SessionService";
315 asyncResp->res.jsonValue["Description"] = "Session Service";
316 asyncResp->res.jsonValue["SessionTimeout"] =
317 persistent_data::SessionStore::getInstance().getTimeoutInSeconds();
318 asyncResp->res.jsonValue["ServiceEnabled"] = true;
319
Ed Tanous14766872022-03-15 10:44:42 -0700320 asyncResp->res.jsonValue["Sessions"]["@odata.id"] =
321 "/redfish/v1/SessionService/Sessions";
Ed Tanous724340d2022-03-14 09:10:07 -0700322}
323
324inline void handleSessionServicePatch(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700325 crow::App& app, const crow::Request& req,
Ed Tanous724340d2022-03-14 09:10:07 -0700326 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
327{
Carson Labrado3ba00072022-06-06 19:40:56 +0000328 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -0700329 {
330 return;
331 }
Ed Tanous724340d2022-03-14 09:10:07 -0700332 std::optional<int64_t> sessionTimeout;
333 if (!json_util::readJsonPatch(req, asyncResp->res, "SessionTimeout",
334 sessionTimeout))
335 {
336 return;
337 }
338
339 if (sessionTimeout)
340 {
Ed Tanous8ece0e42024-01-02 13:16:50 -0800341 // The minimum & maximum allowed values for session timeout
Ed Tanous724340d2022-03-14 09:10:07 -0700342 // are 30 seconds and 86400 seconds respectively as per the
343 // session service schema mentioned at
344 // https://redfish.dmtf.org/schemas/v1/SessionService.v1_1_7.json
345
346 if (*sessionTimeout <= 86400 && *sessionTimeout >= 30)
347 {
348 std::chrono::seconds sessionTimeoutInseconds(*sessionTimeout);
349 persistent_data::SessionStore::getInstance().updateSessionTimeout(
350 sessionTimeoutInseconds);
351 messages::propertyValueModified(asyncResp->res, "SessionTimeOut",
352 std::to_string(*sessionTimeout));
353 }
354 else
355 {
Ed Tanouse2616cc2022-06-27 12:45:55 -0700356 messages::propertyValueNotInList(asyncResp->res, *sessionTimeout,
Ed Tanous724340d2022-03-14 09:10:07 -0700357 "SessionTimeOut");
358 }
359 }
360}
361
Ed Tanousfaa34cc2021-06-03 13:27:02 -0700362inline void requestRoutesSession(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700363{
Ed Tanousfaa34cc2021-06-03 13:27:02 -0700364 BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/<str>/")
Ed Tanousa1e08712022-07-07 16:10:39 -0700365 .privileges(redfish::privileges::headSession)
366 .methods(boost::beast::http::verb::head)(
367 std::bind_front(handleSessionHead, std::ref(app)));
368
369 BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700370 .privileges(redfish::privileges::getSession)
Ed Tanous45ca1b82022-03-25 13:07:27 -0700371 .methods(boost::beast::http::verb::get)(
372 std::bind_front(handleSessionGet, std::ref(app)));
Kowalski, Kamil2b7981f2018-01-31 13:24:59 +0100373
Ed Tanousfaa34cc2021-06-03 13:27:02 -0700374 BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700375 .privileges(redfish::privileges::deleteSession)
Ed Tanous45ca1b82022-03-25 13:07:27 -0700376 .methods(boost::beast::http::verb::delete_)(
377 std::bind_front(handleSessionDelete, std::ref(app)));
Ed Tanousfaa34cc2021-06-03 13:27:02 -0700378
379 BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/")
Ed Tanousa1e08712022-07-07 16:10:39 -0700380 .privileges(redfish::privileges::headSessionCollection)
381 .methods(boost::beast::http::verb::head)(
382 std::bind_front(handleSessionCollectionHead, std::ref(app)));
383
384 BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/")
Ed Tanoused398212021-06-09 17:05:54 -0700385 .privileges(redfish::privileges::getSessionCollection)
Ed Tanous45ca1b82022-03-25 13:07:27 -0700386 .methods(boost::beast::http::verb::get)(
387 std::bind_front(handleSessionCollectionGet, std::ref(app)));
Ed Tanousfaa34cc2021-06-03 13:27:02 -0700388
Ed Tanouse76cd862022-03-14 09:12:00 -0700389 // Note, the next two routes technically don't match the privilege
Ed Tanous724340d2022-03-14 09:10:07 -0700390 // registry given the way login mechanisms work. The base privilege
391 // registry lists this endpoint as requiring login privilege, but because
392 // this is the endpoint responsible for giving the login privilege, and it
393 // is itself its own route, it needs to not require Login
Ed Tanousfaa34cc2021-06-03 13:27:02 -0700394 BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/")
395 .privileges({})
Ed Tanous45ca1b82022-03-25 13:07:27 -0700396 .methods(boost::beast::http::verb::post)(
397 std::bind_front(handleSessionCollectionPost, std::ref(app)));
Kowalski, Kamil2b7981f2018-01-31 13:24:59 +0100398
Ed Tanouse76cd862022-03-14 09:12:00 -0700399 BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/Members/")
400 .privileges({})
Ed Tanous45ca1b82022-03-25 13:07:27 -0700401 .methods(boost::beast::http::verb::post)(
402 std::bind_front(handleSessionCollectionPost, std::ref(app)));
Ed Tanouse76cd862022-03-14 09:12:00 -0700403
Ed Tanousfaa34cc2021-06-03 13:27:02 -0700404 BMCWEB_ROUTE(app, "/redfish/v1/SessionService/")
Ed Tanousa1e08712022-07-07 16:10:39 -0700405 .privileges(redfish::privileges::headSessionService)
406 .methods(boost::beast::http::verb::head)(
407 std::bind_front(handleSessionServiceHead, std::ref(app)));
408
409 BMCWEB_ROUTE(app, "/redfish/v1/SessionService/")
Ed Tanoused398212021-06-09 17:05:54 -0700410 .privileges(redfish::privileges::getSessionService)
Ed Tanous45ca1b82022-03-25 13:07:27 -0700411 .methods(boost::beast::http::verb::get)(
412 std::bind_front(handleSessionServiceGet, std::ref(app)));
Borawski.Lukasz5d27b852018-02-08 13:24:24 +0100413
Ed Tanousfaa34cc2021-06-03 13:27:02 -0700414 BMCWEB_ROUTE(app, "/redfish/v1/SessionService/")
Ed Tanoused398212021-06-09 17:05:54 -0700415 .privileges(redfish::privileges::patchSessionService)
Ed Tanous45ca1b82022-03-25 13:07:27 -0700416 .methods(boost::beast::http::verb::patch)(
417 std::bind_front(handleSessionServicePatch, std::ref(app)));
Ed Tanousfaa34cc2021-06-03 13:27:02 -0700418}
Borawski.Lukasz5d27b852018-02-08 13:24:24 +0100419
Ed Tanous1abe55e2018-09-05 08:30:59 -0700420} // namespace redfish