From c78958502bf4592f2b11310ac8c6427dd4d04f7a Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Tue, 18 Nov 2025 18:14:37 +0200 Subject: [PATCH] Fix 2FA enforcement when admin deletes used 2FA method --- .../mfa/config/DefaultTwoFaConfigManager.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/config/DefaultTwoFaConfigManager.java b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/config/DefaultTwoFaConfigManager.java index ad04d3e962..3f7d711378 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/config/DefaultTwoFaConfigManager.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/config/DefaultTwoFaConfigManager.java @@ -16,7 +16,6 @@ package org.thingsboard.server.service.security.auth.mfa.config; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; @@ -49,12 +48,11 @@ public class DefaultTwoFaConfigManager implements TwoFaConfigManager { private final UserAuthSettingsDao userAuthSettingsDao; private final AdminSettingsService adminSettingsService; private final AdminSettingsDao adminSettingsDao; - @Autowired @Lazy - private TwoFactorAuthService twoFactorAuthService; + @Lazy + private final TwoFactorAuthService twoFactorAuthService; protected static final String TWO_FACTOR_AUTH_SETTINGS_KEY = "twoFaSettings"; - @Override public Optional getAccountTwoFaSettings(TenantId tenantId, User user) { PlatformTwoFaSettings platformTwoFaSettings = getPlatformTwoFaSettings(tenantId, true).orElse(null); @@ -87,11 +85,6 @@ public class DefaultTwoFaConfigManager implements TwoFaConfigManager { } protected AccountTwoFaSettings saveAccountTwoFaSettings(TenantId tenantId, User user, AccountTwoFaSettings settings) { - if (settings.getConfigs().isEmpty()) { - if (twoFactorAuthService.isEnforceTwoFaEnabled(tenantId, user)) { - throw new DataValidationException("At least one 2FA provider is required"); - } - } UserAuthSettings userAuthSettings = Optional.ofNullable(userAuthSettingsDao.findByUserId(user.getId())) .orElseGet(() -> { UserAuthSettings newUserAuthSettings = new UserAuthSettings(); @@ -105,7 +98,6 @@ public class DefaultTwoFaConfigManager implements TwoFaConfigManager { return settings; } - @Override public Optional getTwoFaAccountConfig(TenantId tenantId, User user, TwoFaProviderType providerType) { return getAccountTwoFaSettings(tenantId, user) @@ -134,6 +126,7 @@ public class DefaultTwoFaConfigManager implements TwoFaConfigManager { if (configs.values().stream().noneMatch(TwoFaAccountConfig::isUseByDefault)) { configs.values().stream().findFirst().ifPresent(config -> config.setUseByDefault(true)); } + checkAccountTwoFaSettings(tenantId, user, settings); return saveAccountTwoFaSettings(tenantId, user, settings); } @@ -151,6 +144,7 @@ public class DefaultTwoFaConfigManager implements TwoFaConfigManager { .min(Comparator.comparing(TwoFaAccountConfig::getProviderType)) .ifPresent(config -> config.setUseByDefault(true)); } + checkAccountTwoFaSettings(tenantId, user, settings); return saveAccountTwoFaSettings(tenantId, user, settings); } @@ -203,4 +197,12 @@ public class DefaultTwoFaConfigManager implements TwoFaConfigManager { .ifPresent(adminSettings -> adminSettingsDao.removeById(tenantId, adminSettings.getId().getId())); } + private void checkAccountTwoFaSettings(TenantId tenantId, User user, AccountTwoFaSettings settings) { + if (settings.getConfigs().isEmpty()) { + if (twoFactorAuthService.isEnforceTwoFaEnabled(tenantId, user)) { + throw new DataValidationException("At least one 2FA provider is required"); + } + } + } + }