Browse Source

Update 2FA tests

pull/6235/head
Viacheslav Klimov 4 years ago
parent
commit
05301efe2c
  1. 55
      application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthConfigTest.java
  2. 693
      application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java
  3. 2
      common/message/src/test/java/org/thingsboard/server/common/msg/tools/RateLimitsTest.java

55
application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthConfigTest.java

@ -30,6 +30,7 @@ import org.springframework.web.util.UriComponentsBuilder;
import org.thingsboard.rule.engine.api.SmsService; import org.thingsboard.rule.engine.api.SmsService;
import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.security.model.mfa.account.AccountTwoFaSettings;
import org.thingsboard.server.service.security.auth.mfa.TwoFactorAuthService; import org.thingsboard.server.service.security.auth.mfa.TwoFactorAuthService;
import org.thingsboard.server.service.security.auth.mfa.config.TwoFaConfigManager; import org.thingsboard.server.service.security.auth.mfa.config.TwoFaConfigManager;
import org.thingsboard.server.common.data.security.model.mfa.PlatformTwoFaSettings; import org.thingsboard.server.common.data.security.model.mfa.PlatformTwoFaSettings;
@ -82,15 +83,15 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest {
@Test @Test
public void testSaveTwoFaSettings() throws Exception { public void testSavePlatformTwoFaSettingsForDifferentAuthorities() throws Exception {
loginSysAdmin(); loginSysAdmin();
testSaveTestTwoFaSettings(); testSavePlatformTwoFaSettings();
loginTenantAdmin(); loginTenantAdmin();
testSaveTestTwoFaSettings(); testSavePlatformTwoFaSettings();
} }
private void testSaveTestTwoFaSettings() throws Exception { private void testSavePlatformTwoFaSettings() throws Exception {
TotpTwoFaProviderConfig totpTwoFaProviderConfig = new TotpTwoFaProviderConfig(); TotpTwoFaProviderConfig totpTwoFaProviderConfig = new TotpTwoFaProviderConfig();
totpTwoFaProviderConfig.setIssuerName("tb"); totpTwoFaProviderConfig.setIssuerName("tb");
SmsTwoFaProviderConfig smsTwoFaProviderConfig = new SmsTwoFaProviderConfig(); SmsTwoFaProviderConfig smsTwoFaProviderConfig = new SmsTwoFaProviderConfig();
@ -113,7 +114,7 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest {
} }
@Test @Test
public void testSaveTwoFaSettings_validationError() throws Exception { public void testSavePlatformTwoFaSettings_validationError() throws Exception {
loginTenantAdmin(); loginTenantAdmin();
PlatformTwoFaSettings twoFaSettings = new PlatformTwoFaSettings(); PlatformTwoFaSettings twoFaSettings = new PlatformTwoFaSettings();
@ -147,7 +148,7 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest {
} }
@Test @Test
public void testGetTwoFaSettings_useSysadminSettingsAsDefault() throws Exception { public void testGetPlatformTwoFaSettings_useSysadminSettingsAsDefault() throws Exception {
loginSysAdmin(); loginSysAdmin();
PlatformTwoFaSettings sysadminTwoFaSettings = new PlatformTwoFaSettings(); PlatformTwoFaSettings sysadminTwoFaSettings = new PlatformTwoFaSettings();
TotpTwoFaProviderConfig totpTwoFaProviderConfig = new TotpTwoFaProviderConfig(); TotpTwoFaProviderConfig totpTwoFaProviderConfig = new TotpTwoFaProviderConfig();
@ -204,7 +205,7 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest {
TotpTwoFaProviderConfig invalidTotpTwoFaProviderConfig = new TotpTwoFaProviderConfig(); TotpTwoFaProviderConfig invalidTotpTwoFaProviderConfig = new TotpTwoFaProviderConfig();
invalidTotpTwoFaProviderConfig.setIssuerName(" "); invalidTotpTwoFaProviderConfig.setIssuerName(" ");
String errorResponse = saveTwoFaSettingsAndGetError(invalidTotpTwoFaProviderConfig); String errorResponse = savePlatformTwoFaSettingsAndGetError(invalidTotpTwoFaProviderConfig);
assertThat(errorResponse).containsIgnoringCase("issuer name must not be blank"); assertThat(errorResponse).containsIgnoringCase("issuer name must not be blank");
} }
@ -214,17 +215,17 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest {
invalidSmsTwoFaProviderConfig.setSmsVerificationMessageTemplate("does not contain verification code"); invalidSmsTwoFaProviderConfig.setSmsVerificationMessageTemplate("does not contain verification code");
invalidSmsTwoFaProviderConfig.setVerificationCodeLifetime(60); invalidSmsTwoFaProviderConfig.setVerificationCodeLifetime(60);
String errorResponse = saveTwoFaSettingsAndGetError(invalidSmsTwoFaProviderConfig); String errorResponse = savePlatformTwoFaSettingsAndGetError(invalidSmsTwoFaProviderConfig);
assertThat(errorResponse).containsIgnoringCase("must contain verification code"); assertThat(errorResponse).containsIgnoringCase("must contain verification code");
invalidSmsTwoFaProviderConfig.setSmsVerificationMessageTemplate(null); invalidSmsTwoFaProviderConfig.setSmsVerificationMessageTemplate(null);
invalidSmsTwoFaProviderConfig.setVerificationCodeLifetime(0); invalidSmsTwoFaProviderConfig.setVerificationCodeLifetime(0);
errorResponse = saveTwoFaSettingsAndGetError(invalidSmsTwoFaProviderConfig); errorResponse = savePlatformTwoFaSettingsAndGetError(invalidSmsTwoFaProviderConfig);
assertThat(errorResponse).containsIgnoringCase("verification message template is required"); assertThat(errorResponse).containsIgnoringCase("verification message template is required");
assertThat(errorResponse).containsIgnoringCase("verification code lifetime is required"); assertThat(errorResponse).containsIgnoringCase("verification code lifetime is required");
} }
private String saveTwoFaSettingsAndGetError(TwoFaProviderConfig invalidTwoFaProviderConfig) throws Exception { private String savePlatformTwoFaSettingsAndGetError(TwoFaProviderConfig invalidTwoFaProviderConfig) throws Exception {
PlatformTwoFaSettings twoFaSettings = new PlatformTwoFaSettings(); PlatformTwoFaSettings twoFaSettings = new PlatformTwoFaSettings();
twoFaSettings.setProviders(Collections.singletonList(invalidTwoFaProviderConfig)); twoFaSettings.setProviders(Collections.singletonList(invalidTwoFaProviderConfig));
@ -232,6 +233,7 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest {
.andExpect(status().isBadRequest())); .andExpect(status().isBadRequest()));
} }
@Test @Test
public void testSaveTwoFaAccountConfig_providerNotConfigured() throws Exception { public void testSaveTwoFaAccountConfig_providerNotConfigured() throws Exception {
configureSmsTwoFaProvider("${verificationCode}"); configureSmsTwoFaProvider("${verificationCode}");
@ -255,7 +257,7 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest {
loginTenantAdmin(); loginTenantAdmin();
assertThat(readResponse(doGet("/api/2fa/account/config").andExpect(status().isOk()), String.class)).isNullOrEmpty(); assertThat(readResponse(doGet("/api/2fa/account/settings").andExpect(status().isOk()), String.class)).isNullOrEmpty();
generateTotpTwoFaAccountConfig(totpTwoFaProviderConfig); generateTotpTwoFaAccountConfig(totpTwoFaProviderConfig);
} }
@ -309,7 +311,10 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest {
doPost("/api/2fa/account/config?verificationCode=" + correctVerificationCode, generatedTotpTwoFaAccountConfig) doPost("/api/2fa/account/config?verificationCode=" + correctVerificationCode, generatedTotpTwoFaAccountConfig)
.andExpect(status().isOk()); .andExpect(status().isOk());
TwoFaAccountConfig twoFaAccountConfig = readResponse(doGet("/api/2fa/account/config").andExpect(status().isOk()), TwoFaAccountConfig.class); AccountTwoFaSettings accountTwoFaSettings = readResponse(doGet("/api/2fa/account/settings").andExpect(status().isOk()), AccountTwoFaSettings.class);
assertThat(accountTwoFaSettings.getConfigs()).size().isOne();
TwoFaAccountConfig twoFaAccountConfig = accountTwoFaSettings.getConfigs().get(TwoFaProviderType.TOTP);
assertThat(twoFaAccountConfig).isEqualTo(generatedTotpTwoFaAccountConfig); assertThat(twoFaAccountConfig).isEqualTo(generatedTotpTwoFaAccountConfig);
} }
@ -349,15 +354,16 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest {
@Test @Test
public void testGetTwoFaAccountConfig_whenProviderNotConfigured() throws Exception { public void testGetTwoFaAccountConfig_whenProviderNotConfigured() throws Exception {
testVerifyAndSaveTotpTwoFaAccountConfig(); testVerifyAndSaveTotpTwoFaAccountConfig();
assertThat(readResponse(doGet("/api/2fa/account/config").andExpect(status().isOk()), assertThat(readResponse(doGet("/api/2fa/account/settings").andExpect(status().isOk()),
TotpTwoFaAccountConfig.class)).isNotNull(); AccountTwoFaSettings.class).getConfigs()).isNotEmpty();
loginSysAdmin(); loginSysAdmin();
saveProvidersConfigs(); saveProvidersConfigs();
assertThat(readResponse(doGet("/api/2fa/account/config").andExpect(status().isOk()), String.class)) loginTenantAdmin();
.isNullOrEmpty();
assertThat(readResponse(doGet("/api/2fa/account/settings").andExpect(status().isOk()), AccountTwoFaSettings.class).getConfigs())
.isEmpty();
} }
@Test @Test
@ -427,7 +433,8 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest {
doPost("/api/2fa/account/config?verificationCode=" + correctVerificationCode, smsTwoFaAccountConfig) doPost("/api/2fa/account/config?verificationCode=" + correctVerificationCode, smsTwoFaAccountConfig)
.andExpect(status().isOk()); .andExpect(status().isOk());
TwoFaAccountConfig accountConfig = readResponse(doGet("/api/2fa/account/config").andExpect(status().isOk()), TwoFaAccountConfig.class); AccountTwoFaSettings accountTwoFaSettings = readResponse(doGet("/api/2fa/account/settings").andExpect(status().isOk()), AccountTwoFaSettings.class);
TwoFaAccountConfig accountConfig = accountTwoFaSettings.getConfigs().get(TwoFaProviderType.SMS);
assertThat(accountConfig).isEqualTo(smsTwoFaAccountConfig); assertThat(accountConfig).isEqualTo(smsTwoFaAccountConfig);
} }
@ -470,7 +477,8 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest {
doPost("/api/2fa/account/config?verificationCode=" + correctVerificationCode, initialSmsTwoFaAccountConfig) doPost("/api/2fa/account/config?verificationCode=" + correctVerificationCode, initialSmsTwoFaAccountConfig)
.andExpect(status().isOk()); .andExpect(status().isOk());
TwoFaAccountConfig accountConfig = readResponse(doGet("/api/2fa/account/config").andExpect(status().isOk()), TwoFaAccountConfig.class); AccountTwoFaSettings accountTwoFaSettings = readResponse(doGet("/api/2fa/account/settings").andExpect(status().isOk()), AccountTwoFaSettings.class);
TwoFaAccountConfig accountConfig = accountTwoFaSettings.getConfigs().get(TwoFaProviderType.SMS);
assertThat(accountConfig).isEqualTo(initialSmsTwoFaAccountConfig); assertThat(accountConfig).isEqualTo(initialSmsTwoFaAccountConfig);
} }
@ -518,13 +526,14 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest {
twoFaConfigManager.saveTwoFaAccountConfig(tenantId, tenantAdminUserId, accountConfig); twoFaConfigManager.saveTwoFaAccountConfig(tenantId, tenantAdminUserId, accountConfig);
TwoFaAccountConfig savedAccountConfig = readResponse(doGet("/api/2fa/account/config").andExpect(status().isOk()), TwoFaAccountConfig.class); AccountTwoFaSettings accountTwoFaSettings = readResponse(doGet("/api/2fa/account/settings").andExpect(status().isOk()), AccountTwoFaSettings.class);
TwoFaAccountConfig savedAccountConfig = accountTwoFaSettings.getConfigs().get(TwoFaProviderType.SMS);
assertThat(savedAccountConfig).isEqualTo(accountConfig); assertThat(savedAccountConfig).isEqualTo(accountConfig);
doDelete("/api/2fa/account/config").andExpect(status().isOk()); doDelete("/api/2fa/account/config?providerType=SMS").andExpect(status().isOk());
assertThat(readResponse(doGet("/api/2fa/account/config").andExpect(status().isOk()), String.class)) assertThat(readResponse(doGet("/api/2fa/account/settings").andExpect(status().isOk()), AccountTwoFaSettings.class).getConfigs())
.isNullOrEmpty(); .doesNotContainKey(TwoFaProviderType.SMS);
} }
} }

693
application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java

@ -15,6 +15,7 @@
*/ */
package org.thingsboard.server.controller; package org.thingsboard.server.controller;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -36,23 +37,26 @@ import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.page.SortOrder; import org.thingsboard.server.common.data.page.SortOrder;
import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.audit.AuditLogService;
import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.service.security.auth.mfa.TwoFactorAuthService;
import org.thingsboard.server.service.security.auth.mfa.config.TwoFaConfigManager;
import org.thingsboard.server.common.data.security.model.mfa.PlatformTwoFaSettings; import org.thingsboard.server.common.data.security.model.mfa.PlatformTwoFaSettings;
import org.thingsboard.server.common.data.security.model.mfa.account.EmailTwoFaAccountConfig;
import org.thingsboard.server.common.data.security.model.mfa.account.SmsTwoFaAccountConfig; import org.thingsboard.server.common.data.security.model.mfa.account.SmsTwoFaAccountConfig;
import org.thingsboard.server.common.data.security.model.mfa.account.TotpTwoFaAccountConfig; import org.thingsboard.server.common.data.security.model.mfa.account.TotpTwoFaAccountConfig;
import org.thingsboard.server.common.data.security.model.mfa.provider.EmailTwoFaProviderConfig;
import org.thingsboard.server.common.data.security.model.mfa.provider.SmsTwoFaProviderConfig; import org.thingsboard.server.common.data.security.model.mfa.provider.SmsTwoFaProviderConfig;
import org.thingsboard.server.common.data.security.model.mfa.provider.TotpTwoFaProviderConfig; import org.thingsboard.server.common.data.security.model.mfa.provider.TotpTwoFaProviderConfig;
import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderConfig; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderConfig;
import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType;
import org.thingsboard.server.dao.audit.AuditLogService;
import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.service.security.auth.mfa.TwoFactorAuthService;
import org.thingsboard.server.service.security.auth.mfa.config.TwoFaConfigManager;
import org.thingsboard.server.service.security.auth.rest.LoginRequest; import org.thingsboard.server.service.security.auth.rest.LoginRequest;
import org.thingsboard.server.service.security.model.JwtTokenPair; import org.thingsboard.server.service.security.model.JwtTokenPair;
import java.time.Duration; import java.time.Duration;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -68,319 +72,372 @@ import static org.mockito.Mockito.verify;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
public abstract class TwoFactorAuthTest extends AbstractControllerTest { public abstract class TwoFactorAuthTest extends AbstractControllerTest {
//
// @Autowired @Autowired
// private TwoFaConfigManager twoFaConfigManager; private TwoFaConfigManager twoFaConfigManager;
// @Autowired @Autowired
// private TwoFactorAuthService twoFactorAuthService; private TwoFactorAuthService twoFactorAuthService;
// @MockBean @MockBean
// private SmsService smsService; private SmsService smsService;
// @Autowired @Autowired
// private AuditLogService auditLogService; private AuditLogService auditLogService;
// @Autowired @Autowired
// private UserService userService; private UserService userService;
//
// private User user; private User user;
// private String username; private String username;
// private String password; private String password;
//
// @Before @Before
// public void beforeEach() throws Exception { public void beforeEach() throws Exception {
// username = "mfa@tb.io"; username = "mfa@tb.io";
// password = "psswrd"; password = "psswrd";
//
// user = new User(); user = new User();
// user.setAuthority(Authority.TENANT_ADMIN); user.setAuthority(Authority.TENANT_ADMIN);
// user.setEmail(username); user.setEmail(username);
// user.setTenantId(tenantId); user.setTenantId(tenantId);
//
// loginSysAdmin(); loginSysAdmin();
// user = createUser(user, password); user = createUser(user, password);
// } }
//
// @After @After
// public void afterEach() { public void afterEach() {
// twoFaConfigManager.deletePlatformTwoFaSettings(tenantId); twoFaConfigManager.deletePlatformTwoFaSettings(tenantId);
// twoFaConfigManager.deletePlatformTwoFaSettings(TenantId.SYS_TENANT_ID); twoFaConfigManager.deletePlatformTwoFaSettings(TenantId.SYS_TENANT_ID);
// } }
//
// @Test @Test
// public void testTwoFa_totp() throws Exception { public void testTwoFa_totp() throws Exception {
// TotpTwoFaAccountConfig totpTwoFaAccountConfig = configureTotpTwoFa(); TotpTwoFaAccountConfig totpTwoFaAccountConfig = configureTotpTwoFa();
//
// logInWithPreVerificationToken(); logInWithPreVerificationToken(username, password);
//
// doPost("/api/auth/2fa/verification/send") doPost("/api/auth/2fa/verification/send?providerType=TOTP")
// .andExpect(status().isOk()); .andExpect(status().isOk());
//
// String correctVerificationCode = getCorrectTotp(totpTwoFaAccountConfig); String correctVerificationCode = getCorrectTotp(totpTwoFaAccountConfig);
//
// JsonNode tokenPair = readResponse(doPost("/api/auth/2fa/verification/check?verificationCode=" + correctVerificationCode) JsonNode tokenPair = readResponse(doPost("/api/auth/2fa/verification/check?providerType=TOTP&verificationCode=" + correctVerificationCode)
// .andExpect(status().isOk()), JsonNode.class); .andExpect(status().isOk()), JsonNode.class);
// validateAndSetJwtToken(tokenPair, username); validateAndSetJwtToken(tokenPair, username);
//
// User currentUser = readResponse(doGet("/api/auth/user") User currentUser = readResponse(doGet("/api/auth/user")
// .andExpect(status().isOk()), User.class); .andExpect(status().isOk()), User.class);
// assertThat(currentUser.getId()).isEqualTo(user.getId()); assertThat(currentUser.getId()).isEqualTo(user.getId());
// } }
//
// @Test @Test
// public void testTwoFa_sms() throws Exception { public void testTwoFa_sms() throws Exception {
// configureSmsTwoFa(); configureSmsTwoFa();
//
// logInWithPreVerificationToken(); logInWithPreVerificationToken(username, password);
//
// doPost("/api/auth/2fa/verification/send") doPost("/api/auth/2fa/verification/send?providerType=SMS")
// .andExpect(status().isOk()); .andExpect(status().isOk());
//
// ArgumentCaptor<String> verificationCodeCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor<String> verificationCodeCaptor = ArgumentCaptor.forClass(String.class);
// verify(smsService).sendSms(eq(tenantId), any(), any(), verificationCodeCaptor.capture()); verify(smsService).sendSms(eq(tenantId), any(), any(), verificationCodeCaptor.capture());
// String correctVerificationCode = verificationCodeCaptor.getValue(); String correctVerificationCode = verificationCodeCaptor.getValue();
//
// JsonNode tokenPair = readResponse(doPost("/api/auth/2fa/verification/check?verificationCode=" + correctVerificationCode) JsonNode tokenPair = readResponse(doPost("/api/auth/2fa/verification/check?providerType=SMS&verificationCode=" + correctVerificationCode)
// .andExpect(status().isOk()), JsonNode.class); .andExpect(status().isOk()), JsonNode.class);
// validateAndSetJwtToken(tokenPair, username); validateAndSetJwtToken(tokenPair, username);
//
// User currentUser = readResponse(doGet("/api/auth/user") User currentUser = readResponse(doGet("/api/auth/user")
// .andExpect(status().isOk()), User.class); .andExpect(status().isOk()), User.class);
// assertThat(currentUser.getId()).isEqualTo(user.getId()); assertThat(currentUser.getId()).isEqualTo(user.getId());
// } }
//
// @Test @Test
// public void testTwoFaPreVerificationTokenLifetime() throws Exception { public void testTwoFaPreVerificationTokenLifetime() throws Exception {
// configureTotpTwoFa(twoFaSettings -> { configureTotpTwoFa(twoFaSettings -> {
// twoFaSettings.setTotalAllowedTimeForVerification(5); twoFaSettings.setTotalAllowedTimeForVerification(5);
// }); });
//
// logInWithPreVerificationToken(); logInWithPreVerificationToken(username, password);
//
// await("expiration of the pre-verification token") await("expiration of the pre-verification token")
// .atLeast(Duration.ofSeconds(3).plusMillis(500)) .atLeast(Duration.ofSeconds(3).plusMillis(500))
// .atMost(Duration.ofSeconds(6)) .atMost(Duration.ofSeconds(6))
// .untilAsserted(() -> { .untilAsserted(() -> {
// doPost("/api/auth/2fa/verification/send") doPost("/api/auth/2fa/verification/send?providerType=TOTP")
// .andExpect(status().isUnauthorized()); .andExpect(status().isUnauthorized());
// }); });
// } }
//
// @Test @Test
// public void testCheckVerificationCode_userBlocked() throws Exception { public void testCheckVerificationCode_userBlocked() throws Exception {
// configureTotpTwoFa(twoFaSettings -> { configureTotpTwoFa(twoFaSettings -> {
// twoFaSettings.setMaxVerificationFailuresBeforeUserLockout(10); twoFaSettings.setMaxVerificationFailuresBeforeUserLockout(10);
// }); });
//
// logInWithPreVerificationToken(); logInWithPreVerificationToken(username, password);
//
// Stream.generate(() -> RandomStringUtils.randomNumeric(6)) Stream.generate(() -> RandomStringUtils.randomNumeric(6))
// .limit(9) .limit(9)
// .forEach(incorrectVerificationCode -> { .forEach(incorrectVerificationCode -> {
// try { try {
// String errorMessage = getErrorMessage(doPost("/api/auth/2fa/verification/check?verificationCode=" + incorrectVerificationCode) String errorMessage = getErrorMessage(doPost("/api/auth/2fa/verification/check?providerType=TOTP&verificationCode=" + incorrectVerificationCode)
// .andExpect(status().isBadRequest())); .andExpect(status().isBadRequest()));
// assertThat(errorMessage).containsIgnoringCase("verification code is incorrect"); assertThat(errorMessage).containsIgnoringCase("verification code is incorrect");
// } catch (Exception e) { } catch (Exception e) {
// fail(); fail();
// } }
// }); });
//
// String errorMessage = getErrorMessage(doPost("/api/auth/2fa/verification/check?verificationCode=" + RandomStringUtils.randomNumeric(6)) String errorMessage = getErrorMessage(doPost("/api/auth/2fa/verification/check?providerType=TOTP&verificationCode=" + RandomStringUtils.randomNumeric(6))
// .andExpect(status().isUnauthorized())); .andExpect(status().isUnauthorized()));
// assertThat(errorMessage).containsIgnoringCase("account was locked due to exceeded 2fa verification attempts"); assertThat(errorMessage).containsIgnoringCase("account was locked due to exceeded 2fa verification attempts");
//
// errorMessage = getErrorMessage(doPost("/api/auth/2fa/verification/check?verificationCode=" + RandomStringUtils.randomNumeric(6)) errorMessage = getErrorMessage(doPost("/api/auth/2fa/verification/check?providerType=TOTP&verificationCode=" + RandomStringUtils.randomNumeric(6))
// .andExpect(status().isUnauthorized())); .andExpect(status().isUnauthorized()));
// assertThat(errorMessage).containsIgnoringCase("user is disabled"); assertThat(errorMessage).containsIgnoringCase("user is disabled");
// } }
//
// @Test @Test
// public void testSendVerificationCode_rateLimit() throws Exception { public void testSendVerificationCode_rateLimit() throws Exception {
// configureTotpTwoFa(twoFaSettings -> { configureTotpTwoFa(twoFaSettings -> {
// twoFaSettings.setVerificationCodeSendRateLimit("3:10"); twoFaSettings.setVerificationCodeSendRateLimit("3:10");
// }); });
//
// logInWithPreVerificationToken(); logInWithPreVerificationToken(username, password);
//
// for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
// doPost("/api/auth/2fa/verification/send") doPost("/api/auth/2fa/verification/send?providerType=TOTP")
// .andExpect(status().isOk()); .andExpect(status().isOk());
// } }
//
// String rateLimitExceededError = getErrorMessage(doPost("/api/auth/2fa/verification/send") String rateLimitExceededError = getErrorMessage(doPost("/api/auth/2fa/verification/send?providerType=TOTP")
// .andExpect(status().isTooManyRequests())); .andExpect(status().isTooManyRequests()));
// assertThat(rateLimitExceededError).containsIgnoringCase("too many verification code sending requests"); assertThat(rateLimitExceededError).containsIgnoringCase("too many requests");
//
// await("verification code sending rate limit resetting") await("verification code sending rate limit resetting")
// .atLeast(Duration.ofSeconds(8)) .atLeast(Duration.ofSeconds(8))
// .atMost(Duration.ofSeconds(12)) .atMost(Duration.ofSeconds(12))
// .untilAsserted(() -> { .untilAsserted(() -> {
// doPost("/api/auth/2fa/verification/send") doPost("/api/auth/2fa/verification/send?providerType=TOTP")
// .andExpect(status().isOk()); .andExpect(status().isOk());
// }); });
// } }
//
// @Test @Test
// public void testCheckVerificationCode_rateLimit() throws Exception { public void testCheckVerificationCode_rateLimit() throws Exception {
// TotpTwoFaAccountConfig totpTwoFaAccountConfig = configureTotpTwoFa(twoFaSettings -> { TotpTwoFaAccountConfig totpTwoFaAccountConfig = configureTotpTwoFa(twoFaSettings -> {
// twoFaSettings.setVerificationCodeCheckRateLimit("3:10"); twoFaSettings.setVerificationCodeCheckRateLimit("3:10");
// }); });
//
// logInWithPreVerificationToken(); logInWithPreVerificationToken(username, password);
//
// for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
// String incorrectVerificationCodeError = getErrorMessage(doPost("/api/auth/2fa/verification/check?verificationCode=incorrect") String incorrectVerificationCodeError = getErrorMessage(doPost("/api/auth/2fa/verification/check?providerType=TOTP&verificationCode=incorrect")
// .andExpect(status().isBadRequest())); .andExpect(status().isBadRequest()));
// assertThat(incorrectVerificationCodeError).containsIgnoringCase("verification code is incorrect"); assertThat(incorrectVerificationCodeError).containsIgnoringCase("verification code is incorrect");
// } }
//
// String rateLimitExceededError = getErrorMessage(doPost("/api/auth/2fa/verification/check?verificationCode=incorrect") String rateLimitExceededError = getErrorMessage(doPost("/api/auth/2fa/verification/check?providerType=TOTP&verificationCode=incorrect")
// .andExpect(status().isTooManyRequests())); .andExpect(status().isTooManyRequests()));
// assertThat(rateLimitExceededError).containsIgnoringCase("too many verification code checking requests"); assertThat(rateLimitExceededError).containsIgnoringCase("too many requests");
//
// await("verification code checking rate limit resetting") await("verification code checking rate limit resetting")
// .atLeast(Duration.ofSeconds(8)) .atLeast(Duration.ofSeconds(8))
// .atMost(Duration.ofSeconds(12)) .atMost(Duration.ofSeconds(12))
// .untilAsserted(() -> { .untilAsserted(() -> {
// String incorrectVerificationCodeError = getErrorMessage(doPost("/api/auth/2fa/verification/check?verificationCode=incorrect") String incorrectVerificationCodeError = getErrorMessage(doPost("/api/auth/2fa/verification/check?providerType=TOTP&verificationCode=incorrect")
// .andExpect(status().isBadRequest())); .andExpect(status().isBadRequest()));
// assertThat(incorrectVerificationCodeError).containsIgnoringCase("verification code is incorrect"); assertThat(incorrectVerificationCodeError).containsIgnoringCase("verification code is incorrect");
// }); });
//
// doPost("/api/auth/2fa/verification/check?verificationCode=" + getCorrectTotp(totpTwoFaAccountConfig)) doPost("/api/auth/2fa/verification/check?providerType=TOTP&verificationCode=" + getCorrectTotp(totpTwoFaAccountConfig))
// .andExpect(status().isOk()); .andExpect(status().isOk());
// } }
//
// @Test @Test
// public void testCheckVerificationCode_invalidVerificationCode() throws Exception { public void testCheckVerificationCode_invalidVerificationCode() throws Exception {
// configureTotpTwoFa(); configureTotpTwoFa();
// logInWithPreVerificationToken(); logInWithPreVerificationToken(username, password);
//
// for (String invalidVerificationCode : new String[]{"1234567", "ab1212", "12311 ", "oewkriwejqf"}) { for (String invalidVerificationCode : new String[]{"1234567", "ab1212", "12311 ", "oewkriwejqf"}) {
// String errorMessage = getErrorMessage(doPost("/api/auth/2fa/verification/check?verificationCode=" + invalidVerificationCode) String errorMessage = getErrorMessage(doPost("/api/auth/2fa/verification/check?providerType=TOTP&verificationCode=" + invalidVerificationCode)
// .andExpect(status().isBadRequest())); .andExpect(status().isBadRequest()));
// assertThat(errorMessage).containsIgnoringCase("verification code is incorrect"); assertThat(errorMessage).containsIgnoringCase("verification code is incorrect");
// } }
// } }
//
// @Test @Test
// public void testCheckVerificationCode_codeExpiration() throws Exception { public void testCheckVerificationCode_codeExpiration() throws Exception {
// configureSmsTwoFa(smsTwoFaProviderConfig -> { configureSmsTwoFa(smsTwoFaProviderConfig -> {
// smsTwoFaProviderConfig.setVerificationCodeLifetime(10); smsTwoFaProviderConfig.setVerificationCodeLifetime(10);
// }); });
//
// logInWithPreVerificationToken(); logInWithPreVerificationToken(username, password);
//
// ArgumentCaptor<String> verificationCodeCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor<String> verificationCodeCaptor = ArgumentCaptor.forClass(String.class);
// doPost("/api/auth/2fa/verification/send").andExpect(status().isOk()); doPost("/api/auth/2fa/verification/send?providerType=SMS").andExpect(status().isOk());
// verify(smsService).sendSms(eq(tenantId), any(), any(), verificationCodeCaptor.capture()); verify(smsService).sendSms(eq(tenantId), any(), any(), verificationCodeCaptor.capture());
//
// String correctVerificationCode = verificationCodeCaptor.getValue(); String correctVerificationCode = verificationCodeCaptor.getValue();
//
// await("verification code expiration") await("verification code expiration")
// .pollDelay(10, TimeUnit.SECONDS) .pollDelay(10, TimeUnit.SECONDS)
// .atLeast(10, TimeUnit.SECONDS) .atLeast(10, TimeUnit.SECONDS)
// .atMost(12, TimeUnit.SECONDS) .atMost(12, TimeUnit.SECONDS)
// .untilAsserted(() -> { .untilAsserted(() -> {
// String incorrectVerificationCodeError = getErrorMessage(doPost("/api/auth/2fa/verification/check?verificationCode=" + correctVerificationCode) String incorrectVerificationCodeError = getErrorMessage(doPost("/api/auth/2fa/verification/check?providerType=SMS&verificationCode=" + correctVerificationCode)
// .andExpect(status().isBadRequest())); .andExpect(status().isBadRequest()));
// assertThat(incorrectVerificationCodeError).containsIgnoringCase("verification code is incorrect"); assertThat(incorrectVerificationCodeError).containsIgnoringCase("verification code is incorrect");
// }); });
// } }
//
// @Test @Test
// public void testTwoFa_logLoginAction() throws Exception { public void testTwoFa_logLoginAction() throws Exception {
// TotpTwoFaAccountConfig totpTwoFaAccountConfig = configureTotpTwoFa(); TotpTwoFaAccountConfig totpTwoFaAccountConfig = configureTotpTwoFa();
//
// logInWithPreVerificationToken(); logInWithPreVerificationToken(username, password);
// await("async audit log saving").during(1, TimeUnit.SECONDS); await("async audit log saving").during(1, TimeUnit.SECONDS);
// assertThat(getLogInAuditLogs()).isEmpty(); assertThat(getLogInAuditLogs()).isEmpty();
// assertThat(userService.findUserById(tenantId, user.getId()).getAdditionalInfo() assertThat(userService.findUserById(tenantId, user.getId()).getAdditionalInfo()
// .get("lastLoginTs")).isNull(); .get("lastLoginTs")).isNull();
//
// doPost("/api/auth/2fa/verification/check?verificationCode=incorrect") doPost("/api/auth/2fa/verification/check?providerType=TOTP&verificationCode=incorrect")
// .andExpect(status().isBadRequest()); .andExpect(status().isBadRequest());
//
// await("async audit log saving").atMost(1, TimeUnit.SECONDS) await("async audit log saving").atMost(1, TimeUnit.SECONDS)
// .until(() -> getLogInAuditLogs().size() == 1); .until(() -> getLogInAuditLogs().size() == 1);
// assertThat(getLogInAuditLogs().get(0)).satisfies(failedLogInAuditLog -> { assertThat(getLogInAuditLogs().get(0)).satisfies(failedLogInAuditLog -> {
// assertThat(failedLogInAuditLog.getActionStatus()).isEqualTo(ActionStatus.FAILURE); assertThat(failedLogInAuditLog.getActionStatus()).isEqualTo(ActionStatus.FAILURE);
// assertThat(failedLogInAuditLog.getActionFailureDetails()).containsIgnoringCase("verification code is incorrect"); assertThat(failedLogInAuditLog.getActionFailureDetails()).containsIgnoringCase("verification code is incorrect");
// assertThat(failedLogInAuditLog.getUserName()).isEqualTo(username); assertThat(failedLogInAuditLog.getUserName()).isEqualTo(username);
// }); });
//
// doPost("/api/auth/2fa/verification/check?verificationCode=" + getCorrectTotp(totpTwoFaAccountConfig)) doPost("/api/auth/2fa/verification/check?providerType=TOTP&verificationCode=" + getCorrectTotp(totpTwoFaAccountConfig))
// .andExpect(status().isOk()); .andExpect(status().isOk());
// await("async audit log saving").atMost(1, TimeUnit.SECONDS) await("async audit log saving").atMost(1, TimeUnit.SECONDS)
// .until(() -> getLogInAuditLogs().size() == 2); .until(() -> getLogInAuditLogs().size() == 2);
// assertThat(getLogInAuditLogs().get(0)).satisfies(successfulLogInAuditLog -> { assertThat(getLogInAuditLogs().get(0)).satisfies(successfulLogInAuditLog -> {
// assertThat(successfulLogInAuditLog.getActionStatus()).isEqualTo(ActionStatus.SUCCESS); assertThat(successfulLogInAuditLog.getActionStatus()).isEqualTo(ActionStatus.SUCCESS);
// assertThat(successfulLogInAuditLog.getUserName()).isEqualTo(username); assertThat(successfulLogInAuditLog.getUserName()).isEqualTo(username);
// }); });
// assertThat(userService.findUserById(tenantId, user.getId()).getAdditionalInfo() assertThat(userService.findUserById(tenantId, user.getId()).getAdditionalInfo()
// .get("lastLoginTs").asLong()) .get("lastLoginTs").asLong())
// .isGreaterThan(System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(3)); .isGreaterThan(System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(3));
// } }
//
// private List<AuditLog> getLogInAuditLogs() { private List<AuditLog> getLogInAuditLogs() {
// return auditLogService.findAuditLogsByTenantIdAndUserId(tenantId, user.getId(), List.of(ActionType.LOGIN), return auditLogService.findAuditLogsByTenantIdAndUserId(tenantId, user.getId(), List.of(ActionType.LOGIN),
// new TimePageLink(new PageLink(10, 0, null, new SortOrder("createdTime", SortOrder.Direction.DESC)), 0L, System.currentTimeMillis())).getData(); new TimePageLink(new PageLink(10, 0, null, new SortOrder("createdTime", SortOrder.Direction.DESC)), 0L, System.currentTimeMillis())).getData();
// } }
//
// @Test @Test
// public void testAuthWithoutTwoFaAccountConfig() throws ThingsboardException { public void testAuthWithoutTwoFaAccountConfig() throws ThingsboardException {
// configureTotpTwoFa(); configureTotpTwoFa();
// twoFaConfigManager.deleteTwoFaAccountConfig(tenantId, user.getId(), ); twoFaConfigManager.deleteTwoFaAccountConfig(tenantId, user.getId(), TwoFaProviderType.TOTP);
//
// assertDoesNotThrow(() -> { assertDoesNotThrow(() -> {
// login(username, password); login(username, password);
// }); });
// } }
//
// private void logInWithPreVerificationToken() throws Exception { @Test
// LoginRequest loginRequest = new LoginRequest(username, password); public void testTwoFa_multipleProviders() throws Exception {
// PlatformTwoFaSettings platformTwoFaSettings = new PlatformTwoFaSettings();
// JwtTokenPair response = readResponse(doPost("/api/auth/login", loginRequest).andExpect(status().isOk()), JwtTokenPair.class); platformTwoFaSettings.setUseSystemTwoFactorAuthSettings(true);
// assertThat(response.getToken()).isNotNull();
// assertThat(response.getRefreshToken()).isNull(); TotpTwoFaProviderConfig totpTwoFaProviderConfig = new TotpTwoFaProviderConfig();
// assertThat(response.getScope()).isEqualTo(Authority.PRE_VERIFICATION_TOKEN); totpTwoFaProviderConfig.setIssuerName("TB");
//
// this.token = response.getToken(); SmsTwoFaProviderConfig smsTwoFaProviderConfig = new SmsTwoFaProviderConfig();
// } smsTwoFaProviderConfig.setVerificationCodeLifetime(60);
// smsTwoFaProviderConfig.setSmsVerificationMessageTemplate("${verificationCode}");
// private TotpTwoFaAccountConfig configureTotpTwoFa(Consumer<PlatformTwoFaSettings>... customizer) throws ThingsboardException {
// TotpTwoFaProviderConfig totpTwoFaProviderConfig = new TotpTwoFaProviderConfig(); EmailTwoFaProviderConfig emailTwoFaProviderConfig = new EmailTwoFaProviderConfig();
// totpTwoFaProviderConfig.setIssuerName("tb"); emailTwoFaProviderConfig.setVerificationCodeLifetime(60);
//
// PlatformTwoFaSettings twoFaSettings = new PlatformTwoFaSettings(); platformTwoFaSettings.setProviders(List.of(totpTwoFaProviderConfig, smsTwoFaProviderConfig, emailTwoFaProviderConfig));
// twoFaSettings.setUseSystemTwoFactorAuthSettings(false); twoFaConfigManager.savePlatformTwoFaSettings(TenantId.SYS_TENANT_ID, platformTwoFaSettings);
// twoFaSettings.setProviders(Arrays.stream(new TwoFaProviderConfig[]{totpTwoFaProviderConfig}).collect(Collectors.toList()));
// Arrays.stream(customizer).forEach(c -> c.accept(twoFaSettings)); User twoFaUser = new User();
// twoFaConfigManager.savePlatformTwoFaSettings(tenantId, twoFaSettings); twoFaUser.setAuthority(Authority.TENANT_ADMIN);
// twoFaUser.setTenantId(tenantId);
// TotpTwoFaAccountConfig totpTwoFaAccountConfig = (TotpTwoFaAccountConfig) twoFactorAuthService.generateNewAccountConfig(user, TwoFaProviderType.TOTP); twoFaUser.setEmail("2fa@thingsboard.org");
// twoFaConfigManager.saveTwoFaAccountConfig(tenantId, user.getId(), totpTwoFaAccountConfig); twoFaUser = createUserAndLogin(twoFaUser, "12345678");
// return totpTwoFaAccountConfig;
// } TotpTwoFaAccountConfig totpTwoFaAccountConfig = (TotpTwoFaAccountConfig) twoFactorAuthService.generateNewAccountConfig(twoFaUser, TwoFaProviderType.TOTP);
// totpTwoFaAccountConfig.setUseByDefault(true);
// private SmsTwoFaAccountConfig configureSmsTwoFa(Consumer<SmsTwoFaProviderConfig>... customizer) throws ThingsboardException { twoFaConfigManager.saveTwoFaAccountConfig(tenantId, twoFaUser.getId(), totpTwoFaAccountConfig);
// SmsTwoFaProviderConfig smsTwoFaProviderConfig = new SmsTwoFaProviderConfig();
// smsTwoFaProviderConfig.setVerificationCodeLifetime(60); SmsTwoFaAccountConfig smsTwoFaAccountConfig = new SmsTwoFaAccountConfig();
// smsTwoFaProviderConfig.setSmsVerificationMessageTemplate("${verificationCode}"); smsTwoFaAccountConfig.setPhoneNumber("+38012312322");
// Arrays.stream(customizer).forEach(c -> c.accept(smsTwoFaProviderConfig)); twoFaConfigManager.saveTwoFaAccountConfig(tenantId, twoFaUser.getId(), smsTwoFaAccountConfig);
//
// PlatformTwoFaSettings twoFaSettings = new PlatformTwoFaSettings(); EmailTwoFaAccountConfig emailTwoFaAccountConfig = new EmailTwoFaAccountConfig();
// twoFaSettings.setUseSystemTwoFactorAuthSettings(false); emailTwoFaAccountConfig.setEmail(twoFaUser.getEmail());
// twoFaSettings.setProviders(Arrays.stream(new TwoFaProviderConfig[]{smsTwoFaProviderConfig}).collect(Collectors.toList())); twoFaConfigManager.saveTwoFaAccountConfig(tenantId, twoFaUser.getId(), emailTwoFaAccountConfig);
// twoFaConfigManager.savePlatformTwoFaSettings(tenantId, twoFaSettings);
// logInWithPreVerificationToken(twoFaUser.getEmail(), "12345678");
// SmsTwoFaAccountConfig smsTwoFaAccountConfig = new SmsTwoFaAccountConfig();
// smsTwoFaAccountConfig.setPhoneNumber("+38050505050"); Map<TwoFaProviderType, TwoFactorAuthController.TwoFaProviderInfo> providersInfos = readResponse(doGet("/api/auth/2fa/providers").andExpect(status().isOk()), new TypeReference<List<TwoFactorAuthController.TwoFaProviderInfo>>() {}).stream()
// twoFaConfigManager.saveTwoFaAccountConfig(tenantId, user.getId(), smsTwoFaAccountConfig); .collect(Collectors.toMap(TwoFactorAuthController.TwoFaProviderInfo::getType, v -> v));
// return smsTwoFaAccountConfig;
// } assertThat(providersInfos).size().isEqualTo(3);
//
// private String getCorrectTotp(TotpTwoFaAccountConfig totpTwoFaAccountConfig) { assertThat(providersInfos).containsKey(TwoFaProviderType.TOTP);
// String secret = StringUtils.substringAfterLast(totpTwoFaAccountConfig.getAuthUrl(), "secret="); assertThat(providersInfos.get(TwoFaProviderType.TOTP).isDefault()).isTrue();
// return new Totp(secret).now();
// } assertThat(providersInfos).containsKey(TwoFaProviderType.SMS);
assertThat(providersInfos.get(TwoFaProviderType.SMS).isDefault()).isFalse();
assertThat(providersInfos).containsKey(TwoFaProviderType.EMAIL);
assertThat(providersInfos.get(TwoFaProviderType.EMAIL).isDefault()).isFalse();
}
private void logInWithPreVerificationToken(String username, String password) throws Exception {
LoginRequest loginRequest = new LoginRequest(username, password);
JwtTokenPair response = readResponse(doPost("/api/auth/login", loginRequest).andExpect(status().isOk()), JwtTokenPair.class);
assertThat(response.getToken()).isNotNull();
assertThat(response.getRefreshToken()).isNull();
assertThat(response.getScope()).isEqualTo(Authority.PRE_VERIFICATION_TOKEN);
this.token = response.getToken();
}
private TotpTwoFaAccountConfig configureTotpTwoFa(Consumer<PlatformTwoFaSettings>... customizer) throws ThingsboardException {
TotpTwoFaProviderConfig totpTwoFaProviderConfig = new TotpTwoFaProviderConfig();
totpTwoFaProviderConfig.setIssuerName("tb");
PlatformTwoFaSettings twoFaSettings = new PlatformTwoFaSettings();
twoFaSettings.setUseSystemTwoFactorAuthSettings(false);
twoFaSettings.setProviders(Arrays.stream(new TwoFaProviderConfig[]{totpTwoFaProviderConfig}).collect(Collectors.toList()));
Arrays.stream(customizer).forEach(c -> c.accept(twoFaSettings));
twoFaConfigManager.savePlatformTwoFaSettings(tenantId, twoFaSettings);
TotpTwoFaAccountConfig totpTwoFaAccountConfig = (TotpTwoFaAccountConfig) twoFactorAuthService.generateNewAccountConfig(user, TwoFaProviderType.TOTP);
twoFaConfigManager.saveTwoFaAccountConfig(tenantId, user.getId(), totpTwoFaAccountConfig);
return totpTwoFaAccountConfig;
}
private SmsTwoFaAccountConfig configureSmsTwoFa(Consumer<SmsTwoFaProviderConfig>... customizer) throws ThingsboardException {
SmsTwoFaProviderConfig smsTwoFaProviderConfig = new SmsTwoFaProviderConfig();
smsTwoFaProviderConfig.setVerificationCodeLifetime(60);
smsTwoFaProviderConfig.setSmsVerificationMessageTemplate("${verificationCode}");
Arrays.stream(customizer).forEach(c -> c.accept(smsTwoFaProviderConfig));
PlatformTwoFaSettings twoFaSettings = new PlatformTwoFaSettings();
twoFaSettings.setUseSystemTwoFactorAuthSettings(false);
twoFaSettings.setProviders(Arrays.stream(new TwoFaProviderConfig[]{smsTwoFaProviderConfig}).collect(Collectors.toList()));
twoFaConfigManager.savePlatformTwoFaSettings(tenantId, twoFaSettings);
SmsTwoFaAccountConfig smsTwoFaAccountConfig = new SmsTwoFaAccountConfig();
smsTwoFaAccountConfig.setPhoneNumber("+38050505050");
twoFaConfigManager.saveTwoFaAccountConfig(tenantId, user.getId(), smsTwoFaAccountConfig);
return smsTwoFaAccountConfig;
}
private String getCorrectTotp(TotpTwoFaAccountConfig totpTwoFaAccountConfig) {
String secret = StringUtils.substringAfterLast(totpTwoFaAccountConfig.getAuthUrl(), "secret=");
return new Totp(secret).now();
}
} }

2
common/message/src/test/java/org/thingsboard/server/common/msg/tools/RateLimitsTest.java

@ -67,7 +67,7 @@ public class RateLimitsTest {
assertThat(rateLimits.tryConsume()).as("new token is available").isFalse(); assertThat(rateLimits.tryConsume()).as("new token is available").isFalse();
int expectedRefillTime = period * 1000; int expectedRefillTime = period * 1000;
int gap = 100; int gap = 300;
await("tokens refill for rate limit " + rateLimitConfig) await("tokens refill for rate limit " + rateLimitConfig)
.atLeast(expectedRefillTime - gap, TimeUnit.MILLISECONDS) .atLeast(expectedRefillTime - gap, TimeUnit.MILLISECONDS)

Loading…
Cancel
Save