Skip to content

Commit f23c2e6

Browse files
committed
server: reset 2fa user configuration on incomplete setup
Fixes #9308 When 2FA isn't validated and completed during setup and a login request is done, this PR clears 2FA configuration to allow setting it up again. Signed-off-by: Abhishek Kumar <[email protected]>
1 parent 9967bb3 commit f23c2e6

File tree

6 files changed

+43
-1
lines changed

6 files changed

+43
-1
lines changed

engine/schema/src/main/java/com/cloud/user/UserAccountVO.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535

3636
import com.cloud.utils.db.Encrypt;
3737
import com.cloud.utils.db.GenericDao;
38+
39+
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
3840
import org.apache.commons.lang3.StringUtils;
3941

4042
@Entity
@@ -368,4 +370,9 @@ public Map<String, String> getDetails() {
368370
public void setDetails(Map<String, String> details) {
369371
this.details = details;
370372
}
373+
374+
@Override
375+
public String toString() {
376+
return String.format("User %s", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "id", "name", "uuid"));
377+
}
371378
}

plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,4 +516,9 @@ public String getConfigComponentName() {
516516
public ConfigKey<?>[] getConfigKeys() {
517517
return null;
518518
}
519+
520+
@Override
521+
public UserAccount clearUserTwoFactorAuthenticationInSetupStateOnLogin(UserAccount user) {
522+
return null;
523+
}
519524
}

server/src/main/java/com/cloud/api/ApiServer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1159,7 +1159,7 @@ public ResponseObject loginUser(final HttpSession session, final String username
11591159
domainId = userDomain.getId();
11601160
}
11611161

1162-
final UserAccount userAcct = accountMgr.authenticateUser(username, password, domainId, loginIpAddress, requestParameters);
1162+
UserAccount userAcct = accountMgr.authenticateUser(username, password, domainId, loginIpAddress, requestParameters);
11631163
if (userAcct != null) {
11641164
final String timezone = userAcct.getTimezone();
11651165
float offsetInHrs = 0f;
@@ -1204,6 +1204,7 @@ public ResponseObject loginUser(final HttpSession session, final String username
12041204
session.setAttribute("timezoneoffset", Float.valueOf(offsetInHrs).toString());
12051205
}
12061206

1207+
userAcct = accountMgr.clearUserTwoFactorAuthenticationInSetupStateOnLogin(userAcct);
12071208
boolean is2faEnabled = false;
12081209
if (userAcct.isUser2faEnabled() || (Boolean.TRUE.equals(AccountManagerImpl.enableUserTwoFactorAuthentication.valueIn(userAcct.getDomainId())) && Boolean.TRUE.equals(AccountManagerImpl.mandateUserTwoFactorAuthentication.valueIn(userAcct.getDomainId())))) {
12091210
is2faEnabled = true;

server/src/main/java/com/cloud/user/AccountManager.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> s
195195
UserTwoFactorAuthenticator getUserTwoFactorAuthenticator(final Long domainId, final Long userAccountId);
196196

197197
void verifyUsingTwoFactorAuthenticationCode(String code, Long domainId, Long userAccountId);
198+
198199
UserTwoFactorAuthenticationSetupResponse setupUserTwoFactorAuthentication(SetupUserTwoFactorAuthenticationCmd cmd);
199200

201+
UserAccount clearUserTwoFactorAuthenticationInSetupStateOnLogin(UserAccount user);
202+
200203
}

server/src/main/java/com/cloud/user/AccountManagerImpl.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3475,4 +3475,26 @@ public UserTwoFactorAuthenticator getUserTwoFactorAuthenticator(final String nam
34753475
return userTwoFactorAuthenticationProvidersMap.get(name.toLowerCase());
34763476
}
34773477

3478+
@Override
3479+
public UserAccount clearUserTwoFactorAuthenticationInSetupStateOnLogin(UserAccount user) {
3480+
return Transaction.execute((TransactionCallback<UserAccount>) status -> {
3481+
if (!user.isUser2faEnabled() && StringUtils.isBlank(user.getUser2faProvider())) {
3482+
return user;
3483+
}
3484+
UserDetailVO userDetailVO = _userDetailsDao.findDetail(user.getId(), UserDetailVO.Setup2FADetail);
3485+
if (userDetailVO != null && UserAccountVO.Setup2FAstatus.VERIFIED.name().equals(userDetailVO.getValue())) {
3486+
return user;
3487+
}
3488+
s_logger.info(String.format("Clearing 2FA configurations for %s as it is still in setup on a new login request", user));
3489+
if (userDetailVO != null) {
3490+
_userDetailsDao.remove(userDetailVO.getId());
3491+
}
3492+
UserAccountVO userAccountVO = _userAccountDao.findById(user.getId());
3493+
userAccountVO.setUser2faEnabled(false);
3494+
userAccountVO.setUser2faProvider(null);
3495+
userAccountVO.setKeyFor2fa(null);
3496+
_userAccountDao.update(user.getId(), userAccountVO);
3497+
return userAccountVO;
3498+
});
3499+
}
34783500
}

server/src/test/java/com/cloud/user/MockAccountManagerImpl.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,4 +484,8 @@ public ConfigKey<?>[] getConfigKeys() {
484484
return null;
485485
}
486486

487+
@Override
488+
public UserAccount clearUserTwoFactorAuthenticationInSetupStateOnLogin(UserAccount user) {
489+
return null;
490+
}
487491
}

0 commit comments

Comments
 (0)