diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 553d41e..a773048 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -1238,606 +1238,712 @@
         });
 }
 
+inline void
+    handleAccountServiceGet(App& app, const crow::Request& req,
+                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    const persistent_data::AuthConfigMethods& authMethodsConfig =
+        persistent_data::SessionStore::getInstance().getAuthMethodsConfig();
+
+    nlohmann::json& json = asyncResp->res.jsonValue;
+    json["@odata.id"] = "/redfish/v1/AccountService";
+    json["@odata.type"] = "#AccountService."
+                          "v1_10_0.AccountService";
+    json["Id"] = "AccountService";
+    json["Name"] = "Account Service";
+    json["Description"] = "Account Service";
+    json["ServiceEnabled"] = true;
+    json["MaxPasswordLength"] = 20;
+    json["Accounts"]["@odata.id"] = "/redfish/v1/AccountService/Accounts";
+    json["Roles"]["@odata.id"] = "/redfish/v1/AccountService/Roles";
+    json["Oem"]["OpenBMC"]["@odata.type"] =
+        "#OemAccountService.v1_0_0.AccountService";
+    json["Oem"]["OpenBMC"]["@odata.id"] =
+        "/redfish/v1/AccountService#/Oem/OpenBMC";
+    json["Oem"]["OpenBMC"]["AuthMethods"]["BasicAuth"] =
+        authMethodsConfig.basic;
+    json["Oem"]["OpenBMC"]["AuthMethods"]["SessionToken"] =
+        authMethodsConfig.sessionToken;
+    json["Oem"]["OpenBMC"]["AuthMethods"]["XToken"] = authMethodsConfig.xtoken;
+    json["Oem"]["OpenBMC"]["AuthMethods"]["Cookie"] = authMethodsConfig.cookie;
+    json["Oem"]["OpenBMC"]["AuthMethods"]["TLS"] = authMethodsConfig.tls;
+
+    // /redfish/v1/AccountService/LDAP/Certificates is something only
+    // ConfigureManager can access then only display when the user has
+    // permissions ConfigureManager
+    Privileges effectiveUserPrivileges =
+        redfish::getUserPrivileges(req.userRole);
+
+    if (isOperationAllowedWithPrivileges({{"ConfigureManager"}},
+                                         effectiveUserPrivileges))
+    {
+        asyncResp->res.jsonValue["LDAP"]["Certificates"]["@odata.id"] =
+            "/redfish/v1/AccountService/LDAP/Certificates";
+    }
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code ec,
+                    const dbus::utility::DBusPropertiesMap& propertiesList) {
+        if (ec)
+        {
+            messages::internalError(asyncResp->res);
+            return;
+        }
+        BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
+                         << "properties for AccountService";
+        for (const std::pair<std::string, dbus::utility::DbusVariantType>&
+                 property : propertiesList)
+        {
+            if (property.first == "MinPasswordLength")
+            {
+                const uint8_t* value = std::get_if<uint8_t>(&property.second);
+                if (value != nullptr)
+                {
+                    asyncResp->res.jsonValue["MinPasswordLength"] = *value;
+                }
+            }
+            if (property.first == "AccountUnlockTimeout")
+            {
+                const uint32_t* value = std::get_if<uint32_t>(&property.second);
+                if (value != nullptr)
+                {
+                    asyncResp->res.jsonValue["AccountLockoutDuration"] = *value;
+                }
+            }
+            if (property.first == "MaxLoginAttemptBeforeLockout")
+            {
+                const uint16_t* value = std::get_if<uint16_t>(&property.second);
+                if (value != nullptr)
+                {
+                    asyncResp->res.jsonValue["AccountLockoutThreshold"] =
+                        *value;
+                }
+            }
+        }
+        },
+        "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+        "org.freedesktop.DBus.Properties", "GetAll",
+        "xyz.openbmc_project.User.AccountPolicy");
+
+    auto callback = [asyncResp](bool success, LDAPConfigData& confData,
+                                const std::string& ldapType) {
+        if (!success)
+        {
+            return;
+        }
+        parseLDAPConfigData(asyncResp->res.jsonValue, confData, ldapType);
+    };
+
+    getLDAPConfigData("LDAP", callback);
+    getLDAPConfigData("ActiveDirectory", callback);
+}
+
+inline void handleAccountServicePatch(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    std::optional<uint32_t> unlockTimeout;
+    std::optional<uint16_t> lockoutThreshold;
+    std::optional<uint8_t> minPasswordLength;
+    std::optional<uint16_t> maxPasswordLength;
+    std::optional<nlohmann::json> ldapObject;
+    std::optional<nlohmann::json> activeDirectoryObject;
+    std::optional<nlohmann::json> oemObject;
+
+    if (!json_util::readJsonPatch(
+            req, asyncResp->res, "AccountLockoutDuration", unlockTimeout,
+            "AccountLockoutThreshold", lockoutThreshold, "MaxPasswordLength",
+            maxPasswordLength, "MinPasswordLength", minPasswordLength, "LDAP",
+            ldapObject, "ActiveDirectory", activeDirectoryObject, "Oem",
+            oemObject))
+    {
+        return;
+    }
+
+    if (minPasswordLength)
+    {
+        crow::connections::systemBus->async_method_call(
+            [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::internalError(asyncResp->res);
+                return;
+            }
+            messages::success(asyncResp->res);
+            },
+            "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.User.AccountPolicy", "MinPasswordLength",
+            dbus::utility::DbusVariantType(*minPasswordLength));
+    }
+
+    if (maxPasswordLength)
+    {
+        messages::propertyNotWritable(asyncResp->res, "MaxPasswordLength");
+    }
+
+    if (ldapObject)
+    {
+        handleLDAPPatch(*ldapObject, asyncResp, "LDAP");
+    }
+
+    if (std::optional<nlohmann::json> oemOpenBMCObject;
+        oemObject && json_util::readJson(*oemObject, asyncResp->res, "OpenBMC",
+                                         oemOpenBMCObject))
+    {
+        if (std::optional<nlohmann::json> authMethodsObject;
+            oemOpenBMCObject &&
+            json_util::readJson(*oemOpenBMCObject, asyncResp->res,
+                                "AuthMethods", authMethodsObject))
+        {
+            if (authMethodsObject)
+            {
+                handleAuthMethodsPatch(*authMethodsObject, asyncResp);
+            }
+        }
+    }
+
+    if (activeDirectoryObject)
+    {
+        handleLDAPPatch(*activeDirectoryObject, asyncResp, "ActiveDirectory");
+    }
+
+    if (unlockTimeout)
+    {
+        crow::connections::systemBus->async_method_call(
+            [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::internalError(asyncResp->res);
+                return;
+            }
+            messages::success(asyncResp->res);
+            },
+            "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.User.AccountPolicy", "AccountUnlockTimeout",
+            dbus::utility::DbusVariantType(*unlockTimeout));
+    }
+    if (lockoutThreshold)
+    {
+        crow::connections::systemBus->async_method_call(
+            [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::internalError(asyncResp->res);
+                return;
+            }
+            messages::success(asyncResp->res);
+            },
+            "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.User.AccountPolicy",
+            "MaxLoginAttemptBeforeLockout",
+            dbus::utility::DbusVariantType(*lockoutThreshold));
+    }
+}
+
+inline void handleAccountCollectionGet(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+
+    asyncResp->res.jsonValue["@odata.id"] =
+        "/redfish/v1/AccountService/Accounts";
+    asyncResp->res.jsonValue["@odata.type"] = "#ManagerAccountCollection."
+                                              "ManagerAccountCollection";
+    asyncResp->res.jsonValue["Name"] = "Accounts Collection";
+    asyncResp->res.jsonValue["Description"] = "BMC User Accounts";
+
+    Privileges effectiveUserPrivileges =
+        redfish::getUserPrivileges(req.userRole);
+
+    std::string thisUser;
+    if (req.session)
+    {
+        thisUser = req.session->username;
+    }
+    crow::connections::systemBus->async_method_call(
+        [asyncResp, thisUser, effectiveUserPrivileges](
+            const boost::system::error_code ec,
+            const dbus::utility::ManagedObjectType& users) {
+        if (ec)
+        {
+            messages::internalError(asyncResp->res);
+            return;
+        }
+
+        bool userCanSeeAllAccounts =
+            effectiveUserPrivileges.isSupersetOf({"ConfigureUsers"});
+
+        bool userCanSeeSelf =
+            effectiveUserPrivileges.isSupersetOf({"ConfigureSelf"});
+
+        nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
+        memberArray = nlohmann::json::array();
+
+        for (const auto& userpath : users)
+        {
+            std::string user = userpath.first.filename();
+            if (user.empty())
+            {
+                messages::internalError(asyncResp->res);
+                BMCWEB_LOG_ERROR << "Invalid firmware ID";
+
+                return;
+            }
+
+            // As clarified by Redfish here:
+            // https://redfishforum.com/thread/281/manageraccountcollection-change-allows-account-enumeration
+            // Users without ConfigureUsers, only see their own
+            // account. Users with ConfigureUsers, see all
+            // accounts.
+            if (userCanSeeAllAccounts || (thisUser == user && userCanSeeSelf))
+            {
+                nlohmann::json::object_t member;
+                member["@odata.id"] =
+                    "/redfish/v1/AccountService/Accounts/" + user;
+                memberArray.push_back(std::move(member));
+            }
+        }
+        asyncResp->res.jsonValue["Members@odata.count"] = memberArray.size();
+        },
+        "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+}
+
+inline void handleAccountCollectionPost(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    std::string username;
+    std::string password;
+    std::optional<std::string> roleId("User");
+    std::optional<bool> enabled = true;
+    if (!json_util::readJsonPatch(req, asyncResp->res, "UserName", username,
+                                  "Password", password, "RoleId", roleId,
+                                  "Enabled", enabled))
+    {
+        return;
+    }
+
+    std::string priv = getPrivilegeFromRoleId(*roleId);
+    if (priv.empty())
+    {
+        messages::propertyValueNotInList(asyncResp->res, *roleId, "RoleId");
+        return;
+    }
+    // TODO: Following override will be reverted once support in
+    // phosphor-user-manager is added. In order to avoid dependency
+    // issues, this is added in bmcweb, which will removed, once
+    // phosphor-user-manager supports priv-noaccess.
+    if (priv == "priv-noaccess")
+    {
+        roleId = "";
+    }
+    else
+    {
+        roleId = priv;
+    }
+
+    // Reading AllGroups property
+    sdbusplus::asio::getProperty<std::vector<std::string>>(
+        *crow::connections::systemBus, "xyz.openbmc_project.User.Manager",
+        "/xyz/openbmc_project/user", "xyz.openbmc_project.User.Manager",
+        "AllGroups",
+        [asyncResp, username, password{std::move(password)}, roleId,
+         enabled](const boost::system::error_code ec,
+                  const std::vector<std::string>& allGroupsList) {
+        if (ec)
+        {
+            BMCWEB_LOG_DEBUG << "ERROR with async_method_call";
+            messages::internalError(asyncResp->res);
+            return;
+        }
+
+        if (allGroupsList.empty())
+        {
+            messages::internalError(asyncResp->res);
+            return;
+        }
+
+        crow::connections::systemBus->async_method_call(
+            [asyncResp, username, password](const boost::system::error_code ec2,
+                                            sdbusplus::message::message& m) {
+            if (ec2)
+            {
+                userErrorMessageHandler(m.get_error(), asyncResp, username, "");
+                return;
+            }
+
+            if (pamUpdatePassword(username, password) != PAM_SUCCESS)
+            {
+                // At this point we have a user that's been
+                // 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) {
+                    if (ec3)
+                    {
+                        messages::internalError(asyncResp->res);
+                        return;
+                    }
+
+                    // If password is invalid
+                    messages::propertyValueFormatError(asyncResp->res, password,
+                                                       "Password");
+                    },
+                    "xyz.openbmc_project.User.Manager", userPath,
+                    "xyz.openbmc_project.Object.Delete", "Delete");
+
+                BMCWEB_LOG_ERROR << "pamUpdatePassword Failed";
+                return;
+            }
+
+            messages::created(asyncResp->res);
+            asyncResp->res.addHeader(
+                "Location", "/redfish/v1/AccountService/Accounts/" + username);
+            },
+            "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+            "xyz.openbmc_project.User.Manager", "CreateUser", username,
+            allGroupsList, *roleId, *enabled);
+        });
+}
+
+inline void
+    handleAccountGet(App& app, const crow::Request& req,
+                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                     const std::string& accountName)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+#ifdef BMCWEB_INSECURE_DISABLE_AUTHENTICATION
+    // If authentication is disabled, there are no user accounts
+    messages::resourceNotFound(
+        asyncResp->res, "#ManagerAccount.v1_4_0.ManagerAccount", accountName);
+    return;
+
+#endif // BMCWEB_INSECURE_DISABLE_AUTHENTICATION
+    if (req.session == nullptr)
+    {
+        messages::internalError(asyncResp->res);
+        return;
+    }
+    if (req.session->username != accountName)
+    {
+        // At this point we've determined that the user is trying to
+        // modify a user that isn't them.  We need to verify that they
+        // have permissions to modify other users, so re-run the auth
+        // check with the same permissions, minus ConfigureSelf.
+        Privileges effectiveUserPrivileges =
+            redfish::getUserPrivileges(req.userRole);
+        Privileges requiredPermissionsToChangeNonSelf = {"ConfigureUsers",
+                                                         "ConfigureManager"};
+        if (!effectiveUserPrivileges.isSupersetOf(
+                requiredPermissionsToChangeNonSelf))
+        {
+            BMCWEB_LOG_DEBUG << "GET Account denied access";
+            messages::insufficientPrivilege(asyncResp->res);
+            return;
+        }
+    }
+
+    crow::connections::systemBus->async_method_call(
+        [asyncResp,
+         accountName](const boost::system::error_code ec,
+                      const dbus::utility::ManagedObjectType& users) {
+        if (ec)
+        {
+            messages::internalError(asyncResp->res);
+            return;
+        }
+        const auto userIt = std::find_if(
+            users.begin(), users.end(),
+            [accountName](
+                const std::pair<sdbusplus::message::object_path,
+                                dbus::utility::DBusInteracesMap>& user) {
+            return accountName == user.first.filename();
+            });
+
+        if (userIt == users.end())
+        {
+            messages::resourceNotFound(asyncResp->res, "ManagerAccount",
+                                       accountName);
+            return;
+        }
+
+        asyncResp->res.jsonValue["@odata.type"] =
+            "#ManagerAccount.v1_4_0.ManagerAccount";
+        asyncResp->res.jsonValue["Name"] = "User Account";
+        asyncResp->res.jsonValue["Description"] = "User Account";
+        asyncResp->res.jsonValue["Password"] = nullptr;
+        asyncResp->res.jsonValue["AccountTypes"] = {"Redfish"};
+
+        for (const auto& interface : userIt->second)
+        {
+            if (interface.first == "xyz.openbmc_project.User.Attributes")
+            {
+                for (const auto& property : interface.second)
+                {
+                    if (property.first == "UserEnabled")
+                    {
+                        const bool* userEnabled =
+                            std::get_if<bool>(&property.second);
+                        if (userEnabled == nullptr)
+                        {
+                            BMCWEB_LOG_ERROR << "UserEnabled wasn't a bool";
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        asyncResp->res.jsonValue["Enabled"] = *userEnabled;
+                    }
+                    else if (property.first == "UserLockedForFailedAttempt")
+                    {
+                        const bool* userLocked =
+                            std::get_if<bool>(&property.second);
+                        if (userLocked == nullptr)
+                        {
+                            BMCWEB_LOG_ERROR << "UserLockedForF"
+                                                "ailedAttempt "
+                                                "wasn't a bool";
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        asyncResp->res.jsonValue["Locked"] = *userLocked;
+                        asyncResp->res
+                            .jsonValue["Locked@Redfish.AllowableValues"] = {
+                            "false"}; // can only unlock accounts
+                    }
+                    else if (property.first == "UserPrivilege")
+                    {
+                        const std::string* userPrivPtr =
+                            std::get_if<std::string>(&property.second);
+                        if (userPrivPtr == nullptr)
+                        {
+                            BMCWEB_LOG_ERROR << "UserPrivilege wasn't a "
+                                                "string";
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        std::string role = getRoleIdFromPrivilege(*userPrivPtr);
+                        if (role.empty())
+                        {
+                            BMCWEB_LOG_ERROR << "Invalid user role";
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        asyncResp->res.jsonValue["RoleId"] = role;
+
+                        nlohmann::json& roleEntry =
+                            asyncResp->res.jsonValue["Links"]["Role"];
+                        roleEntry["@odata.id"] =
+                            "/redfish/v1/AccountService/Roles/" + role;
+                    }
+                    else if (property.first == "UserPasswordExpired")
+                    {
+                        const bool* userPasswordExpired =
+                            std::get_if<bool>(&property.second);
+                        if (userPasswordExpired == nullptr)
+                        {
+                            BMCWEB_LOG_ERROR
+                                << "UserPasswordExpired wasn't a bool";
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        asyncResp->res.jsonValue["PasswordChangeRequired"] =
+                            *userPasswordExpired;
+                    }
+                }
+            }
+        }
+
+        asyncResp->res.jsonValue["@odata.id"] =
+            "/redfish/v1/AccountService/Accounts/" + accountName;
+        asyncResp->res.jsonValue["Id"] = accountName;
+        asyncResp->res.jsonValue["UserName"] = accountName;
+        },
+        "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+}
+
+inline void
+    handleAccounttDelete(App& app, const crow::Request& req,
+                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                         const std::string& username)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+
+#ifdef BMCWEB_INSECURE_DISABLE_AUTHENTICATION
+    // If authentication is disabled, there are no user accounts
+    messages::resourceNotFound(
+        asyncResp->res, "#ManagerAccount.v1_4_0.ManagerAccount", username);
+    return;
+
+#endif // BMCWEB_INSECURE_DISABLE_AUTHENTICATION
+    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) {
+        if (ec)
+        {
+            messages::resourceNotFound(asyncResp->res,
+                                       "#ManagerAccount.v1_4_0.ManagerAccount",
+                                       username);
+            return;
+        }
+
+        messages::accountRemoved(asyncResp->res);
+        },
+        "xyz.openbmc_project.User.Manager", userPath,
+        "xyz.openbmc_project.Object.Delete", "Delete");
+}
+
+inline void
+    handleAccountPatch(App& app, const crow::Request& req,
+                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                       const std::string& username)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+#ifdef BMCWEB_INSECURE_DISABLE_AUTHENTICATION
+    // If authentication is disabled, there are no user accounts
+    messages::resourceNotFound(
+        asyncResp->res, "#ManagerAccount.v1_4_0.ManagerAccount", username);
+    return;
+
+#endif // BMCWEB_INSECURE_DISABLE_AUTHENTICATION
+    std::optional<std::string> newUserName;
+    std::optional<std::string> password;
+    std::optional<bool> enabled;
+    std::optional<std::string> roleId;
+    std::optional<bool> locked;
+
+    if (req.session == nullptr)
+    {
+        messages::internalError(asyncResp->res);
+        return;
+    }
+
+    Privileges effectiveUserPrivileges =
+        redfish::getUserPrivileges(req.userRole);
+    Privileges configureUsers = {"ConfigureUsers"};
+    bool userHasConfigureUsers =
+        effectiveUserPrivileges.isSupersetOf(configureUsers);
+    if (userHasConfigureUsers)
+    {
+        // Users with ConfigureUsers can modify for all users
+        if (!json_util::readJsonPatch(req, asyncResp->res, "UserName",
+                                      newUserName, "Password", password,
+                                      "RoleId", roleId, "Enabled", enabled,
+                                      "Locked", locked))
+        {
+            return;
+        }
+    }
+    else
+    {
+        // ConfigureSelf accounts can only modify their own account
+        if (username != req.session->username)
+        {
+            messages::insufficientPrivilege(asyncResp->res);
+            return;
+        }
+
+        // ConfigureSelf accounts can only modify their password
+        if (!json_util::readJsonPatch(req, asyncResp->res, "Password",
+                                      password))
+        {
+            return;
+        }
+    }
+
+    // if user name is not provided in the patch method or if it
+    // matches the user name in the URI, then we are treating it as
+    // updating user properties other then username. If username
+    // provided doesn't match the URI, then we are treating this as
+    // user rename request.
+    if (!newUserName || (newUserName.value() == username))
+    {
+        updateUserProperties(asyncResp, username, password, enabled, roleId,
+                             locked);
+        return;
+    }
+    crow::connections::systemBus->async_method_call(
+        [asyncResp, username, password(std::move(password)),
+         roleId(std::move(roleId)), enabled, newUser{std::string(*newUserName)},
+         locked](const boost::system::error_code ec,
+                 sdbusplus::message::message& m) {
+        if (ec)
+        {
+            userErrorMessageHandler(m.get_error(), asyncResp, newUser,
+                                    username);
+            return;
+        }
+
+        updateUserProperties(asyncResp, newUser, password, enabled, roleId,
+                             locked);
+        },
+        "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+        "xyz.openbmc_project.User.Manager", "RenameUser", username,
+        *newUserName);
+}
+
 inline void requestAccountServiceRoutes(App& app)
 {
 
     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/")
         .privileges(redfish::privileges::getAccountService)
         .methods(boost::beast::http::verb::get)(
-            [&app](
-                const crow::Request& req,
-                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) -> void {
-                if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-                {
-                    return;
-                }
-                const persistent_data::AuthConfigMethods& authMethodsConfig =
-                    persistent_data::SessionStore::getInstance()
-                        .getAuthMethodsConfig();
-
-                nlohmann::json& json = asyncResp->res.jsonValue;
-                json["@odata.id"] = "/redfish/v1/AccountService";
-                json["@odata.type"] = "#AccountService."
-                                      "v1_10_0.AccountService";
-                json["Id"] = "AccountService";
-                json["Name"] = "Account Service";
-                json["Description"] = "Account Service";
-                json["ServiceEnabled"] = true;
-                json["MaxPasswordLength"] = 20;
-                json["Accounts"]["@odata.id"] =
-                    "/redfish/v1/AccountService/Accounts";
-                json["Roles"]["@odata.id"] = "/redfish/v1/AccountService/Roles";
-                json["Oem"]["OpenBMC"]["@odata.type"] =
-                    "#OemAccountService.v1_0_0.AccountService";
-                json["Oem"]["OpenBMC"]["@odata.id"] =
-                    "/redfish/v1/AccountService#/Oem/OpenBMC";
-                json["Oem"]["OpenBMC"]["AuthMethods"]["BasicAuth"] =
-                    authMethodsConfig.basic;
-                json["Oem"]["OpenBMC"]["AuthMethods"]["SessionToken"] =
-                    authMethodsConfig.sessionToken;
-                json["Oem"]["OpenBMC"]["AuthMethods"]["XToken"] =
-                    authMethodsConfig.xtoken;
-                json["Oem"]["OpenBMC"]["AuthMethods"]["Cookie"] =
-                    authMethodsConfig.cookie;
-                json["Oem"]["OpenBMC"]["AuthMethods"]["TLS"] =
-                    authMethodsConfig.tls;
-
-                // /redfish/v1/AccountService/LDAP/Certificates is something
-                // only ConfigureManager can access then only display when the
-                // user has permissions ConfigureManager
-                Privileges effectiveUserPrivileges =
-                    redfish::getUserPrivileges(req.userRole);
-
-                if (isOperationAllowedWithPrivileges({{"ConfigureManager"}},
-                                                     effectiveUserPrivileges))
-                {
-                    asyncResp->res
-                        .jsonValue["LDAP"]["Certificates"]["@odata.id"] =
-                        "/redfish/v1/AccountService/LDAP/Certificates";
-                }
-                crow::connections::systemBus->async_method_call(
-                    [asyncResp](const boost::system::error_code ec,
-                                const dbus::utility::DBusPropertiesMap&
-                                    propertiesList) {
-            if (ec)
-            {
-                messages::internalError(asyncResp->res);
-                return;
-            }
-            BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
-                             << "properties for AccountService";
-            for (const std::pair<std::string, dbus::utility::DbusVariantType>&
-                     property : propertiesList)
-            {
-                if (property.first == "MinPasswordLength")
-                {
-                    const uint8_t* value =
-                        std::get_if<uint8_t>(&property.second);
-                    if (value != nullptr)
-                    {
-                        asyncResp->res.jsonValue["MinPasswordLength"] = *value;
-                    }
-                }
-                if (property.first == "AccountUnlockTimeout")
-                {
-                    const uint32_t* value =
-                        std::get_if<uint32_t>(&property.second);
-                    if (value != nullptr)
-                    {
-                        asyncResp->res.jsonValue["AccountLockoutDuration"] =
-                            *value;
-                    }
-                }
-                if (property.first == "MaxLoginAttemptBeforeLockout")
-                {
-                    const uint16_t* value =
-                        std::get_if<uint16_t>(&property.second);
-                    if (value != nullptr)
-                    {
-                        asyncResp->res.jsonValue["AccountLockoutThreshold"] =
-                            *value;
-                    }
-                }
-            }
-                    },
-                    "xyz.openbmc_project.User.Manager",
-                    "/xyz/openbmc_project/user",
-                    "org.freedesktop.DBus.Properties", "GetAll",
-                    "xyz.openbmc_project.User.AccountPolicy");
-
-                auto callback =
-                    [asyncResp](bool success, LDAPConfigData& confData,
-                                const std::string& ldapType) {
-            if (!success)
-            {
-                return;
-            }
-            parseLDAPConfigData(asyncResp->res.jsonValue, confData, ldapType);
-                };
-
-                getLDAPConfigData("LDAP", callback);
-                getLDAPConfigData("ActiveDirectory", callback);
-            });
+            std::bind_front(handleAccountServiceGet, std::ref(app)));
 
     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/")
         .privileges(redfish::privileges::patchAccountService)
         .methods(boost::beast::http::verb::patch)(
-            [&app](
-                const crow::Request& req,
-                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) -> void {
-                if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-                {
-                    return;
-                }
-                std::optional<uint32_t> unlockTimeout;
-                std::optional<uint16_t> lockoutThreshold;
-                std::optional<uint8_t> minPasswordLength;
-                std::optional<uint16_t> maxPasswordLength;
-                std::optional<nlohmann::json> ldapObject;
-                std::optional<nlohmann::json> activeDirectoryObject;
-                std::optional<nlohmann::json> oemObject;
-
-                if (!json_util::readJsonPatch(
-                        req, asyncResp->res, "AccountLockoutDuration",
-                        unlockTimeout, "AccountLockoutThreshold",
-                        lockoutThreshold, "MaxPasswordLength",
-                        maxPasswordLength, "MinPasswordLength",
-                        minPasswordLength, "LDAP", ldapObject,
-                        "ActiveDirectory", activeDirectoryObject, "Oem",
-                        oemObject))
-                {
-                    return;
-                }
-
-                if (minPasswordLength)
-                {
-                    crow::connections::systemBus->async_method_call(
-                        [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                messages::success(asyncResp->res);
-                        },
-                        "xyz.openbmc_project.User.Manager",
-                        "/xyz/openbmc_project/user",
-                        "org.freedesktop.DBus.Properties", "Set",
-                        "xyz.openbmc_project.User.AccountPolicy",
-                        "MinPasswordLength",
-                        dbus::utility::DbusVariantType(*minPasswordLength));
-                }
-
-                if (maxPasswordLength)
-                {
-                    messages::propertyNotWritable(asyncResp->res,
-                                                  "MaxPasswordLength");
-                }
-
-                if (ldapObject)
-                {
-                    handleLDAPPatch(*ldapObject, asyncResp, "LDAP");
-                }
-
-                if (std::optional<nlohmann::json> oemOpenBMCObject;
-                    oemObject &&
-                    json_util::readJson(*oemObject, asyncResp->res, "OpenBMC",
-                                        oemOpenBMCObject))
-                {
-                    if (std::optional<nlohmann::json> authMethodsObject;
-                        oemOpenBMCObject &&
-                        json_util::readJson(*oemOpenBMCObject, asyncResp->res,
-                                            "AuthMethods", authMethodsObject))
-                    {
-                        if (authMethodsObject)
-                        {
-                            handleAuthMethodsPatch(*authMethodsObject,
-                                                   asyncResp);
-                        }
-                    }
-                }
-
-                if (activeDirectoryObject)
-                {
-                    handleLDAPPatch(*activeDirectoryObject, asyncResp,
-                                    "ActiveDirectory");
-                }
-
-                if (unlockTimeout)
-                {
-                    crow::connections::systemBus->async_method_call(
-                        [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                messages::success(asyncResp->res);
-                        },
-                        "xyz.openbmc_project.User.Manager",
-                        "/xyz/openbmc_project/user",
-                        "org.freedesktop.DBus.Properties", "Set",
-                        "xyz.openbmc_project.User.AccountPolicy",
-                        "AccountUnlockTimeout",
-                        dbus::utility::DbusVariantType(*unlockTimeout));
-                }
-                if (lockoutThreshold)
-                {
-                    crow::connections::systemBus->async_method_call(
-                        [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                messages::success(asyncResp->res);
-                        },
-                        "xyz.openbmc_project.User.Manager",
-                        "/xyz/openbmc_project/user",
-                        "org.freedesktop.DBus.Properties", "Set",
-                        "xyz.openbmc_project.User.AccountPolicy",
-                        "MaxLoginAttemptBeforeLockout",
-                        dbus::utility::DbusVariantType(*lockoutThreshold));
-                }
-            });
+            std::bind_front(handleAccountServicePatch, std::ref(app)));
 
     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/")
         .privileges(redfish::privileges::getManagerAccountCollection)
         .methods(boost::beast::http::verb::get)(
-            [&app](
-                const crow::Request& req,
-                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) -> void {
-                if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-                {
-                    return;
-                }
-
-                asyncResp->res.jsonValue["@odata.id"] =
-                    "/redfish/v1/AccountService/Accounts";
-                asyncResp->res.jsonValue["@odata.type"] =
-                    "#ManagerAccountCollection."
-                    "ManagerAccountCollection";
-                asyncResp->res.jsonValue["Name"] = "Accounts Collection";
-                asyncResp->res.jsonValue["Description"] = "BMC User Accounts";
-
-                Privileges effectiveUserPrivileges =
-                    redfish::getUserPrivileges(req.userRole);
-
-                std::string thisUser;
-                if (req.session)
-                {
-                    thisUser = req.session->username;
-                }
-                crow::connections::systemBus->async_method_call(
-                    [asyncResp, thisUser, effectiveUserPrivileges](
-                        const boost::system::error_code ec,
-                        const dbus::utility::ManagedObjectType& users) {
-            if (ec)
-            {
-                messages::internalError(asyncResp->res);
-                return;
-            }
-
-            bool userCanSeeAllAccounts =
-                effectiveUserPrivileges.isSupersetOf({"ConfigureUsers"});
-
-            bool userCanSeeSelf =
-                effectiveUserPrivileges.isSupersetOf({"ConfigureSelf"});
-
-            nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
-            memberArray = nlohmann::json::array();
-
-            for (const auto& userpath : users)
-            {
-                std::string user = userpath.first.filename();
-                if (user.empty())
-                {
-                    messages::internalError(asyncResp->res);
-                    BMCWEB_LOG_ERROR << "Invalid firmware ID";
-
-                    return;
-                }
-
-                // As clarified by Redfish here:
-                // https://redfishforum.com/thread/281/manageraccountcollection-change-allows-account-enumeration
-                // Users without ConfigureUsers, only see their own
-                // account. Users with ConfigureUsers, see all
-                // accounts.
-                if (userCanSeeAllAccounts ||
-                    (thisUser == user && userCanSeeSelf))
-                {
-                    nlohmann::json::object_t member;
-                    member["@odata.id"] =
-                        "/redfish/v1/AccountService/Accounts/" + user;
-                    memberArray.push_back(std::move(member));
-                }
-            }
-            asyncResp->res.jsonValue["Members@odata.count"] =
-                memberArray.size();
-                    },
-                    "xyz.openbmc_project.User.Manager",
-                    "/xyz/openbmc_project/user",
-                    "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-            });
+            std::bind_front(handleAccountCollectionGet, std::ref(app)));
 
     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/")
         .privileges(redfish::privileges::postManagerAccountCollection)
         .methods(boost::beast::http::verb::post)(
-            [&app](
-                const crow::Request& req,
-                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) -> void {
-                if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-                {
-                    return;
-                }
-                std::string username;
-                std::string password;
-                std::optional<std::string> roleId("User");
-                std::optional<bool> enabled = true;
-                if (!json_util::readJsonPatch(
-                        req, asyncResp->res, "UserName", username, "Password",
-                        password, "RoleId", roleId, "Enabled", enabled))
-                {
-                    return;
-                }
-
-                std::string priv = getPrivilegeFromRoleId(*roleId);
-                if (priv.empty())
-                {
-                    messages::propertyValueNotInList(asyncResp->res, *roleId,
-                                                     "RoleId");
-                    return;
-                }
-                // TODO: Following override will be reverted once support in
-                // phosphor-user-manager is added. In order to avoid dependency
-                // issues, this is added in bmcweb, which will removed, once
-                // phosphor-user-manager supports priv-noaccess.
-                if (priv == "priv-noaccess")
-                {
-                    roleId = "";
-                }
-                else
-                {
-                    roleId = priv;
-                }
-
-                // Reading AllGroups property
-                sdbusplus::asio::getProperty<std::vector<std::string>>(
-                    *crow::connections::systemBus,
-                    "xyz.openbmc_project.User.Manager",
-                    "/xyz/openbmc_project/user",
-                    "xyz.openbmc_project.User.Manager", "AllGroups",
-                    [asyncResp, username, password{std::move(password)}, roleId,
-                     enabled](const boost::system::error_code ec,
-                              const std::vector<std::string>& allGroupsList) {
-            if (ec)
-            {
-                BMCWEB_LOG_DEBUG << "ERROR with async_method_call";
-                messages::internalError(asyncResp->res);
-                return;
-            }
-
-            if (allGroupsList.empty())
-            {
-                messages::internalError(asyncResp->res);
-                return;
-            }
-
-            crow::connections::systemBus->async_method_call(
-                [asyncResp, username,
-                 password](const boost::system::error_code ec2,
-                           sdbusplus::message::message& m) {
-                if (ec2)
-                {
-                    userErrorMessageHandler(m.get_error(), asyncResp, username,
-                                            "");
-                    return;
-                }
-
-                if (pamUpdatePassword(username, password) != PAM_SUCCESS)
-                {
-                    // At this point we have a user that's been
-                    // 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) {
-                        if (ec3)
-                        {
-                            messages::internalError(asyncResp->res);
-                            return;
-                        }
-
-                        // If password is invalid
-                        messages::propertyValueFormatError(
-                            asyncResp->res, password, "Password");
-                        },
-                        "xyz.openbmc_project.User.Manager", userPath,
-                        "xyz.openbmc_project.Object.Delete", "Delete");
-
-                    BMCWEB_LOG_ERROR << "pamUpdatePassword Failed";
-                    return;
-                }
-
-                messages::created(asyncResp->res);
-                asyncResp->res.addHeader(
-                    "Location",
-                    "/redfish/v1/AccountService/Accounts/" + username);
-                },
-                "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
-                "xyz.openbmc_project.User.Manager", "CreateUser", username,
-                allGroupsList, *roleId, *enabled);
-                    });
-            });
+            std::bind_front(handleAccountCollectionPost, std::ref(app)));
 
     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/")
         .privileges(redfish::privileges::getManagerAccount)
         .methods(boost::beast::http::verb::get)(
-            [&app]([[maybe_unused]] const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& accountName) -> void {
-                if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-                {
-                    return;
-                }
-#ifdef BMCWEB_INSECURE_DISABLE_AUTHX
-                // If authentication is disabled, there are no user accounts
-                messages::resourceNotFound(
-                    asyncResp->res, "#ManagerAccount.v1_4_0.ManagerAccount",
-                    accountName);
-                return;
-
-#endif // BMCWEB_INSECURE_DISABLE_AUTHX
-                if (req.session == nullptr)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                if (req.session->username != accountName)
-                {
-                    // At this point we've determined that the user is trying to
-                    // modify a user that isn't them.  We need to verify that
-                    // they have permissions to modify other users, so re-run
-                    // the auth check with the same permissions, minus
-                    // ConfigureSelf.
-                    Privileges effectiveUserPrivileges =
-                        redfish::getUserPrivileges(req.userRole);
-                    Privileges requiredPermissionsToChangeNonSelf = {
-                        "ConfigureUsers", "ConfigureManager"};
-                    if (!effectiveUserPrivileges.isSupersetOf(
-                            requiredPermissionsToChangeNonSelf))
-                    {
-                        BMCWEB_LOG_DEBUG << "GET Account denied access";
-                        messages::insufficientPrivilege(asyncResp->res);
-                        return;
-                    }
-                }
-
-                crow::connections::systemBus->async_method_call(
-                    [asyncResp, accountName](
-                        const boost::system::error_code ec,
-                        const dbus::utility::ManagedObjectType& users) {
-            if (ec)
-            {
-                messages::internalError(asyncResp->res);
-                return;
-            }
-            const auto userIt = std::find_if(
-                users.begin(), users.end(),
-                [accountName](
-                    const std::pair<sdbusplus::message::object_path,
-                                    dbus::utility::DBusInteracesMap>& user) {
-                return accountName == user.first.filename();
-                });
-
-            if (userIt == users.end())
-            {
-                messages::resourceNotFound(asyncResp->res, "ManagerAccount",
-                                           accountName);
-                return;
-            }
-
-            asyncResp->res.jsonValue["@odata.type"] =
-                "#ManagerAccount.v1_4_0.ManagerAccount";
-            asyncResp->res.jsonValue["Name"] = "User Account";
-            asyncResp->res.jsonValue["Description"] = "User Account";
-            asyncResp->res.jsonValue["Password"] = nullptr;
-            asyncResp->res.jsonValue["AccountTypes"] = {"Redfish"};
-
-            for (const auto& interface : userIt->second)
-            {
-                if (interface.first == "xyz.openbmc_project.User.Attributes")
-                {
-                    for (const auto& property : interface.second)
-                    {
-                        if (property.first == "UserEnabled")
-                        {
-                            const bool* userEnabled =
-                                std::get_if<bool>(&property.second);
-                            if (userEnabled == nullptr)
-                            {
-                                BMCWEB_LOG_ERROR << "UserEnabled wasn't a bool";
-                                messages::internalError(asyncResp->res);
-                                return;
-                            }
-                            asyncResp->res.jsonValue["Enabled"] = *userEnabled;
-                        }
-                        else if (property.first == "UserLockedForFailedAttempt")
-                        {
-                            const bool* userLocked =
-                                std::get_if<bool>(&property.second);
-                            if (userLocked == nullptr)
-                            {
-                                BMCWEB_LOG_ERROR << "UserLockedForF"
-                                                    "ailedAttempt "
-                                                    "wasn't a bool";
-                                messages::internalError(asyncResp->res);
-                                return;
-                            }
-                            asyncResp->res.jsonValue["Locked"] = *userLocked;
-                            asyncResp->res
-                                .jsonValue["Locked@Redfish.AllowableValues"] = {
-                                "false"}; // can only unlock accounts
-                        }
-                        else if (property.first == "UserPrivilege")
-                        {
-                            const std::string* userPrivPtr =
-                                std::get_if<std::string>(&property.second);
-                            if (userPrivPtr == nullptr)
-                            {
-                                BMCWEB_LOG_ERROR << "UserPrivilege wasn't a "
-                                                    "string";
-                                messages::internalError(asyncResp->res);
-                                return;
-                            }
-                            std::string role =
-                                getRoleIdFromPrivilege(*userPrivPtr);
-                            if (role.empty())
-                            {
-                                BMCWEB_LOG_ERROR << "Invalid user role";
-                                messages::internalError(asyncResp->res);
-                                return;
-                            }
-                            asyncResp->res.jsonValue["RoleId"] = role;
-
-                            nlohmann::json& roleEntry =
-                                asyncResp->res.jsonValue["Links"]["Role"];
-                            roleEntry["@odata.id"] =
-                                "/redfish/v1/AccountService/Roles/" + role;
-                        }
-                        else if (property.first == "UserPasswordExpired")
-                        {
-                            const bool* userPasswordExpired =
-                                std::get_if<bool>(&property.second);
-                            if (userPasswordExpired == nullptr)
-                            {
-                                BMCWEB_LOG_ERROR
-                                    << "UserPasswordExpired wasn't a bool";
-                                messages::internalError(asyncResp->res);
-                                return;
-                            }
-                            asyncResp->res.jsonValue["PasswordChangeRequired"] =
-                                *userPasswordExpired;
-                        }
-                    }
-                }
-            }
-
-            asyncResp->res.jsonValue["@odata.id"] =
-                "/redfish/v1/AccountService/Accounts/" + accountName;
-            asyncResp->res.jsonValue["Id"] = accountName;
-            asyncResp->res.jsonValue["UserName"] = accountName;
-                    },
-                    "xyz.openbmc_project.User.Manager",
-                    "/xyz/openbmc_project/user",
-                    "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-            });
+            std::bind_front(handleAccountGet, std::ref(app)));
 
     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/")
         // TODO this privilege should be using the generated endpoints, but
@@ -1845,137 +1951,12 @@
         // yet
         .privileges({{"ConfigureUsers"}, {"ConfigureSelf"}})
         .methods(boost::beast::http::verb::patch)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& username) -> void {
-                if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-                {
-                    return;
-                }
-#ifdef BMCWEB_INSECURE_DISABLE_AUTHX
-                // If authentication is disabled, there are no user accounts
-                messages::resourceNotFound(
-                    asyncResp->res, "#ManagerAccount.v1_4_0.ManagerAccount",
-                    username);
-                return;
-
-#endif // BMCWEB_INSECURE_DISABLE_AUTHX
-                std::optional<std::string> newUserName;
-                std::optional<std::string> password;
-                std::optional<bool> enabled;
-                std::optional<std::string> roleId;
-                std::optional<bool> locked;
-
-                if (req.session == nullptr)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                Privileges effectiveUserPrivileges =
-                    redfish::getUserPrivileges(req.userRole);
-                Privileges configureUsers = {"ConfigureUsers"};
-                bool userHasConfigureUsers =
-                    effectiveUserPrivileges.isSupersetOf(configureUsers);
-                if (userHasConfigureUsers)
-                {
-                    // Users with ConfigureUsers can modify for all users
-                    if (!json_util::readJsonPatch(
-                            req, asyncResp->res, "UserName", newUserName,
-                            "Password", password, "RoleId", roleId, "Enabled",
-                            enabled, "Locked", locked))
-                    {
-                        return;
-                    }
-                }
-                else
-                {
-                    // ConfigureSelf accounts can only modify their own account
-                    if (username != req.session->username)
-                    {
-                        messages::insufficientPrivilege(asyncResp->res);
-                        return;
-                    }
-
-                    // ConfigureSelf accounts can only modify their password
-                    if (!json_util::readJsonPatch(req, asyncResp->res,
-                                                  "Password", password))
-                    {
-                        return;
-                    }
-                }
-
-                // if user name is not provided in the patch method or if it
-                // matches the user name in the URI, then we are treating it as
-                // updating user properties other then username. If username
-                // provided doesn't match the URI, then we are treating this as
-                // user rename request.
-                if (!newUserName || (newUserName.value() == username))
-                {
-                    updateUserProperties(asyncResp, username, password, enabled,
-                                         roleId, locked);
-                    return;
-                }
-                crow::connections::systemBus->async_method_call(
-                    [asyncResp, username, password(std::move(password)),
-                     roleId(std::move(roleId)), enabled,
-                     newUser{std::string(*newUserName)},
-                     locked](const boost::system::error_code ec,
-                             sdbusplus::message::message& m) {
-            if (ec)
-            {
-                userErrorMessageHandler(m.get_error(), asyncResp, newUser,
-                                        username);
-                return;
-            }
-
-            updateUserProperties(asyncResp, newUser, password, enabled, roleId,
-                                 locked);
-                    },
-                    "xyz.openbmc_project.User.Manager",
-                    "/xyz/openbmc_project/user",
-                    "xyz.openbmc_project.User.Manager", "RenameUser", username,
-                    *newUserName);
-            });
+            std::bind_front(handleAccountPatch, std::ref(app)));
 
     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/")
         .privileges(redfish::privileges::deleteManagerAccount)
         .methods(boost::beast::http::verb::delete_)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& username) -> void {
-                if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-                {
-                    return;
-                }
-
-#ifdef BMCWEB_INSECURE_DISABLE_AUTHX
-                // If authentication is disabled, there are no user accounts
-                messages::resourceNotFound(
-                    asyncResp->res, "#ManagerAccount.v1_4_0.ManagerAccount",
-                    username);
-                return;
-
-#endif // BMCWEB_INSECURE_DISABLE_AUTHX
-                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) {
-            if (ec)
-            {
-                messages::resourceNotFound(
-                    asyncResp->res, "#ManagerAccount.v1_4_0.ManagerAccount",
-                    username);
-                return;
-            }
-
-            messages::accountRemoved(asyncResp->res);
-                    },
-                    "xyz.openbmc_project.User.Manager", userPath,
-                    "xyz.openbmc_project.Object.Delete", "Delete");
-            });
+            std::bind_front(handleAccounttDelete, std::ref(app)));
 }
 
 } // namespace redfish
