Add Link header handling to AccountService

Per the prior patches in this series, this updates AccountService to
respond to HEAD requests in the way the redfish spec requires.

Tested:
RESP_HEADERS_LINK_REL_DESCRIBED_BY now passes for AccountService routes.

GET /redfish/v1/AccountService returns a correct looking Link header.
Following that Link header resolves the schema file.

Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: Ib91a33dc6af0213aff8a1420ec4bb5e786b4a355
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 9a8142d..d7c70c1 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -1238,14 +1238,25 @@
         });
 }
 
-inline void
-    handleAccountServiceGet(App& app, const crow::Request& req,
-                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+inline void handleAccountServiceHead(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 {
+
     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
     {
         return;
     }
+    asyncResp->res.addHeader(
+        boost::beast::http::field::link,
+        "</redfish/v1/JsonSchemas/AccountService/AccountService.json>; rel=describedby");
+}
+
+inline void
+    handleAccountServiceGet(App& app, const crow::Request& req,
+                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    handleAccountServiceHead(app, req, asyncResp);
     const persistent_data::AuthConfigMethods& authMethodsConfig =
         persistent_data::SessionStore::getInstance().getAuthMethodsConfig();
 
@@ -1450,14 +1461,25 @@
     }
 }
 
-inline void handleAccountCollectionGet(
+inline void handleAccountCollectionHead(
     App& app, const crow::Request& req,
     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 {
+
     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
     {
         return;
     }
+    asyncResp->res.addHeader(
+        boost::beast::http::field::link,
+        "</redfish/v1/JsonSchemas/ManagerAccountCollection.json>; rel=describedby");
+}
+
+inline void handleAccountCollectionGet(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    handleAccountCollectionHead(app, req, asyncResp);
 
     asyncResp->res.jsonValue["@odata.id"] =
         "/redfish/v1/AccountService/Accounts";
@@ -1631,14 +1653,25 @@
 }
 
 inline void
-    handleAccountGet(App& app, const crow::Request& req,
-                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                     const std::string& accountName)
+    handleAccountHead(App& app, const crow::Request& req,
+                      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                      const std::string& /*accountName*/)
 {
+
     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
     {
         return;
     }
+    asyncResp->res.addHeader(
+        boost::beast::http::field::link,
+        "</redfish/v1/JsonSchemas/ManagerAccount/ManagerAccount.json>; rel=describedby");
+}
+inline void
+    handleAccountGet(App& app, const crow::Request& req,
+                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                     const std::string& accountName)
+{
+    handleAccountHead(app, req, asyncResp, accountName);
 #ifdef BMCWEB_INSECURE_DISABLE_AUTHENTICATION
     // If authentication is disabled, there are no user accounts
     messages::resourceNotFound(
@@ -1920,6 +1953,11 @@
 {
 
     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/")
+        .privileges(redfish::privileges::headAccountService)
+        .methods(boost::beast::http::verb::head)(
+            std::bind_front(handleAccountServiceHead, std::ref(app)));
+
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/")
         .privileges(redfish::privileges::getAccountService)
         .methods(boost::beast::http::verb::get)(
             std::bind_front(handleAccountServiceGet, std::ref(app)));
@@ -1930,6 +1968,11 @@
             std::bind_front(handleAccountServicePatch, std::ref(app)));
 
     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/")
+        .privileges(redfish::privileges::headManagerAccountCollection)
+        .methods(boost::beast::http::verb::head)(
+            std::bind_front(handleAccountCollectionHead, std::ref(app)));
+
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/")
         .privileges(redfish::privileges::getManagerAccountCollection)
         .methods(boost::beast::http::verb::get)(
             std::bind_front(handleAccountCollectionGet, std::ref(app)));
@@ -1940,6 +1983,11 @@
             std::bind_front(handleAccountCollectionPost, std::ref(app)));
 
     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/")
+        .privileges(redfish::privileges::headManagerAccount)
+        .methods(boost::beast::http::verb::head)(
+            std::bind_front(handleAccountHead, std::ref(app)));
+
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/")
         .privileges(redfish::privileges::getManagerAccount)
         .methods(boost::beast::http::verb::get)(
             std::bind_front(handleAccountGet, std::ref(app)));