diff --git a/redfish-core/include/node.hpp b/redfish-core/include/node.hpp
index 1793a50..a1b7d72 100644
--- a/redfish-core/include/node.hpp
+++ b/redfish-core/include/node.hpp
@@ -218,36 +218,6 @@
     {
         asyncResp->res.result(boost::beast::http::status::method_not_allowed);
     }
-
-    /* @brief Would the operation be allowed if the user did not have the
-     * ConfigureSelf Privilege?  Also honors session.isConfigureSelfOnly.
-     *
-     * @param req      the request
-     *
-     * @returns        True if allowed, false otherwise
-     */
-    inline bool isAllowedWithoutConfigureSelf(const crow::Request& req)
-    {
-        const std::string& userRole = req.userRole;
-        BMCWEB_LOG_DEBUG << "isAllowedWithoutConfigureSelf for the role "
-                         << req.userRole;
-        Privileges effectiveUserPrivileges;
-        if (req.session && req.session->isConfigureSelfOnly)
-        {
-            // The session has no privileges because it is limited to
-            // configureSelfOnly and we are disregarding that privilege.
-            // Note that some operations do not require any privilege.
-        }
-        else
-        {
-            effectiveUserPrivileges = redfish::getUserPrivileges(userRole);
-            effectiveUserPrivileges.resetSinglePrivilege("ConfigureSelf");
-        }
-        const auto& requiredPrivilegesIt = entityPrivileges.find(req.method());
-        return (requiredPrivilegesIt != entityPrivileges.end()) &&
-               isOperationAllowedWithPrivileges(requiredPrivilegesIt->second,
-                                                effectiveUserPrivileges);
-    }
 };
 
 } // namespace redfish
diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index 7429b77..2ff7b62 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -63,10 +63,7 @@
      */
     RedfishService(App& app)
     {
-        nodes.emplace_back(std::make_unique<AccountService>(app));
-        nodes.emplace_back(std::make_unique<AccountsCollection>(app));
-        nodes.emplace_back(std::make_unique<ManagerAccount>(app));
-        nodes.emplace_back(std::make_unique<SessionCollection>(app));
+        requestAccountServiceRoutes(app);
         requestRoutesRoles(app);
         requestRoutesRoleCollection(app);
         requestRoutesServiceRoot(app);
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 2e81104..4c639ad 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -558,1398 +558,1262 @@
         ldapConfigObjectName, interfaces);
 }
 
-class AccountService : public Node
+/**
+ * @brief parses the authentication section under the LDAP
+ * @param input JSON data
+ * @param asyncResp pointer to the JSON response
+ * @param userName  userName to be filled from the given JSON.
+ * @param password  password to be filled from the given JSON.
+ */
+void parseLDAPAuthenticationJson(
+    nlohmann::json input, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    std::optional<std::string>& username, std::optional<std::string>& password)
 {
-  public:
-    AccountService(App& app) : Node(app, "/redfish/v1/AccountService/")
+    std::optional<std::string> authType;
+
+    if (!json_util::readJson(input, asyncResp->res, "AuthenticationType",
+                             authType, "Username", username, "Password",
+                             password))
     {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureUsers"}}},
-            {boost::beast::http::verb::put, {{"ConfigureUsers"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}},
-            {boost::beast::http::verb::post, {{"ConfigureUsers"}}}};
+        return;
     }
-
-  private:
-    /**
-     * @brief parses the authentication section under the LDAP
-     * @param input JSON data
-     * @param asyncResp pointer to the JSON response
-     * @param userName  userName to be filled from the given JSON.
-     * @param password  password to be filled from the given JSON.
-     */
-    void parseLDAPAuthenticationJson(
-        nlohmann::json input,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-        std::optional<std::string>& username,
-        std::optional<std::string>& password)
+    if (!authType)
     {
-        std::optional<std::string> authType;
-
-        if (!json_util::readJson(input, asyncResp->res, "AuthenticationType",
-                                 authType, "Username", username, "Password",
-                                 password))
-        {
-            return;
-        }
-        if (!authType)
-        {
-            return;
-        }
-        if (*authType != "UsernameAndPassword")
-        {
-            messages::propertyValueNotInList(asyncResp->res, *authType,
-                                             "AuthenticationType");
-            return;
-        }
+        return;
     }
-    /**
-     * @brief parses the LDAPService section under the LDAP
-     * @param input JSON data
-     * @param asyncResp pointer to the JSON response
-     * @param baseDNList baseDN to be filled from the given JSON.
-     * @param userNameAttribute  userName to be filled from the given JSON.
-     * @param groupaAttribute  password to be filled from the given JSON.
-     */
-
-    void parseLDAPServiceJson(
-        nlohmann::json input,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-        std::optional<std::vector<std::string>>& baseDNList,
-        std::optional<std::string>& userNameAttribute,
-        std::optional<std::string>& groupsAttribute)
+    if (*authType != "UsernameAndPassword")
     {
-        std::optional<nlohmann::json> searchSettings;
-
-        if (!json_util::readJson(input, asyncResp->res, "SearchSettings",
-                                 searchSettings))
-        {
-            return;
-        }
-        if (!searchSettings)
-        {
-            return;
-        }
-        if (!json_util::readJson(*searchSettings, asyncResp->res,
-                                 "BaseDistinguishedNames", baseDNList,
-                                 "UsernameAttribute", userNameAttribute,
-                                 "GroupsAttribute", groupsAttribute))
-        {
-            return;
-        }
+        messages::propertyValueNotInList(asyncResp->res, *authType,
+                                         "AuthenticationType");
+        return;
     }
-    /**
-     * @brief updates the LDAP server address and updates the
-              json response with the new value.
-     * @param serviceAddressList address to be updated.
-     * @param asyncResp pointer to the JSON response
-     * @param ldapServerElementName Type of LDAP
-     server(openLDAP/ActiveDirectory)
-     */
+}
+/**
+ * @brief parses the LDAPService section under the LDAP
+ * @param input JSON data
+ * @param asyncResp pointer to the JSON response
+ * @param baseDNList baseDN to be filled from the given JSON.
+ * @param userNameAttribute  userName to be filled from the given JSON.
+ * @param groupaAttribute  password to be filled from the given JSON.
+ */
 
-    void handleServiceAddressPatch(
-        const std::vector<std::string>& serviceAddressList,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-        const std::string& ldapServerElementName,
-        const std::string& ldapConfigObject)
+void parseLDAPServiceJson(nlohmann::json input,
+                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                          std::optional<std::vector<std::string>>& baseDNList,
+                          std::optional<std::string>& userNameAttribute,
+                          std::optional<std::string>& groupsAttribute)
+{
+    std::optional<nlohmann::json> searchSettings;
+
+    if (!json_util::readJson(input, asyncResp->res, "SearchSettings",
+                             searchSettings))
     {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, ldapServerElementName,
-             serviceAddressList](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_DEBUG
-                        << "Error Occurred in updating the service address";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                std::vector<std::string> modifiedserviceAddressList = {
-                    serviceAddressList.front()};
-                asyncResp->res
-                    .jsonValue[ldapServerElementName]["ServiceAddresses"] =
-                    modifiedserviceAddressList;
-                if ((serviceAddressList).size() > 1)
-                {
-                    messages::propertyValueModified(asyncResp->res,
-                                                    "ServiceAddresses",
-                                                    serviceAddressList.front());
-                }
-                BMCWEB_LOG_DEBUG << "Updated the service address";
-            },
-            ldapDbusService, ldapConfigObject, propertyInterface, "Set",
-            ldapConfigInterface, "LDAPServerURI",
-            std::variant<std::string>(serviceAddressList.front()));
+        return;
     }
-    /**
-     * @brief updates the LDAP Bind DN and updates the
-              json response with the new value.
-     * @param username name of the user which needs to be updated.
-     * @param asyncResp pointer to the JSON response
-     * @param ldapServerElementName Type of LDAP
-     server(openLDAP/ActiveDirectory)
-     */
-
-    void
-        handleUserNamePatch(const std::string& username,
-                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                            const std::string& ldapServerElementName,
-                            const std::string& ldapConfigObject)
+    if (!searchSettings)
     {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, username,
-             ldapServerElementName](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_DEBUG
-                        << "Error occurred in updating the username";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                asyncResp->res.jsonValue[ldapServerElementName]
-                                        ["Authentication"]["Username"] =
-                    username;
-                BMCWEB_LOG_DEBUG << "Updated the username";
-            },
-            ldapDbusService, ldapConfigObject, propertyInterface, "Set",
-            ldapConfigInterface, "LDAPBindDN",
-            std::variant<std::string>(username));
+        return;
     }
-
-    /**
-     * @brief updates the LDAP password
-     * @param password : ldap password which needs to be updated.
-     * @param asyncResp pointer to the JSON response
-     * @param ldapServerElementName Type of LDAP
-     *        server(openLDAP/ActiveDirectory)
-     */
-
-    void
-        handlePasswordPatch(const std::string& password,
-                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                            const std::string& ldapServerElementName,
-                            const std::string& ldapConfigObject)
+    if (!json_util::readJson(*searchSettings, asyncResp->res,
+                             "BaseDistinguishedNames", baseDNList,
+                             "UsernameAttribute", userNameAttribute,
+                             "GroupsAttribute", groupsAttribute))
     {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, password,
-             ldapServerElementName](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_DEBUG
-                        << "Error occurred in updating the password";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                asyncResp->res.jsonValue[ldapServerElementName]
-                                        ["Authentication"]["Password"] = "";
-                BMCWEB_LOG_DEBUG << "Updated the password";
-            },
-            ldapDbusService, ldapConfigObject, propertyInterface, "Set",
-            ldapConfigInterface, "LDAPBindDNPassword",
-            std::variant<std::string>(password));
+        return;
     }
+}
+/**
+ * @brief updates the LDAP server address and updates the
+          json response with the new value.
+ * @param serviceAddressList address to be updated.
+ * @param asyncResp pointer to the JSON response
+ * @param ldapServerElementName Type of LDAP
+ server(openLDAP/ActiveDirectory)
+ */
 
-    /**
-     * @brief updates the LDAP BaseDN and updates the
-              json response with the new value.
-     * @param baseDNList baseDN list which needs to be updated.
-     * @param asyncResp pointer to the JSON response
-     * @param ldapServerElementName Type of LDAP
-     server(openLDAP/ActiveDirectory)
-     */
+void handleServiceAddressPatch(
+    const std::vector<std::string>& serviceAddressList,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& ldapServerElementName,
+    const std::string& ldapConfigObject)
+{
+    crow::connections::systemBus->async_method_call(
+        [asyncResp, ldapServerElementName,
+         serviceAddressList](const boost::system::error_code ec) {
+            if (ec)
+            {
+                BMCWEB_LOG_DEBUG
+                    << "Error Occurred in updating the service address";
+                messages::internalError(asyncResp->res);
+                return;
+            }
+            std::vector<std::string> modifiedserviceAddressList = {
+                serviceAddressList.front()};
+            asyncResp->res
+                .jsonValue[ldapServerElementName]["ServiceAddresses"] =
+                modifiedserviceAddressList;
+            if ((serviceAddressList).size() > 1)
+            {
+                messages::propertyValueModified(asyncResp->res,
+                                                "ServiceAddresses",
+                                                serviceAddressList.front());
+            }
+            BMCWEB_LOG_DEBUG << "Updated the service address";
+        },
+        ldapDbusService, ldapConfigObject, propertyInterface, "Set",
+        ldapConfigInterface, "LDAPServerURI",
+        std::variant<std::string>(serviceAddressList.front()));
+}
+/**
+ * @brief updates the LDAP Bind DN and updates the
+          json response with the new value.
+ * @param username name of the user which needs to be updated.
+ * @param asyncResp pointer to the JSON response
+ * @param ldapServerElementName Type of LDAP
+ server(openLDAP/ActiveDirectory)
+ */
 
-    void handleBaseDNPatch(const std::vector<std::string>& baseDNList,
-                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                           const std::string& ldapServerElementName,
-                           const std::string& ldapConfigObject)
-    {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, baseDNList,
-             ldapServerElementName](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_DEBUG
-                        << "Error Occurred in Updating the base DN";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                auto& serverTypeJson =
-                    asyncResp->res.jsonValue[ldapServerElementName];
-                auto& searchSettingsJson =
-                    serverTypeJson["LDAPService"]["SearchSettings"];
-                std::vector<std::string> modifiedBaseDNList = {
-                    baseDNList.front()};
-                searchSettingsJson["BaseDistinguishedNames"] =
-                    modifiedBaseDNList;
-                if (baseDNList.size() > 1)
-                {
-                    messages::propertyValueModified(asyncResp->res,
-                                                    "BaseDistinguishedNames",
-                                                    baseDNList.front());
-                }
-                BMCWEB_LOG_DEBUG << "Updated the base DN";
-            },
-            ldapDbusService, ldapConfigObject, propertyInterface, "Set",
-            ldapConfigInterface, "LDAPBaseDN",
-            std::variant<std::string>(baseDNList.front()));
-    }
-    /**
-     * @brief updates the LDAP user name attribute and updates the
-              json response with the new value.
-     * @param userNameAttribute attribute to be updated.
-     * @param asyncResp pointer to the JSON response
-     * @param ldapServerElementName Type of LDAP
-     server(openLDAP/ActiveDirectory)
-     */
-
-    void handleUserNameAttrPatch(
-        const std::string& userNameAttribute,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-        const std::string& ldapServerElementName,
-        const std::string& ldapConfigObject)
-    {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, userNameAttribute,
-             ldapServerElementName](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_DEBUG << "Error Occurred in Updating the "
-                                        "username attribute";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                auto& serverTypeJson =
-                    asyncResp->res.jsonValue[ldapServerElementName];
-                auto& searchSettingsJson =
-                    serverTypeJson["LDAPService"]["SearchSettings"];
-                searchSettingsJson["UsernameAttribute"] = userNameAttribute;
-                BMCWEB_LOG_DEBUG << "Updated the user name attr.";
-            },
-            ldapDbusService, ldapConfigObject, propertyInterface, "Set",
-            ldapConfigInterface, "UserNameAttribute",
-            std::variant<std::string>(userNameAttribute));
-    }
-    /**
-     * @brief updates the LDAP group attribute and updates the
-              json response with the new value.
-     * @param groupsAttribute attribute to be updated.
-     * @param asyncResp pointer to the JSON response
-     * @param ldapServerElementName Type of LDAP
-     server(openLDAP/ActiveDirectory)
-     */
-
-    void handleGroupNameAttrPatch(
-        const std::string& groupsAttribute,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-        const std::string& ldapServerElementName,
-        const std::string& ldapConfigObject)
-    {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, groupsAttribute,
-             ldapServerElementName](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_DEBUG << "Error Occurred in Updating the "
-                                        "groupname attribute";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                auto& serverTypeJson =
-                    asyncResp->res.jsonValue[ldapServerElementName];
-                auto& searchSettingsJson =
-                    serverTypeJson["LDAPService"]["SearchSettings"];
-                searchSettingsJson["GroupsAttribute"] = groupsAttribute;
-                BMCWEB_LOG_DEBUG << "Updated the groupname attr";
-            },
-            ldapDbusService, ldapConfigObject, propertyInterface, "Set",
-            ldapConfigInterface, "GroupNameAttribute",
-            std::variant<std::string>(groupsAttribute));
-    }
-    /**
-     * @brief updates the LDAP service enable and updates the
-              json response with the new value.
-     * @param input JSON data.
-     * @param asyncResp pointer to the JSON response
-     * @param ldapServerElementName Type of LDAP
-     server(openLDAP/ActiveDirectory)
-     */
-
-    void handleServiceEnablePatch(
-        bool serviceEnabled,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-        const std::string& ldapServerElementName,
-        const std::string& ldapConfigObject)
-    {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, serviceEnabled,
-             ldapServerElementName](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_DEBUG
-                        << "Error Occurred in Updating the service enable";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                asyncResp->res
-                    .jsonValue[ldapServerElementName]["ServiceEnabled"] =
-                    serviceEnabled;
-                BMCWEB_LOG_DEBUG << "Updated Service enable = "
-                                 << serviceEnabled;
-            },
-            ldapDbusService, ldapConfigObject, propertyInterface, "Set",
-            ldapEnableInterface, "Enabled", std::variant<bool>(serviceEnabled));
-    }
-
-    void handleAuthMethodsPatch(
-        nlohmann::json& input,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        std::optional<bool> basicAuth;
-        std::optional<bool> cookie;
-        std::optional<bool> sessionToken;
-        std::optional<bool> xToken;
-        std::optional<bool> tls;
-
-        if (!json_util::readJson(input, asyncResp->res, "BasicAuth", basicAuth,
-                                 "Cookie", cookie, "SessionToken", sessionToken,
-                                 "XToken", xToken, "TLS", tls))
-        {
-            BMCWEB_LOG_ERROR << "Cannot read values from AuthMethod tag";
-            return;
-        }
-
-        // Make a copy of methods configuration
-        persistent_data::AuthConfigMethods authMethodsConfig =
-            persistent_data::SessionStore::getInstance().getAuthMethodsConfig();
-
-        if (basicAuth)
-        {
-#ifndef BMCWEB_ENABLE_BASIC_AUTHENTICATION
-            messages::actionNotSupported(
-                asyncResp->res, "Setting BasicAuth when basic-auth feature "
-                                "is disabled");
-            return;
-#endif
-            authMethodsConfig.basic = *basicAuth;
-        }
-
-        if (cookie)
-        {
-#ifndef BMCWEB_ENABLE_COOKIE_AUTHENTICATION
-            messages::actionNotSupported(
-                asyncResp->res, "Setting Cookie when cookie-auth feature "
-                                "is disabled");
-            return;
-#endif
-            authMethodsConfig.cookie = *cookie;
-        }
-
-        if (sessionToken)
-        {
-#ifndef BMCWEB_ENABLE_SESSION_AUTHENTICATION
-            messages::actionNotSupported(
-                asyncResp->res,
-                "Setting SessionToken when session-auth feature "
-                "is disabled");
-            return;
-#endif
-            authMethodsConfig.sessionToken = *sessionToken;
-        }
-
-        if (xToken)
-        {
-#ifndef BMCWEB_ENABLE_XTOKEN_AUTHENTICATION
-            messages::actionNotSupported(
-                asyncResp->res, "Setting XToken when xtoken-auth feature "
-                                "is disabled");
-            return;
-#endif
-            authMethodsConfig.xtoken = *xToken;
-        }
-
-        if (tls)
-        {
-#ifndef BMCWEB_ENABLE_MUTUAL_TLS_AUTHENTICATION
-            messages::actionNotSupported(
-                asyncResp->res, "Setting TLS when mutual-tls-auth feature "
-                                "is disabled");
-            return;
-#endif
-            authMethodsConfig.tls = *tls;
-        }
-
-        if (!authMethodsConfig.basic && !authMethodsConfig.cookie &&
-            !authMethodsConfig.sessionToken && !authMethodsConfig.xtoken &&
-            !authMethodsConfig.tls)
-        {
-            // Do not allow user to disable everything
-            messages::actionNotSupported(asyncResp->res,
-                                         "of disabling all available methods");
-            return;
-        }
-
-        persistent_data::SessionStore::getInstance().updateAuthMethodsConfig(
-            authMethodsConfig);
-        // Save configuration immediately
-        persistent_data::getConfig().writeData();
-
-        messages::success(asyncResp->res);
-    }
-
-    /**
-     * @brief Get the required values from the given JSON, validates the
-     *        value and create the LDAP config object.
-     * @param input JSON data
-     * @param asyncResp pointer to the JSON response
-     * @param serverType Type of LDAP server(openLDAP/ActiveDirectory)
-     */
-
-    void handleLDAPPatch(nlohmann::json& input,
+void handleUserNamePatch(const std::string& username,
                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                         const std::string& serverType)
+                         const std::string& ldapServerElementName,
+                         const std::string& ldapConfigObject)
+{
+    crow::connections::systemBus->async_method_call(
+        [asyncResp, username,
+         ldapServerElementName](const boost::system::error_code ec) {
+            if (ec)
+            {
+                BMCWEB_LOG_DEBUG << "Error occurred in updating the username";
+                messages::internalError(asyncResp->res);
+                return;
+            }
+            asyncResp->res.jsonValue[ldapServerElementName]["Authentication"]
+                                    ["Username"] = username;
+            BMCWEB_LOG_DEBUG << "Updated the username";
+        },
+        ldapDbusService, ldapConfigObject, propertyInterface, "Set",
+        ldapConfigInterface, "LDAPBindDN", std::variant<std::string>(username));
+}
+
+/**
+ * @brief updates the LDAP password
+ * @param password : ldap password which needs to be updated.
+ * @param asyncResp pointer to the JSON response
+ * @param ldapServerElementName Type of LDAP
+ *        server(openLDAP/ActiveDirectory)
+ */
+
+void handlePasswordPatch(const std::string& password,
+                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                         const std::string& ldapServerElementName,
+                         const std::string& ldapConfigObject)
+{
+    crow::connections::systemBus->async_method_call(
+        [asyncResp, password,
+         ldapServerElementName](const boost::system::error_code ec) {
+            if (ec)
+            {
+                BMCWEB_LOG_DEBUG << "Error occurred in updating the password";
+                messages::internalError(asyncResp->res);
+                return;
+            }
+            asyncResp->res.jsonValue[ldapServerElementName]["Authentication"]
+                                    ["Password"] = "";
+            BMCWEB_LOG_DEBUG << "Updated the password";
+        },
+        ldapDbusService, ldapConfigObject, propertyInterface, "Set",
+        ldapConfigInterface, "LDAPBindDNPassword",
+        std::variant<std::string>(password));
+}
+
+/**
+ * @brief updates the LDAP BaseDN and updates the
+          json response with the new value.
+ * @param baseDNList baseDN list which needs to be updated.
+ * @param asyncResp pointer to the JSON response
+ * @param ldapServerElementName Type of LDAP
+ server(openLDAP/ActiveDirectory)
+ */
+
+void handleBaseDNPatch(const std::vector<std::string>& baseDNList,
+                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                       const std::string& ldapServerElementName,
+                       const std::string& ldapConfigObject)
+{
+    crow::connections::systemBus->async_method_call(
+        [asyncResp, baseDNList,
+         ldapServerElementName](const boost::system::error_code ec) {
+            if (ec)
+            {
+                BMCWEB_LOG_DEBUG << "Error Occurred in Updating the base DN";
+                messages::internalError(asyncResp->res);
+                return;
+            }
+            auto& serverTypeJson =
+                asyncResp->res.jsonValue[ldapServerElementName];
+            auto& searchSettingsJson =
+                serverTypeJson["LDAPService"]["SearchSettings"];
+            std::vector<std::string> modifiedBaseDNList = {baseDNList.front()};
+            searchSettingsJson["BaseDistinguishedNames"] = modifiedBaseDNList;
+            if (baseDNList.size() > 1)
+            {
+                messages::propertyValueModified(asyncResp->res,
+                                                "BaseDistinguishedNames",
+                                                baseDNList.front());
+            }
+            BMCWEB_LOG_DEBUG << "Updated the base DN";
+        },
+        ldapDbusService, ldapConfigObject, propertyInterface, "Set",
+        ldapConfigInterface, "LDAPBaseDN",
+        std::variant<std::string>(baseDNList.front()));
+}
+/**
+ * @brief updates the LDAP user name attribute and updates the
+          json response with the new value.
+ * @param userNameAttribute attribute to be updated.
+ * @param asyncResp pointer to the JSON response
+ * @param ldapServerElementName Type of LDAP
+ server(openLDAP/ActiveDirectory)
+ */
+
+void handleUserNameAttrPatch(
+    const std::string& userNameAttribute,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& ldapServerElementName,
+    const std::string& ldapConfigObject)
+{
+    crow::connections::systemBus->async_method_call(
+        [asyncResp, userNameAttribute,
+         ldapServerElementName](const boost::system::error_code ec) {
+            if (ec)
+            {
+                BMCWEB_LOG_DEBUG << "Error Occurred in Updating the "
+                                    "username attribute";
+                messages::internalError(asyncResp->res);
+                return;
+            }
+            auto& serverTypeJson =
+                asyncResp->res.jsonValue[ldapServerElementName];
+            auto& searchSettingsJson =
+                serverTypeJson["LDAPService"]["SearchSettings"];
+            searchSettingsJson["UsernameAttribute"] = userNameAttribute;
+            BMCWEB_LOG_DEBUG << "Updated the user name attr.";
+        },
+        ldapDbusService, ldapConfigObject, propertyInterface, "Set",
+        ldapConfigInterface, "UserNameAttribute",
+        std::variant<std::string>(userNameAttribute));
+}
+/**
+ * @brief updates the LDAP group attribute and updates the
+          json response with the new value.
+ * @param groupsAttribute attribute to be updated.
+ * @param asyncResp pointer to the JSON response
+ * @param ldapServerElementName Type of LDAP
+ server(openLDAP/ActiveDirectory)
+ */
+
+void handleGroupNameAttrPatch(
+    const std::string& groupsAttribute,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& ldapServerElementName,
+    const std::string& ldapConfigObject)
+{
+    crow::connections::systemBus->async_method_call(
+        [asyncResp, groupsAttribute,
+         ldapServerElementName](const boost::system::error_code ec) {
+            if (ec)
+            {
+                BMCWEB_LOG_DEBUG << "Error Occurred in Updating the "
+                                    "groupname attribute";
+                messages::internalError(asyncResp->res);
+                return;
+            }
+            auto& serverTypeJson =
+                asyncResp->res.jsonValue[ldapServerElementName];
+            auto& searchSettingsJson =
+                serverTypeJson["LDAPService"]["SearchSettings"];
+            searchSettingsJson["GroupsAttribute"] = groupsAttribute;
+            BMCWEB_LOG_DEBUG << "Updated the groupname attr";
+        },
+        ldapDbusService, ldapConfigObject, propertyInterface, "Set",
+        ldapConfigInterface, "GroupNameAttribute",
+        std::variant<std::string>(groupsAttribute));
+}
+/**
+ * @brief updates the LDAP service enable and updates the
+          json response with the new value.
+ * @param input JSON data.
+ * @param asyncResp pointer to the JSON response
+ * @param ldapServerElementName Type of LDAP
+ server(openLDAP/ActiveDirectory)
+ */
+
+void handleServiceEnablePatch(
+    bool serviceEnabled, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& ldapServerElementName,
+    const std::string& ldapConfigObject)
+{
+    crow::connections::systemBus->async_method_call(
+        [asyncResp, serviceEnabled,
+         ldapServerElementName](const boost::system::error_code ec) {
+            if (ec)
+            {
+                BMCWEB_LOG_DEBUG
+                    << "Error Occurred in Updating the service enable";
+                messages::internalError(asyncResp->res);
+                return;
+            }
+            asyncResp->res.jsonValue[ldapServerElementName]["ServiceEnabled"] =
+                serviceEnabled;
+            BMCWEB_LOG_DEBUG << "Updated Service enable = " << serviceEnabled;
+        },
+        ldapDbusService, ldapConfigObject, propertyInterface, "Set",
+        ldapEnableInterface, "Enabled", std::variant<bool>(serviceEnabled));
+}
+
+void handleAuthMethodsPatch(nlohmann::json& input,
+                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    std::optional<bool> basicAuth;
+    std::optional<bool> cookie;
+    std::optional<bool> sessionToken;
+    std::optional<bool> xToken;
+    std::optional<bool> tls;
+
+    if (!json_util::readJson(input, asyncResp->res, "BasicAuth", basicAuth,
+                             "Cookie", cookie, "SessionToken", sessionToken,
+                             "XToken", xToken, "TLS", tls))
     {
-        std::string dbusObjectPath;
-        if (serverType == "ActiveDirectory")
+        BMCWEB_LOG_ERROR << "Cannot read values from AuthMethod tag";
+        return;
+    }
+
+    // Make a copy of methods configuration
+    persistent_data::AuthConfigMethods authMethodsConfig =
+        persistent_data::SessionStore::getInstance().getAuthMethodsConfig();
+
+    if (basicAuth)
+    {
+#ifndef BMCWEB_ENABLE_BASIC_AUTHENTICATION
+        messages::actionNotSupported(
+            asyncResp->res, "Setting BasicAuth when basic-auth feature "
+                            "is disabled");
+        return;
+#endif
+        authMethodsConfig.basic = *basicAuth;
+    }
+
+    if (cookie)
+    {
+#ifndef BMCWEB_ENABLE_COOKIE_AUTHENTICATION
+        messages::actionNotSupported(asyncResp->res,
+                                     "Setting Cookie when cookie-auth feature "
+                                     "is disabled");
+        return;
+#endif
+        authMethodsConfig.cookie = *cookie;
+    }
+
+    if (sessionToken)
+    {
+#ifndef BMCWEB_ENABLE_SESSION_AUTHENTICATION
+        messages::actionNotSupported(
+            asyncResp->res, "Setting SessionToken when session-auth feature "
+                            "is disabled");
+        return;
+#endif
+        authMethodsConfig.sessionToken = *sessionToken;
+    }
+
+    if (xToken)
+    {
+#ifndef BMCWEB_ENABLE_XTOKEN_AUTHENTICATION
+        messages::actionNotSupported(asyncResp->res,
+                                     "Setting XToken when xtoken-auth feature "
+                                     "is disabled");
+        return;
+#endif
+        authMethodsConfig.xtoken = *xToken;
+    }
+
+    if (tls)
+    {
+#ifndef BMCWEB_ENABLE_MUTUAL_TLS_AUTHENTICATION
+        messages::actionNotSupported(asyncResp->res,
+                                     "Setting TLS when mutual-tls-auth feature "
+                                     "is disabled");
+        return;
+#endif
+        authMethodsConfig.tls = *tls;
+    }
+
+    if (!authMethodsConfig.basic && !authMethodsConfig.cookie &&
+        !authMethodsConfig.sessionToken && !authMethodsConfig.xtoken &&
+        !authMethodsConfig.tls)
+    {
+        // Do not allow user to disable everything
+        messages::actionNotSupported(asyncResp->res,
+                                     "of disabling all available methods");
+        return;
+    }
+
+    persistent_data::SessionStore::getInstance().updateAuthMethodsConfig(
+        authMethodsConfig);
+    // Save configuration immediately
+    persistent_data::getConfig().writeData();
+
+    messages::success(asyncResp->res);
+}
+
+/**
+ * @brief Get the required values from the given JSON, validates the
+ *        value and create the LDAP config object.
+ * @param input JSON data
+ * @param asyncResp pointer to the JSON response
+ * @param serverType Type of LDAP server(openLDAP/ActiveDirectory)
+ */
+
+inline void handleLDAPPatch(nlohmann::json& input,
+                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                            const std::string& serverType)
+{
+    std::string dbusObjectPath;
+    if (serverType == "ActiveDirectory")
+    {
+        dbusObjectPath = adConfigObject;
+    }
+    else if (serverType == "LDAP")
+    {
+        dbusObjectPath = ldapConfigObjectName;
+    }
+    else
+    {
+        return;
+    }
+
+    std::optional<nlohmann::json> authentication;
+    std::optional<nlohmann::json> ldapService;
+    std::optional<std::vector<std::string>> serviceAddressList;
+    std::optional<bool> serviceEnabled;
+    std::optional<std::vector<std::string>> baseDNList;
+    std::optional<std::string> userNameAttribute;
+    std::optional<std::string> groupsAttribute;
+    std::optional<std::string> userName;
+    std::optional<std::string> password;
+    std::optional<std::vector<nlohmann::json>> remoteRoleMapData;
+
+    if (!json_util::readJson(input, asyncResp->res, "Authentication",
+                             authentication, "LDAPService", ldapService,
+                             "ServiceAddresses", serviceAddressList,
+                             "ServiceEnabled", serviceEnabled,
+                             "RemoteRoleMapping", remoteRoleMapData))
+    {
+        return;
+    }
+
+    if (authentication)
+    {
+        parseLDAPAuthenticationJson(*authentication, asyncResp, userName,
+                                    password);
+    }
+    if (ldapService)
+    {
+        parseLDAPServiceJson(*ldapService, asyncResp, baseDNList,
+                             userNameAttribute, groupsAttribute);
+    }
+    if (serviceAddressList)
+    {
+        if ((*serviceAddressList).size() == 0)
         {
-            dbusObjectPath = adConfigObject;
-        }
-        else if (serverType == "LDAP")
-        {
-            dbusObjectPath = ldapConfigObjectName;
-        }
-        else
-        {
+            messages::propertyValueNotInList(asyncResp->res, "[]",
+                                             "ServiceAddress");
             return;
         }
-
-        std::optional<nlohmann::json> authentication;
-        std::optional<nlohmann::json> ldapService;
-        std::optional<std::vector<std::string>> serviceAddressList;
-        std::optional<bool> serviceEnabled;
-        std::optional<std::vector<std::string>> baseDNList;
-        std::optional<std::string> userNameAttribute;
-        std::optional<std::string> groupsAttribute;
-        std::optional<std::string> userName;
-        std::optional<std::string> password;
-        std::optional<std::vector<nlohmann::json>> remoteRoleMapData;
-
-        if (!json_util::readJson(input, asyncResp->res, "Authentication",
-                                 authentication, "LDAPService", ldapService,
-                                 "ServiceAddresses", serviceAddressList,
-                                 "ServiceEnabled", serviceEnabled,
-                                 "RemoteRoleMapping", remoteRoleMapData))
+    }
+    if (baseDNList)
+    {
+        if ((*baseDNList).size() == 0)
         {
+            messages::propertyValueNotInList(asyncResp->res, "[]",
+                                             "BaseDistinguishedNames");
             return;
         }
+    }
 
-        if (authentication)
+    // nothing to update, then return
+    if (!userName && !password && !serviceAddressList && !baseDNList &&
+        !userNameAttribute && !groupsAttribute && !serviceEnabled &&
+        !remoteRoleMapData)
+    {
+        return;
+    }
+
+    // Get the existing resource first then keep modifying
+    // whenever any property gets updated.
+    getLDAPConfigData(serverType, [asyncResp, userName, password, baseDNList,
+                                   userNameAttribute, groupsAttribute,
+                                   serviceAddressList, serviceEnabled,
+                                   dbusObjectPath, remoteRoleMapData](
+                                      bool success,
+                                      const LDAPConfigData& confData,
+                                      const std::string& serverT) {
+        if (!success)
         {
-            parseLDAPAuthenticationJson(*authentication, asyncResp, userName,
-                                        password);
+            messages::internalError(asyncResp->res);
+            return;
         }
-        if (ldapService)
+        parseLDAPConfigData(asyncResp->res.jsonValue, confData, serverT);
+        if (confData.serviceEnabled)
         {
-            parseLDAPServiceJson(*ldapService, asyncResp, baseDNList,
-                                 userNameAttribute, groupsAttribute);
+            // Disable the service first and update the rest of
+            // the properties.
+            handleServiceEnablePatch(false, asyncResp, serverT, dbusObjectPath);
         }
+
         if (serviceAddressList)
         {
-            if ((*serviceAddressList).size() == 0)
-            {
-                messages::propertyValueNotInList(asyncResp->res, "[]",
-                                                 "ServiceAddress");
-                return;
-            }
+            handleServiceAddressPatch(*serviceAddressList, asyncResp, serverT,
+                                      dbusObjectPath);
         }
+        if (userName)
+        {
+            handleUserNamePatch(*userName, asyncResp, serverT, dbusObjectPath);
+        }
+        if (password)
+        {
+            handlePasswordPatch(*password, asyncResp, serverT, dbusObjectPath);
+        }
+
         if (baseDNList)
         {
-            if ((*baseDNList).size() == 0)
+            handleBaseDNPatch(*baseDNList, asyncResp, serverT, dbusObjectPath);
+        }
+        if (userNameAttribute)
+        {
+            handleUserNameAttrPatch(*userNameAttribute, asyncResp, serverT,
+                                    dbusObjectPath);
+        }
+        if (groupsAttribute)
+        {
+            handleGroupNameAttrPatch(*groupsAttribute, asyncResp, serverT,
+                                     dbusObjectPath);
+        }
+        if (serviceEnabled)
+        {
+            // if user has given the value as true then enable
+            // the service. if user has given false then no-op
+            // as service is already stopped.
+            if (*serviceEnabled)
             {
-                messages::propertyValueNotInList(asyncResp->res, "[]",
-                                                 "BaseDistinguishedNames");
-                return;
+                handleServiceEnablePatch(*serviceEnabled, asyncResp, serverT,
+                                         dbusObjectPath);
             }
         }
-
-        // nothing to update, then return
-        if (!userName && !password && !serviceAddressList && !baseDNList &&
-            !userNameAttribute && !groupsAttribute && !serviceEnabled &&
-            !remoteRoleMapData)
-        {
-            return;
-        }
-
-        // Get the existing resource first then keep modifying
-        // whenever any property gets updated.
-        getLDAPConfigData(
-            serverType, [this, asyncResp, userName, password, baseDNList,
-                         userNameAttribute, groupsAttribute, serviceAddressList,
-                         serviceEnabled, dbusObjectPath, remoteRoleMapData](
-                            bool success, const LDAPConfigData& confData,
-                            const std::string& serverT) {
-                if (!success)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                parseLDAPConfigData(asyncResp->res.jsonValue, confData,
-                                    serverT);
-                if (confData.serviceEnabled)
-                {
-                    // Disable the service first and update the rest of
-                    // the properties.
-                    handleServiceEnablePatch(false, asyncResp, serverT,
-                                             dbusObjectPath);
-                }
-
-                if (serviceAddressList)
-                {
-                    handleServiceAddressPatch(*serviceAddressList, asyncResp,
-                                              serverT, dbusObjectPath);
-                }
-                if (userName)
-                {
-                    handleUserNamePatch(*userName, asyncResp, serverT,
-                                        dbusObjectPath);
-                }
-                if (password)
-                {
-                    handlePasswordPatch(*password, asyncResp, serverT,
-                                        dbusObjectPath);
-                }
-
-                if (baseDNList)
-                {
-                    handleBaseDNPatch(*baseDNList, asyncResp, serverT,
-                                      dbusObjectPath);
-                }
-                if (userNameAttribute)
-                {
-                    handleUserNameAttrPatch(*userNameAttribute, asyncResp,
-                                            serverT, dbusObjectPath);
-                }
-                if (groupsAttribute)
-                {
-                    handleGroupNameAttrPatch(*groupsAttribute, asyncResp,
-                                             serverT, dbusObjectPath);
-                }
-                if (serviceEnabled)
-                {
-                    // if user has given the value as true then enable
-                    // the service. if user has given false then no-op
-                    // as service is already stopped.
-                    if (*serviceEnabled)
-                    {
-                        handleServiceEnablePatch(*serviceEnabled, asyncResp,
-                                                 serverT, dbusObjectPath);
-                    }
-                }
-                else
-                {
-                    // if user has not given the service enabled value
-                    // then revert it to the same state as it was
-                    // before.
-                    handleServiceEnablePatch(confData.serviceEnabled, asyncResp,
-                                             serverT, dbusObjectPath);
-                }
-
-                if (remoteRoleMapData)
-                {
-                    handleRoleMapPatch(asyncResp, confData.groupRoleList,
-                                       serverT, *remoteRoleMapData);
-                }
-            });
-    }
-
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        const persistent_data::AuthConfigMethods& authMethodsConfig =
-            persistent_data::SessionStore::getInstance().getAuthMethodsConfig();
-
-        asyncResp->res.jsonValue = {
-            {"@odata.id", "/redfish/v1/AccountService"},
-            {"@odata.type", "#AccountService."
-                            "v1_5_0.AccountService"},
-            {"Id", "AccountService"},
-            {"Name", "Account Service"},
-            {"Description", "Account Service"},
-            {"ServiceEnabled", true},
-            {"MaxPasswordLength", 20},
-            {"Accounts",
-             {{"@odata.id", "/redfish/v1/AccountService/Accounts"}}},
-            {"Roles", {{"@odata.id", "/redfish/v1/AccountService/Roles"}}},
-            {"Oem",
-             {{"OpenBMC",
-               {{"@odata.type", "#OemAccountService.v1_0_0.AccountService"},
-                {"AuthMethods",
-                 {
-                     {"BasicAuth", authMethodsConfig.basic},
-                     {"SessionToken", authMethodsConfig.sessionToken},
-                     {"XToken", authMethodsConfig.xtoken},
-                     {"Cookie", authMethodsConfig.cookie},
-                     {"TLS", authMethodsConfig.tls},
-                 }}}}}},
-            {"LDAP",
-             {{"Certificates",
-               {{"@odata.id",
-                 "/redfish/v1/AccountService/LDAP/Certificates"}}}}}};
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](
-                const boost::system::error_code ec,
-                const std::vector<std::pair<
-                    std::string, std::variant<uint32_t, uint16_t, uint8_t>>>&
-                    propertiesList) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
-                                 << "properties for AccountService";
-                for (const std::pair<std::string,
-                                     std::variant<uint32_t, uint16_t, uint8_t>>&
-                         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);
-    }
-
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>&) override
-    {
-        std::optional<uint32_t> unlockTimeout;
-        std::optional<uint16_t> lockoutThreshold;
-        std::optional<uint16_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::readJson(
-                req, asyncResp->res, "AccountLockoutDuration", unlockTimeout,
-                "AccountLockoutThreshold", lockoutThreshold,
-                "MaxPasswordLength", maxPasswordLength, "MinPasswordLength",
-                minPasswordLength, "LDAP", ldapObject, "ActiveDirectory",
-                activeDirectoryObject, "Oem", oemObject))
-        {
-            return;
-        }
-
-        if (minPasswordLength)
-        {
-            messages::propertyNotWritable(asyncResp->res, "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", std::variant<uint32_t>(*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",
-                std::variant<uint16_t>(*lockoutThreshold));
-        }
-    }
-};
-
-class AccountsCollection : public Node
-{
-  public:
-    AccountsCollection(App& app) :
-        Node(app, "/redfish/v1/AccountService/Accounts/")
-    {
-        entityPrivileges = {
-            // According to the PrivilegeRegistry, GET should actually be
-            // "Login". A "Login" only privilege would return an empty "Members"
-            // list. Not going to worry about this since none of the defined
-            // roles are just "Login". E.g. Readonly is {"Login",
-            // "ConfigureSelf"}. In the rare event anyone defines a role that
-            // has Login but not ConfigureSelf, implement this.
-            {boost::beast::http::verb::get,
-             {{"ConfigureUsers"}, {"ConfigureSelf"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureUsers"}}},
-            {boost::beast::http::verb::put, {{"ConfigureUsers"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}},
-            {boost::beast::http::verb::post, {{"ConfigureUsers"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request& req,
-               const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue = {
-            {"@odata.id", "/redfish/v1/AccountService/Accounts"},
-            {"@odata.type", "#ManagerAccountCollection."
-                            "ManagerAccountCollection"},
-            {"Name", "Accounts Collection"},
-            {"Description", "BMC User Accounts"}};
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, &req, this](const boost::system::error_code ec,
-                                    const ManagedObjectType& users) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                nlohmann::json& memberArray =
-                    asyncResp->res.jsonValue["Members"];
-                memberArray = nlohmann::json::array();
-
-                for (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 (req.session->username == user ||
-                        isAllowedWithoutConfigureSelf(req))
-                    {
-                        memberArray.push_back(
-                            {{"@odata.id",
-                              "/redfish/v1/AccountService/Accounts/" + user}});
-                    }
-                }
-                asyncResp->res.jsonValue["Members@odata.count"] =
-                    memberArray.size();
-            },
-            "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
-            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-    }
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
-        std::string username;
-        std::string password;
-        std::optional<std::string> roleId("User");
-        std::optional<bool> enabled = true;
-        if (!json_util::readJson(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;
+            // if user has not given the service enabled value
+            // then revert it to the same state as it was
+            // before.
+            handleServiceEnablePatch(confData.serviceEnabled, asyncResp,
+                                     serverT, dbusObjectPath);
         }
 
-        // Reading AllGroups property
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, username, password{std::move(password)}, roleId,
-             enabled](const boost::system::error_code ec,
-                      const std::variant<std::vector<std::string>>& allGroups) {
-                if (ec)
+        if (remoteRoleMapData)
+        {
+            handleRoleMapPatch(asyncResp, confData.groupRoleList, serverT,
+                               *remoteRoleMapData);
+        }
+    });
+}
+
+inline void updateUserProperties(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
+                                 const std::string& username,
+                                 std::optional<std::string> password,
+                                 std::optional<bool> enabled,
+                                 std::optional<std::string> roleId,
+                                 std::optional<bool> locked)
+{
+    std::string dbusObjectPath = "/xyz/openbmc_project/user/" + username;
+    dbus::utility::escapePathForDbus(dbusObjectPath);
+
+    dbus::utility::checkDbusPathExists(
+        dbusObjectPath,
+        [dbusObjectPath(std::move(dbusObjectPath)), username,
+         password(std::move(password)), roleId(std::move(roleId)), enabled,
+         locked, asyncResp{std::move(asyncResp)}](int rc) {
+            if (!rc)
+            {
+                messages::resourceNotFound(
+                    asyncResp->res, "#ManagerAccount.v1_4_0.ManagerAccount",
+                    username);
+                return;
+            }
+
+            if (password)
+            {
+                int retval = pamUpdatePassword(username, *password);
+
+                if (retval == PAM_USER_UNKNOWN)
                 {
-                    BMCWEB_LOG_DEBUG << "ERROR with async_method_call";
+                    messages::resourceNotFound(
+                        asyncResp->res, "#ManagerAccount.v1_4_0.ManagerAccount",
+                        username);
+                }
+                else if (retval == PAM_AUTHTOK_ERR)
+                {
+                    // If password is invalid
+                    messages::propertyValueFormatError(asyncResp->res,
+                                                       *password, "Password");
+                    BMCWEB_LOG_ERROR << "pamUpdatePassword Failed";
+                }
+                else if (retval != PAM_SUCCESS)
+                {
                     messages::internalError(asyncResp->res);
                     return;
                 }
+            }
 
-                const std::vector<std::string>* allGroupsList =
-                    std::get_if<std::vector<std::string>>(&allGroups);
+            if (enabled)
+            {
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](const boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        messages::success(asyncResp->res);
+                        return;
+                    },
+                    "xyz.openbmc_project.User.Manager", dbusObjectPath.c_str(),
+                    "org.freedesktop.DBus.Properties", "Set",
+                    "xyz.openbmc_project.User.Attributes", "UserEnabled",
+                    std::variant<bool>{*enabled});
+            }
 
-                if (allGroupsList == nullptr || allGroupsList->empty())
+            if (roleId)
+            {
+                std::string priv = getPrivilegeFromRoleId(*roleId);
+                if (priv.empty())
                 {
-                    messages::internalError(asyncResp->res);
+                    messages::propertyValueNotInList(asyncResp->res, *roleId,
+                                                     "RoleId");
+                    return;
+                }
+                if (priv == "priv-noaccess")
+                {
+                    priv = "";
+                }
+
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](const boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        messages::success(asyncResp->res);
+                    },
+                    "xyz.openbmc_project.User.Manager", dbusObjectPath.c_str(),
+                    "org.freedesktop.DBus.Properties", "Set",
+                    "xyz.openbmc_project.User.Attributes", "UserPrivilege",
+                    std::variant<std::string>{priv});
+            }
+
+            if (locked)
+            {
+                // admin can unlock the account which is locked by
+                // successive authentication failures but admin should
+                // not be allowed to lock an account.
+                if (*locked)
+                {
+                    messages::propertyValueNotInList(asyncResp->res, "true",
+                                                     "Locked");
                     return;
                 }
 
                 crow::connections::systemBus->async_method_call(
-                    [asyncResp, username,
-                     password](const boost::system::error_code ec2,
-                               sdbusplus::message::message& m) {
-                        if (ec2)
+                    [asyncResp](const boost::system::error_code ec) {
+                        if (ec)
                         {
-                            userErrorMessageHandler(m.get_error(), asyncResp,
-                                                    username, "");
+                            BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+                            messages::internalError(asyncResp->res);
                             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
-                            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",
-                                "/xyz/openbmc_project/user/" + username,
-                                "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);
+                        messages::success(asyncResp->res);
+                        return;
                     },
-                    "xyz.openbmc_project.User.Manager",
-                    "/xyz/openbmc_project/user",
-                    "xyz.openbmc_project.User.Manager", "CreateUser", username,
-                    *allGroupsList, *roleId, *enabled);
-            },
-            "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
-            "org.freedesktop.DBus.Properties", "Get",
-            "xyz.openbmc_project.User.Manager", "AllGroups");
-    }
-};
+                    "xyz.openbmc_project.User.Manager", dbusObjectPath.c_str(),
+                    "org.freedesktop.DBus.Properties", "Set",
+                    "xyz.openbmc_project.User.Attributes",
+                    "UserLockedForFailedAttempt", std::variant<bool>{*locked});
+            }
+        });
+}
 
-class ManagerAccount : public Node
+inline void requestAccountServiceRoutes(App& app)
 {
-  public:
-    ManagerAccount(App& app) :
-        Node(app, "/redfish/v1/AccountService/Accounts/<str>/", std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get,
-             {{"ConfigureUsers"}, {"ConfigureManager"}, {"ConfigureSelf"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch,
-             {{"ConfigureUsers"}, {"ConfigureSelf"}}},
-            {boost::beast::http::verb::put, {{"ConfigureUsers"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}},
-            {boost::beast::http::verb::post, {{"ConfigureUsers"}}}};
-    }
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request& req,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/")
+        .privileges({{"Login"}})
+        .methods(
+            boost::beast::http::verb::get)([](const crow::Request& /* req */,
+                                              const std::shared_ptr<
+                                                  bmcweb::AsyncResp>& asyncResp)
+                                               -> void {
+            const persistent_data::AuthConfigMethods& authMethodsConfig =
+                persistent_data::SessionStore::getInstance()
+                    .getAuthMethodsConfig();
 
-        // Perform a proper ConfigureSelf authority check.  If the
-        // user is operating on an account not their own, then their
-        // ConfigureSelf privilege does not apply.  In this case,
-        // perform the authority check again without the user's
-        // ConfigureSelf privilege.
-        if (req.session->username != params[0])
-        {
-            if (!isAllowedWithoutConfigureSelf(req))
-            {
-                BMCWEB_LOG_DEBUG << "GET Account denied access";
-                messages::insufficientPrivilege(asyncResp->res);
-                return;
-            }
-        }
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, accountName{std::string(params[0])}](
-                const boost::system::error_code ec,
-                const ManagedObjectType& users) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                auto userIt = users.begin();
-
-                for (; userIt != users.end(); userIt++)
-                {
-                    if (boost::ends_with(userIt->first.str, "/" + accountName))
-                    {
-                        break;
-                    }
-                }
-                if (userIt == users.end())
-                {
-                    messages::resourceNotFound(asyncResp->res, "ManagerAccount",
-                                               accountName);
-                    return;
-                }
-
-                asyncResp->res.jsonValue = {
-                    {"@odata.type", "#ManagerAccount.v1_4_0.ManagerAccount"},
-                    {"Name", "User Account"},
-                    {"Description", "User Account"},
-                    {"Password", nullptr},
-                    {"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;
-
-                                asyncResp->res.jsonValue["Links"]["Role"] = {
-                                    {"@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 << "UserPassword"
-                                                        "Expired "
-                                                        "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");
-    }
-
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        std::optional<std::string> newUserName;
-        std::optional<std::string> password;
-        std::optional<bool> enabled;
-        std::optional<std::string> roleId;
-        std::optional<bool> locked;
-        if (!json_util::readJson(req, asyncResp->res, "UserName", newUserName,
-                                 "Password", password, "RoleId", roleId,
-                                 "Enabled", enabled, "Locked", locked))
-        {
-            return;
-        }
-
-        const std::string& username = params[0];
-
-        // Perform a proper ConfigureSelf authority check.  If the
-        // session is being used to PATCH a property other than
-        // Password, then the ConfigureSelf privilege does not apply.
-        // If the user is operating on an account not their own, then
-        // their ConfigureSelf privilege does not apply.  In either
-        // case, perform the authority check again without the user's
-        // ConfigureSelf privilege.
-        if ((username != req.session->username) ||
-            (newUserName || enabled || roleId || locked))
-        {
-            if (!isAllowedWithoutConfigureSelf(req))
-            {
-                BMCWEB_LOG_WARNING << "PATCH Password denied access";
-                asyncResp->res.clear();
-                messages::insufficientPrivilege(asyncResp->res);
-                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(
-            [this, 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);
-    }
-
-    void updateUserProperties(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
-                              const std::string& username,
-                              std::optional<std::string> password,
-                              std::optional<bool> enabled,
-                              std::optional<std::string> roleId,
-                              std::optional<bool> locked)
-    {
-        std::string dbusObjectPath = "/xyz/openbmc_project/user/" + username;
-        dbus::utility::escapePathForDbus(dbusObjectPath);
-
-        dbus::utility::checkDbusPathExists(
-            dbusObjectPath,
-            [dbusObjectPath(std::move(dbusObjectPath)), username,
-             password(std::move(password)), roleId(std::move(roleId)), enabled,
-             locked, asyncResp{std::move(asyncResp)}](int rc) {
-                if (!rc)
-                {
-                    messages::resourceNotFound(
-                        asyncResp->res, "#ManagerAccount.v1_4_0.ManagerAccount",
-                        username);
-                    return;
-                }
-
-                if (password)
-                {
-                    int retval = pamUpdatePassword(username, *password);
-
-                    if (retval == PAM_USER_UNKNOWN)
-                    {
-                        messages::resourceNotFound(
-                            asyncResp->res,
-                            "#ManagerAccount.v1_4_0.ManagerAccount", username);
-                    }
-                    else if (retval == PAM_AUTHTOK_ERR)
-                    {
-                        // If password is invalid
-                        messages::propertyValueFormatError(
-                            asyncResp->res, *password, "Password");
-                        BMCWEB_LOG_ERROR << "pamUpdatePassword Failed";
-                    }
-                    else if (retval != PAM_SUCCESS)
+            asyncResp->res.jsonValue = {
+                {"@odata.id", "/redfish/v1/AccountService"},
+                {"@odata.type", "#AccountService."
+                                "v1_5_0.AccountService"},
+                {"Id", "AccountService"},
+                {"Name", "Account Service"},
+                {"Description", "Account Service"},
+                {"ServiceEnabled", true},
+                {"MaxPasswordLength", 20},
+                {"Accounts",
+                 {{"@odata.id", "/redfish/v1/AccountService/Accounts"}}},
+                {"Roles", {{"@odata.id", "/redfish/v1/AccountService/Roles"}}},
+                {"Oem",
+                 {{"OpenBMC",
+                   {{"@odata.type", "#OemAccountService.v1_0_0.AccountService"},
+                    {"AuthMethods",
+                     {
+                         {"BasicAuth", authMethodsConfig.basic},
+                         {"SessionToken", authMethodsConfig.sessionToken},
+                         {"XToken", authMethodsConfig.xtoken},
+                         {"Cookie", authMethodsConfig.cookie},
+                         {"TLS", authMethodsConfig.tls},
+                     }}}}}},
+                {"LDAP",
+                 {{"Certificates",
+                   {{"@odata.id",
+                     "/redfish/v1/AccountService/LDAP/Certificates"}}}}}};
+            crow::connections::systemBus->async_method_call(
+                [asyncResp](
+                    const boost::system::error_code ec,
+                    const std::vector<
+                        std::pair<std::string,
+                                  std::variant<uint32_t, uint16_t, uint8_t>>>&
+                        propertiesList) {
+                    if (ec)
                     {
                         messages::internalError(asyncResp->res);
                         return;
                     }
-                }
-
-                if (enabled)
-                {
-                    crow::connections::systemBus->async_method_call(
-                        [asyncResp](const boost::system::error_code ec) {
-                            if (ec)
+                    BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
+                                     << "properties for AccountService";
+                    for (const std::pair<std::string,
+                                         std::variant<uint32_t, uint16_t,
+                                                      uint8_t>>& property :
+                         propertiesList)
+                    {
+                        if (property.first == "MinPasswordLength")
+                        {
+                            const uint8_t* value =
+                                std::get_if<uint8_t>(&property.second);
+                            if (value != nullptr)
                             {
-                                BMCWEB_LOG_ERROR << "D-Bus responses error: "
-                                                 << ec;
-                                messages::internalError(asyncResp->res);
-                                return;
+                                asyncResp->res.jsonValue["MinPasswordLength"] =
+                                    *value;
                             }
-                            messages::success(asyncResp->res);
+                        }
+                        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);
+        });
+
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/")
+        // According to the PrivilegeRegistry, GET should actually be
+        // "Login". A "Login" only privilege would return an empty "Members"
+        // list. Not going to worry about this since none of the defined
+        // roles are just "Login". E.g. Readonly is {"Login",
+        // "ConfigureSelf"}. In the rare event anyone defines a role that
+        // has Login but not ConfigureSelf, implement this.
+        .privileges({{"ConfigureUsers"}, {"ConfigureSelf"}})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) -> void {
+                asyncResp->res.jsonValue = {
+                    {"@odata.id", "/redfish/v1/AccountService/Accounts"},
+                    {"@odata.type", "#ManagerAccountCollection."
+                                    "ManagerAccountCollection"},
+                    {"Name", "Accounts Collection"},
+                    {"Description", "BMC User Accounts"}};
+
+                Privileges requiredPermissionsToSeeNonSelf = {
+                    {"ConfigureUsers"}};
+                Privileges effectiveUserPrivileges =
+                    redfish::getUserPrivileges(req.userRole);
+                bool userCanSeeAllAccounts =
+                    effectiveUserPrivileges.isSupersetOf(
+                        requiredPermissionsToSeeNonSelf);
+
+                std::string thisUser = req.session->username;
+
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp, userCanSeeAllAccounts,
+                     thisUser](const boost::system::error_code ec,
+                               const ManagedObjectType& users) {
+                        if (ec)
+                        {
+                            messages::internalError(asyncResp->res);
                             return;
-                        },
-                        "xyz.openbmc_project.User.Manager",
-                        dbusObjectPath.c_str(),
-                        "org.freedesktop.DBus.Properties", "Set",
-                        "xyz.openbmc_project.User.Attributes", "UserEnabled",
-                        std::variant<bool>{*enabled});
-                }
+                        }
 
-                if (roleId)
-                {
-                    std::string priv = getPrivilegeFromRoleId(*roleId);
-                    if (priv.empty())
-                    {
-                        messages::propertyValueNotInList(asyncResp->res,
-                                                         *roleId, "RoleId");
-                        return;
-                    }
-                    if (priv == "priv-noaccess")
-                    {
-                        priv = "";
-                    }
+                        nlohmann::json& memberArray =
+                            asyncResp->res.jsonValue["Members"];
+                        memberArray = nlohmann::json::array();
 
-                    crow::connections::systemBus->async_method_call(
-                        [asyncResp](const boost::system::error_code ec) {
-                            if (ec)
+                        for (auto& userpath : users)
+                        {
+                            std::string user = userpath.first.filename();
+                            if (user.empty())
                             {
-                                BMCWEB_LOG_ERROR << "D-Bus responses error: "
-                                                 << ec;
                                 messages::internalError(asyncResp->res);
+                                BMCWEB_LOG_ERROR << "Invalid firmware ID";
+
                                 return;
                             }
-                            messages::success(asyncResp->res);
-                        },
-                        "xyz.openbmc_project.User.Manager",
-                        dbusObjectPath.c_str(),
-                        "org.freedesktop.DBus.Properties", "Set",
-                        "xyz.openbmc_project.User.Attributes", "UserPrivilege",
-                        std::variant<std::string>{priv});
-                }
 
-                if (locked)
-                {
-                    // admin can unlock the account which is locked by
-                    // successive authentication failures but admin should
-                    // not be allowed to lock an account.
-                    if (*locked)
-                    {
-                        messages::propertyValueNotInList(asyncResp->res, "true",
-                                                         "Locked");
-                        return;
-                    }
-
-                    crow::connections::systemBus->async_method_call(
-                        [asyncResp](const boost::system::error_code ec) {
-                            if (ec)
+                            // 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 (thisUser == user || userCanSeeAllAccounts)
                             {
-                                BMCWEB_LOG_ERROR << "D-Bus responses error: "
-                                                 << ec;
-                                messages::internalError(asyncResp->res);
-                                return;
+                                memberArray.push_back(
+                                    {{"@odata.id",
+                                      "/redfish/v1/AccountService/Accounts/" +
+                                          user}});
                             }
-                            messages::success(asyncResp->res);
-                            return;
-                        },
-                        "xyz.openbmc_project.User.Manager",
-                        dbusObjectPath.c_str(),
-                        "org.freedesktop.DBus.Properties", "Set",
-                        "xyz.openbmc_project.User.Attributes",
-                        "UserLockedForFailedAttempt",
-                        std::variant<bool>{*locked});
-                }
+                        }
+                        asyncResp->res.jsonValue["Members@odata.count"] =
+                            memberArray.size();
+                    },
+                    "xyz.openbmc_project.User.Manager",
+                    "/xyz/openbmc_project/user",
+                    "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
             });
-    }
 
-    void doDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                  const crow::Request&,
-                  const std::vector<std::string>& params) override
-    {
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/")
+        .privileges({{"ConfigureUsers"}})
+        .methods(boost::beast::http::verb::post)([](const crow::Request& req,
+                                                    const std::shared_ptr<
+                                                        bmcweb::AsyncResp>&
+                                                        asyncResp) -> void {
+            std::string username;
+            std::string password;
+            std::optional<std::string> roleId("User");
+            std::optional<bool> enabled = true;
+            if (!json_util::readJson(req, asyncResp->res, "UserName", username,
+                                     "Password", password, "RoleId", roleId,
+                                     "Enabled", enabled))
+            {
+                return;
+            }
 
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            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;
+            }
 
-        const std::string userPath = "/xyz/openbmc_project/user/" + params[0];
+            // Reading AllGroups property
+            crow::connections::systemBus->async_method_call(
+                [asyncResp, username, password{std::move(password)}, roleId,
+                 enabled](
+                    const boost::system::error_code ec,
+                    const std::variant<std::vector<std::string>>& allGroups) {
+                    if (ec)
+                    {
+                        BMCWEB_LOG_DEBUG << "ERROR with async_method_call";
+                        messages::internalError(asyncResp->res);
+                        return;
+                    }
 
-        crow::connections::systemBus->async_method_call(
-            [asyncResp,
-             username{params[0]}](const boost::system::error_code ec) {
-                if (ec)
+                    const std::vector<std::string>* allGroupsList =
+                        std::get_if<std::vector<std::string>>(&allGroups);
+
+                    if (allGroupsList == nullptr || 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
+                                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",
+                                    "/xyz/openbmc_project/user/" + username,
+                                    "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);
+                },
+                "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+                "org.freedesktop.DBus.Properties", "Get",
+                "xyz.openbmc_project.User.Manager", "AllGroups");
+        });
+
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/")
+        .privileges(
+            {{"ConfigureUsers"}, {"ConfigureManager"}, {"ConfigureSelf"}})
+        .methods(
+            boost::beast::http::verb::
+                get)([](const crow::Request& req,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                        const std::string& accountName) -> void {
+            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))
                 {
-                    messages::resourceNotFound(
-                        asyncResp->res, "#ManagerAccount.v1_4_0.ManagerAccount",
-                        username);
+                    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 ManagedObjectType& users) {
+                    if (ec)
+                    {
+                        messages::internalError(asyncResp->res);
+                        return;
+                    }
+                    auto userIt = users.begin();
+
+                    for (; userIt != users.end(); userIt++)
+                    {
+                        if (boost::ends_with(userIt->first.str,
+                                             "/" + accountName))
+                        {
+                            break;
+                        }
+                    }
+                    if (userIt == users.end())
+                    {
+                        messages::resourceNotFound(
+                            asyncResp->res, "ManagerAccount", accountName);
+                        return;
+                    }
+
+                    asyncResp->res.jsonValue = {
+                        {"@odata.type",
+                         "#ManagerAccount.v1_4_0.ManagerAccount"},
+                        {"Name", "User Account"},
+                        {"Description", "User Account"},
+                        {"Password", nullptr},
+                        {"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;
+
+                                    asyncResp->res.jsonValue["Links"]["Role"] =
+                                        {{"@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 << "UserPassword"
+                                                            "Expired "
+                                                            "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");
+        });
+
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/")
+        .privileges({{"ConfigureUsers"}, {"ConfigureSelf"}})
+        .methods(boost::beast::http::verb::patch)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& username) -> void {
+                std::optional<std::string> newUserName;
+                std::optional<std::string> password;
+                std::optional<bool> enabled;
+                std::optional<std::string> roleId;
+                std::optional<bool> locked;
+                if (!json_util::readJson(req, asyncResp->res, "UserName",
+                                         newUserName, "Password", password,
+                                         "RoleId", roleId, "Enabled", enabled,
+                                         "Locked", locked))
+                {
                     return;
                 }
 
-                messages::accountRemoved(asyncResp->res);
-            },
-            "xyz.openbmc_project.User.Manager", userPath,
-            "xyz.openbmc_project.Object.Delete", "Delete");
-    }
-};
+                // Perform a proper ConfigureSelf authority check.  If the
+                // session is being used to PATCH a property other than
+                // Password, then the ConfigureSelf privilege does not apply.
+                // If the user is operating on an account not their own, then
+                // their ConfigureSelf privilege does not apply.  In either
+                // case, perform the authority check again without the user's
+                // ConfigureSelf privilege.
+                if ((username != req.session->username))
+                {
+                    Privileges requiredPermissionsToChangeNonSelf = {
+                        {"ConfigureUsers"}};
+                    Privileges effectiveUserPrivileges =
+                        redfish::getUserPrivileges(req.userRole);
+
+                    if (!effectiveUserPrivileges.isSupersetOf(
+                            requiredPermissionsToChangeNonSelf))
+                    {
+                        messages::insufficientPrivilege(asyncResp->res);
+                        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);
+            });
+
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/")
+        .privileges({{"ConfigureUsers"}})
+        .methods(boost::beast::http::verb::delete_)(
+            [](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;
+
+                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");
+            });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp
index 3ae75ea..f7cb7a7 100644
--- a/redfish-core/lib/redfish_sessions.hpp
+++ b/redfish-core/lib/redfish_sessions.hpp
@@ -106,9 +106,11 @@
         // ConfigureSelf privilege.
         if (session->username != req.session->username)
         {
-            if (!isAllowedWithoutConfigureSelf(req))
+            Privileges effectiveUserPrivileges =
+                redfish::getUserPrivileges(req.userRole);
+
+            if (!effectiveUserPrivileges.isSupersetOf({{"ConfigureUsers"}}))
             {
-                BMCWEB_LOG_WARNING << "DELETE Session denied access";
                 messages::insufficientPrivilege(asyncResp->res);
                 return;
             }
