Merge branch 'develop/3.5' of github.com:thingsboard/thingsboard into develop/3.5
This commit is contained in:
commit
9c388c5135
@ -30,3 +30,12 @@ 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
|
||||
);
|
||||
|
||||
ALTER TABLE user_credentials
|
||||
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'))
|
||||
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';
|
||||
@ -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<String, String> userPasswordHistoryMap = JacksonUtil.convertValue(userPasswordHistoryJson, new TypeReference<>() {});
|
||||
|
||||
@ -15,10 +15,20 @@
|
||||
*/
|
||||
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 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<UserCredentialsId> {
|
||||
@ -30,6 +40,20 @@ public class UserCredentials extends BaseData<UserCredentialsId> {
|
||||
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();
|
||||
@ -46,6 +70,7 @@ public class UserCredentials extends BaseData<UserCredentialsId> {
|
||||
this.enabled = userCredentials.isEnabled();
|
||||
this.activateToken = userCredentials.getActivateToken();
|
||||
this.resetToken = userCredentials.getResetToken();
|
||||
setAdditionalInfo(userCredentials.getAdditionalInfo());
|
||||
}
|
||||
|
||||
public UserId getUserId() {
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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<UserCredentials>
|
||||
@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<UserCredentials>
|
||||
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>
|
||||
userCredentials.setPassword(password);
|
||||
userCredentials.setActivateToken(activateToken);
|
||||
userCredentials.setResetToken(resetToken);
|
||||
userCredentials.setAdditionalInfo(additionalInfo);
|
||||
return userCredentials;
|
||||
}
|
||||
|
||||
|
||||
@ -127,7 +127,8 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
|
||||
userCredentials.setEnabled(false);
|
||||
userCredentials.setActivateToken(generateSafeToken(DEFAULT_TOKEN_LENGTH));
|
||||
userCredentials.setUserId(new UserId(savedUser.getUuidId()));
|
||||
saveUserCredentialsAndPasswordHistory(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 saveUserCredentialsAndPasswordHistory(tenantId, userCredentials);
|
||||
return userCredentialsDao.save(tenantId, userCredentials);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -175,7 +176,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);
|
||||
}
|
||||
|
||||
@ -211,7 +214,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
|
||||
@ -342,17 +348,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();
|
||||
}
|
||||
@ -373,8 +370,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<TenantId, User> tenantAdminsRemover = new PaginatedRemover<>() {
|
||||
|
||||
@ -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 DEFAULT '{}'
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS widget_type (
|
||||
|
||||
@ -137,7 +137,7 @@ public class TbMsgGeneratorNode implements TbNode {
|
||||
}
|
||||
lastScheduledTs = lastScheduledTs + delay;
|
||||
long curDelay = Math.max(0L, (lastScheduledTs - curTs));
|
||||
TbMsg tickMsg = ctx.newMsg(null, TB_MSG_GENERATOR_NODE_MSG, ctx.getSelfId(), new TbMsgMetaData(), "");
|
||||
TbMsg tickMsg = ctx.newMsg(config.getQueueName(), TB_MSG_GENERATOR_NODE_MSG, ctx.getSelfId(), new TbMsgMetaData(), "");
|
||||
nextTickId = tickMsg.getId();
|
||||
ctx.tellSelf(tickMsg, curDelay);
|
||||
}
|
||||
@ -145,14 +145,14 @@ public class TbMsgGeneratorNode implements TbNode {
|
||||
private ListenableFuture<TbMsg> generate(TbContext ctx, TbMsg msg) {
|
||||
log.trace("generate, config {}", config);
|
||||
if (prevMsg == null) {
|
||||
prevMsg = ctx.newMsg(null, "", originatorId, msg.getCustomerId(), new TbMsgMetaData(), "{}");
|
||||
prevMsg = ctx.newMsg(config.getQueueName(), "", originatorId, msg.getCustomerId(), new TbMsgMetaData(), "{}");
|
||||
}
|
||||
if (initialized.get()) {
|
||||
ctx.logJsEvalRequest();
|
||||
return Futures.transformAsync(scriptEngine.executeGenerateAsync(prevMsg), generated -> {
|
||||
log.trace("generate process response, generated {}, config {}", generated, config);
|
||||
ctx.logJsEvalResponse();
|
||||
prevMsg = ctx.newMsg(null, generated.getType(), originatorId, msg.getCustomerId(), generated.getMetaData(), generated.getData());
|
||||
prevMsg = ctx.newMsg(config.getQueueName(), generated.getType(), originatorId, msg.getCustomerId(), generated.getMetaData(), generated.getData());
|
||||
return Futures.immediateFuture(prevMsg);
|
||||
}, MoreExecutors.directExecutor()); //usually it runs on js-executor-remote-callback thread pool
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ public class TbMsgGeneratorNodeConfiguration implements NodeConfiguration<TbMsgG
|
||||
private ScriptLanguage scriptLang;
|
||||
private String jsScript;
|
||||
private String tbelScript;
|
||||
private String queueName;
|
||||
|
||||
@Override
|
||||
public TbMsgGeneratorNodeConfiguration defaultConfiguration() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user