From 7b4ebc75ff720f10a7e58a2f7e78e331ad47c824 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Mon, 4 May 2020 11:41:37 +0300 Subject: [PATCH 1/5] Renamed env variabled. Added sync --- .../security/auth/oauth2/BasicOAuth2ClientMapper.java | 7 +++---- .../security/auth/oauth2/CustomOAuth2ClientMapper.java | 2 +- application/src/main/resources/thingsboard.yml | 4 ++-- .../server/dao/oauth2/OAuth2ClientMapperConfig.java | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicOAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicOAuth2ClientMapper.java index 935f7f5e3a..1d44a772aa 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicOAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicOAuth2ClientMapper.java @@ -51,9 +51,9 @@ public class BasicOAuth2ClientMapper extends AbstractOAuth2ClientMapper implemen String firstName = getStringAttributeByKey(attributes, config.getBasic().getFirstNameAttributeKey()); oauth2User.setFirstName(firstName); } - if (!StringUtils.isEmpty(config.getBasic().getCustomerNameStrategyPattern())) { + if (!StringUtils.isEmpty(config.getBasic().getCustomerNamePattern())) { StrSubstitutor sub = new StrSubstitutor(attributes, START_PLACEHOLDER_PREFIX, END_PLACEHOLDER_PREFIX); - String customerName = sub.replace(config.getBasic().getCustomerNameStrategyPattern()); + String customerName = sub.replace(config.getBasic().getCustomerNamePattern()); oauth2User.setCustomerName(customerName); } return getOrCreateSecurityUserFromOAuth2User(oauth2User, config.getBasic().isAllowUserCreation()); @@ -68,7 +68,7 @@ public class BasicOAuth2ClientMapper extends AbstractOAuth2ClientMapper implemen return email.substring(email .indexOf("@") + 1); case CUSTOM_TENANT_STRATEGY: StrSubstitutor sub = new StrSubstitutor(attributes, START_PLACEHOLDER_PREFIX, END_PLACEHOLDER_PREFIX); - return sub.replace(config.getBasic().getTenantNameStrategyPattern()); + return sub.replace(config.getBasic().getTenantNamePattern()); default: throw new RuntimeException("Tenant Name Strategy with type " + config.getBasic().getTenantNameStrategy() + " is not supported!"); } @@ -78,7 +78,6 @@ public class BasicOAuth2ClientMapper extends AbstractOAuth2ClientMapper implemen String result = null; try { result = (String) attributes.get(key); - } catch (Exception e) { log.warn("Can't convert attribute to String by key " + key); } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java index 31e2c2bbec..832a1cd39b 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java @@ -41,7 +41,7 @@ public class CustomOAuth2ClientMapper extends AbstractOAuth2ClientMapper impleme return getOrCreateSecurityUserFromOAuth2User(oauth2User, config.getBasic().isAllowUserCreation()); } - public OAuth2User getOAuth2User(OAuth2AuthenticationToken token, OAuth2ClientMapperConfig.CustomOAuth2ClientMapperConfig custom) { + private synchronized OAuth2User getOAuth2User(OAuth2AuthenticationToken token, OAuth2ClientMapperConfig.CustomOAuth2ClientMapperConfig custom) { if (!StringUtils.isEmpty(custom.getUsername()) && !StringUtils.isEmpty(custom.getPassword())) { restTemplateBuilder = restTemplateBuilder.basicAuthentication(custom.getUsername(), custom.getPassword()); } diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 1aada9dd9d..254162b56b 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -126,8 +126,8 @@ security: firstNameAttributeKey: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_FIRST_NAME_ATTRIBUTE_KEY:}" lastNameAttributeKey: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_LAST_NAME_ATTRIBUTE_KEY:}" tenantNameStrategy: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_TENANT_NAME_STRATEGY:domain}" # domain, email or custom - tenantNameStrategyPattern: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_TENANT_NAME_STRATEGY_PATTERN:}" - customerNameStrategyPattern: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_CUSTOMER_NAME_STRATEGY_PATTERN:}" + tenantNamePattern: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_TENANT_NAME_PATTERN:}" # %{attribute_key} as placeholder for attributes value by key + customerNamePattern: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_CUSTOMER_NAME_PATTERN:}" # %{attribute_key} as placeholder for attributes value by key custom: url: "${SECURITY_OAUTH2_DEFAULT_MAPPER_CUSTOM_URL:}" username: "${SECURITY_OAUTH2_DEFAULT_MAPPER_CUSTOM_USERNAME:}" diff --git a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientMapperConfig.java b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientMapperConfig.java index ec4f199549..695bb0aa0e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientMapperConfig.java +++ b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ClientMapperConfig.java @@ -31,8 +31,8 @@ public class OAuth2ClientMapperConfig { private String firstNameAttributeKey; private String lastNameAttributeKey; private String tenantNameStrategy; - private String tenantNameStrategyPattern; - private String customerNameStrategyPattern; + private String tenantNamePattern; + private String customerNamePattern; } @Data From 1c2361fedd0bcbcb4936580daa34c9f2af6401ab Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Tue, 5 May 2020 19:16:02 +0300 Subject: [PATCH 2/5] Exclude old spring-core version --- pom.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pom.xml b/pom.xml index 524fb8ec3e..0fb32edc10 100755 --- a/pom.xml +++ b/pom.xml @@ -468,11 +468,23 @@ org.springframework.security spring-security-oauth2-client ${spring-security.version} + + + org.springframework + spring-core + + org.springframework.security spring-security-oauth2-jose ${spring-security.version} + + + org.springframework + spring-core + + org.springframework.boot From 7a633ed60a710113de91fb47a7d3e110d1373c91 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 6 May 2020 11:10:54 +0300 Subject: [PATCH 3/5] Fixed issue with cretion/delete of relation because of concurrent access to class variable --- .../action/TbAbstractRelationActionNode.java | 15 ++--- .../engine/action/TbCreateRelationNode.java | 57 +++++++++---------- .../engine/action/TbDeleteRelationNode.java | 21 +++---- 3 files changed, 44 insertions(+), 49 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractRelationActionNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractRelationActionNode.java index 5ec91bdf0e..dd23c794f4 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractRelationActionNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractRelationActionNode.java @@ -78,7 +78,8 @@ public abstract class TbAbstractRelationActionNode ctx.tellNext(filterResult.getMsg(), filterResult.isResult() ? SUCCESS : FAILURE), t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); } @@ -86,13 +87,13 @@ public abstract class TbAbstractRelationActionNode processEntityRelationAction(TbContext ctx, TbMsg msg) { - return Futures.transformAsync(getEntity(ctx, msg), entityContainer -> doProcessEntityRelationAction(ctx, msg, entityContainer), MoreExecutors.directExecutor()); + protected ListenableFuture processEntityRelationAction(TbContext ctx, TbMsg msg, String relationType) { + return Futures.transformAsync(getEntity(ctx, msg), entityContainer -> doProcessEntityRelationAction(ctx, msg, entityContainer, relationType), MoreExecutors.directExecutor()); } protected abstract boolean createEntityIfNotExists(); - protected abstract ListenableFuture doProcessEntityRelationAction(TbContext ctx, TbMsg msg, EntityContainer entityContainer); + protected abstract ListenableFuture doProcessEntityRelationAction(TbContext ctx, TbMsg msg, EntityContainer entityContainer, String relationType); protected abstract C loadEntityNodeActionConfig(TbNodeConfiguration configuration) throws TbNodeException; @@ -120,11 +121,11 @@ public abstract class TbAbstractRelationActionNode { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java index de74551c22..3c2e0bc405 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java @@ -57,8 +57,6 @@ import java.util.List; ) public class TbCreateRelationNode extends TbAbstractRelationActionNode { - private String relationType; - @Override protected TbCreateRelationNodeConfiguration loadEntityNodeActionConfig(TbNodeConfiguration configuration) throws TbNodeException { return TbNodeUtils.convert(configuration, TbCreateRelationNodeConfiguration.class); @@ -70,8 +68,8 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode doProcessEntityRelationAction(TbContext ctx, TbMsg msg, EntityContainer entity) { - ListenableFuture future = createIfAbsent(ctx, msg, entity); + protected ListenableFuture doProcessEntityRelationAction(TbContext ctx, TbMsg msg, EntityContainer entity, String relationType) { + ListenableFuture future = createIfAbsent(ctx, msg, entity, relationType); return Futures.transform(future, result -> { RelationContainer container = new RelationContainer(); if (result && config.isChangeOriginatorToRelatedEntity()) { @@ -85,13 +83,12 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode createIfAbsent(TbContext ctx, TbMsg msg, EntityContainer entityContainer) { - relationType = processPattern(msg, config.getRelationType()); + private ListenableFuture createIfAbsent(TbContext ctx, TbMsg msg, EntityContainer entityContainer, String relationType) { SearchDirectionIds sdId = processSingleSearchDirection(msg, entityContainer); ListenableFuture checkRelationFuture = Futures.transformAsync(ctx.getRelationService().checkRelation(ctx.getTenantId(), sdId.getFromId(), sdId.getToId(), relationType, RelationTypeGroup.COMMON), result -> { if (!result) { if (config.isRemoveCurrentRelations()) { - return processDeleteRelations(ctx, processFindRelations(ctx, msg, sdId)); + return processDeleteRelations(ctx, processFindRelations(ctx, msg, sdId, relationType)); } return Futures.immediateFuture(false); } @@ -100,14 +97,14 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode { if (!result) { - return processCreateRelation(ctx, entityContainer, sdId); + return processCreateRelation(ctx, entityContainer, sdId, relationType); } return Futures.immediateFuture(true); }, ctx.getDbCallbackExecutor()); } - private ListenableFuture> processFindRelations(TbContext ctx, TbMsg msg, SearchDirectionIds sdId) { - if (sdId.isOrignatorDirectionFrom()) { + private ListenableFuture> processFindRelations(TbContext ctx, TbMsg msg, SearchDirectionIds sdId, String relationType) { + if (sdId.isOriginatorDirectionFrom()) { return ctx.getRelationService().findByFromAndTypeAsync(ctx.getTenantId(), msg.getOriginator(), relationType, RelationTypeGroup.COMMON); } else { return ctx.getRelationService().findByToAndTypeAsync(ctx.getTenantId(), msg.getOriginator(), relationType, RelationTypeGroup.COMMON); @@ -127,85 +124,85 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode processCreateRelation(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) { + private ListenableFuture processCreateRelation(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId, String relationType) { switch (entityContainer.getEntityType()) { case ASSET: - return processAsset(ctx, entityContainer, sdId); + return processAsset(ctx, entityContainer, sdId, relationType); case DEVICE: - return processDevice(ctx, entityContainer, sdId); + return processDevice(ctx, entityContainer, sdId, relationType); case CUSTOMER: - return processCustomer(ctx, entityContainer, sdId); + return processCustomer(ctx, entityContainer, sdId, relationType); case DASHBOARD: - return processDashboard(ctx, entityContainer, sdId); + return processDashboard(ctx, entityContainer, sdId, relationType); case ENTITY_VIEW: - return processView(ctx, entityContainer, sdId); + return processView(ctx, entityContainer, sdId, relationType); case TENANT: - return processTenant(ctx, entityContainer, sdId); + return processTenant(ctx, entityContainer, sdId, relationType); } return Futures.immediateFuture(true); } - private ListenableFuture processView(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) { + private ListenableFuture processView(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId, String relationType) { return Futures.transformAsync(ctx.getEntityViewService().findEntityViewByIdAsync(ctx.getTenantId(), new EntityViewId(entityContainer.getEntityId().getId())), entityView -> { if (entityView != null) { - return processSave(ctx, sdId); + return processSave(ctx, sdId, relationType); } else { return Futures.immediateFuture(true); } }, ctx.getDbCallbackExecutor()); } - private ListenableFuture processDevice(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) { + private ListenableFuture processDevice(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId, String relationType) { return Futures.transformAsync(ctx.getDeviceService().findDeviceByIdAsync(ctx.getTenantId(), new DeviceId(entityContainer.getEntityId().getId())), device -> { if (device != null) { - return processSave(ctx, sdId); + return processSave(ctx, sdId, relationType); } else { return Futures.immediateFuture(true); } }, MoreExecutors.directExecutor()); } - private ListenableFuture processAsset(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) { + private ListenableFuture processAsset(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId, String relationType) { return Futures.transformAsync(ctx.getAssetService().findAssetByIdAsync(ctx.getTenantId(), new AssetId(entityContainer.getEntityId().getId())), asset -> { if (asset != null) { - return processSave(ctx, sdId); + return processSave(ctx, sdId, relationType); } else { return Futures.immediateFuture(true); } }, ctx.getDbCallbackExecutor()); } - private ListenableFuture processCustomer(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) { + private ListenableFuture processCustomer(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId, String relationType) { return Futures.transformAsync(ctx.getCustomerService().findCustomerByIdAsync(ctx.getTenantId(), new CustomerId(entityContainer.getEntityId().getId())), customer -> { if (customer != null) { - return processSave(ctx, sdId); + return processSave(ctx, sdId, relationType); } else { return Futures.immediateFuture(true); } }, ctx.getDbCallbackExecutor()); } - private ListenableFuture processDashboard(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) { + private ListenableFuture processDashboard(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId, String relationType) { return Futures.transformAsync(ctx.getDashboardService().findDashboardByIdAsync(ctx.getTenantId(), new DashboardId(entityContainer.getEntityId().getId())), dashboard -> { if (dashboard != null) { - return processSave(ctx, sdId); + return processSave(ctx, sdId, relationType); } else { return Futures.immediateFuture(true); } }, ctx.getDbCallbackExecutor()); } - private ListenableFuture processTenant(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) { + private ListenableFuture processTenant(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId, String relationType) { return Futures.transformAsync(ctx.getTenantService().findTenantByIdAsync(ctx.getTenantId(), new TenantId(entityContainer.getEntityId().getId())), tenant -> { if (tenant != null) { - return processSave(ctx, sdId); + return processSave(ctx, sdId, relationType); } else { return Futures.immediateFuture(true); } }, ctx.getDbCallbackExecutor()); } - private ListenableFuture processSave(TbContext ctx, SearchDirectionIds sdId) { + private ListenableFuture processSave(TbContext ctx, SearchDirectionIds sdId, String relationType) { return ctx.getRelationService().saveRelationAsync(ctx.getTenantId(), new EntityRelation(sdId.getFromId(), sdId.getToId(), relationType, RelationTypeGroup.COMMON)); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java index 9af3708fcd..7758845329 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java @@ -48,8 +48,6 @@ import java.util.List; ) public class TbDeleteRelationNode extends TbAbstractRelationActionNode { - private String relationType; - @Override protected TbDeleteRelationNodeConfiguration loadEntityNodeActionConfig(TbNodeConfiguration configuration) throws TbNodeException { return TbNodeUtils.convert(configuration, TbDeleteRelationNodeConfiguration.class); @@ -61,19 +59,18 @@ public class TbDeleteRelationNode extends TbAbstractRelationActionNode processEntityRelationAction(TbContext ctx, TbMsg msg) { - return getRelationContainerListenableFuture(ctx, msg); + protected ListenableFuture processEntityRelationAction(TbContext ctx, TbMsg msg, String relationType) { + return getRelationContainerListenableFuture(ctx, msg, relationType); } @Override - protected ListenableFuture doProcessEntityRelationAction(TbContext ctx, TbMsg msg, EntityContainer entityContainer) { - return Futures.transform(processSingle(ctx, msg, entityContainer), result -> new RelationContainer(msg, result), MoreExecutors.directExecutor()); + protected ListenableFuture doProcessEntityRelationAction(TbContext ctx, TbMsg msg, EntityContainer entityContainer, String relationType) { + return Futures.transform(processSingle(ctx, msg, entityContainer, relationType), result -> new RelationContainer(msg, result), MoreExecutors.directExecutor()); } - private ListenableFuture getRelationContainerListenableFuture(TbContext ctx, TbMsg msg) { - relationType = processPattern(msg, config.getRelationType()); + private ListenableFuture getRelationContainerListenableFuture(TbContext ctx, TbMsg msg, String relationType) { if (config.isDeleteForSingleEntity()) { - return Futures.transformAsync(getEntity(ctx, msg), entityContainer -> doProcessEntityRelationAction(ctx, msg, entityContainer), MoreExecutors.directExecutor()); + return Futures.transformAsync(getEntity(ctx, msg), entityContainer -> doProcessEntityRelationAction(ctx, msg, entityContainer, relationType), MoreExecutors.directExecutor()); } else { return Futures.transform(processList(ctx, msg), result -> new RelationContainer(msg, result), MoreExecutors.directExecutor()); } @@ -100,18 +97,18 @@ public class TbDeleteRelationNode extends TbAbstractRelationActionNode processSingle(TbContext ctx, TbMsg msg, EntityContainer entityContainer) { + private ListenableFuture processSingle(TbContext ctx, TbMsg msg, EntityContainer entityContainer, String relationType) { SearchDirectionIds sdId = processSingleSearchDirection(msg, entityContainer); return Futures.transformAsync(ctx.getRelationService().checkRelation(ctx.getTenantId(), sdId.getFromId(), sdId.getToId(), relationType, RelationTypeGroup.COMMON), result -> { if (result) { - return processSingleDeleteRelation(ctx, sdId); + return processSingleDeleteRelation(ctx, sdId, relationType); } return Futures.immediateFuture(true); }, MoreExecutors.directExecutor()); } - private ListenableFuture processSingleDeleteRelation(TbContext ctx, SearchDirectionIds sdId) { + private ListenableFuture processSingleDeleteRelation(TbContext ctx, SearchDirectionIds sdId, String relationType) { return ctx.getRelationService().deleteRelationAsync(ctx.getTenantId(), sdId.getFromId(), sdId.getToId(), relationType, RelationTypeGroup.COMMON); } From d67ab523097052eb541b64214f0e51703ef5a7e4 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 6 May 2020 12:17:41 +0300 Subject: [PATCH 4/5] Changed direct executors to db executors --- .../engine/action/TbAbstractRelationActionNode.java | 3 +-- .../rule/engine/action/TbCreateRelationNode.java | 7 +++---- .../rule/engine/action/TbDeleteRelationNode.java | 13 ++++++------- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractRelationActionNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractRelationActionNode.java index dd23c794f4..46e4e3e396 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractRelationActionNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractRelationActionNode.java @@ -20,7 +20,6 @@ import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -88,7 +87,7 @@ public abstract class TbAbstractRelationActionNode processEntityRelationAction(TbContext ctx, TbMsg msg, String relationType) { - return Futures.transformAsync(getEntity(ctx, msg), entityContainer -> doProcessEntityRelationAction(ctx, msg, entityContainer, relationType), MoreExecutors.directExecutor()); + return Futures.transformAsync(getEntity(ctx, msg), entityContainer -> doProcessEntityRelationAction(ctx, msg, entityContainer, relationType), ctx.getDbCallbackExecutor()); } protected abstract boolean createEntityIfNotExists(); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java index 3c2e0bc405..ea4b801a4f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java @@ -17,7 +17,6 @@ package org.thingsboard.rule.engine.action; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; @@ -80,7 +79,7 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode createIfAbsent(TbContext ctx, TbMsg msg, EntityContainer entityContainer, String relationType) { @@ -118,7 +117,7 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode false, MoreExecutors.directExecutor()); + return Futures.transform(Futures.allAsList(list), result -> false, ctx.getDbCallbackExecutor()); } return Futures.immediateFuture(false); }, ctx.getDbCallbackExecutor()); @@ -159,7 +158,7 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode processAsset(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId, String relationType) { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java index 7758845329..b27dde1140 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java @@ -17,7 +17,6 @@ package org.thingsboard.rule.engine.action; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; @@ -65,14 +64,14 @@ public class TbDeleteRelationNode extends TbAbstractRelationActionNode doProcessEntityRelationAction(TbContext ctx, TbMsg msg, EntityContainer entityContainer, String relationType) { - return Futures.transform(processSingle(ctx, msg, entityContainer, relationType), result -> new RelationContainer(msg, result), MoreExecutors.directExecutor()); + return Futures.transform(processSingle(ctx, msg, entityContainer, relationType), result -> new RelationContainer(msg, result), ctx.getDbCallbackExecutor()); } private ListenableFuture getRelationContainerListenableFuture(TbContext ctx, TbMsg msg, String relationType) { if (config.isDeleteForSingleEntity()) { - return Futures.transformAsync(getEntity(ctx, msg), entityContainer -> doProcessEntityRelationAction(ctx, msg, entityContainer, relationType), MoreExecutors.directExecutor()); + return Futures.transformAsync(getEntity(ctx, msg), entityContainer -> doProcessEntityRelationAction(ctx, msg, entityContainer, relationType), ctx.getDbCallbackExecutor()); } else { - return Futures.transform(processList(ctx, msg), result -> new RelationContainer(msg, result), MoreExecutors.directExecutor()); + return Futures.transform(processList(ctx, msg), result -> new RelationContainer(msg, result), ctx.getDbCallbackExecutor()); } } @@ -92,9 +91,9 @@ public class TbDeleteRelationNode extends TbAbstractRelationActionNode processSingle(TbContext ctx, TbMsg msg, EntityContainer entityContainer, String relationType) { @@ -105,7 +104,7 @@ public class TbDeleteRelationNode extends TbAbstractRelationActionNode processSingleDeleteRelation(TbContext ctx, SearchDirectionIds sdId, String relationType) { From 175a9c903db751f0c391faa4d3df8f1d4f935f8d Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Wed, 6 May 2020 12:29:26 +0300 Subject: [PATCH 5/5] OAuth: activate user with empty password - to be able to set up it later --- .../security/auth/oauth2/AbstractOAuth2ClientMapper.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java index 53acdd5e85..f620c34436 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java @@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.util.StringUtils; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Tenant; @@ -27,6 +28,7 @@ import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.TextPageLink; import org.thingsboard.server.common.data.security.Authority; +import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.dao.oauth2.OAuth2User; import org.thingsboard.server.dao.tenant.TenantService; @@ -47,6 +49,9 @@ public abstract class AbstractOAuth2ClientMapper { @Autowired private UserService userService; + @Autowired + private BCryptPasswordEncoder passwordEncoder; + @Autowired private TenantService tenantService; @@ -88,6 +93,8 @@ public abstract class AbstractOAuth2ClientMapper { user.setFirstName(oauth2User.getFirstName()); user.setLastName(oauth2User.getLastName()); user = userService.saveUser(user); + UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getTenantId(), user.getId()); + userService.activateUserCredentials(user.getTenantId(), userCredentials.getActivateToken(), passwordEncoder.encode("")); } } catch (Exception e) { log.error("Can't get or create security user from oauth2 user", e);