Fetch the ClientIP during session creation

This commit saves the IP Address of the client from where the session
was created.

- This is not a user supplied value. The BMC will internally pull the
  IP address from the incoming create-session request.

- It should also be noted that ClientIP will not change if the same session
  token is used from some other IP address for further management of the BMC.

Tested by:
1. Create session
2. Display the Session details with GET command to check the IP from where
the session is created/updated.

GET https://${bmc}/redfish/v1/SessionService/Sessions/<id>
{
  "@odata.id": "/redfish/v1/SessionService/Sessions/<id>",
  "@odata.type": "#Session.v1_0_2.Session",
  "Description": "Manager User Session",
  "Id": "<id>",
  "Name": "User Session",
  "Oem": {
    "OpenBMC": {
      "@odata.type": "#OemSession.v1_0_0.Session",
      "ClientOriginIP": "<ip address>"
    }
  },
  "UserName": "root"
}
3. Redfish validator is run successfully.

Signed-off-by: Sunitha Harish <sunithaharish04@gmail.com>
Change-Id: I0076f260f50a991600ec060c72f3e46fb9a9cbb8
diff --git a/include/sessions.hpp b/include/sessions.hpp
index e455809..217ce95 100644
--- a/include/sessions.hpp
+++ b/include/sessions.hpp
@@ -44,6 +44,7 @@
     std::string username;
     std::string csrfToken;
     std::string clientId;
+    std::string clientIp;
     std::chrono::time_point<std::chrono::steady_clock> lastUpdated;
     PersistenceType persistence;
     bool cookieAuth = false;
@@ -101,6 +102,11 @@
             {
                 userSession->clientId = *thisValue;
             }
+            else if (element.key() == "client_ip")
+            {
+                userSession->clientIp = *thisValue;
+            }
+
             else
             {
                 BMCWEB_LOG_ERROR
@@ -212,7 +218,8 @@
     std::shared_ptr<UserSession> generateUserSession(
         const std::string_view username,
         PersistenceType persistence = PersistenceType::TIMEOUT,
-        bool isConfigureSelfOnly = false, const std::string_view clientId = "")
+        bool isConfigureSelfOnly = false, const std::string_view clientId = "",
+        const std::string_view clientIp = "")
     {
         // TODO(ed) find a secure way to not generate session identifiers if
         // persistence is set to SINGLE_REQUEST
@@ -259,10 +266,11 @@
                 return nullptr;
             }
         }
-        auto session = std::make_shared<UserSession>(UserSession{
-            uniqueId, sessionToken, std::string(username), csrfToken,
-            std::string(clientId), std::chrono::steady_clock::now(),
-            persistence, false, isConfigureSelfOnly});
+        auto session = std::make_shared<UserSession>(
+            UserSession{uniqueId, sessionToken, std::string(username),
+                        csrfToken, std::string(clientId), std::string(clientIp),
+                        std::chrono::steady_clock::now(), persistence, false,
+                        isConfigureSelfOnly});
         auto it = authTokens.emplace(std::make_pair(sessionToken, session));
         // Only need to write to disk if session isn't about to be destroyed.
         needWrite = persistence == PersistenceType::TIMEOUT;
@@ -428,17 +436,16 @@
             crow::persistent_data::PersistenceType::SINGLE_REQUEST)
         {
 #ifdef BMCWEB_ENABLE_IBM_MANAGEMENT_CONSOLE
-            j = nlohmann::json{{"unique_id", p->uniqueId},
-                               {"session_token", p->sessionToken},
-                               {"username", p->username},
-                               {"csrf_token", p->csrfToken},
-                               { "client_id",
-                                 p->clientId }};
+            j = nlohmann::json{
+                {"unique_id", p->uniqueId}, {"session_token", p->sessionToken},
+                {"username", p->username},  {"csrf_token", p->csrfToken},
+                {"client_id", p->clientId}, { "client_ip", p->clientIp }};
 #else
             j = nlohmann::json{{"unique_id", p->uniqueId},
                                {"session_token", p->sessionToken},
                                {"username", p->username},
-                               {"csrf_token", p->csrfToken}};
+                               {"csrf_token", p->csrfToken},
+                               {"client_ip", p->clientIp}};
 #endif
         }
     }