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 22e679170c..5659e5f84d 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.PageLink; 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); 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 3b18c540e8..5c2392b6f7 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; @@ -78,7 +77,8 @@ public abstract class TbAbstractRelationActionNode ctx.tellNext(filterResult.getMsg(), filterResult.isResult() ? SUCCESS : FAILURE), t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); } @@ -86,13 +86,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), ctx.getDbCallbackExecutor()); } 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 +120,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..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; @@ -57,8 +56,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 +67,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()) { @@ -82,16 +79,15 @@ 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 +96,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); @@ -121,91 +117,91 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode false, MoreExecutors.directExecutor()); + return Futures.transform(Futures.allAsList(list), result -> false, ctx.getDbCallbackExecutor()); } return Futures.immediateFuture(false); }, ctx.getDbCallbackExecutor()); } - private ListenableFuture 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()); + }, ctx.getDbCallbackExecutor()); } - 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..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; @@ -48,8 +47,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,21 +58,20 @@ 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), ctx.getDbCallbackExecutor()); } - 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), 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()); } } @@ -95,23 +91,23 @@ 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()); + }, ctx.getDbCallbackExecutor()); } - 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); }