|
|
|
@ -15,6 +15,7 @@ |
|
|
|
*/ |
|
|
|
package org.thingsboard.server.service.security.auth.mfa.config; |
|
|
|
|
|
|
|
import com.fasterxml.jackson.databind.JsonNode; |
|
|
|
import com.fasterxml.jackson.databind.node.ObjectNode; |
|
|
|
import lombok.RequiredArgsConstructor; |
|
|
|
import lombok.SneakyThrows; |
|
|
|
@ -22,13 +23,13 @@ import org.springframework.stereotype.Service; |
|
|
|
import org.thingsboard.common.util.JacksonUtil; |
|
|
|
import org.thingsboard.server.common.data.AdminSettings; |
|
|
|
import org.thingsboard.server.common.data.DataConstants; |
|
|
|
import org.thingsboard.server.common.data.User; |
|
|
|
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; |
|
|
|
import org.thingsboard.server.common.data.exception.ThingsboardException; |
|
|
|
import org.thingsboard.server.common.data.id.TenantId; |
|
|
|
import org.thingsboard.server.common.data.id.UserId; |
|
|
|
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; |
|
|
|
import org.thingsboard.server.common.data.kv.JsonDataEntry; |
|
|
|
import org.thingsboard.server.common.data.security.UserCredentials; |
|
|
|
import org.thingsboard.server.dao.attributes.AttributesService; |
|
|
|
import org.thingsboard.server.dao.service.ConstraintValidator; |
|
|
|
import org.thingsboard.server.dao.settings.AdminSettingsDao; |
|
|
|
@ -41,6 +42,7 @@ import org.thingsboard.server.service.security.auth.mfa.provider.TwoFactorAuthPr |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.Optional; |
|
|
|
import java.util.concurrent.ExecutionException; |
|
|
|
import java.util.function.Consumer; |
|
|
|
|
|
|
|
@Service |
|
|
|
@RequiredArgsConstructor |
|
|
|
@ -62,9 +64,8 @@ public class DefaultTwoFactorAuthConfigManager implements TwoFactorAuthConfigMan |
|
|
|
|
|
|
|
@Override |
|
|
|
public Optional<TwoFactorAuthAccountConfig> getTwoFaAccountConfig(TenantId tenantId, UserId userId) { |
|
|
|
User user = userService.findUserById(tenantId, userId); |
|
|
|
return Optional.ofNullable(user.getAdditionalInfo()) |
|
|
|
.flatMap(additionalInfo -> Optional.ofNullable(additionalInfo.get(TWO_FACTOR_AUTH_ACCOUNT_CONFIG_KEY)).filter(jsonNode -> !jsonNode.isNull())) |
|
|
|
return Optional.ofNullable(getAccountInfo(tenantId, userId).get(TWO_FACTOR_AUTH_ACCOUNT_CONFIG_KEY)) |
|
|
|
.filter(JsonNode::isObject) |
|
|
|
.map(jsonNode -> JacksonUtil.treeToValue(jsonNode, TwoFactorAuthAccountConfig.class)) |
|
|
|
.filter(twoFactorAuthAccountConfig -> { |
|
|
|
return getTwoFaProviderConfig(tenantId, twoFactorAuthAccountConfig.getProviderType()).isPresent(); |
|
|
|
@ -76,24 +77,33 @@ public class DefaultTwoFactorAuthConfigManager implements TwoFactorAuthConfigMan |
|
|
|
getTwoFaProviderConfig(tenantId, accountConfig.getProviderType()) |
|
|
|
.orElseThrow(() -> new ThingsboardException("2FA provider is not configured", ThingsboardErrorCode.BAD_REQUEST_PARAMS)); |
|
|
|
|
|
|
|
User user = userService.findUserById(tenantId, userId); |
|
|
|
ObjectNode additionalInfo = (ObjectNode) Optional.ofNullable(user.getAdditionalInfo()) |
|
|
|
.orElseGet(JacksonUtil::newObjectNode); |
|
|
|
additionalInfo.set(TWO_FACTOR_AUTH_ACCOUNT_CONFIG_KEY, JacksonUtil.valueToTree(accountConfig)); |
|
|
|
user.setAdditionalInfo(additionalInfo); |
|
|
|
|
|
|
|
userService.saveUser(user); |
|
|
|
updateAccountInfo(tenantId, userId, accountInfo -> { |
|
|
|
accountInfo.set(TWO_FACTOR_AUTH_ACCOUNT_CONFIG_KEY, JacksonUtil.valueToTree(accountConfig)); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public void deleteTwoFaAccountConfig(TenantId tenantId, UserId userId) { |
|
|
|
User user = userService.findUserById(tenantId, userId); |
|
|
|
ObjectNode additionalInfo = (ObjectNode) Optional.ofNullable(user.getAdditionalInfo()) |
|
|
|
updateAccountInfo(tenantId, userId, accountInfo -> { |
|
|
|
accountInfo.remove(TWO_FACTOR_AUTH_ACCOUNT_CONFIG_KEY); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
private ObjectNode getAccountInfo(TenantId tenantId, UserId userId) { |
|
|
|
return (ObjectNode) Optional.ofNullable(userService.findUserCredentialsByUserId(tenantId, userId).getAdditionalInfo()) |
|
|
|
.filter(JsonNode::isObject) |
|
|
|
.orElseGet(JacksonUtil::newObjectNode); |
|
|
|
additionalInfo.remove(TWO_FACTOR_AUTH_ACCOUNT_CONFIG_KEY); |
|
|
|
user.setAdditionalInfo(additionalInfo); |
|
|
|
} |
|
|
|
|
|
|
|
userService.saveUser(user); |
|
|
|
// FIXME [viacheslav]: upgrade script for credentials' additional info
|
|
|
|
private void updateAccountInfo(TenantId tenantId, UserId userId, Consumer<ObjectNode> updater) { |
|
|
|
UserCredentials credentials = userService.findUserCredentialsByUserId(tenantId, userId); |
|
|
|
ObjectNode additionalInfo = (ObjectNode) Optional.ofNullable(credentials.getAdditionalInfo()) |
|
|
|
.filter(JsonNode::isObject) |
|
|
|
.orElseGet(JacksonUtil::newObjectNode); |
|
|
|
updater.accept(additionalInfo); |
|
|
|
credentials.setAdditionalInfo(additionalInfo); |
|
|
|
userService.saveUserCredentials(tenantId, credentials); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|