Ensure at least one 2FA account config is default
This commit is contained in:
parent
2ff2cf7ad8
commit
d3c23c914d
@ -50,7 +50,6 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE;
|
import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE;
|
||||||
@ -191,20 +190,10 @@ public class TwoFaConfigController extends BaseController {
|
|||||||
@RequestBody TwoFaAccountConfigUpdateRequest updateRequest) throws ThingsboardException {
|
@RequestBody TwoFaAccountConfigUpdateRequest updateRequest) throws ThingsboardException {
|
||||||
SecurityUser user = getCurrentUser();
|
SecurityUser user = getCurrentUser();
|
||||||
|
|
||||||
AccountTwoFaSettings settings = twoFaConfigManager.getAccountTwoFaSettings(user.getTenantId(), user.getId())
|
TwoFaAccountConfig accountConfig = twoFaConfigManager.getTwoFaAccountConfig(user.getTenantId(), user.getId(), providerType)
|
||||||
.orElseThrow(() -> new IllegalArgumentException("No 2FA config found"));
|
.orElseThrow(() -> new IllegalArgumentException("Config for " + providerType + " 2FA provider not found"));
|
||||||
Map<TwoFaProviderType, TwoFaAccountConfig> configs = settings.getConfigs();
|
|
||||||
|
|
||||||
TwoFaAccountConfig accountConfig;
|
|
||||||
if ((accountConfig = configs.get(providerType)) == null) {
|
|
||||||
throw new IllegalArgumentException("Config for " + providerType + " 2FA provider not found");
|
|
||||||
}
|
|
||||||
if (updateRequest.isUseByDefault()) {
|
|
||||||
configs.values().forEach(config -> config.setUseByDefault(false));
|
|
||||||
}
|
|
||||||
accountConfig.setUseByDefault(updateRequest.isUseByDefault());
|
accountConfig.setUseByDefault(updateRequest.isUseByDefault());
|
||||||
|
return twoFaConfigManager.saveTwoFaAccountConfig(user.getTenantId(), user.getId(), accountConfig);
|
||||||
return twoFaConfigManager.saveAccountTwoFaSettings(user.getTenantId(), user.getId(), settings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "Delete 2FA account config (deleteTwoFaAccountConfig)", notes =
|
@ApiOperation(value = "Delete 2FA account config (deleteTwoFaAccountConfig)", notes =
|
||||||
|
|||||||
@ -38,11 +38,10 @@ import org.thingsboard.server.dao.settings.AdminSettingsService;
|
|||||||
import org.thingsboard.server.dao.user.UserAuthSettingsDao;
|
import org.thingsboard.server.dao.user.UserAuthSettingsDao;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@ -68,8 +67,7 @@ public class DefaultTwoFaConfigManager implements TwoFaConfigManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected AccountTwoFaSettings saveAccountTwoFaSettings(TenantId tenantId, UserId userId, AccountTwoFaSettings settings) {
|
||||||
public AccountTwoFaSettings saveAccountTwoFaSettings(TenantId tenantId, UserId userId, AccountTwoFaSettings settings) {
|
|
||||||
UserAuthSettings userAuthSettings = Optional.ofNullable(userAuthSettingsDao.findByUserId(userId))
|
UserAuthSettings userAuthSettings = Optional.ofNullable(userAuthSettingsDao.findByUserId(userId))
|
||||||
.orElseGet(() -> {
|
.orElseGet(() -> {
|
||||||
UserAuthSettings newUserAuthSettings = new UserAuthSettings();
|
UserAuthSettings newUserAuthSettings = new UserAuthSettings();
|
||||||
@ -99,7 +97,13 @@ public class DefaultTwoFaConfigManager implements TwoFaConfigManager {
|
|||||||
newSettings.setConfigs(new LinkedHashMap<>());
|
newSettings.setConfigs(new LinkedHashMap<>());
|
||||||
return newSettings;
|
return newSettings;
|
||||||
});
|
});
|
||||||
|
if (accountConfig.isUseByDefault()) {
|
||||||
|
settings.getConfigs().values().forEach(config -> config.setUseByDefault(false));
|
||||||
|
}
|
||||||
settings.getConfigs().put(accountConfig.getProviderType(), accountConfig);
|
settings.getConfigs().put(accountConfig.getProviderType(), accountConfig);
|
||||||
|
if (settings.getConfigs().values().stream().noneMatch(TwoFaAccountConfig::isUseByDefault)) {
|
||||||
|
settings.getConfigs().values().stream().findFirst().ifPresent(config -> config.setUseByDefault(true));
|
||||||
|
}
|
||||||
return saveAccountTwoFaSettings(tenantId, userId, settings);
|
return saveAccountTwoFaSettings(tenantId, userId, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,6 +112,11 @@ public class DefaultTwoFaConfigManager implements TwoFaConfigManager {
|
|||||||
AccountTwoFaSettings settings = getAccountTwoFaSettings(tenantId, userId)
|
AccountTwoFaSettings settings = getAccountTwoFaSettings(tenantId, userId)
|
||||||
.orElseThrow(() -> new IllegalArgumentException("2FA not configured"));
|
.orElseThrow(() -> new IllegalArgumentException("2FA not configured"));
|
||||||
settings.getConfigs().remove(providerType);
|
settings.getConfigs().remove(providerType);
|
||||||
|
if (!settings.getConfigs().isEmpty() && settings.getConfigs().values().stream().noneMatch(TwoFaAccountConfig::isUseByDefault)) {
|
||||||
|
settings.getConfigs().values().stream()
|
||||||
|
.min(Comparator.comparing(TwoFaAccountConfig::getProviderType))
|
||||||
|
.ifPresent(config -> config.setUseByDefault(true));
|
||||||
|
}
|
||||||
return saveAccountTwoFaSettings(tenantId, userId, settings);
|
return saveAccountTwoFaSettings(tenantId, userId, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,6 @@ public interface TwoFaConfigManager {
|
|||||||
|
|
||||||
Optional<AccountTwoFaSettings> getAccountTwoFaSettings(TenantId tenantId, UserId userId);
|
Optional<AccountTwoFaSettings> getAccountTwoFaSettings(TenantId tenantId, UserId userId);
|
||||||
|
|
||||||
AccountTwoFaSettings saveAccountTwoFaSettings(TenantId tenantId, UserId userId, AccountTwoFaSettings settings);
|
|
||||||
|
|
||||||
Optional<TwoFaAccountConfig> getTwoFaAccountConfig(TenantId tenantId, UserId userId, TwoFaProviderType providerType);
|
Optional<TwoFaAccountConfig> getTwoFaAccountConfig(TenantId tenantId, UserId userId, TwoFaProviderType providerType);
|
||||||
|
|
||||||
|
|||||||
@ -303,6 +303,7 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest {
|
|||||||
loginTenantAdmin();
|
loginTenantAdmin();
|
||||||
|
|
||||||
TotpTwoFaAccountConfig generatedTotpTwoFaAccountConfig = generateTotpTwoFaAccountConfig(totpTwoFaProviderConfig);
|
TotpTwoFaAccountConfig generatedTotpTwoFaAccountConfig = generateTotpTwoFaAccountConfig(totpTwoFaProviderConfig);
|
||||||
|
generatedTotpTwoFaAccountConfig.setUseByDefault(true);
|
||||||
|
|
||||||
String secret = UriComponentsBuilder.fromUriString(generatedTotpTwoFaAccountConfig.getAuthUrl()).build()
|
String secret = UriComponentsBuilder.fromUriString(generatedTotpTwoFaAccountConfig.getAuthUrl()).build()
|
||||||
.getQueryParams().getFirst("secret");
|
.getQueryParams().getFirst("secret");
|
||||||
@ -421,6 +422,7 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest {
|
|||||||
|
|
||||||
SmsTwoFaAccountConfig smsTwoFaAccountConfig = new SmsTwoFaAccountConfig();
|
SmsTwoFaAccountConfig smsTwoFaAccountConfig = new SmsTwoFaAccountConfig();
|
||||||
smsTwoFaAccountConfig.setPhoneNumber("+38051889445");
|
smsTwoFaAccountConfig.setPhoneNumber("+38051889445");
|
||||||
|
smsTwoFaAccountConfig.setUseByDefault(true);
|
||||||
|
|
||||||
ArgumentCaptor<String> verificationCodeCaptor = ArgumentCaptor.forClass(String.class);
|
ArgumentCaptor<String> verificationCodeCaptor = ArgumentCaptor.forClass(String.class);
|
||||||
doPost("/api/2fa/account/config/submit", smsTwoFaAccountConfig).andExpect(status().isOk());
|
doPost("/api/2fa/account/config/submit", smsTwoFaAccountConfig).andExpect(status().isOk());
|
||||||
@ -459,6 +461,7 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest {
|
|||||||
|
|
||||||
SmsTwoFaAccountConfig initialSmsTwoFaAccountConfig = new SmsTwoFaAccountConfig();
|
SmsTwoFaAccountConfig initialSmsTwoFaAccountConfig = new SmsTwoFaAccountConfig();
|
||||||
initialSmsTwoFaAccountConfig.setPhoneNumber("+38051889445");
|
initialSmsTwoFaAccountConfig.setPhoneNumber("+38051889445");
|
||||||
|
initialSmsTwoFaAccountConfig.setUseByDefault(true);
|
||||||
|
|
||||||
ArgumentCaptor<String> verificationCodeCaptor = ArgumentCaptor.forClass(String.class);
|
ArgumentCaptor<String> verificationCodeCaptor = ArgumentCaptor.forClass(String.class);
|
||||||
doPost("/api/2fa/account/config/submit", initialSmsTwoFaAccountConfig).andExpect(status().isOk());
|
doPost("/api/2fa/account/config/submit", initialSmsTwoFaAccountConfig).andExpect(status().isOk());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user