diff --git a/tyr-server/pom.xml b/tyr-server/pom.xml index 7b7f6217..49da2119 100644 --- a/tyr-server/pom.xml +++ b/tyr-server/pom.xml @@ -144,6 +144,12 @@ alibaba-dingtalk-service-sdk 2.0.0 + + + cn.axzo.platform + axzo-log-api + 1.0.0-SNAPSHOT + diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/config/RocketMQEventConfiguration.java b/tyr-server/src/main/java/cn/axzo/tyr/server/config/RocketMQEventConfiguration.java index 86ff70f1..6f7170b9 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/config/RocketMQEventConfiguration.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/config/RocketMQEventConfiguration.java @@ -15,6 +15,7 @@ import org.apache.rocketmq.spring.core.RocketMQTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; import java.util.function.Consumer; @@ -63,6 +64,7 @@ public class RocketMQEventConfiguration { return new DefaultEventConsumer(appName, eventHandlerRepository, callback); } + @Profile("!unittest") @Slf4j @Component @RocketMQMessageListener(topic = "topic_thrones_${spring.profiles.active}", @@ -81,6 +83,7 @@ public class RocketMQEventConfiguration { } } + @Profile("!unittest") @Slf4j @Component @RocketMQMessageListener(topic = "topic_tyr_${spring.profiles.active}", @@ -99,6 +102,7 @@ public class RocketMQEventConfiguration { } } + @Profile("!unittest") @Slf4j @Component @RocketMQMessageListener(topic = "topic_apisix_plat_${spring.profiles.active}", diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java index 656ea649..656f8860 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/config/exception/BizResultCode.java @@ -13,7 +13,8 @@ public enum BizResultCode implements IResultCode { REDIS_ROLE_NOT_NULL("100003", "角色id不能为空"), REDIS_PRODUCT_NOT_NULL("100004", "产品不能为空"), FEATURE_RESOURCE_NOT_FOUND("100005", "菜单资源不存在"), - WORKSPACE_ID_NOT_NULL("100006", "项目id不能为空"); + WORKSPACE_ID_NOT_NULL("100006", "项目id不能为空"), + REMOVE_USER_ROLE_ERROR("100007", "删除用户角色数据异常"); private String errorCode; private String errorMessage; diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/EventTypeEnum.java b/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/EventTypeEnum.java index 3883080e..ab8f938b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/EventTypeEnum.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/EventTypeEnum.java @@ -11,6 +11,7 @@ public enum EventTypeEnum { SAAS_FEATURE_UPSERT("saas-feature", "saas-feature-upsert", "旧菜单树更新"), SAAS_FEATURE_RESOURCE_UPSERT("saas-feature-resource", "saas-feature-resource-upsert", "新菜单树更新"), PAGE_ELEMENT_FEATURE_RESOURCE_UPSERT("page-element-feature-resource", "page-element-feature-resource-upsert", "菜单-页面元素绑定关系更新"), + SAAS_ROLE_USER_RELATION_REMOVED("saas-role-user-relation", "saas-role-user-relation-removed", "删除用户角色信息"), ; EventTypeEnum(String model, String name, String desc) { diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/event/payload/SaasRoleUserRelationRemovePayload.java b/tyr-server/src/main/java/cn/axzo/tyr/server/event/payload/SaasRoleUserRelationRemovePayload.java new file mode 100644 index 00000000..6fd72f87 --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/event/payload/SaasRoleUserRelationRemovePayload.java @@ -0,0 +1,19 @@ +package cn.axzo.tyr.server.event.payload; + +import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SaasRoleUserRelationRemovePayload implements Serializable { + + private List values; +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserRelationService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserRelationService.java index 6a8a6089..52b4a13b 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserRelationService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/SaasRoleUserRelationService.java @@ -5,8 +5,13 @@ import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam; import cn.axzo.tyr.client.model.roleuser.req.PageRoleUserRelationParam; import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; import com.baomidou.mybatisplus.extension.service.IService; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; import java.util.List; +import java.util.Set; /** * @author haiyangjin @@ -19,4 +24,17 @@ public interface SaasRoleUserRelationService extends IService page(PageRoleUserRelationParam param); void upsert(List saasRoleUserRelations); + + void batchRemove(BatchRemoveParam param); + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class BatchRemoveParam { + + private Set ids; + + private Long operator; + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java index 1a05911c..c710ee64 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImpl.java @@ -1,13 +1,19 @@ package cn.axzo.tyr.server.service.impl; +import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; import cn.axzo.basics.profiles.api.UserProfileServiceApi; import cn.axzo.basics.profiles.dto.basic.PersonProfileDto; import cn.axzo.foundation.dao.support.converter.PageConverter; import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper; +import cn.axzo.foundation.exception.Axssert; +import cn.axzo.framework.rocketmq.Event; +import cn.axzo.log.platform.client.LogPlatClient; import cn.axzo.tyr.client.model.res.SaasRoleRes; import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam; import cn.axzo.tyr.client.model.roleuser.req.PageRoleUserRelationParam; +import cn.axzo.tyr.server.config.MqProducer; +import cn.axzo.tyr.server.event.payload.SaasRoleUserRelationRemovePayload; import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; import cn.axzo.tyr.server.repository.mapper.SaasRoleUserRelationMapper; import cn.axzo.tyr.server.service.RoleService; @@ -36,6 +42,9 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; +import static cn.axzo.tyr.server.config.exception.BizResultCode.REMOVE_USER_ROLE_ERROR; +import static cn.axzo.tyr.server.event.inner.EventTypeEnum.SAAS_ROLE_USER_RELATION_REMOVED; + /** * @author haiyangjin * @date 2023/9/14 @@ -49,6 +58,12 @@ public class SaasRoleUserRelationServiceImpl extends ServiceImpl listV2(ListRoleUserRelationParam param) { @@ -98,6 +113,36 @@ public class SaasRoleUserRelationServiceImpl extends ServiceImpl saasRoleUserRelations = this.listByIds(param.getIds()); + + // 不做准确的提示,防止恶意删数据 + Axssert.check(Objects.equals(param.getIds().size(), saasRoleUserRelations.size()), + REMOVE_USER_ROLE_ERROR); + + this.lambdaUpdate() + .in(SaasRoleUserRelation::getId, param.getIds()) + .set(SaasRoleUserRelation::getIsDelete, TableIsDeleteEnum.DELETE.value) + .set(Objects.nonNull(param.getOperator()), SaasRoleUserRelation::getUpdateBy, param.getOperator()) + .update(); + + Event event = Event.builder() + .targetType(TARGET_TYPE) + .eventCode(SAAS_ROLE_USER_RELATION_REMOVED.getEventCode()) + .data(SaasRoleUserRelationRemovePayload.builder() + .values(saasRoleUserRelations) + .build()) + .build(); + mqProducer.send(event); + } + private Set resolveRoleIds(PageRoleUserRelationParam param) { if (CollectionUtils.isEmpty(param.getRoleCodes())) { return Optional.ofNullable(param.getRoleIds()) diff --git a/tyr-server/src/test/java/cn/axzo/tyr/base/TestConfig.java b/tyr-server/src/test/java/cn/axzo/tyr/base/TestConfig.java index 177fd203..802471b6 100644 --- a/tyr-server/src/test/java/cn/axzo/tyr/base/TestConfig.java +++ b/tyr-server/src/test/java/cn/axzo/tyr/base/TestConfig.java @@ -1,16 +1,20 @@ package cn.axzo.tyr.base; +import cn.axzo.framework.rocketmq.Event; +import cn.axzo.framework.rocketmq.EventProducer; import cn.axzo.thrones.client.saas.ServicePkgClient; -import cn.axzo.tyr.base.MysqlDataLoader; +import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; import redis.embedded.RedisServer; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.io.IOException; +import java.util.Map; @Slf4j @TestConfiguration @@ -38,4 +42,25 @@ public class TestConfig { @MockBean private ServicePkgClient servicePkgClient; + + @Bean + @Primary + public EventProducer dummyEventProducer() { + return new EventProducer() { + @Override + public void send(Event event, Context context) { + log.info("send event to console, event = {}, content = {}", event.toJsonString(), JSONObject.toJSONString(context)); + } + + @Override + public void send(Event event) { + log.info("send event to console, event = {}", event.toJsonString()); + } + + @Override + public void send(Event event, Map addHeaders) { + log.info("send event to console, event = {}", event.toJsonString()); + } + }; + } } \ No newline at end of file diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/permission/JobTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/permission/JobTest.java index e1abbed6..2babfb87 100644 --- a/tyr-server/src/test/java/cn/axzo/tyr/server/permission/JobTest.java +++ b/tyr-server/src/test/java/cn/axzo/tyr/server/permission/JobTest.java @@ -1,10 +1,8 @@ package cn.axzo.tyr.server.permission; import cn.axzo.tyr.server.job.ProductFeatureRefreshJobHandler; -import cn.axzo.tyr.server.job.UserRoleRelationCleanJob; import cn.axzo.tyr.server.model.ProductFeatureRefreshParam; import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -18,8 +16,6 @@ import org.springframework.boot.test.context.SpringBootTest; public class JobTest { @Autowired private ProductFeatureRefreshJobHandler productFeatureRefreshJobHandler; - @Autowired - private UserRoleRelationCleanJob userRoleRelationCleanJob; @Test public void testProductFeatureRefresh() throws Exception { @@ -29,14 +25,4 @@ public class JobTest { productFeatureRefreshJobHandler.execute(JSON.toJSONString(param)); } - @Test - public void testUserRoleCleanJob() throws Exception { - UserRoleRelationCleanJob.CleanTarget param = UserRoleRelationCleanJob.CleanTarget.builder() - //.ouId(1L) - //.workspaceId(31L) - .personId(5367L) - .build(); - - userRoleRelationCleanJob.execute(JSON.toJSONString(param)); - } } diff --git a/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImplTest.java b/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImplTest.java new file mode 100644 index 00000000..ff4bb510 --- /dev/null +++ b/tyr-server/src/test/java/cn/axzo/tyr/server/service/impl/SaasRoleUserRelationServiceImplTest.java @@ -0,0 +1,59 @@ +package cn.axzo.tyr.server.service.impl; + +import cn.axzo.foundation.exception.BusinessException; +import cn.axzo.tyr.base.BaseTest; +import cn.axzo.tyr.base.MysqlDataLoader; +import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; +import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam; +import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; +import cn.axzo.tyr.server.service.SaasRoleUserRelationService; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static cn.axzo.tyr.server.config.exception.BizResultCode.REMOVE_USER_ROLE_ERROR; +import static org.junit.jupiter.api.Assertions.*; + +class SaasRoleUserRelationServiceImplTest extends BaseTest { + + @Autowired + private SaasRoleUserRelationService saasRoleUserRelationService; + @Autowired + private MysqlDataLoader mysqlDataLoader; + + @BeforeEach + @Override + public void setup() { + super.setup(); + mysqlDataLoader.loadFromClassName(getClass().getSimpleName()); + } + + @Test + void batchRemove() { + + List saasRoleUsers = saasRoleUserRelationService.listV2(ListRoleUserRelationParam.builder().build()); + Assertions.assertEquals(saasRoleUsers.size(), 4); + + SaasRoleUserRelationService.BatchRemoveParam batchRemoveParam = + SaasRoleUserRelationService.BatchRemoveParam.builder().build(); + saasRoleUserRelationService.batchRemove(batchRemoveParam); + Assertions.assertEquals(saasRoleUserRelationService.listV2(ListRoleUserRelationParam.builder().build()).size(), 4); + + BusinessException businessException = assertThrows(BusinessException.class, ()->{ + saasRoleUserRelationService.batchRemove(SaasRoleUserRelationService.BatchRemoveParam.builder() + .ids(Sets.newHashSet(1L)) + .build()); + }); + assertEquals(businessException.getErrorMsg(), REMOVE_USER_ROLE_ERROR.getErrorMessage()); + + saasRoleUserRelationService.batchRemove(SaasRoleUserRelationService.BatchRemoveParam.builder() + .ids(Sets.newHashSet(16399L, 16400L)) + .build()); + Assertions.assertEquals(saasRoleUserRelationService.listV2(ListRoleUserRelationParam.builder().build()).size(), 2); + } +} \ No newline at end of file diff --git a/tyr-server/src/test/resources/application-unittest.yml b/tyr-server/src/test/resources/application-unittest.yml index 8d13ff83..b9e541f1 100644 --- a/tyr-server/src/test/resources/application-unittest.yml +++ b/tyr-server/src/test/resources/application-unittest.yml @@ -42,3 +42,6 @@ axzo: # service.base.tyr: https://test-api.axzo.cn/tyr # 超管编码 role.superAdmin: '{1:"entSuperAdmin",2:"projSuperAdmin",6:"omsSuperAdmin"}' + +topic: topic_tyr_${spring.profiles.active} +sendMq: true \ No newline at end of file diff --git a/tyr-server/src/test/resources/mysql/SaasRoleUserRelationServiceImplTest.sql b/tyr-server/src/test/resources/mysql/SaasRoleUserRelationServiceImplTest.sql new file mode 100644 index 00000000..c1d5014d --- /dev/null +++ b/tyr-server/src/test/resources/mysql/SaasRoleUserRelationServiceImplTest.sql @@ -0,0 +1,8 @@ +#-->DEFAULT + +INSERT INTO saas_role_user_relation (id, identity_id, role_id, identity_type, natural_person_id, workspace_id, ou_id, resource_type, resource_id, is_delete, create_at, update_at, create_by, update_by, job_type) VALUES (16399, 40, 3415, 3, 2232, 8, 1, 0, 0, 0, '2021-09-16 22:09:29', '2022-09-13 09:48:24', 0, 0, 2); +INSERT INTO saas_role_user_relation (id, identity_id, role_id, identity_type, natural_person_id, workspace_id, ou_id, resource_type, resource_id, is_delete, create_at, update_at, create_by, update_by, job_type) VALUES (16400, 1327, 3416, 3, 1561, 9, 1, 0, 0, 0, '2021-09-16 22:09:29', '2021-09-16 22:09:29', 0, 0, 2); +INSERT INTO saas_role_user_relation (id, identity_id, role_id, identity_type, natural_person_id, workspace_id, ou_id, resource_type, resource_id, is_delete, create_at, update_at, create_by, update_by, job_type) VALUES (16401, 98, 3417, 3, 2020, 6, 1, 0, 0, 0, '2021-09-16 22:09:29', '2021-09-16 22:09:29', 0, 0, 2); +INSERT INTO saas_role_user_relation (id, identity_id, role_id, identity_type, natural_person_id, workspace_id, ou_id, resource_type, resource_id, is_delete, create_at, update_at, create_by, update_by, job_type) VALUES (16402, 106, 3418, 3, 3577, 12, 1, 0, 0, 0, '2021-09-16 22:09:29', '2021-09-16 22:09:29', 0, 0, 2); + +#-->SaasRoleUserRelationServiceImplTest.sql \ No newline at end of file diff --git a/tyr-server/src/test/resources/mysql/data.sql b/tyr-server/src/test/resources/mysql/data.sql index 0165323c..10f81f54 100644 --- a/tyr-server/src/test/resources/mysql/data.sql +++ b/tyr-server/src/test/resources/mysql/data.sql @@ -1,10 +1,2 @@ select 1; --- saas_role 表初始化数据 -INSERT INTO `saas_role` (`id`, `NAME`, `description`, `role_type`, `role_code`, `workspace_id`, `owner_ou_id`, `product_unit_type`, `workspace_type`, `is_delete`, `create_at`, `update_at`, `create_by`, `update_by`, `fit_ou_type_bit`, `fit_ou_node_type_bit`, `position_template_id`, `project_team_manage_role_resource_id`, `from_pre_role_id`, `job_code`, `is_display`, `enabled`, `sort`) VALUES (1, '代班长', '', 'common', '7722', 2, 1, 0, 2, 0, '2022-10-19 15:53:32', '2024-04-17 11:02:19', 0, 0, 32, 1, 2, 59, 0, '', 1, 1, 1); - --- saas_role_user_relation 表初始化数据 --- DemoTest.testDeleteUserRole 使用 -INSERT INTO `saas_role_user_relation` (`id`, `identity_id`, `role_id`, `identity_type`, `natural_person_id`, `workspace_id`, `ou_id`, `resource_type`, `resource_id`, `is_delete`, `create_at`, `update_at`, `create_by`, `update_by`, `job_type`) VALUES (1, 2008231, 100001, 2, 1, 1, 1, 1, 9592, 0, '2024-05-22 18:23:40', '2024-05-22 18:23:39', 0, 0, 2); - - diff --git a/tyr-server/src/test/resources/mysql/schema.sql b/tyr-server/src/test/resources/mysql/schema.sql index 812b5503..de84bdd8 100644 --- a/tyr-server/src/test/resources/mysql/schema.sql +++ b/tyr-server/src/test/resources/mysql/schema.sql @@ -256,3 +256,23 @@ CREATE TABLE `saas_pgroup_role_relation` ( alter table saas_feature_resource add index `idx_feature_resource_uni_code` (`uni_code`); alter table saas_feature_resource add index `idx_feature_resource_path` (`path`); + +CREATE TABLE `permission_rule` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `name` varchar(64) NOT NULL COMMENT '规则名称', + `key_code` varchar(128) NOT NULL COMMENT '规则编码', + `type` varchar(64) NOT NULL COMMENT '规则类型:CREATE_ROLE_CHECK:check创建角色', +-- `content` JSON NULL COMMENT 'pipeline信息:{"pipelines":[{"pipeline":"","params":{}}]}', + `content` VARCHAR(2048) NOT NULL DEFAULT '{}' COMMENT 'pipeline信息:{"pipelines":[{"pipeline":"实现规则类实例名字","params":{执行规则的默认参数}}]}', + `status` varchar(32) NOT NULL DEFAULT 'ENABLED' COMMENT '状态:ENABLED、DISABLED', + `description` varchar(512) NOT NULL DEFAULT '' COMMENT '规则的描述', +-- `ext` JSON NULL COMMENT '额外信息', + `ext` VARCHAR(2048) NOT NULL DEFAULT '{}' COMMENT '额外信息', + `create_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `create_by` bigint NOT NULL DEFAULT '0' COMMENT '创建者', + `update_by` bigint NOT NULL DEFAULT '0' COMMENT '更新者', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_permission_rule_key_code` (`key_code`), + UNIQUE KEY `uk_permission_rule_name` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COMMENT='权限系统规则定义表'; \ No newline at end of file