harikrishna-patnala commented on code in PR #6924:
URL: https://github.com/apache/cloudstack/pull/6924#discussion_r1035565094


##########
server/src/main/java/com/cloud/user/AccountManagerImpl.java:
##########
@@ -3100,6 +3171,151 @@ public String getConfigComponentName() {
 
     @Override
     public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {UseSecretKeyInResponse};
+        return new ConfigKey<?>[] {UseSecretKeyInResponse, 
enableUserTwoFactorAuthentication, userTwoFactorAuthenticationDefaultProvider, 
mandateUserTwoFactorAuthentication};
+    }
+
+    public List<UserTwoFactorAuthenticator> 
getUserTwoFactorAuthenticationProviders() {
+        return userTwoFactorAuthenticationProviders;
+    }
+
+    public void setUserTwoFactorAuthenticationProviders(final 
List<UserTwoFactorAuthenticator> userTwoFactorAuthenticationProviders) {
+        this.userTwoFactorAuthenticationProviders = 
userTwoFactorAuthenticationProviders;
+    }
+
+    private void initializeUserTwoFactorAuthenticationProvidersMap() {
+        if (userTwoFactorAuthenticationProviders != null) {
+            for (final UserTwoFactorAuthenticator userTwoFactorAuthenticator : 
userTwoFactorAuthenticationProviders) {
+                
userTwoFactorAuthenticationProvidersMap.put(userTwoFactorAuthenticator.getName().toLowerCase(),
 userTwoFactorAuthenticator);
+            }
+        }
+    }
+
+    @Override
+    public void verifyUsingTwoFactorAuthenticationCode(final String code, 
final Long domainId, final Long userAccountId) {
+
+        Account caller = CallContext.current().getCallingAccount();
+        Account owner = _accountService.getActiveAccountById(caller.getId());
+
+        checkAccess(caller, null, true, owner);
+
+        UserAccount userAccount = 
_accountService.getUserAccountById(userAccountId);
+        if (!userAccount.isUser2faEnabled()) {
+            throw new CloudRuntimeException(String.format("Two factor 
authentication is not enabled on the user: %s", userAccount.getUsername()));
+        }
+        UserTwoFactorAuthenticator userTwoFactorAuthenticator = 
getUserTwoFactorAuthenticator(domainId, userAccountId);
+        userTwoFactorAuthenticator.check2FA(code, userAccount);
+    }
+
+    @Override
+    public UserTwoFactorAuthenticator getUserTwoFactorAuthenticator(Long 
domainId, Long userAccountId) {
+        if (userAccountId != null) {
+            UserAccount userAccount = 
_accountService.getUserAccountById(userAccountId);
+            if (userAccount.getUser2faProvider() != null) {
+                return 
getUserTwoFactorAuthenticator(userAccount.getUser2faProvider());
+            }
+        }
+        final String name = 
userTwoFactorAuthenticationDefaultProvider.valueIn(domainId);
+        return getUserTwoFactorAuthenticator(name);
+    }
+
+    @Override
+    public UserTwoFactorAuthenticationSetupResponse 
setupUserTwoFactorAuthentication(SetupUserTwoFactorAuthenticationCmd cmd) {
+        String providerName = cmd.getProvider();
+
+        Account caller = CallContext.current().getCallingAccount();
+        Account owner = _accountService.getActiveAccountById(caller.getId());
+
+        if (cmd.getEnable()) {
+            checkAccess(caller, null, true, owner);
+            Long userId = CallContext.current().getCallingUserId();
+
+            UserTwoFactorAuthenticationSetupResponse response = 
enableTwoFactorAuthentication(userId, providerName);
+            return response;
+        }
+
+        // Admin can disable 2FA of the users
+        Long userId = cmd.getUserId();
+        UserTwoFactorAuthenticationSetupResponse response = 
disableTwoFactorAuthentication(userId, caller, owner);
+
+        return response;
+    }
+
+    protected UserTwoFactorAuthenticationSetupResponse 
enableTwoFactorAuthentication(Long userId, String providerName) {
+        UserAccountVO userAccount = _userAccountDao.findById(userId);
+        UserVO userVO = _userDao.findById(userId);
+
+        if 
(!enableUserTwoFactorAuthentication.valueIn(userAccount.getDomainId())) {
+            throw new CloudRuntimeException("2FA is not enabled for this 
domain or at global level");
+        }
+
+        if (StringUtils.isEmpty(providerName)) {
+            throw new InvalidParameterValueException("Provider name is 
mandatory to setup 2FA");
+        }
+        UserTwoFactorAuthenticator provider = 
getUserTwoFactorAuthenticationProvider(providerName);
+        String code = provider.setup2FAKey(userAccount);
+        UserVO user = _userDao.createForUpdate();
+        user.setKeyFor2fa(code);
+        user.setUser2faProvider(provider.getName());
+        user.setUser2faEnabled(true);
+        _userDao.update(userId, user);
+
+        UserTwoFactorAuthenticationSetupResponse response = new 
UserTwoFactorAuthenticationSetupResponse();
+        response.setId(userVO.getUuid());
+        response.setUsername(userAccount.getUsername());
+        response.setSecretCode(code);
+
+        return response;
     }
+
+    protected UserTwoFactorAuthenticationSetupResponse 
disableTwoFactorAuthentication(Long userId, Account caller, Account owner) {
+        UserVO userVO = null;
+        if (userId != null) {
+            userVO = validateUser(userId, caller.getDomainId());
+            if (userVO == null) {
+                throw new InvalidParameterValueException("Unable to find user= 
" + userVO.getUsername() + " in domain id = " + caller.getDomainId());
+            }
+            owner = 
_accountService.getActiveAccountById(userVO.getAccountId());
+        } else {
+            userId = CallContext.current().getCallingUserId();
+            userVO = _userDao.findById(userId);
+        }
+        checkAccess(caller, null, true, owner);
+
+        UserVO user = _userDao.createForUpdate();
+        user.setKeyFor2fa(null);
+        user.setUser2faProvider(null);
+        user.setUser2faEnabled(false);
+        _userDao.update(userVO.getId(), user);
+
+        UserTwoFactorAuthenticationSetupResponse response = new 
UserTwoFactorAuthenticationSetupResponse();
+        response.setId(userVO.getUuid());
+        response.setUsername(userVO.getUsername());
+
+        return response;
+    }
+
+    private UserVO validateUser(Long userId, Long domainId) {
+        UserVO user = null;
+        if (userId != null) {
+            user = _userDao.findById(userId);
+            if (user == null) {
+                throw new InvalidParameterValueException("Invalid user ID 
provided");
+            }
+            if (_accountDao.findById(user.getAccountId()).getDomainId() != 
domainId) {
+                throw new InvalidParameterValueException("User doesn't belong 
to the specified account or domain");
+            }
+        }
+        return user;
+    }
+
+    public UserTwoFactorAuthenticator getUserTwoFactorAuthenticator(final 
String name) {
+        if (StringUtils.isEmpty(name)) {
+            throw new CloudRuntimeException("Invalid 
UserTwoFactorAuthenticator name provided");
+        }
+        if (!userTwoFactorAuthenticationProvidersMap.containsKey(name)) {

Review Comment:
   yeah, added toLowerCase() methods while adding and fetching from the map.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to