Enable encoding/decoding object paths of User Name

Any string used to form a Dbus object path needs to be encoded.
This commit enables encoding the User Name before it is used as
Object path and decodes the object path to get the user readable
text.

The encoding is essemtial while getting details of a user,
deleting user and modifying properties of user as we need
the object path for these actions.
Decoding and getting the User name using object_path.filename()
is essential to display the user name in human readable format.

Tested:
 - Successfully created new user using POST to
   /redfish/v1/AccountService/Accounts
   with body
   {
     "UserName": "_test_6566",
     "Password": "openbmc123",
     "RoleId": "NoAccess",
     "Enabled": true
   }
   and it created a Dbus Object:
   /xyz/openbmc_project/user/_5ftest_5f6566

 - GET on
   displayed all user names in correct human redable
   format.
   Example: The user name for
   /xyz/openbmc_project/user/_5ftest_5f6566
   was displayed as "_test_6566"

 - Successfully fetched user Detais by GET to
   /redfish/v1/AccountService/Accounts/<UserName>

 - Successfully modified user details by PATCH to
   /redfish/v1/AccountService/Accounts/<UserName>
   Example body:
   {
     Enabled: false
   }

 - Successfully removed user by DELETE to
   /redfish/v1/AccountService/Accounts/<UserName>
   removed the user with given name
   Example: Deleting _test_6566 actually removed
   /xyz/openbmc_project/user/_5ftest_5f6566 object
   path successfully.

Signed-off-by: P Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com>
Change-Id: I6e7559f7543ee504e2f8c137911f42887eb4cf16
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index d59c8c2..865a383 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -33,6 +33,7 @@
 constexpr const char* adConfigObject =
     "/xyz/openbmc_project/user/ldap/active_directory";
 
+constexpr const char* rootUserDbusPath = "/xyz/openbmc_project/user/";
 constexpr const char* ldapRootObject = "/xyz/openbmc_project/user/ldap";
 constexpr const char* ldapDbusService = "xyz.openbmc_project.Ldap.Config";
 constexpr const char* ldapConfigInterface =
@@ -1139,8 +1140,9 @@
                                  std::optional<std::string> roleId,
                                  std::optional<bool> locked)
 {
-    std::string dbusObjectPath = "/xyz/openbmc_project/user/" + username;
-    dbus::utility::escapePathForDbus(dbusObjectPath);
+    sdbusplus::message::object_path tempObjPath(rootUserDbusPath);
+    tempObjPath /= username;
+    std::string dbusObjectPath(tempObjPath);
 
     dbus::utility::checkDbusPathExists(
         dbusObjectPath,
@@ -1638,6 +1640,11 @@
                                 // created, but the password set
                                 // failed.Something is wrong, so delete the user
                                 // that we've already created
+                                sdbusplus::message::object_path tempObjPath(
+                                    rootUserDbusPath);
+                                tempObjPath /= username;
+                                const std::string userPath(tempObjPath);
+
                                 crow::connections::systemBus->async_method_call(
                                     [asyncResp, password](
                                         const boost::system::error_code ec3) {
@@ -1654,7 +1661,7 @@
                                             "Password");
                                     },
                                     "xyz.openbmc_project.User.Manager",
-                                    "/xyz/openbmc_project/user/" + username,
+                                    userPath,
                                     "xyz.openbmc_project.Object.Delete",
                                     "Delete");
 
@@ -1712,16 +1719,14 @@
                         messages::internalError(asyncResp->res);
                         return;
                     }
-                    auto userIt = users.begin();
+                    auto userIt = std::find_if(
+                        users.begin(), users.end(),
+                        [accountName](
+                            const std::pair<sdbusplus::message::object_path,
+                                            DbusInterfaceType>& user) {
+                            return !accountName.compare(user.first.filename());
+                        });
 
-                    for (; userIt != users.end(); userIt++)
-                    {
-                        if (boost::ends_with(userIt->first.str,
-                                             "/" + accountName))
-                        {
-                            break;
-                        }
-                    }
                     if (userIt == users.end())
                     {
                         messages::resourceNotFound(
@@ -1920,8 +1925,9 @@
             [](const crow::Request& /*req*/,
                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                const std::string& username) -> void {
-                const std::string userPath =
-                    "/xyz/openbmc_project/user/" + username;
+                sdbusplus::message::object_path tempObjPath(rootUserDbusPath);
+                tempObjPath /= username;
+                const std::string userPath(tempObjPath);
 
                 crow::connections::systemBus->async_method_call(
                     [asyncResp, username](const boost::system::error_code ec) {