Store 2FA account config is UserCredentials' additionalInfo
This commit is contained in:
parent
b7db4ed604
commit
95f41810ac
@ -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())
|
||||
.orElseGet(JacksonUtil::newObjectNode);
|
||||
additionalInfo.remove(TWO_FACTOR_AUTH_ACCOUNT_CONFIG_KEY);
|
||||
user.setAdditionalInfo(additionalInfo);
|
||||
updateAccountInfo(tenantId, userId, accountInfo -> {
|
||||
accountInfo.remove(TWO_FACTOR_AUTH_ACCOUNT_CONFIG_KEY);
|
||||
});
|
||||
}
|
||||
|
||||
userService.saveUser(user);
|
||||
private ObjectNode getAccountInfo(TenantId tenantId, UserId userId) {
|
||||
return (ObjectNode) Optional.ofNullable(userService.findUserCredentialsByUserId(tenantId, userId).getAdditionalInfo())
|
||||
.filter(JsonNode::isObject)
|
||||
.orElseGet(JacksonUtil::newObjectNode);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -51,24 +51,24 @@ public interface UserService {
|
||||
|
||||
UserCredentials replaceUserCredentials(TenantId tenantId, UserCredentials userCredentials);
|
||||
|
||||
void deleteUser(TenantId tenantId, UserId userId);
|
||||
void deleteUser(TenantId tenantId, UserId userId);
|
||||
|
||||
PageData<User> findUsersByTenantId(TenantId tenantId, PageLink pageLink);
|
||||
|
||||
PageData<User> findTenantAdmins(TenantId tenantId, PageLink pageLink);
|
||||
|
||||
void deleteTenantAdmins(TenantId tenantId);
|
||||
void deleteTenantAdmins(TenantId tenantId);
|
||||
|
||||
PageData<User> findCustomerUsers(TenantId tenantId, CustomerId customerId, PageLink pageLink);
|
||||
|
||||
void deleteCustomerUsers(TenantId tenantId, CustomerId customerId);
|
||||
void deleteCustomerUsers(TenantId tenantId, CustomerId customerId);
|
||||
|
||||
void setUserCredentialsEnabled(TenantId tenantId, UserId userId, boolean enabled);
|
||||
void setUserCredentialsEnabled(TenantId tenantId, UserId userId, boolean enabled);
|
||||
|
||||
void resetFailedLoginAttempts(TenantId tenantId, UserId userId);
|
||||
void resetFailedLoginAttempts(TenantId tenantId, UserId userId);
|
||||
|
||||
int increaseFailedLoginAttempts(TenantId tenantId, UserId userId);
|
||||
int increaseFailedLoginAttempts(TenantId tenantId, UserId userId);
|
||||
|
||||
void setLastLoginTs(TenantId tenantId, UserId userId);
|
||||
void setLastLoginTs(TenantId tenantId, UserId userId);
|
||||
|
||||
}
|
||||
|
||||
@ -16,12 +16,12 @@
|
||||
package org.thingsboard.server.common.data.security;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.thingsboard.server.common.data.BaseData;
|
||||
import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo;
|
||||
import org.thingsboard.server.common.data.id.UserCredentialsId;
|
||||
import org.thingsboard.server.common.data.id.UserId;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class UserCredentials extends BaseData<UserCredentialsId> {
|
||||
public class UserCredentials extends SearchTextBasedWithAdditionalInfo<UserCredentialsId> {
|
||||
|
||||
private static final long serialVersionUID = -2108436378880529163L;
|
||||
|
||||
@ -87,6 +87,11 @@ public class UserCredentials extends BaseData<UserCredentialsId> {
|
||||
public void setResetToken(String resetToken) {
|
||||
this.resetToken = resetToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSearchText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
@ -15,14 +15,18 @@
|
||||
*/
|
||||
package org.thingsboard.server.dao.model.sql;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.hibernate.annotations.TypeDef;
|
||||
import org.thingsboard.server.common.data.id.UserCredentialsId;
|
||||
import org.thingsboard.server.common.data.id.UserId;
|
||||
import org.thingsboard.server.common.data.security.UserCredentials;
|
||||
import org.thingsboard.server.dao.model.BaseEntity;
|
||||
import org.thingsboard.server.dao.model.BaseSqlEntity;
|
||||
import org.thingsboard.server.dao.model.ModelConstants;
|
||||
import org.thingsboard.server.dao.util.mapping.JsonStringType;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
@ -31,6 +35,7 @@ import java.util.UUID;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TypeDef(name = "json", typeClass = JsonStringType.class)
|
||||
@Entity
|
||||
@Table(name = ModelConstants.USER_CREDENTIALS_COLUMN_FAMILY_NAME)
|
||||
public final class UserCredentialsEntity extends BaseSqlEntity<UserCredentials> implements BaseEntity<UserCredentials> {
|
||||
@ -50,6 +55,10 @@ public final class UserCredentialsEntity extends BaseSqlEntity<UserCredentials>
|
||||
@Column(name = ModelConstants.USER_CREDENTIALS_RESET_TOKEN_PROPERTY, unique = true)
|
||||
private String resetToken;
|
||||
|
||||
@Type(type = "json")
|
||||
@Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY)
|
||||
private JsonNode additionalInfo;
|
||||
|
||||
public UserCredentialsEntity() {
|
||||
super();
|
||||
}
|
||||
@ -66,6 +75,7 @@ public final class UserCredentialsEntity extends BaseSqlEntity<UserCredentials>
|
||||
this.password = userCredentials.getPassword();
|
||||
this.activateToken = userCredentials.getActivateToken();
|
||||
this.resetToken = userCredentials.getResetToken();
|
||||
this.additionalInfo = userCredentials.getAdditionalInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -79,6 +89,7 @@ public final class UserCredentialsEntity extends BaseSqlEntity<UserCredentials>
|
||||
userCredentials.setPassword(password);
|
||||
userCredentials.setActivateToken(activateToken);
|
||||
userCredentials.setResetToken(resetToken);
|
||||
userCredentials.setAdditionalInfo(additionalInfo);
|
||||
return userCredentials;
|
||||
}
|
||||
|
||||
|
||||
@ -370,7 +370,8 @@ CREATE TABLE IF NOT EXISTS user_credentials (
|
||||
enabled boolean,
|
||||
password varchar(255),
|
||||
reset_token varchar(255) UNIQUE,
|
||||
user_id uuid UNIQUE
|
||||
user_id uuid UNIQUE,
|
||||
additional_info varchar
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS widget_type (
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user