19f630d9eSRichard Marian Thomaiyar /*
29f630d9eSRichard Marian Thomaiyar // Copyright (c) 2018 Intel Corporation
39f630d9eSRichard Marian Thomaiyar //
49f630d9eSRichard Marian Thomaiyar // Licensed under the Apache License, Version 2.0 (the "License");
59f630d9eSRichard Marian Thomaiyar // you may not use this file except in compliance with the License.
69f630d9eSRichard Marian Thomaiyar // You may obtain a copy of the License at
79f630d9eSRichard Marian Thomaiyar //
89f630d9eSRichard Marian Thomaiyar // http://www.apache.org/licenses/LICENSE-2.0
99f630d9eSRichard Marian Thomaiyar //
109f630d9eSRichard Marian Thomaiyar // Unless required by applicable law or agreed to in writing, software
119f630d9eSRichard Marian Thomaiyar // distributed under the License is distributed on an "AS IS" BASIS,
129f630d9eSRichard Marian Thomaiyar // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139f630d9eSRichard Marian Thomaiyar // See the License for the specific language governing permissions and
149f630d9eSRichard Marian Thomaiyar // limitations under the License.
159f630d9eSRichard Marian Thomaiyar */
169f630d9eSRichard Marian Thomaiyar
179638afb9SPatrick Williams #include "config.h"
189638afb9SPatrick Williams
199638afb9SPatrick Williams #include "users.hpp"
209638afb9SPatrick Williams
21a1a754c2SAbhilash Raju #include "totp.hpp"
229638afb9SPatrick Williams #include "user_mgr.hpp"
239638afb9SPatrick Williams
24a1a754c2SAbhilash Raju #include <pwd.h>
259f630d9eSRichard Marian Thomaiyar #include <sys/types.h>
269f630d9eSRichard Marian Thomaiyar #include <sys/wait.h>
279638afb9SPatrick Williams #include <unistd.h>
289638afb9SPatrick Williams
299638afb9SPatrick Williams #include <phosphor-logging/elog-errors.hpp>
309638afb9SPatrick Williams #include <phosphor-logging/elog.hpp>
3111ec666bSJiaqing Zhao #include <phosphor-logging/lg2.hpp>
329f630d9eSRichard Marian Thomaiyar #include <xyz/openbmc_project/Common/error.hpp>
339f630d9eSRichard Marian Thomaiyar #include <xyz/openbmc_project/User/Common/error.hpp>
349638afb9SPatrick Williams
359638afb9SPatrick Williams #include <filesystem>
36a1a754c2SAbhilash Raju #include <fstream>
37a1a754c2SAbhilash Raju #include <map>
389f630d9eSRichard Marian Thomaiyar namespace phosphor
399f630d9eSRichard Marian Thomaiyar {
409f630d9eSRichard Marian Thomaiyar namespace user
419f630d9eSRichard Marian Thomaiyar {
429f630d9eSRichard Marian Thomaiyar
439f630d9eSRichard Marian Thomaiyar using namespace phosphor::logging;
449f630d9eSRichard Marian Thomaiyar using InsufficientPermission =
459f630d9eSRichard Marian Thomaiyar sdbusplus::xyz::openbmc_project::Common::Error::InsufficientPermission;
469f630d9eSRichard Marian Thomaiyar using InternalFailure =
479f630d9eSRichard Marian Thomaiyar sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
489f630d9eSRichard Marian Thomaiyar using InvalidArgument =
499f630d9eSRichard Marian Thomaiyar sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
509f630d9eSRichard Marian Thomaiyar using NoResource =
519f630d9eSRichard Marian Thomaiyar sdbusplus::xyz::openbmc_project::User::Common::Error::NoResource;
52a1a754c2SAbhilash Raju using UnsupportedRequest =
53a1a754c2SAbhilash Raju sdbusplus::xyz::openbmc_project::Common::Error::UnsupportedRequest;
549f630d9eSRichard Marian Thomaiyar
559f630d9eSRichard Marian Thomaiyar using Argument = xyz::openbmc_project::Common::InvalidArgument;
56a1a754c2SAbhilash Raju static constexpr auto authAppPath = "/usr/bin/google-authenticator";
57a1a754c2SAbhilash Raju static constexpr auto secretKeyPath = "/home/{}/.google_authenticator";
58a1a754c2SAbhilash Raju static constexpr auto secretKeyTempPath =
59a1a754c2SAbhilash Raju "/home/{}/.config/phosphor-user-manager/.google_authenticator.tmp";
609f630d9eSRichard Marian Thomaiyar
619f630d9eSRichard Marian Thomaiyar /** @brief Constructs UserMgr object.
629f630d9eSRichard Marian Thomaiyar *
639f630d9eSRichard Marian Thomaiyar * @param[in] bus - sdbusplus handler
649f630d9eSRichard Marian Thomaiyar * @param[in] path - D-Bus path
659f630d9eSRichard Marian Thomaiyar * @param[in] groups - users group list
669f630d9eSRichard Marian Thomaiyar * @param[in] priv - user privilege
679f630d9eSRichard Marian Thomaiyar * @param[in] enabled - user enabled state
689f630d9eSRichard Marian Thomaiyar * @param[in] parent - user manager - parent object
699f630d9eSRichard Marian Thomaiyar */
Users(sdbusplus::bus_t & bus,const char * path,std::vector<std::string> groups,std::string priv,bool enabled,UserMgr & parent)70b3ef4e1aSPatrick Williams Users::Users(sdbusplus::bus_t& bus, const char* path,
719f630d9eSRichard Marian Thomaiyar std::vector<std::string> groups, std::string priv, bool enabled,
729f630d9eSRichard Marian Thomaiyar UserMgr& parent) :
73224559b4SPatrick Williams Interfaces(bus, path, Interfaces::action::defer_emit),
74b01e2fe7SP Dheeraj Srujan Kumar userName(sdbusplus::message::object_path(path).filename()), manager(parent)
759f630d9eSRichard Marian Thomaiyar {
769f630d9eSRichard Marian Thomaiyar UsersIface::userPrivilege(priv, true);
779f630d9eSRichard Marian Thomaiyar UsersIface::userGroups(groups, true);
789f630d9eSRichard Marian Thomaiyar UsersIface::userEnabled(enabled, true);
79*93804ebaSAbhilash Raju load(manager.getSerializer());
801af12233SRatan Gupta this->emit_object_added();
819f630d9eSRichard Marian Thomaiyar }
~Users()82*93804ebaSAbhilash Raju Users::~Users()
83*93804ebaSAbhilash Raju {
84*93804ebaSAbhilash Raju manager.getSerializer().erase(userName);
85*93804ebaSAbhilash Raju }
869f630d9eSRichard Marian Thomaiyar /** @brief delete user method.
879f630d9eSRichard Marian Thomaiyar * This method deletes the user as requested
889f630d9eSRichard Marian Thomaiyar *
899f630d9eSRichard Marian Thomaiyar */
delete_(void)909f630d9eSRichard Marian Thomaiyar void Users::delete_(void)
919f630d9eSRichard Marian Thomaiyar {
929f630d9eSRichard Marian Thomaiyar manager.deleteUser(userName);
939f630d9eSRichard Marian Thomaiyar }
949f630d9eSRichard Marian Thomaiyar
959f630d9eSRichard Marian Thomaiyar /** @brief update user privilege
969f630d9eSRichard Marian Thomaiyar *
979f630d9eSRichard Marian Thomaiyar * @param[in] value - User privilege
989f630d9eSRichard Marian Thomaiyar */
userPrivilege(std::string value)999f630d9eSRichard Marian Thomaiyar std::string Users::userPrivilege(std::string value)
1009f630d9eSRichard Marian Thomaiyar {
1019f630d9eSRichard Marian Thomaiyar if (value == UsersIface::userPrivilege())
1029f630d9eSRichard Marian Thomaiyar {
1039f630d9eSRichard Marian Thomaiyar return value;
1049f630d9eSRichard Marian Thomaiyar }
1059f630d9eSRichard Marian Thomaiyar manager.updateGroupsAndPriv(userName, UsersIface::userGroups(), value);
1069f630d9eSRichard Marian Thomaiyar return UsersIface::userPrivilege(value);
1079f630d9eSRichard Marian Thomaiyar }
1089f630d9eSRichard Marian Thomaiyar
setUserPrivilege(const std::string & value)109fef63038SNan Zhou void Users::setUserPrivilege(const std::string& value)
110fef63038SNan Zhou {
111fef63038SNan Zhou UsersIface::userPrivilege(value);
112fef63038SNan Zhou }
113fef63038SNan Zhou
setUserGroups(const std::vector<std::string> & groups)114fef63038SNan Zhou void Users::setUserGroups(const std::vector<std::string>& groups)
115fef63038SNan Zhou {
116fef63038SNan Zhou UsersIface::userGroups(groups);
117fef63038SNan Zhou }
118fef63038SNan Zhou
1199f630d9eSRichard Marian Thomaiyar /** @brief list user privilege
1209f630d9eSRichard Marian Thomaiyar *
1219f630d9eSRichard Marian Thomaiyar */
userPrivilege(void) const1229f630d9eSRichard Marian Thomaiyar std::string Users::userPrivilege(void) const
1239f630d9eSRichard Marian Thomaiyar {
1249f630d9eSRichard Marian Thomaiyar return UsersIface::userPrivilege();
1259f630d9eSRichard Marian Thomaiyar }
1269f630d9eSRichard Marian Thomaiyar
1279f630d9eSRichard Marian Thomaiyar /** @brief update user groups
1289f630d9eSRichard Marian Thomaiyar *
1299f630d9eSRichard Marian Thomaiyar * @param[in] value - User groups
1309f630d9eSRichard Marian Thomaiyar */
userGroups(std::vector<std::string> value)1319f630d9eSRichard Marian Thomaiyar std::vector<std::string> Users::userGroups(std::vector<std::string> value)
1329f630d9eSRichard Marian Thomaiyar {
1339f630d9eSRichard Marian Thomaiyar if (value == UsersIface::userGroups())
1349f630d9eSRichard Marian Thomaiyar {
1359f630d9eSRichard Marian Thomaiyar return value;
1369f630d9eSRichard Marian Thomaiyar }
1379f630d9eSRichard Marian Thomaiyar std::sort(value.begin(), value.end());
1389f630d9eSRichard Marian Thomaiyar manager.updateGroupsAndPriv(userName, value, UsersIface::userPrivilege());
1399f630d9eSRichard Marian Thomaiyar return UsersIface::userGroups(value);
1409f630d9eSRichard Marian Thomaiyar }
1419f630d9eSRichard Marian Thomaiyar
1429f630d9eSRichard Marian Thomaiyar /** @brief list user groups
1439f630d9eSRichard Marian Thomaiyar *
1449f630d9eSRichard Marian Thomaiyar */
userGroups(void) const1459f630d9eSRichard Marian Thomaiyar std::vector<std::string> Users::userGroups(void) const
1469f630d9eSRichard Marian Thomaiyar {
1479f630d9eSRichard Marian Thomaiyar return UsersIface::userGroups();
1489f630d9eSRichard Marian Thomaiyar }
1499f630d9eSRichard Marian Thomaiyar
1509f630d9eSRichard Marian Thomaiyar /** @brief lists user enabled state
1519f630d9eSRichard Marian Thomaiyar *
1529f630d9eSRichard Marian Thomaiyar */
userEnabled(void) const1539f630d9eSRichard Marian Thomaiyar bool Users::userEnabled(void) const
1549f630d9eSRichard Marian Thomaiyar {
155e8edab57SDenis Zlobin return manager.isUserEnabled(userName);
1569f630d9eSRichard Marian Thomaiyar }
1579f630d9eSRichard Marian Thomaiyar
setUserEnabled(bool value)1586b6f2d80SNan Zhou void Users::setUserEnabled(bool value)
1596b6f2d80SNan Zhou {
1606b6f2d80SNan Zhou UsersIface::userEnabled(value);
1616b6f2d80SNan Zhou }
1626b6f2d80SNan Zhou
1639f630d9eSRichard Marian Thomaiyar /** @brief update user enabled state
1649f630d9eSRichard Marian Thomaiyar *
1659f630d9eSRichard Marian Thomaiyar * @param[in] value - bool value
1669f630d9eSRichard Marian Thomaiyar */
userEnabled(bool value)1679f630d9eSRichard Marian Thomaiyar bool Users::userEnabled(bool value)
1689f630d9eSRichard Marian Thomaiyar {
1699f630d9eSRichard Marian Thomaiyar if (value == UsersIface::userEnabled())
1709f630d9eSRichard Marian Thomaiyar {
1719f630d9eSRichard Marian Thomaiyar return value;
1729f630d9eSRichard Marian Thomaiyar }
1739f630d9eSRichard Marian Thomaiyar manager.userEnable(userName, value);
1749f630d9eSRichard Marian Thomaiyar return UsersIface::userEnabled(value);
1759f630d9eSRichard Marian Thomaiyar }
1769f630d9eSRichard Marian Thomaiyar
177c704519eSRichard Marian Thomaiyar /** @brief lists user locked state for failed attempt
178c704519eSRichard Marian Thomaiyar *
179c704519eSRichard Marian Thomaiyar **/
userLockedForFailedAttempt(void) const180c704519eSRichard Marian Thomaiyar bool Users::userLockedForFailedAttempt(void) const
181c704519eSRichard Marian Thomaiyar {
182c704519eSRichard Marian Thomaiyar return manager.userLockedForFailedAttempt(userName);
183c704519eSRichard Marian Thomaiyar }
184c704519eSRichard Marian Thomaiyar
185c704519eSRichard Marian Thomaiyar /** @brief unlock user locked state for failed attempt
186c704519eSRichard Marian Thomaiyar *
187c704519eSRichard Marian Thomaiyar * @param[in]: value - false - unlock user account, true - no action taken
188c704519eSRichard Marian Thomaiyar **/
userLockedForFailedAttempt(bool value)189c704519eSRichard Marian Thomaiyar bool Users::userLockedForFailedAttempt(bool value)
190c704519eSRichard Marian Thomaiyar {
191c704519eSRichard Marian Thomaiyar if (value != false)
192c704519eSRichard Marian Thomaiyar {
193c704519eSRichard Marian Thomaiyar return userLockedForFailedAttempt();
194c704519eSRichard Marian Thomaiyar }
195c704519eSRichard Marian Thomaiyar else
196c704519eSRichard Marian Thomaiyar {
197c704519eSRichard Marian Thomaiyar return manager.userLockedForFailedAttempt(userName, value);
198c704519eSRichard Marian Thomaiyar }
199c704519eSRichard Marian Thomaiyar }
200c704519eSRichard Marian Thomaiyar
2013ab6cc28SJoseph Reynolds /** @brief indicates if the user's password is expired
2023ab6cc28SJoseph Reynolds *
2033ab6cc28SJoseph Reynolds **/
userPasswordExpired(void) const2043ab6cc28SJoseph Reynolds bool Users::userPasswordExpired(void) const
2053ab6cc28SJoseph Reynolds {
2063ab6cc28SJoseph Reynolds return manager.userPasswordExpired(userName);
2073ab6cc28SJoseph Reynolds }
changeFileOwnership(const std::string & filePath,const std::string & userName)208a1a754c2SAbhilash Raju bool changeFileOwnership(const std::string& filePath,
209a1a754c2SAbhilash Raju const std::string& userName)
210a1a754c2SAbhilash Raju {
211a1a754c2SAbhilash Raju // Get the user ID
212a1a754c2SAbhilash Raju passwd* pwd = getpwnam(userName.c_str());
213a1a754c2SAbhilash Raju if (pwd == nullptr)
214a1a754c2SAbhilash Raju {
215a1a754c2SAbhilash Raju lg2::error("Failed to get user ID for user:{USER}", "USER", userName);
216a1a754c2SAbhilash Raju return false;
217a1a754c2SAbhilash Raju }
218a1a754c2SAbhilash Raju // Change the ownership of the file
219a1a754c2SAbhilash Raju if (chown(filePath.c_str(), pwd->pw_uid, pwd->pw_gid) != 0)
220a1a754c2SAbhilash Raju {
221a1a754c2SAbhilash Raju lg2::error("Ownership change error {PATH}", "PATH", filePath);
222a1a754c2SAbhilash Raju return false;
223a1a754c2SAbhilash Raju }
224a1a754c2SAbhilash Raju return true;
225a1a754c2SAbhilash Raju }
checkMfaStatus() const226a1a754c2SAbhilash Raju bool Users::checkMfaStatus() const
227a1a754c2SAbhilash Raju {
228a1a754c2SAbhilash Raju return (manager.enabled() != MultiFactorAuthType::None &&
229a1a754c2SAbhilash Raju Interfaces::bypassedProtocol() == MultiFactorAuthType::None);
230a1a754c2SAbhilash Raju }
createSecretKey()231a1a754c2SAbhilash Raju std::string Users::createSecretKey()
232a1a754c2SAbhilash Raju {
233a1a754c2SAbhilash Raju if (!std::filesystem::exists(authAppPath))
234a1a754c2SAbhilash Raju {
235a1a754c2SAbhilash Raju lg2::error("No authenticator app found at {PATH}", "PATH", authAppPath);
236a1a754c2SAbhilash Raju throw UnsupportedRequest();
237a1a754c2SAbhilash Raju }
238a1a754c2SAbhilash Raju std::string path = std::format(secretKeyTempPath, userName);
239a1a754c2SAbhilash Raju if (!std::filesystem::exists(std::filesystem::path(path).parent_path()))
240a1a754c2SAbhilash Raju {
241a1a754c2SAbhilash Raju std::filesystem::create_directories(
242a1a754c2SAbhilash Raju std::filesystem::path(path).parent_path());
243a1a754c2SAbhilash Raju }
244a1a754c2SAbhilash Raju /*
245a1a754c2SAbhilash Raju -u no-rate-limit
246a1a754c2SAbhilash Raju -W minimal-window
247a1a754c2SAbhilash Raju -Q qr-mode (NONE, ANSI, UTF8)
248a1a754c2SAbhilash Raju -t time-based
249a1a754c2SAbhilash Raju -f force file
250a1a754c2SAbhilash Raju -d disallow-reuse
251a1a754c2SAbhilash Raju -C no-confirm no confirmation required for code provisioned
252a1a754c2SAbhilash Raju */
253a1a754c2SAbhilash Raju executeCmd(authAppPath, "-s", path.c_str(), "-u", "-W", "-Q", "NONE", "-t",
254a1a754c2SAbhilash Raju "-f", "-d", "-C");
255a1a754c2SAbhilash Raju if (!std::filesystem::exists(path))
256a1a754c2SAbhilash Raju {
257a1a754c2SAbhilash Raju lg2::error("Failed to create secret key for user {USER}", "USER",
258a1a754c2SAbhilash Raju userName);
259a1a754c2SAbhilash Raju throw UnsupportedRequest();
260a1a754c2SAbhilash Raju }
261a1a754c2SAbhilash Raju std::ifstream file(path);
262a1a754c2SAbhilash Raju if (!file.is_open())
263a1a754c2SAbhilash Raju {
264a1a754c2SAbhilash Raju lg2::error("Failed to open secret key file {PATH}", "PATH", path);
265a1a754c2SAbhilash Raju throw UnsupportedRequest();
266a1a754c2SAbhilash Raju }
267a1a754c2SAbhilash Raju std::string secret;
268a1a754c2SAbhilash Raju std::getline(file, secret);
269a1a754c2SAbhilash Raju file.close();
270a1a754c2SAbhilash Raju if (!changeFileOwnership(path, userName))
271a1a754c2SAbhilash Raju {
272a1a754c2SAbhilash Raju throw UnsupportedRequest();
273a1a754c2SAbhilash Raju }
274a1a754c2SAbhilash Raju return secret;
275a1a754c2SAbhilash Raju }
verifyOTP(std::string otp)276a1a754c2SAbhilash Raju bool Users::verifyOTP(std::string otp)
277a1a754c2SAbhilash Raju {
278a1a754c2SAbhilash Raju if (Totp::verify(getUserName(), otp) == PAM_SUCCESS)
279a1a754c2SAbhilash Raju {
280a1a754c2SAbhilash Raju // If MFA is enabled for the user register the secret key
281a1a754c2SAbhilash Raju if (checkMfaStatus())
282a1a754c2SAbhilash Raju {
283a1a754c2SAbhilash Raju try
284a1a754c2SAbhilash Raju {
285a1a754c2SAbhilash Raju std::filesystem::rename(
286a1a754c2SAbhilash Raju std::format(secretKeyTempPath, getUserName()),
287a1a754c2SAbhilash Raju std::format(secretKeyPath, getUserName()));
288a1a754c2SAbhilash Raju }
289a1a754c2SAbhilash Raju catch (const std::filesystem::filesystem_error& e)
290a1a754c2SAbhilash Raju {
291a1a754c2SAbhilash Raju lg2::error("Failed to rename file: {CODE}", "CODE", e);
292a1a754c2SAbhilash Raju return false;
293a1a754c2SAbhilash Raju }
294a1a754c2SAbhilash Raju }
295a1a754c2SAbhilash Raju else
296a1a754c2SAbhilash Raju {
297a1a754c2SAbhilash Raju std::filesystem::remove(
298a1a754c2SAbhilash Raju std::format(secretKeyTempPath, getUserName()));
299a1a754c2SAbhilash Raju }
300a1a754c2SAbhilash Raju return true;
301a1a754c2SAbhilash Raju }
302a1a754c2SAbhilash Raju return false;
303a1a754c2SAbhilash Raju }
clearSecretFile(const std::string & path)304a1a754c2SAbhilash Raju static void clearSecretFile(const std::string& path)
305a1a754c2SAbhilash Raju {
306a1a754c2SAbhilash Raju if (std::filesystem::exists(path))
307a1a754c2SAbhilash Raju {
308a1a754c2SAbhilash Raju std::filesystem::remove(path);
309a1a754c2SAbhilash Raju }
310a1a754c2SAbhilash Raju }
clearGoogleAuthenticator(Users & thisp)311a1a754c2SAbhilash Raju static void clearGoogleAuthenticator(Users& thisp)
312a1a754c2SAbhilash Raju {
313a1a754c2SAbhilash Raju clearSecretFile(std::format(secretKeyPath, thisp.getUserName()));
314a1a754c2SAbhilash Raju clearSecretFile(std::format(secretKeyTempPath, thisp.getUserName()));
315a1a754c2SAbhilash Raju }
316a1a754c2SAbhilash Raju static std::map<MultiFactorAuthType, std::function<void(Users&)>>
317a1a754c2SAbhilash Raju mfaBypassHandlers{{MultiFactorAuthType::GoogleAuthenticator,
318a1a754c2SAbhilash Raju clearGoogleAuthenticator},
__anon90507c8b0102(Users&) 319a1a754c2SAbhilash Raju {MultiFactorAuthType::None, [](Users&) {}}};
320a1a754c2SAbhilash Raju
bypassedProtocol(MultiFactorAuthType value,bool skipSignal)321a1a754c2SAbhilash Raju MultiFactorAuthType Users::bypassedProtocol(MultiFactorAuthType value,
322a1a754c2SAbhilash Raju bool skipSignal)
323a1a754c2SAbhilash Raju {
324a1a754c2SAbhilash Raju auto iter = mfaBypassHandlers.find(value);
325a1a754c2SAbhilash Raju if (iter != end(mfaBypassHandlers))
326a1a754c2SAbhilash Raju {
327a1a754c2SAbhilash Raju iter->second(*this);
328a1a754c2SAbhilash Raju }
329*93804ebaSAbhilash Raju std::string path = std::format("{}/bypassedprotocol", getUserName());
330*93804ebaSAbhilash Raju manager.getSerializer().serialize(
331*93804ebaSAbhilash Raju path, MultiFactorAuthConfiguration::convertTypeToString(value));
332*93804ebaSAbhilash Raju manager.getSerializer().store();
333a1a754c2SAbhilash Raju return Interfaces::bypassedProtocol(value, skipSignal);
334a1a754c2SAbhilash Raju }
335a1a754c2SAbhilash Raju
secretKeyIsValid() const336a1a754c2SAbhilash Raju bool Users::secretKeyIsValid() const
337a1a754c2SAbhilash Raju {
338a1a754c2SAbhilash Raju std::string path = std::format(secretKeyPath, getUserName());
339a1a754c2SAbhilash Raju return std::filesystem::exists(path);
340a1a754c2SAbhilash Raju }
341a1a754c2SAbhilash Raju
googleAuthenticatorEnabled(Users & user,bool)342a1a754c2SAbhilash Raju inline void googleAuthenticatorEnabled(Users& user, bool /*unused*/)
343a1a754c2SAbhilash Raju {
344a1a754c2SAbhilash Raju clearGoogleAuthenticator(user);
345a1a754c2SAbhilash Raju }
346a1a754c2SAbhilash Raju static std::map<MultiFactorAuthType, std::function<void(Users&, bool)>>
347a1a754c2SAbhilash Raju mfaEnableHandlers{{MultiFactorAuthType::GoogleAuthenticator,
348a1a754c2SAbhilash Raju googleAuthenticatorEnabled},
__anon90507c8b0202(Users&, bool) 349a1a754c2SAbhilash Raju {MultiFactorAuthType::None, [](Users&, bool) {}}};
350a1a754c2SAbhilash Raju
enableMultiFactorAuth(MultiFactorAuthType type,bool value)351a1a754c2SAbhilash Raju void Users::enableMultiFactorAuth(MultiFactorAuthType type, bool value)
352a1a754c2SAbhilash Raju {
353a1a754c2SAbhilash Raju auto iter = mfaEnableHandlers.find(type);
354a1a754c2SAbhilash Raju if (iter != end(mfaEnableHandlers))
355a1a754c2SAbhilash Raju {
356a1a754c2SAbhilash Raju iter->second(*this, value);
357a1a754c2SAbhilash Raju }
358a1a754c2SAbhilash Raju }
secretKeyGenerationRequired() const359a1a754c2SAbhilash Raju bool Users::secretKeyGenerationRequired() const
360a1a754c2SAbhilash Raju {
361a1a754c2SAbhilash Raju return checkMfaStatus() && !secretKeyIsValid();
362a1a754c2SAbhilash Raju }
clearSecretKey()363a1a754c2SAbhilash Raju void Users::clearSecretKey()
364a1a754c2SAbhilash Raju {
365a1a754c2SAbhilash Raju if (!checkMfaStatus())
366a1a754c2SAbhilash Raju {
367a1a754c2SAbhilash Raju throw UnsupportedRequest();
368a1a754c2SAbhilash Raju }
369a1a754c2SAbhilash Raju clearGoogleAuthenticator(*this);
370a1a754c2SAbhilash Raju }
3713ab6cc28SJoseph Reynolds
load(JsonSerializer & ts)372*93804ebaSAbhilash Raju void Users::load(JsonSerializer& ts)
373*93804ebaSAbhilash Raju {
374*93804ebaSAbhilash Raju std::optional<std::string> protocol;
375*93804ebaSAbhilash Raju std::string path = std::format("{}/bypassedprotocol", userName);
376*93804ebaSAbhilash Raju ts.deserialize(path, protocol);
377*93804ebaSAbhilash Raju if (protocol)
378*93804ebaSAbhilash Raju {
379*93804ebaSAbhilash Raju MultiFactorAuthType type =
380*93804ebaSAbhilash Raju MultiFactorAuthConfiguration::convertTypeFromString(*protocol);
381*93804ebaSAbhilash Raju bypassedProtocol(type, true);
382*93804ebaSAbhilash Raju return;
383*93804ebaSAbhilash Raju }
384*93804ebaSAbhilash Raju bypassedProtocol(MultiFactorAuthType::None, true);
385*93804ebaSAbhilash Raju ts.serialize(path, MultiFactorAuthConfiguration::convertTypeToString(
386*93804ebaSAbhilash Raju MultiFactorAuthType::None));
387*93804ebaSAbhilash Raju }
388*93804ebaSAbhilash Raju
3899f630d9eSRichard Marian Thomaiyar } // namespace user
3909f630d9eSRichard Marian Thomaiyar } // namespace phosphor
391