From 133c8f9ae4178095f1742242fd9361e11eed3d46 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 15 Feb 2023 12:25:30 +0200 Subject: [PATCH 01/13] added new column for user_credentials table --- .../main/data/upgrade/3.4.4/schema_update.sql | 17 +++++++++++++++ .../common/data/security/UserCredentials.java | 21 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/application/src/main/data/upgrade/3.4.4/schema_update.sql b/application/src/main/data/upgrade/3.4.4/schema_update.sql index f8c133f352..83d148e914 100644 --- a/application/src/main/data/upgrade/3.4.4/schema_update.sql +++ b/application/src/main/data/upgrade/3.4.4/schema_update.sql @@ -30,3 +30,20 @@ CREATE TABLE IF NOT EXISTS user_settings ( settings varchar(100000), CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES tb_user(id) ON DELETE CASCADE ); + +-- move password history from user to user_credentials table +ALTER TABLE user_credentials + ADD COLUMN IF NOT EXISTS additional_info varchar; + +CREATE OR REPLACE PROCEDURE migrate_password_history() + LANGUAGE plpgsql AS +$$ +BEGIN + UPDATE user_credentials AS c + SET additional_info = u.additional_info + FROM tb_user AS u + WHERE u.id = c.id; +END; +$$; +-- USER PASSWORD MIGRATION END +call migrate_password_history(); \ No newline at end of file diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java index 900fd966e8..16cf5f090d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java @@ -15,10 +15,17 @@ */ package org.thingsboard.server.common.data.security; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.databind.JsonNode; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.id.UserCredentialsId; import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.common.data.validation.Length; +import org.thingsboard.server.common.data.validation.NoXss; + +import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.getJson; +import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.setJson; @EqualsAndHashCode(callSuper = true) public class UserCredentials extends BaseData { @@ -30,6 +37,20 @@ public class UserCredentials extends BaseData { private String password; private String activateToken; private String resetToken; + + @NoXss + private transient JsonNode additionalInfo; + + @JsonIgnore + private byte[] additionalInfoBytes; + + public JsonNode getAdditionalInfo() { + return getJson(() -> additionalInfo, () -> additionalInfoBytes); + } + + public void setAdditionalInfo(JsonNode settings) { + setJson(settings, json -> this.additionalInfo = json, bytes -> this.additionalInfoBytes = bytes); + } public UserCredentials() { super(); From 453e81e57e3c9f00489d22ac457e4195fe7a5f28 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 15 Feb 2023 18:57:11 +0200 Subject: [PATCH 02/13] updated sql script --- .../main/data/upgrade/3.4.4/schema_update.sql | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/application/src/main/data/upgrade/3.4.4/schema_update.sql b/application/src/main/data/upgrade/3.4.4/schema_update.sql index 83d148e914..1a06d33d52 100644 --- a/application/src/main/data/upgrade/3.4.4/schema_update.sql +++ b/application/src/main/data/upgrade/3.4.4/schema_update.sql @@ -35,15 +35,9 @@ CREATE TABLE IF NOT EXISTS user_settings ( ALTER TABLE user_credentials ADD COLUMN IF NOT EXISTS additional_info varchar; -CREATE OR REPLACE PROCEDURE migrate_password_history() - LANGUAGE plpgsql AS -$$ -BEGIN - UPDATE user_credentials AS c - SET additional_info = u.additional_info - FROM tb_user AS u - WHERE u.id = c.id; -END; -$$; --- USER PASSWORD MIGRATION END -call migrate_password_history(); \ No newline at end of file +UPDATE user_credentials AS c + SET additional_info = u.additional_info FROM tb_user AS u + WHERE u.id = c.user_id AND u.additional_info is not null; + +UPDATE tb_user + SET additional_info = null WHERE id is not null; \ No newline at end of file From e046e8caa64c53f42520089d678ea7cb1e0464db Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 15 Feb 2023 18:58:26 +0200 Subject: [PATCH 03/13] updated sql script --- application/src/main/data/upgrade/3.4.4/schema_update.sql | 1 - 1 file changed, 1 deletion(-) diff --git a/application/src/main/data/upgrade/3.4.4/schema_update.sql b/application/src/main/data/upgrade/3.4.4/schema_update.sql index 1a06d33d52..9ecc68e47b 100644 --- a/application/src/main/data/upgrade/3.4.4/schema_update.sql +++ b/application/src/main/data/upgrade/3.4.4/schema_update.sql @@ -31,7 +31,6 @@ CREATE TABLE IF NOT EXISTS user_settings ( CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES tb_user(id) ON DELETE CASCADE ); --- move password history from user to user_credentials table ALTER TABLE user_credentials ADD COLUMN IF NOT EXISTS additional_info varchar; From f5b029d43effae31d62eec60327652c4f511e40a Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Mon, 20 Feb 2023 19:18:53 +0200 Subject: [PATCH 04/13] moved password history from tb_user to user_credential --- .../main/data/upgrade/3.4.4/schema_update.sql | 9 +---- .../install/SqlDatabaseUpgradeService.java | 31 ++++++++++++++ .../system/DefaultSystemSecurityService.java | 3 +- .../server/dao/user/UserService.java | 2 + .../common/data/security/UserCredentials.java | 23 ++++++++++- .../server/dao/model/ModelConstants.java | 1 + .../dao/model/sql/UserCredentialsEntity.java | 8 ++++ .../server/dao/sql/user/JpaUserDao.java | 7 ++++ .../thingsboard/server/dao/user/UserDao.java | 8 ++++ .../server/dao/user/UserServiceImpl.java | 40 ++++++++++--------- .../main/resources/sql/schema-entities.sql | 3 +- 11 files changed, 105 insertions(+), 30 deletions(-) diff --git a/application/src/main/data/upgrade/3.4.4/schema_update.sql b/application/src/main/data/upgrade/3.4.4/schema_update.sql index 9ecc68e47b..418e4066fc 100644 --- a/application/src/main/data/upgrade/3.4.4/schema_update.sql +++ b/application/src/main/data/upgrade/3.4.4/schema_update.sql @@ -32,11 +32,4 @@ CREATE TABLE IF NOT EXISTS user_settings ( ); ALTER TABLE user_credentials - ADD COLUMN IF NOT EXISTS additional_info varchar; - -UPDATE user_credentials AS c - SET additional_info = u.additional_info FROM tb_user AS u - WHERE u.id = c.user_id AND u.additional_info is not null; - -UPDATE tb_user - SET additional_info = null WHERE id is not null; \ No newline at end of file + ADD COLUMN IF NOT EXISTS additional_info varchar NULL; \ No newline at end of file diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index b9ff5383b5..e91bad3e18 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -15,6 +15,8 @@ */ package org.thingsboard.server.service.install; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; @@ -24,8 +26,10 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -34,6 +38,7 @@ import org.thingsboard.server.common.data.queue.ProcessingStrategyType; import org.thingsboard.server.common.data.queue.Queue; import org.thingsboard.server.common.data.queue.SubmitStrategy; import org.thingsboard.server.common.data.queue.SubmitStrategyType; +import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.dao.asset.AssetDao; import org.thingsboard.server.dao.asset.AssetProfileService; import org.thingsboard.server.dao.dashboard.DashboardService; @@ -44,6 +49,7 @@ import org.thingsboard.server.dao.queue.QueueService; import org.thingsboard.server.dao.sql.tenant.TenantRepository; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.usagerecord.ApiUsageStateService; +import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.queue.settings.TbRuleEngineQueueConfiguration; import org.thingsboard.server.service.install.sql.SqlDbHelper; @@ -110,6 +116,9 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService @Autowired private TenantService tenantService; + @Autowired + private UserService userService; + @Autowired private TenantRepository tenantRepository; @@ -701,6 +710,28 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService } catch (Exception e) { } + PageLink pageLink = new PageLink(1000); + PageData users; + do { + List> futures = new ArrayList<>(); + users = userService.findAllUsers(pageLink); + for (User user : users.getData()) { + futures.add(dbUpgradeExecutor.submit(() -> { + JsonNode additionalInfo = user.getAdditionalInfo(); + if (additionalInfo.isObject() && additionalInfo.has("userPasswordHistory")){ + UserCredentials creds = userService.findUserCredentialsByUserId(user.getTenantId(), user.getId()); + if (creds != null) { + creds.setAdditionalInfo(JacksonUtil.newObjectNode().set("userPasswordHistory", additionalInfo.get("userPasswordHistory"))); + userService.saveUserCredentials(user.getTenantId(), creds); + } + ((ObjectNode) additionalInfo).remove("userPasswordHistory"); + userService.saveUser(user); + }})); + } + Futures.allAsList(futures).get(); + pageLink = pageLink.nextPageLink(); + } while (users.hasNext()); + conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3005000;"); } log.info("Schema updated."); diff --git a/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java b/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java index 1a81c6617f..726a5d98f0 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java +++ b/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java @@ -228,8 +228,7 @@ public class DefaultSystemSecurityService implements SystemSecurityService { if (userCredentials != null && isPositiveInteger(passwordPolicy.getPasswordReuseFrequencyDays())) { long passwordReuseFrequencyTs = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(passwordPolicy.getPasswordReuseFrequencyDays()); - User user = userService.findUserById(tenantId, userCredentials.getUserId()); - JsonNode additionalInfo = user.getAdditionalInfo(); + JsonNode additionalInfo = userCredentials.getAdditionalInfo(); if (additionalInfo instanceof ObjectNode && additionalInfo.has(UserServiceImpl.USER_PASSWORD_HISTORY)) { JsonNode userPasswordHistoryJson = additionalInfo.get(UserServiceImpl.USER_PASSWORD_HISTORY); Map userPasswordHistoryMap = JacksonUtil.convertValue(userPasswordHistoryJson, new TypeReference<>() {}); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java index bb40507772..a981292d82 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java @@ -58,6 +58,8 @@ public interface UserService extends EntityDaoService { PageData findUsersByTenantId(TenantId tenantId, PageLink pageLink); + PageData findAllUsers(PageLink pageLink); + PageData findTenantAdmins(TenantId tenantId, PageLink pageLink); void deleteTenantAdmins(TenantId tenantId); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java index 16cf5f090d..5719e46495 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java @@ -24,10 +24,12 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; +import java.util.Arrays; +import java.util.Objects; + import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.getJson; import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.setJson; -@EqualsAndHashCode(callSuper = true) public class UserCredentials extends BaseData { private static final long serialVersionUID = -2108436378880529163L; @@ -67,6 +69,7 @@ public class UserCredentials extends BaseData { this.enabled = userCredentials.isEnabled(); this.activateToken = userCredentials.getActivateToken(); this.resetToken = userCredentials.getResetToken(); + setAdditionalInfo(userCredentials.getAdditionalInfo()); } public UserId getUserId() { @@ -109,6 +112,24 @@ public class UserCredentials extends BaseData { this.resetToken = resetToken; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + UserCredentials that = (UserCredentials) o; + return enabled == that.enabled && userId.equals(that.userId) && Objects.equals(password, that.password) + && Objects.equals(activateToken, that.activateToken) && Objects.equals(resetToken, that.resetToken) + && Arrays.equals(additionalInfoBytes, that.additionalInfoBytes); + } + + @Override + public int hashCode() { + int result = Objects.hash(super.hashCode(), userId, enabled, password, activateToken, resetToken); + result = 31 * result + Arrays.hashCode(additionalInfoBytes); + return result; + } + @Override public String toString() { StringBuilder builder = new StringBuilder(); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index cf953583d1..526876adba 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -81,6 +81,7 @@ public class ModelConstants { public static final String USER_CREDENTIALS_PASSWORD_PROPERTY = "password"; //NOSONAR, the constant used to identify password column name (not password value itself) public static final String USER_CREDENTIALS_ACTIVATE_TOKEN_PROPERTY = "activate_token"; public static final String USER_CREDENTIALS_RESET_TOKEN_PROPERTY = "reset_token"; + public static final String USER_CREDENTIALS_ADDITIONAL_PROPERTY = "additional_info"; public static final String USER_CREDENTIALS_BY_USER_COLUMN_FAMILY_NAME = "user_credentials_by_user"; public static final String USER_CREDENTIALS_BY_ACTIVATE_TOKEN_COLUMN_FAMILY_NAME = "user_credentials_by_activate_token"; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java index 97868a1e07..5229c2cad6 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java @@ -15,8 +15,10 @@ */ 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.thingsboard.server.common.data.id.UserCredentialsId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.security.UserCredentials; @@ -50,6 +52,10 @@ public final class UserCredentialsEntity extends BaseSqlEntity @Column(name = ModelConstants.USER_CREDENTIALS_RESET_TOKEN_PROPERTY, unique = true) private String resetToken; + @Type(type = "json") + @Column(name = ModelConstants.USER_CREDENTIALS_ADDITIONAL_PROPERTY) + private JsonNode additionalInfo; + public UserCredentialsEntity() { super(); } @@ -66,6 +72,7 @@ public final class UserCredentialsEntity extends BaseSqlEntity this.password = userCredentials.getPassword(); this.activateToken = userCredentials.getActivateToken(); this.resetToken = userCredentials.getResetToken(); + this.additionalInfo = userCredentials.getAdditionalInfo(); } @Override @@ -79,6 +86,7 @@ public final class UserCredentialsEntity extends BaseSqlEntity userCredentials.setPassword(password); userCredentials.setActivateToken(activateToken); userCredentials.setResetToken(resetToken); + userCredentials.setAdditionalInfo(additionalInfo); return userCredentials; } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java index 473c145b5d..34386132da 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java @@ -75,6 +75,13 @@ public class JpaUserDao extends JpaAbstractSearchTextDao imple DaoUtil.toPageable(pageLink))); } + @Override + public PageData findAll(PageLink pageLink) { + return DaoUtil.toPageData( + userRepository + .findAll(DaoUtil.toPageable(pageLink))); + } + @Override public PageData findTenantAdmins(UUID tenantId, PageLink pageLink) { return DaoUtil.toPageData( diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserDao.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserDao.java index c2551c84d3..456676664e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/UserDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserDao.java @@ -60,6 +60,14 @@ public interface UserDao extends Dao, TenantEntityDao { */ PageData findByTenantId(UUID tenantId, PageLink pageLink); + /** + * Find users by page link. + * + * @param pageLink the page link + * @return the list of user entities + */ + PageData findAll(PageLink pageLink); + /** * Find tenant admin users by tenantId and page link. * diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java index c8c5175e5f..560105a85e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java @@ -40,7 +40,6 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.UserCredentials; -import org.thingsboard.server.common.data.security.UserSettings; import org.thingsboard.server.common.data.security.event.UserCredentialsInvalidationEvent; import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.exception.IncorrectParameterException; @@ -128,7 +127,10 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic userCredentials.setEnabled(false); userCredentials.setActivateToken(StringUtils.randomAlphanumeric(DEFAULT_TOKEN_LENGTH)); userCredentials.setUserId(new UserId(savedUser.getUuidId())); - saveUserCredentialsAndPasswordHistory(user.getTenantId(), userCredentials); + if (userCredentials.getPassword() != null) { + updatePasswordHistory(userCredentials); + } + userCredentialsDao.save(user.getTenantId(), userCredentials); } return savedUser; } @@ -158,7 +160,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic public UserCredentials saveUserCredentials(TenantId tenantId, UserCredentials userCredentials) { log.trace("Executing saveUserCredentials [{}]", userCredentials); userCredentialsValidator.validate(userCredentials, data -> tenantId); - return saveUserCredentialsAndPasswordHistory(tenantId, userCredentials); + return userCredentialsDao.save(tenantId, userCredentials); } @Override @@ -176,7 +178,9 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic userCredentials.setEnabled(true); userCredentials.setActivateToken(null); userCredentials.setPassword(password); - + if (userCredentials.getPassword() != null) { + updatePasswordHistory(userCredentials); + } return saveUserCredentials(tenantId, userCredentials); } @@ -212,7 +216,10 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic userCredentialsValidator.validate(userCredentials, data -> tenantId); userCredentialsDao.removeById(tenantId, userCredentials.getUuidId()); userCredentials.setId(null); - return saveUserCredentialsAndPasswordHistory(tenantId, userCredentials); + if (userCredentials.getPassword() != null) { + updatePasswordHistory(userCredentials); + } + return userCredentialsDao.save(tenantId, userCredentials); } @Override @@ -236,6 +243,13 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic return userDao.findByTenantId(tenantId.getId(), pageLink); } + @Override + public PageData findAllUsers(PageLink pageLink) { + log.trace("Executing findAllUsers, pageLink [{}]", pageLink); + validatePageLink(pageLink); + return userDao.findAll(pageLink); + } + @Override public PageData findTenantAdmins(TenantId tenantId, PageLink pageLink) { log.trace("Executing findTenantAdmins, tenantId [{}], pageLink [{}]", tenantId, pageLink); @@ -343,17 +357,8 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic return failedLoginAttempts; } - private UserCredentials saveUserCredentialsAndPasswordHistory(TenantId tenantId, UserCredentials userCredentials) { - UserCredentials result = userCredentialsDao.save(tenantId, userCredentials); - User user = findUserById(tenantId, userCredentials.getUserId()); - if (userCredentials.getPassword() != null) { - updatePasswordHistory(user, userCredentials); - } - return result; - } - - private void updatePasswordHistory(User user, UserCredentials userCredentials) { - JsonNode additionalInfo = user.getAdditionalInfo(); + private void updatePasswordHistory(UserCredentials userCredentials) { + JsonNode additionalInfo = userCredentials.getAdditionalInfo(); if (!(additionalInfo instanceof ObjectNode)) { additionalInfo = JacksonUtil.newObjectNode(); } @@ -374,8 +379,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic userPasswordHistoryJson = JacksonUtil.valueToTree(userPasswordHistoryMap); ((ObjectNode) additionalInfo).set(USER_PASSWORD_HISTORY, userPasswordHistoryJson); } - user.setAdditionalInfo(additionalInfo); - saveUser(user); + userCredentials.setAdditionalInfo(additionalInfo); } private final PaginatedRemover tenantAdminsRemover = new PaginatedRemover<>() { diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index b222cf4b96..8c47b46aff 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -487,7 +487,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 ( From fff1f555e8c187948afb5f4c77b03b85c394924e Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Mon, 20 Feb 2023 19:33:36 +0200 Subject: [PATCH 05/13] refactoring --- .../java/org/thingsboard/server/dao/user/UserServiceImpl.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java index 560105a85e..ea6b96d910 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java @@ -127,9 +127,6 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic userCredentials.setEnabled(false); userCredentials.setActivateToken(StringUtils.randomAlphanumeric(DEFAULT_TOKEN_LENGTH)); userCredentials.setUserId(new UserId(savedUser.getUuidId())); - if (userCredentials.getPassword() != null) { - updatePasswordHistory(userCredentials); - } userCredentialsDao.save(user.getTenantId(), userCredentials); } return savedUser; From 4ddcd99e44d9ee5e937fba934969f763ab7a15ce Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Tue, 21 Feb 2023 12:11:11 +0200 Subject: [PATCH 06/13] refactoring --- .../common/data/security/UserCredentials.java | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java index 5719e46495..c9bd9fbad2 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java @@ -30,6 +30,7 @@ import java.util.Objects; import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.getJson; import static org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo.setJson; +@EqualsAndHashCode(callSuper = true) public class UserCredentials extends BaseData { private static final long serialVersionUID = -2108436378880529163L; @@ -112,24 +113,6 @@ public class UserCredentials extends BaseData { this.resetToken = resetToken; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - UserCredentials that = (UserCredentials) o; - return enabled == that.enabled && userId.equals(that.userId) && Objects.equals(password, that.password) - && Objects.equals(activateToken, that.activateToken) && Objects.equals(resetToken, that.resetToken) - && Arrays.equals(additionalInfoBytes, that.additionalInfoBytes); - } - - @Override - public int hashCode() { - int result = Objects.hash(super.hashCode(), userId, enabled, password, activateToken, resetToken); - result = 31 * result + Arrays.hashCode(additionalInfoBytes); - return result; - } - @Override public String toString() { StringBuilder builder = new StringBuilder(); From 63a5a053a24fc9ccd3eb12228c62096f48ae442a Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Tue, 28 Feb 2023 12:42:33 +0200 Subject: [PATCH 07/13] added try catch to not fail upgrade --- .../install/SqlDatabaseUpgradeService.java | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index e91bad3e18..cbb51a9a3c 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -717,16 +717,22 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService users = userService.findAllUsers(pageLink); for (User user : users.getData()) { futures.add(dbUpgradeExecutor.submit(() -> { - JsonNode additionalInfo = user.getAdditionalInfo(); - if (additionalInfo.isObject() && additionalInfo.has("userPasswordHistory")){ - UserCredentials creds = userService.findUserCredentialsByUserId(user.getTenantId(), user.getId()); - if (creds != null) { - creds.setAdditionalInfo(JacksonUtil.newObjectNode().set("userPasswordHistory", additionalInfo.get("userPasswordHistory"))); - userService.saveUserCredentials(user.getTenantId(), creds); + try { + log.info("Migrating password history for user: " + user.getId()); + JsonNode additionalInfo = user.getAdditionalInfo(); + if (additionalInfo != null && additionalInfo.has("userPasswordHistory")){ + UserCredentials creds = userService.findUserCredentialsByUserId(user.getTenantId(), user.getId()); + if (creds != null) { + creds.setAdditionalInfo(JacksonUtil.newObjectNode().set("userPasswordHistory", additionalInfo.get("userPasswordHistory"))); + userService.saveUserCredentials(user.getTenantId(), creds); + } + ((ObjectNode) additionalInfo).remove("userPasswordHistory"); + userService.saveUser(user); } - ((ObjectNode) additionalInfo).remove("userPasswordHistory"); - userService.saveUser(user); - }})); + } catch (Exception e){ + log.error("Failed to migrate password history for user: " + user.getId(), e); + } + })); } Futures.allAsList(futures).get(); pageLink = pageLink.nextPageLink(); From ecd923ba1037436fd4e074f5d6193e2b3130077c Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Tue, 28 Feb 2023 13:23:58 +0200 Subject: [PATCH 08/13] updated default value --- application/src/main/data/upgrade/3.4.4/schema_update.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/data/upgrade/3.4.4/schema_update.sql b/application/src/main/data/upgrade/3.4.4/schema_update.sql index 418e4066fc..c8e5cbe4b4 100644 --- a/application/src/main/data/upgrade/3.4.4/schema_update.sql +++ b/application/src/main/data/upgrade/3.4.4/schema_update.sql @@ -32,4 +32,4 @@ CREATE TABLE IF NOT EXISTS user_settings ( ); ALTER TABLE user_credentials - ADD COLUMN IF NOT EXISTS additional_info varchar NULL; \ No newline at end of file + ADD COLUMN IF NOT EXISTS additional_info varchar DEFAULT '{}'; \ No newline at end of file From 76f74766fd2c57336f7392df4778f41809ccec77 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 1 Mar 2023 14:23:53 +0200 Subject: [PATCH 09/13] refactored upgrade to be executed with PostgreSQL --- .../main/data/upgrade/3.4.4/schema_update.sql | 8 ++++- .../install/SqlDatabaseUpgradeService.java | 31 ------------------- .../server/dao/user/UserService.java | 2 -- .../server/dao/sql/user/JpaUserDao.java | 7 ----- .../thingsboard/server/dao/user/UserDao.java | 8 ----- .../server/dao/user/UserServiceImpl.java | 7 ----- .../main/resources/sql/schema-entities.sql | 2 +- 7 files changed, 8 insertions(+), 57 deletions(-) diff --git a/application/src/main/data/upgrade/3.4.4/schema_update.sql b/application/src/main/data/upgrade/3.4.4/schema_update.sql index c8e5cbe4b4..858227dd5f 100644 --- a/application/src/main/data/upgrade/3.4.4/schema_update.sql +++ b/application/src/main/data/upgrade/3.4.4/schema_update.sql @@ -32,4 +32,10 @@ CREATE TABLE IF NOT EXISTS user_settings ( ); ALTER TABLE user_credentials - ADD COLUMN IF NOT EXISTS additional_info varchar DEFAULT '{}'; \ No newline at end of file + ADD COLUMN IF NOT EXISTS additional_info varchar DEFAULT '{}'; + +UPDATE user_credentials + SET additional_info = json_build_object('userPasswordHistory', (u.additional_info::json -> 'userPasswordHistory')) + FROM tb_user u WHERE user_credentials.user_id = u.id AND u.additional_info::jsonb ? 'userPasswordHistory'; + +UPDATE tb_user SET additional_info = tb_user.additional_info::jsonb - 'userPasswordHistory'; \ No newline at end of file diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index cbb51a9a3c..20e899aaad 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -116,9 +116,6 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService @Autowired private TenantService tenantService; - @Autowired - private UserService userService; - @Autowired private TenantRepository tenantRepository; @@ -710,34 +707,6 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService } catch (Exception e) { } - PageLink pageLink = new PageLink(1000); - PageData users; - do { - List> futures = new ArrayList<>(); - users = userService.findAllUsers(pageLink); - for (User user : users.getData()) { - futures.add(dbUpgradeExecutor.submit(() -> { - try { - log.info("Migrating password history for user: " + user.getId()); - JsonNode additionalInfo = user.getAdditionalInfo(); - if (additionalInfo != null && additionalInfo.has("userPasswordHistory")){ - UserCredentials creds = userService.findUserCredentialsByUserId(user.getTenantId(), user.getId()); - if (creds != null) { - creds.setAdditionalInfo(JacksonUtil.newObjectNode().set("userPasswordHistory", additionalInfo.get("userPasswordHistory"))); - userService.saveUserCredentials(user.getTenantId(), creds); - } - ((ObjectNode) additionalInfo).remove("userPasswordHistory"); - userService.saveUser(user); - } - } catch (Exception e){ - log.error("Failed to migrate password history for user: " + user.getId(), e); - } - })); - } - Futures.allAsList(futures).get(); - pageLink = pageLink.nextPageLink(); - } while (users.hasNext()); - conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3005000;"); } log.info("Schema updated."); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java index a981292d82..bb40507772 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/user/UserService.java @@ -58,8 +58,6 @@ public interface UserService extends EntityDaoService { PageData findUsersByTenantId(TenantId tenantId, PageLink pageLink); - PageData findAllUsers(PageLink pageLink); - PageData findTenantAdmins(TenantId tenantId, PageLink pageLink); void deleteTenantAdmins(TenantId tenantId); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java index 34386132da..473c145b5d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/user/JpaUserDao.java @@ -75,13 +75,6 @@ public class JpaUserDao extends JpaAbstractSearchTextDao imple DaoUtil.toPageable(pageLink))); } - @Override - public PageData findAll(PageLink pageLink) { - return DaoUtil.toPageData( - userRepository - .findAll(DaoUtil.toPageable(pageLink))); - } - @Override public PageData findTenantAdmins(UUID tenantId, PageLink pageLink) { return DaoUtil.toPageData( diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserDao.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserDao.java index 456676664e..c2551c84d3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/UserDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserDao.java @@ -60,14 +60,6 @@ public interface UserDao extends Dao, TenantEntityDao { */ PageData findByTenantId(UUID tenantId, PageLink pageLink); - /** - * Find users by page link. - * - * @param pageLink the page link - * @return the list of user entities - */ - PageData findAll(PageLink pageLink); - /** * Find tenant admin users by tenantId and page link. * diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java index ea6b96d910..12265d526c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java @@ -240,13 +240,6 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic return userDao.findByTenantId(tenantId.getId(), pageLink); } - @Override - public PageData findAllUsers(PageLink pageLink) { - log.trace("Executing findAllUsers, pageLink [{}]", pageLink); - validatePageLink(pageLink); - return userDao.findAll(pageLink); - } - @Override public PageData findTenantAdmins(TenantId tenantId, PageLink pageLink) { log.trace("Executing findTenantAdmins, tenantId [{}], pageLink [{}]", tenantId, pageLink); diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 8c47b46aff..6cdf431ce0 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -488,7 +488,7 @@ CREATE TABLE IF NOT EXISTS user_credentials ( password varchar(255), reset_token varchar(255) UNIQUE, user_id uuid UNIQUE, - additional_info varchar + additional_info varchar DEFAULT '{}' ); CREATE TABLE IF NOT EXISTS widget_type ( From 0c4ad9cc76653d9528624ed478f7ef9e4bc25771 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 1 Mar 2023 15:19:12 +0200 Subject: [PATCH 10/13] refactoring --- .../server/service/install/SqlDatabaseUpgradeService.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index 20e899aaad..b9ff5383b5 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -15,8 +15,6 @@ */ package org.thingsboard.server.service.install; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; @@ -26,10 +24,8 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; -import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.Tenant; -import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -38,7 +34,6 @@ import org.thingsboard.server.common.data.queue.ProcessingStrategyType; import org.thingsboard.server.common.data.queue.Queue; import org.thingsboard.server.common.data.queue.SubmitStrategy; import org.thingsboard.server.common.data.queue.SubmitStrategyType; -import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.dao.asset.AssetDao; import org.thingsboard.server.dao.asset.AssetProfileService; import org.thingsboard.server.dao.dashboard.DashboardService; @@ -49,7 +44,6 @@ import org.thingsboard.server.dao.queue.QueueService; import org.thingsboard.server.dao.sql.tenant.TenantRepository; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.usagerecord.ApiUsageStateService; -import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.queue.settings.TbRuleEngineQueueConfiguration; import org.thingsboard.server.service.install.sql.SqlDbHelper; From 84419ebd970083fc2d2b7176fa98243f820d515b Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 1 Mar 2023 18:20:25 +0200 Subject: [PATCH 11/13] make additional_info not null --- .../server/dao/user/UserServiceImpl.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java index 12265d526c..8017c319b7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java @@ -127,7 +127,8 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic userCredentials.setEnabled(false); userCredentials.setActivateToken(StringUtils.randomAlphanumeric(DEFAULT_TOKEN_LENGTH)); userCredentials.setUserId(new UserId(savedUser.getUuidId())); - userCredentialsDao.save(user.getTenantId(), userCredentials); + userCredentials.setAdditionalInfo(JacksonUtil.newObjectNode()); + checkAdditionalInfoAndSaveUserCredentials(user.getTenantId(), userCredentials); } return savedUser; } @@ -157,7 +158,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic public UserCredentials saveUserCredentials(TenantId tenantId, UserCredentials userCredentials) { log.trace("Executing saveUserCredentials [{}]", userCredentials); userCredentialsValidator.validate(userCredentials, data -> tenantId); - return userCredentialsDao.save(tenantId, userCredentials); + return checkAdditionalInfoAndSaveUserCredentials(tenantId, userCredentials); } @Override @@ -216,7 +217,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic if (userCredentials.getPassword() != null) { updatePasswordHistory(userCredentials); } - return userCredentialsDao.save(tenantId, userCredentials); + return checkAdditionalInfoAndSaveUserCredentials(tenantId, userCredentials); } @Override @@ -347,9 +348,16 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic return failedLoginAttempts; } + private UserCredentials checkAdditionalInfoAndSaveUserCredentials(TenantId tenantId, UserCredentials userCredentials) { + if (userCredentials.getAdditionalInfo() == null){ + userCredentials.setAdditionalInfo(JacksonUtil.newObjectNode()); + } + return userCredentialsDao.save(tenantId, userCredentials); + } + private void updatePasswordHistory(UserCredentials userCredentials) { JsonNode additionalInfo = userCredentials.getAdditionalInfo(); - if (!(additionalInfo instanceof ObjectNode)) { + if (additionalInfo == null) { additionalInfo = JacksonUtil.newObjectNode(); } Map userPasswordHistoryMap = null; From a93373bbde89bb259f5d19ddc140b7fe73f25181 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 1 Mar 2023 18:27:18 +0200 Subject: [PATCH 12/13] refactoring --- .../java/org/thingsboard/server/dao/user/UserServiceImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java index 8017c319b7..57bd9925d6 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java @@ -127,7 +127,6 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic userCredentials.setEnabled(false); userCredentials.setActivateToken(StringUtils.randomAlphanumeric(DEFAULT_TOKEN_LENGTH)); userCredentials.setUserId(new UserId(savedUser.getUuidId())); - userCredentials.setAdditionalInfo(JacksonUtil.newObjectNode()); checkAdditionalInfoAndSaveUserCredentials(user.getTenantId(), userCredentials); } return savedUser; From e5ba36a13b4d7f4e7311a097cebeaee7a674bcee Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 2 Mar 2023 11:49:23 +0200 Subject: [PATCH 13/13] refactoring --- .../main/data/upgrade/3.4.4/schema_update.sql | 2 +- .../server/dao/user/UserServiceImpl.java | 16 +++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/application/src/main/data/upgrade/3.4.4/schema_update.sql b/application/src/main/data/upgrade/3.4.4/schema_update.sql index 858227dd5f..e54c6a9e7e 100644 --- a/application/src/main/data/upgrade/3.4.4/schema_update.sql +++ b/application/src/main/data/upgrade/3.4.4/schema_update.sql @@ -32,7 +32,7 @@ CREATE TABLE IF NOT EXISTS user_settings ( ); ALTER TABLE user_credentials - ADD COLUMN IF NOT EXISTS additional_info varchar DEFAULT '{}'; + ADD COLUMN IF NOT EXISTS additional_info varchar NOT NULL DEFAULT '{}'; UPDATE user_credentials SET additional_info = json_build_object('userPasswordHistory', (u.additional_info::json -> 'userPasswordHistory')) diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java index 57bd9925d6..366f2b7306 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java @@ -127,7 +127,8 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic userCredentials.setEnabled(false); userCredentials.setActivateToken(StringUtils.randomAlphanumeric(DEFAULT_TOKEN_LENGTH)); userCredentials.setUserId(new UserId(savedUser.getUuidId())); - checkAdditionalInfoAndSaveUserCredentials(user.getTenantId(), userCredentials); + userCredentials.setAdditionalInfo(JacksonUtil.newObjectNode()); + userCredentialsDao.save(user.getTenantId(), userCredentials); } return savedUser; } @@ -157,7 +158,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic public UserCredentials saveUserCredentials(TenantId tenantId, UserCredentials userCredentials) { log.trace("Executing saveUserCredentials [{}]", userCredentials); userCredentialsValidator.validate(userCredentials, data -> tenantId); - return checkAdditionalInfoAndSaveUserCredentials(tenantId, userCredentials); + return userCredentialsDao.save(tenantId, userCredentials); } @Override @@ -216,7 +217,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic if (userCredentials.getPassword() != null) { updatePasswordHistory(userCredentials); } - return checkAdditionalInfoAndSaveUserCredentials(tenantId, userCredentials); + return userCredentialsDao.save(tenantId, userCredentials); } @Override @@ -347,16 +348,9 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic return failedLoginAttempts; } - private UserCredentials checkAdditionalInfoAndSaveUserCredentials(TenantId tenantId, UserCredentials userCredentials) { - if (userCredentials.getAdditionalInfo() == null){ - userCredentials.setAdditionalInfo(JacksonUtil.newObjectNode()); - } - return userCredentialsDao.save(tenantId, userCredentials); - } - private void updatePasswordHistory(UserCredentials userCredentials) { JsonNode additionalInfo = userCredentials.getAdditionalInfo(); - if (additionalInfo == null) { + if (!(additionalInfo instanceof ObjectNode)) { additionalInfo = JacksonUtil.newObjectNode(); } Map userPasswordHistoryMap = null;