mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-02-08 22:54:59 +08:00
Merge branch 'master' of https://github.com/YunaiV/ruoyi-vue-pro
This commit is contained in:
commit
8f333562af
@ -11,7 +11,7 @@
|
||||
Target Server Version : 80026
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 13/05/2022 00:25:55
|
||||
Date: 25/05/2022 23:28:25
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
@ -300,7 +300,7 @@ CREATE TABLE `bpm_form` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '工作流的表单定义';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '工作流的表单定义';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of bpm_form
|
||||
@ -359,7 +359,7 @@ CREATE TABLE `bpm_process_definition_ext` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 98 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Bpm 流程定义的拓展表\n';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 104 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Bpm 流程定义的拓展表\n';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of bpm_process_definition_ext
|
||||
@ -389,7 +389,7 @@ CREATE TABLE `bpm_process_instance_ext` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 201 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '工作流的流程实例的拓展';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 204 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '工作流的流程实例的拓展';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of bpm_process_instance_ext
|
||||
@ -415,7 +415,7 @@ CREATE TABLE `bpm_task_assign_rule` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 192 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Bpm 任务规则表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 201 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Bpm 任务规则表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of bpm_task_assign_rule
|
||||
@ -444,7 +444,7 @@ CREATE TABLE `bpm_task_ext` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 214 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '工作流的流程任务的拓展表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 217 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '工作流的流程任务的拓展表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of bpm_task_ext
|
||||
@ -504,7 +504,7 @@ CREATE TABLE `infra_api_access_log` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 29228 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'API 访问日志表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 33232 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'API 访问日志表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of infra_api_access_log
|
||||
@ -546,7 +546,7 @@ CREATE TABLE `infra_api_error_log` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 429 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 454 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of infra_api_error_log
|
||||
@ -673,7 +673,7 @@ CREATE TABLE `infra_data_source_config` (
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '数据源配置表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '数据源配置表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of infra_data_source_config
|
||||
@ -698,7 +698,7 @@ CREATE TABLE `infra_file` (
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 39 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 83 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of infra_file
|
||||
@ -1153,11 +1153,11 @@ CREATE TABLE `system_dept` (
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, '芋道源码', 0, 0, 1, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '103', '2022-01-14 01:04:05', b'0', 1);
|
||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (101, '深圳总公司', 100, 1, 104, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '1', '2022-02-22 19:47:48', b'0', 1);
|
||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (101, '深圳总公司', 100, 1, 104, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '1', '2022-05-16 20:25:23', b'0', 1);
|
||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (102, '长沙分公司', 100, 2, NULL, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '', '2021-12-15 05:01:40', b'0', 1);
|
||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, '研发部门', 101, 1, 104, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '103', '2022-01-14 01:04:14', b'0', 1);
|
||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, '市场部门', 101, 2, NULL, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '', '2021-12-15 05:01:38', b'0', 1);
|
||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (105, '测试部门', 101, 3, NULL, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '', '2021-12-15 05:01:37', b'0', 1);
|
||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (105, '测试部门', 101, 3, NULL, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '1', '2022-05-16 20:25:15', b'0', 1);
|
||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (106, '财务部门', 101, 4, 103, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '103', '2022-01-15 21:32:22', b'0', 1);
|
||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (107, '运维部门', 101, 5, NULL, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '', '2021-12-15 05:01:33', b'0', 1);
|
||||
INSERT INTO `system_dept` (`id`, `name`, `parent_id`, `sort`, `leader_user_id`, `phone`, `email`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (108, '市场部门', 102, 1, NULL, '15888888888', 'ry@qq.com', 0, 'admin', '2021-01-05 17:03:47', '1', '2022-02-16 08:35:45', b'0', 1);
|
||||
@ -1186,7 +1186,7 @@ CREATE TABLE `system_dict_data` (
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1161 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1162 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_dict_data
|
||||
@ -1346,13 +1346,13 @@ CREATE TABLE `system_dict_type` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `dict_type`(`type` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 148 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典类型表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 149 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典类型表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_dict_type
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '用户性别', 'system_user_sex', 0, NULL, 'admin', '2021-01-05 17:03:48', '', '2022-02-01 16:30:31', b'0');
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '用户性别', 'system_user_sex', 0, NULL, 'admin', '2021-01-05 17:03:48', '1', '2022-05-16 20:29:32', b'0');
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6, '参数类型', 'infra_config_type', 0, NULL, 'admin', '2021-01-05 17:03:48', '', '2022-02-01 16:36:54', b'0');
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (7, '通知类型', 'system_notice_type', 0, NULL, 'admin', '2021-01-05 17:03:48', '', '2022-02-01 16:35:26', b'0');
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (9, '操作类型', 'system_operate_type', 0, NULL, 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 09:32:21', b'0');
|
||||
@ -1360,7 +1360,7 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (11, 'Boolean 是否类型', 'infra_boolean_string', 0, 'boolean 转是否', '', '2021-01-19 03:20:08', '', '2022-02-01 16:37:10', b'0');
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (104, '登陆结果', 'system_login_result', 0, '登陆结果', '', '2021-01-18 06:17:11', '', '2022-02-01 16:36:00', b'0');
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (105, 'Redis 超时类型', 'infra_redis_timeout_type', 0, 'RedisKeyDefine.TimeoutTypeEnum', '', '2021-01-26 00:52:50', '', '2022-02-01 16:50:29', b'0');
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (106, '代码生成模板类型', 'infra_codegen_template_type', 0, NULL, '', '2021-02-05 07:08:06', '', '2022-03-10 16:33:42', b'0');
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (106, '代码生成模板类型', 'infra_codegen_template_type', 0, NULL, '', '2021-02-05 07:08:06', '1', '2022-05-16 20:26:50', b'0');
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (107, '定时任务状态', 'infra_job_status', 0, NULL, '', '2021-02-07 07:44:16', '', '2022-02-01 16:51:11', b'0');
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (108, '定时任务日志状态', 'infra_job_log_status', 0, NULL, '', '2021-02-08 10:03:51', '', '2022-02-01 16:50:43', b'0');
|
||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (109, '用户类型', 'user_type', 0, NULL, '', '2021-02-26 00:15:51', '', '2021-02-26 00:15:51', b'0');
|
||||
@ -1411,7 +1411,7 @@ CREATE TABLE `system_error_code` (
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 5458 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '错误码表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 5829 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '错误码表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_error_code
|
||||
@ -1440,7 +1440,7 @@ CREATE TABLE `system_login_log` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1341 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1416 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_login_log
|
||||
@ -1744,10 +1744,11 @@ DROP TABLE IF EXISTS `system_oauth2_access_token`;
|
||||
CREATE TABLE `system_oauth2_access_token` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`user_id` bigint NOT NULL COMMENT '用户编号',
|
||||
`user_type` tinyint NOT NULL COMMENT '用户类型',
|
||||
`access_token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '访问令牌',
|
||||
`refresh_token` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '刷新令牌',
|
||||
`user_type` tinyint NOT NULL COMMENT '用户类型',
|
||||
`client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '客户端编号',
|
||||
`scopes` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '授权范围',
|
||||
`expires_time` datetime NOT NULL COMMENT '过期时间',
|
||||
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
@ -1756,7 +1757,7 @@ CREATE TABLE `system_oauth2_access_token` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 56 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '刷新令牌';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 172 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_oauth2_access_token
|
||||
@ -1764,6 +1765,33 @@ CREATE TABLE `system_oauth2_access_token` (
|
||||
BEGIN;
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for system_oauth2_approve
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `system_oauth2_approve`;
|
||||
CREATE TABLE `system_oauth2_approve` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`user_id` bigint NOT NULL COMMENT '用户编号',
|
||||
`user_type` tinyint NOT NULL COMMENT '用户类型',
|
||||
`client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '客户端编号',
|
||||
`scope` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '授权范围',
|
||||
`approved` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否接受',
|
||||
`expires_time` datetime NOT NULL COMMENT '过期时间',
|
||||
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 80 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 批准表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_oauth2_approve
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for system_oauth2_client
|
||||
-- ----------------------------
|
||||
@ -1779,9 +1807,9 @@ CREATE TABLE `system_oauth2_client` (
|
||||
`access_token_validity_seconds` int NOT NULL COMMENT '访问令牌的有效期',
|
||||
`refresh_token_validity_seconds` int NOT NULL COMMENT '刷新令牌的有效期',
|
||||
`redirect_uris` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '可重定向的 URI 地址',
|
||||
`auto_approve` bit(1) NOT NULL COMMENT '是否自动授权',
|
||||
`authorized_grant_types` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '授权类型',
|
||||
`scopes` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '授权范围',
|
||||
`auto_approve_scopes` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '自动通过的授权范围',
|
||||
`authorities` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '权限',
|
||||
`resource_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '资源',
|
||||
`additional_information` varchar(4096) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '附加信息',
|
||||
@ -1797,8 +1825,37 @@ CREATE TABLE `system_oauth2_client` (
|
||||
-- Records of system_oauth2_client
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `auto_approve`, `authorized_grant_types`, `scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, 'default', 'admin123', '芋道源码', 'http://test.yudao.iocoder.cn/a5e2e244368878a366b516805a4aabf1.png', '我是描述', 0, 999999999, 8640, '[\"https://www.iocoder.cn\",\"https://doc.iocoder.cn\"]', b'1', '[\"password\",\"authorization_code\",\"implicit\",\"refresh_token\"]', '[\"user_info\"]', '[\"system:user:query\"]', '[]', '{}', '1', '2022-05-11 21:47:12', '1', '2022-05-12 01:00:20', b'0');
|
||||
INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `auto_approve`, `authorized_grant_types`, `scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (40, 'test', 'test2', 'biubiu', 'http://test.yudao.iocoder.cn/277a899d573723f1fcdfb57340f00379.png', NULL, 0, 1800, 43200, '[\"https://www.iocoder.cn\"]', b'1', '[\"password\",\"authorization_code\",\"implicit\"]', '[]', '[]', '[]', '{}', '1', '2022-05-12 00:28:20', '1', '2022-05-12 00:59:53', b'0');
|
||||
INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, 'default', 'admin123', '芋道源码', 'http://test.yudao.iocoder.cn/a5e2e244368878a366b516805a4aabf1.png', '我是描述', 0, 999999999, 8640, '[\"https://www.iocoder.cn\",\"https://doc.iocoder.cn\"]', '[\"password\",\"authorization_code\",\"implicit\",\"refresh_token\"]', '[\"user.read\",\"user.write\"]', '[]', '[\"user.read\",\"user.write\"]', '[]', '{}', '1', '2022-05-11 21:47:12', '1', '2022-05-23 13:33:11', b'0');
|
||||
INSERT INTO `system_oauth2_client` (`id`, `client_id`, `secret`, `name`, `logo`, `description`, `status`, `access_token_validity_seconds`, `refresh_token_validity_seconds`, `redirect_uris`, `authorized_grant_types`, `scopes`, `auto_approve_scopes`, `authorities`, `resource_ids`, `additional_information`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (40, 'test', 'test2', 'biubiu', 'http://test.yudao.iocoder.cn/277a899d573723f1fcdfb57340f00379.png', NULL, 0, 1800, 43200, '[\"https://www.iocoder.cn\"]', '[\"password\",\"authorization_code\",\"implicit\"]', '[\"user_info\",\"projects\"]', '[\"user_info\"]', '[]', '[]', '{}', '1', '2022-05-12 00:28:20', '1', '2022-05-14 15:11:31', b'0');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for system_oauth2_code
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `system_oauth2_code`;
|
||||
CREATE TABLE `system_oauth2_code` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
|
||||
`user_id` bigint NOT NULL COMMENT '用户编号',
|
||||
`user_type` tinyint NOT NULL COMMENT '用户类型',
|
||||
`code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '授权码',
|
||||
`client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '客户端编号',
|
||||
`scopes` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '授权范围',
|
||||
`expires_time` datetime NOT NULL COMMENT '过期时间',
|
||||
`redirect_uri` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '可重定向的 URI 地址',
|
||||
`state` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '状态',
|
||||
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 授权码表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_oauth2_code
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
@ -1811,6 +1868,7 @@ CREATE TABLE `system_oauth2_refresh_token` (
|
||||
`refresh_token` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '刷新令牌',
|
||||
`user_type` tinyint NOT NULL COMMENT '用户类型',
|
||||
`client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '客户端编号',
|
||||
`scopes` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '授权范围',
|
||||
`expires_time` datetime NOT NULL COMMENT '过期时间',
|
||||
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
@ -1819,7 +1877,7 @@ CREATE TABLE `system_oauth2_refresh_token` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 37 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '刷新令牌';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 106 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '刷新令牌';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_oauth2_refresh_token
|
||||
@ -1859,7 +1917,7 @@ CREATE TABLE `system_operate_log` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2097 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2214 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_operate_log
|
||||
@ -1917,7 +1975,7 @@ CREATE TABLE `system_role` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 112 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色信息表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 114 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色信息表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_role
|
||||
@ -1929,6 +1987,7 @@ INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_sco
|
||||
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, '租户管理员', 'tenant_admin', 0, 1, '', 0, 1, '系统自动生成', '1', '2022-02-22 00:56:14', '1', '2022-02-22 00:56:14', b'0', 121);
|
||||
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (110, '测试角色', 'test', 0, 1, '[]', 0, 2, '嘿嘿', '110', '2022-02-23 00:14:34', '110', '2022-02-23 13:14:58', b'0', 121);
|
||||
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, '租户管理员', 'tenant_admin', 0, 1, '', 0, 1, '系统自动生成', '1', '2022-03-07 21:37:58', '1', '2022-03-07 21:37:58', b'0', 122);
|
||||
INSERT INTO `system_role` (`id`, `name`, `code`, `sort`, `data_scope`, `data_scope_dept_ids`, `status`, `type`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (113, '租户管理员', 'tenant_admin', 0, 1, '', 0, 1, '系统自动生成', '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
@ -1946,7 +2005,7 @@ CREATE TABLE `system_role_menu` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1695 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色和菜单关联表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1729 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色和菜单关联表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_role_menu
|
||||
@ -2143,6 +2202,23 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1692, 101, 114, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1693, 101, 115, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1694, 101, 116, '1', '2022-04-01 22:21:37', '1', '2022-04-01 22:21:37', b'0', 1);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1712, 113, 1024, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1713, 113, 1025, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1714, 113, 1, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1715, 113, 102, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1716, 113, 103, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1717, 113, 104, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1718, 113, 1013, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1719, 113, 1014, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1720, 113, 1015, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1721, 113, 1016, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1722, 113, 1017, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1723, 113, 1018, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1724, 113, 1019, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1725, 113, 1020, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1726, 113, 1021, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1727, 113, 1022, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1728, 113, 1023, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
@ -2199,7 +2275,7 @@ BEGIN;
|
||||
INSERT INTO `system_sms_channel` (`id`, `signature`, `code`, `status`, `remark`, `api_key`, `api_secret`, `callback_url`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '芋道', 'YUN_PIAN', 0, '呵呵呵哒', '1555a14277cb8a608cf45a9e6a80d510', NULL, 'http://vdwapu.natappfree.cc/admin-api/system/sms/callback/yunpian', '', '2021-03-31 06:12:20', '1', '2022-02-23 16:48:44', b'0');
|
||||
INSERT INTO `system_sms_channel` (`id`, `signature`, `code`, `status`, `remark`, `api_key`, `api_secret`, `callback_url`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2, 'Ballcat', 'ALIYUN', 0, '啦啦啦', 'LTAI5tCnKso2uG3kJ5gRav88', 'fGJ5SNXL7P1NHNRmJ7DJaMJGPyE55C', NULL, '', '2021-03-31 11:53:10', '1', '2021-04-14 00:08:37', b'0');
|
||||
INSERT INTO `system_sms_channel` (`id`, `signature`, `code`, `status`, `remark`, `api_key`, `api_secret`, `callback_url`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '测试渠道', 'DEBUG_DING_TALK', 0, '123', '696b5d8ead48071237e4aa5861ff08dbadb2b4ded1c688a7b7c9afc615579859', 'SEC5c4e5ff888bc8a9923ae47f59e7ccd30af1f14d93c55b4e2c9cb094e35aeed67', NULL, '1', '2021-04-13 00:23:14', '1', '2022-03-27 20:29:49', b'0');
|
||||
INSERT INTO `system_sms_channel` (`id`, `signature`, `code`, `status`, `remark`, `api_key`, `api_secret`, `callback_url`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6, '测试演示', 'DEBUG_DING_TALK', 0, NULL, '696b5d8ead48071237e4aa5861ff08dbadb2b4ded1c688a7b7c9afc615579859', 'SEC5c4e5ff888bc8a9923ae47f59e7ccd30af1f14d93c55b4e2c9cb094e35aeed67', NULL, '1', '2022-04-10 23:07:59', '1', '2022-04-10 23:07:59', b'0');
|
||||
INSERT INTO `system_sms_channel` (`id`, `signature`, `code`, `status`, `remark`, `api_key`, `api_secret`, `callback_url`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6, '测试演示', 'DEBUG_DING_TALK', 0, NULL, '696b5d8ead48071237e4aa5861ff08dbadb2b4ded1c688a7b7c9afc615579859', 'SEC5c4e5ff888bc8a9923ae47f59e7ccd30af1f14d93c55b4e2c9cb094e35aeed67', NULL, '1', '2022-04-10 23:07:59', '1', '2022-05-16 20:34:49', b'0');
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
@ -2224,7 +2300,7 @@ CREATE TABLE `system_sms_code` (
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号'
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 467 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 468 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_sms_code
|
||||
@ -2267,7 +2343,7 @@ CREATE TABLE `system_sms_log` (
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 140 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 144 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_sms_log
|
||||
@ -2337,7 +2413,7 @@ CREATE TABLE `system_social_user` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_social_user
|
||||
@ -2362,7 +2438,7 @@ CREATE TABLE `system_social_user_bind` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_social_user_bind
|
||||
@ -2391,14 +2467,14 @@ CREATE TABLE `system_tenant` (
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 123 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '租户表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 125 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '租户表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_tenant
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `domain`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '芋道源码', NULL, '芋艿', '17321315478', 0, 'https://www.iocoder.cn', 0, '2099-02-19 17:14:16', 9999, '1', '2021-01-05 17:03:47', '1', '2022-02-23 12:15:11', b'0');
|
||||
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `domain`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (121, '小租户', 110, '小王2', '15601691300', 0, 'http://www.iocoder.cn', 111, '2024-03-11 00:00:00', 20, '1', '2022-02-22 00:56:14', '1', '2022-03-19 18:37:20', b'0');
|
||||
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `domain`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (121, '小租户', 110, '小王2', '15601691300', 0, 'http://www.iocoder.cn', 111, '2024-03-11 00:00:00', 20, '1', '2022-02-22 00:56:14', '1', '2022-05-17 10:03:59', b'0');
|
||||
INSERT INTO `system_tenant` (`id`, `name`, `contact_user_id`, `contact_name`, `contact_mobile`, `status`, `domain`, `package_id`, `expire_time`, `account_count`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (122, '测试租户', 113, '芋道', '15601691300', 0, 'https://www.iocoder.cn', 111, '2022-04-30 00:00:00', 50, '1', '2022-03-07 21:37:58', '1', '2022-03-07 21:37:58', b'0');
|
||||
COMMIT;
|
||||
|
||||
@ -2442,7 +2518,7 @@ CREATE TABLE `system_user_post` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 115 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户岗位表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 116 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户岗位表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_user_post
|
||||
@ -2451,6 +2527,7 @@ BEGIN;
|
||||
INSERT INTO `system_user_post` (`id`, `user_id`, `post_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (112, 1, 1, 'admin', '2022-05-02 07:25:24', 'admin', '2022-05-02 07:25:24', b'0', 1);
|
||||
INSERT INTO `system_user_post` (`id`, `user_id`, `post_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (113, 100, 1, 'admin', '2022-05-02 07:25:24', 'admin', '2022-05-02 07:25:24', b'0', 1);
|
||||
INSERT INTO `system_user_post` (`id`, `user_id`, `post_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (114, 114, 3, 'admin', '2022-05-02 07:25:24', 'admin', '2022-05-02 07:25:24', b'0', 1);
|
||||
INSERT INTO `system_user_post` (`id`, `user_id`, `post_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (115, 104, 1, '1', '2022-05-16 19:36:28', '1', '2022-05-16 19:36:28', b'0', 1);
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
@ -2468,7 +2545,7 @@ CREATE TABLE `system_user_role` (
|
||||
`deleted` bit(1) NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 19 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户和角色关联表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户和角色关联表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_user_role
|
||||
@ -2489,6 +2566,7 @@ INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_t
|
||||
INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (16, 113, 111, '1', '2022-03-07 21:37:58', '1', '2022-03-07 21:37:58', b'0', 122);
|
||||
INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (17, 114, 101, '1', '2022-03-19 21:51:13', '1', '2022-03-19 21:51:13', b'0', 1);
|
||||
INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (18, 1, 2, '1', '2022-05-12 20:39:29', '1', '2022-05-12 20:39:29', b'0', 1);
|
||||
INSERT INTO `system_user_role` (`id`, `user_id`, `role_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (19, 116, 113, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
@ -2546,16 +2624,16 @@ CREATE TABLE `system_users` (
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `idx_username`(`username` ASC, `update_time` ASC, `tenant_id` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 116 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户信息表';
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 117 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户信息表';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of system_users
|
||||
-- ----------------------------
|
||||
BEGIN;
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://test.yudao.iocoder.cn/48934f2f-92d4-4250-b917-d10d2b262c6a', 0, '127.0.0.1', '2022-05-13 00:12:13', 'admin', '2021-01-05 17:03:47', NULL, '2022-05-13 00:12:13', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '', NULL, '', '2021-01-07 09:07:17', '104', '2021-12-16 09:26:10', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://test.yudao.iocoder.cn/48934f2f-92d4-4250-b917-d10d2b262c6a', 0, '127.0.0.1', '2022-05-23 20:27:29', 'admin', '2021-01-05 17:03:47', NULL, '2022-05-23 20:27:29', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '127.0.0.1', '2022-05-22 19:35:33', '', '2021-01-07 09:07:17', NULL, '2022-05-22 19:35:33', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$10$wWoPT7sqriM2O1YXRL.je.GiL538OR6ZTN8aQZr9JAGdnpCH2tpYe', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, '', 0, '127.0.0.1', '2022-01-18 00:33:40', '', '2021-01-13 23:50:35', NULL, '2022-01-18 00:33:40', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$10$e5RpuDCC0GYSt0Hvd2.CjujIXwgGct4SnXi6dVGxdgFsnqgEryk5a', '测试号', NULL, 107, '[]', '111@qq.com', '15601691200', 1, '', 0, '127.0.0.1', '2022-03-19 21:46:19', '', '2021-01-21 02:13:53', NULL, '2022-03-19 21:46:19', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$10$e5RpuDCC0GYSt0Hvd2.CjujIXwgGct4SnXi6dVGxdgFsnqgEryk5a', '测试号', NULL, 107, '[1]', '111@qq.com', '15601691200', 1, '', 0, '127.0.0.1', '2022-03-19 21:46:19', '', '2021-01-21 02:13:53', '1', '2022-05-16 19:36:28', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (107, 'admin107', '$2a$10$dYOOBKMO93v/.ReCqzyFg.o67Tqk.bbc2bhrpyBGkIw9aypCtr2pm', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 22:59:33', '1', '2022-02-27 08:26:51', b'0', 118);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (108, 'admin108', '$2a$10$y6mfvKoNYL1GXWak8nYwVOH.kCWqjactkzdoIDgiKl93WN3Ejg.Lu', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:00:50', '1', '2022-02-27 08:26:53', b'0', 119);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, 'admin109', '$2a$10$JAqvH0tEc0I7dfDVBI7zyuB4E3j.uH6daIjV53.vUS6PknFkDJkuK', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:11:50', '1', '2022-02-27 08:26:56', b'0', 120);
|
||||
@ -2564,7 +2642,8 @@ INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`,
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (112, 'newobject', '$2a$10$jh5MsR.ud/gKe3mVeUp5t.nEXGDSmHyv5OYjWQwHO8wlGmMSI9Twy', '新对象', NULL, NULL, '[]', '', '', 0, '', 0, '', NULL, '1', '2022-02-23 19:08:03', '1', '2022-02-23 19:08:03', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (113, 'aoteman', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '127.0.0.1', '2022-03-19 18:38:51', '1', '2022-03-07 21:37:58', NULL, '2022-03-19 18:38:51', b'0', 122);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (114, 'hrmgr', '$2a$10$TR4eybBioGRhBmDBWkqWLO6NIh3mzYa8KBKDDB5woiGYFVlRAi.fu', 'hr 小姐姐', NULL, NULL, '[3]', '', '', 0, '', 0, '127.0.0.1', '2022-03-19 22:15:43', '1', '2022-03-19 21:50:58', NULL, '2022-03-19 22:15:43', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (115, 'aotemane', '$2a$10$/WCwGHu1eq0wOVDd/u8HweJ0gJCHyLS6T7ndCqI8UXZAQom1etk2e', '1', '11', 100, '[]', '', '', 0, '', 0, '', NULL, '1', '2022-04-30 02:55:43', '1', '2022-04-30 02:55:43', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (115, 'aotemane', '$2a$10$/WCwGHu1eq0wOVDd/u8HweJ0gJCHyLS6T7ndCqI8UXZAQom1etk2e', '1', '11', 101, '[]', '', '', 1, '', 0, '', NULL, '1', '2022-04-30 02:55:43', '1', '2022-05-22 20:18:45', b'0', 1);
|
||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (116, '15601691302', '$2a$10$L5C4S0U6adBWMvFv1Wwl4.DI/NwYS3WIfLj5Q.Naqr5II8CmqsDZ6', '小豆', NULL, NULL, NULL, '', '', 0, '', 0, '', NULL, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||
COMMIT;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -2,13 +2,16 @@ package cn.iocoder.yudao.framework.test.core.util;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||
import uk.co.jemos.podam.api.PodamFactory;
|
||||
import uk.co.jemos.podam.api.PodamFactoryImpl;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@ -22,7 +25,6 @@ public class RandomUtils {
|
||||
|
||||
private static final int RANDOM_STRING_LENGTH = 10;
|
||||
|
||||
private static final Set<String> TINYINT_FIELDS = SetUtils.asSet("type", "category");
|
||||
private static final int TINYINT_MAX = 127;
|
||||
|
||||
private static final int RANDOM_DATE_MAX = 30;
|
||||
@ -41,9 +43,10 @@ public class RandomUtils {
|
||||
if (attributeMetadata.getAttributeName().equals("status")) {
|
||||
return RandomUtil.randomEle(CommonStatusEnum.values()).getStatus();
|
||||
}
|
||||
// 针对部分字段,使用 tinyint 范围
|
||||
if (TINYINT_FIELDS.contains(attributeMetadata.getAttributeName())) {
|
||||
return RandomUtil.randomInt(1, TINYINT_MAX + 1);
|
||||
// 如果是 type、status 结尾的字段,返回 tinyint 范围
|
||||
if (StrUtil.endWithAnyIgnoreCase(attributeMetadata.getAttributeName(),
|
||||
"type", "status", "category", "scope")) {
|
||||
return RandomUtil.randomInt(0, TINYINT_MAX + 1);
|
||||
}
|
||||
return RandomUtil.randomInt();
|
||||
});
|
||||
|
@ -9,6 +9,7 @@ VALUES (
|
||||
);
|
||||
|
||||
-- 按钮父菜单ID
|
||||
-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码
|
||||
SELECT @parentId := LAST_INSERT_ID();
|
||||
|
||||
-- 按钮 SQL
|
||||
|
@ -52,18 +52,3 @@ tenant-id: {{adminTenentId}}
|
||||
POST {{baseUrl}}/system/oauth2/check-token?token=620d307c5b4148df8a98dd6c6c547106
|
||||
Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw==
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
### 请求 /system/oauth2/user/get 接口 => 成功
|
||||
GET {{baseUrl}}/system/oauth2/user/get
|
||||
Authorization: Bearer 9502bd7a768a4ade920b90f41e2efd5c
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
### 请求 /system/oauth2/user/update 接口 => 成功
|
||||
PUT {{baseUrl}}/system/oauth2/user/update
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer 9502bd7a768a4ade920b90f41e2efd5c
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
{
|
||||
"nickname": "芋道源码"
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.oauth2;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
@ -13,36 +12,26 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAccessTokenRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAuthorizeInfoRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenCheckTokenRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user.OAuth2OpenUserInfoRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user.OAuth2OpenUserUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.convert.oauth2.OAuth2OpenConvert;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ApproveDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.enums.auth.OAuth2GrantTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.service.dept.DeptService;
|
||||
import cn.iocoder.yudao.module.system.service.dept.PostService;
|
||||
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ApproveService;
|
||||
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ClientService;
|
||||
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2GrantService;
|
||||
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService;
|
||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||
import cn.iocoder.yudao.module.system.util.oauth2.OAuth2Utils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -61,7 +50,7 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti
|
||||
* 另外,一个公司如果有多个管理后台,它们 client_id 产生的 access token 相互之间是无法互通的,即无法访问它们系统的 API 接口,直到两个 client_id 产生信任授权。
|
||||
*
|
||||
* 考虑到【本系统】暂时不想做的过于复杂,默认只有获取到 access token 之后,可以访问【本系统】管理后台的 /system-api/* 所有接口,除非手动添加 scope 控制。
|
||||
* scope 的使用示例,可见当前类的 getUserInfo 和 updateUserInfo 方法,上面有 @PreAuthorize("@ss.hasScope('user.read')") 和 @PreAuthorize("@ss.hasScope('user.write')") 注解
|
||||
* scope 的使用示例,可见 {@link OAuth2UserController} 类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@ -194,8 +183,7 @@ public class OAuth2OpenController {
|
||||
// 0. 校验用户已经登录。通过 Spring Security 实现
|
||||
|
||||
// 1. 获得 Client 客户端的信息
|
||||
OAuth2ClientDO client = oauth2ClientService.validOAuthClientFromCache(clientId, null,
|
||||
null, null, null);
|
||||
OAuth2ClientDO client = oauth2ClientService.validOAuthClientFromCache(clientId);
|
||||
// 2. 获得用户已经授权的信息
|
||||
List<OAuth2ApproveDO> approves = oauth2ApproveService.getApproveList(getLoginUserId(), getUserType(), clientId);
|
||||
// 拼接返回
|
||||
@ -232,7 +220,6 @@ public class OAuth2OpenController {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Boolean> scopes = JsonUtils.parseObject(scope, Map.class);
|
||||
scopes = ObjectUtil.defaultIfNull(scopes, Collections.emptyMap());
|
||||
// TODO 芋艿:针对 approved + scopes 在看看 spring security 的实现
|
||||
// 0. 校验用户已经登录。通过 Spring Security 实现
|
||||
|
||||
// 1.1 校验 responseType 是否满足 code 或者 token 值
|
||||
@ -271,7 +258,7 @@ public class OAuth2OpenController {
|
||||
if (StrUtil.equalsAny(responseType, "token")) {
|
||||
return OAuth2GrantTypeEnum.IMPLICIT;
|
||||
}
|
||||
throw exception0(BAD_REQUEST.getCode(), "response_type 参数值允许 code 和 token");
|
||||
throw exception0(BAD_REQUEST.getCode(), "response_type 参数值只允许 code 和 token");
|
||||
}
|
||||
|
||||
private String getImplicitGrantRedirect(Long userId, OAuth2ClientDO client,
|
||||
@ -288,7 +275,7 @@ public class OAuth2OpenController {
|
||||
private String getAuthorizationCodeRedirect(Long userId, OAuth2ClientDO client,
|
||||
List<String> scopes, String redirectUri, String state) {
|
||||
// 1. 创建 code 授权码
|
||||
String authorizationCode = oauth2GrantService.grantAuthorizationCodeForCode(userId,getUserType(), client.getClientId(), scopes,
|
||||
String authorizationCode = oauth2GrantService.grantAuthorizationCodeForCode(userId, getUserType(), client.getClientId(), scopes,
|
||||
redirectUri, state);
|
||||
// 2. 拼接重定向的 URL
|
||||
return OAuth2Utils.buildAuthorizationCodeRedirectUri(redirectUri, authorizationCode, state);
|
||||
@ -306,43 +293,4 @@ public class OAuth2OpenController {
|
||||
return clientIdAndSecret;
|
||||
}
|
||||
|
||||
// ============ 用户操作的示例,展示 scope 的使用 ============
|
||||
|
||||
@Resource
|
||||
private AdminUserService userService;
|
||||
@Resource
|
||||
private DeptService deptService;
|
||||
@Resource
|
||||
private PostService postService;
|
||||
|
||||
@GetMapping("/user/get")
|
||||
@ApiOperation("获得用户基本信息")
|
||||
@PreAuthorize("@ss.hasScope('user.read')")
|
||||
public CommonResult<OAuth2OpenUserInfoRespVO> getUserInfo() {
|
||||
// 获得用户基本信息
|
||||
AdminUserDO user = userService.getUser(getLoginUserId());
|
||||
OAuth2OpenUserInfoRespVO resp = OAuth2OpenConvert.INSTANCE.convert(user);
|
||||
// 获得部门信息
|
||||
if (user.getDeptId() != null) {
|
||||
DeptDO dept = deptService.getDept(user.getDeptId());
|
||||
resp.setDept(OAuth2OpenConvert.INSTANCE.convert(dept));
|
||||
}
|
||||
// 获得岗位信息
|
||||
if (CollUtil.isNotEmpty(user.getPostIds())) {
|
||||
List<PostDO> posts = postService.getPosts(user.getPostIds());
|
||||
resp.setPosts(OAuth2OpenConvert.INSTANCE.convertList(posts));
|
||||
}
|
||||
return success(resp);
|
||||
}
|
||||
|
||||
@PutMapping("/user/update")
|
||||
@ApiOperation("更新用户基本信息")
|
||||
@PreAuthorize("@ss.hasScope('user.write')")
|
||||
public CommonResult<Boolean> updateUserInfo(@Valid @RequestBody OAuth2OpenUserUpdateReqVO reqVO) {
|
||||
// 这里将 UserProfileUpdateReqVO =》UserProfileUpdateReqVO 对象,实现接口的复用。
|
||||
// 主要是,AdminUserService 没有自己的 BO 对象,所以复用只能这么做
|
||||
userService.updateUserProfile(getLoginUserId(), OAuth2OpenConvert.INSTANCE.convert(reqVO));
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
### 请求 /system/oauth2/user/get 接口 => 成功
|
||||
GET {{baseUrl}}/system/oauth2/user/get
|
||||
Authorization: Bearer 47f9c74ec11041f193b777ebb95c3b0d
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
### 请求 /system/oauth2/user/update 接口 => 成功
|
||||
PUT {{baseUrl}}/system/oauth2/user/update
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer 47f9c74ec11041f193b777ebb95c3b0d
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
{
|
||||
"nickname": "芋道源码"
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.oauth2;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user.OAuth2UserInfoRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user.OAuth2UserUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.convert.oauth2.OAuth2UserConvert;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.service.dept.DeptService;
|
||||
import cn.iocoder.yudao.module.system.service.dept.PostService;
|
||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
/**
|
||||
* 提供给外部应用调用为主
|
||||
*
|
||||
* 1. 在 getUserInfo 方法上,添加 @PreAuthorize("@ss.hasScope('user.read')") 注解,声明需要满足 scope = user.read
|
||||
* 2. 在 updateUserInfo 方法上,添加 @PreAuthorize("@ss.hasScope('user.write')") 注解,声明需要满足 scope = user.write
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Api(tags = "管理后台 - OAuth2.0 用户")
|
||||
@RestController
|
||||
@RequestMapping("/system/oauth2/user")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class OAuth2UserController {
|
||||
|
||||
@Resource
|
||||
private AdminUserService userService;
|
||||
@Resource
|
||||
private DeptService deptService;
|
||||
@Resource
|
||||
private PostService postService;
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得用户基本信息")
|
||||
@PreAuthorize("@ss.hasScope('user.read')") //
|
||||
public CommonResult<OAuth2UserInfoRespVO> getUserInfo() {
|
||||
// 获得用户基本信息
|
||||
AdminUserDO user = userService.getUser(getLoginUserId());
|
||||
OAuth2UserInfoRespVO resp = OAuth2UserConvert.INSTANCE.convert(user);
|
||||
// 获得部门信息
|
||||
if (user.getDeptId() != null) {
|
||||
DeptDO dept = deptService.getDept(user.getDeptId());
|
||||
resp.setDept(OAuth2UserConvert.INSTANCE.convert(dept));
|
||||
}
|
||||
// 获得岗位信息
|
||||
if (CollUtil.isNotEmpty(user.getPostIds())) {
|
||||
List<PostDO> posts = postService.getPosts(user.getPostIds());
|
||||
resp.setPosts(OAuth2UserConvert.INSTANCE.convertList(posts));
|
||||
}
|
||||
return success(resp);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@ApiOperation("更新用户基本信息")
|
||||
@PreAuthorize("@ss.hasScope('user.write')")
|
||||
public CommonResult<Boolean> updateUserInfo(@Valid @RequestBody OAuth2UserUpdateReqVO reqVO) {
|
||||
// 这里将 UserProfileUpdateReqVO =》UserProfileUpdateReqVO 对象,实现接口的复用。
|
||||
// 主要是,AdminUserService 没有自己的 BO 对象,所以复用只能这么做
|
||||
userService.updateUserProfile(getLoginUserId(), OAuth2UserConvert.INSTANCE.convert(reqVO));
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
@ -7,7 +7,7 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel("管理后台 - 【开放接口】校验令牌 Response VO")
|
||||
@Data
|
||||
@ -28,13 +28,13 @@ public class OAuth2OpenCheckTokenRespVO {
|
||||
@ApiModelProperty(value = "客户端编号", required = true, example = "car")
|
||||
private String clientId;
|
||||
@ApiModelProperty(value = "授权范围", required = true, example = "user_info")
|
||||
private Set<String> scopes;
|
||||
private List<String> scopes;
|
||||
|
||||
@ApiModelProperty(value = "访问令牌", required = true, example = "tudou")
|
||||
@JsonProperty("access_token")
|
||||
private String accessToken;
|
||||
|
||||
@ApiModelProperty(value = "过期时间", required = true, example = "1593092157", notes = "时间戳 / 1000,即单位:秒")
|
||||
@JsonProperty("exp")
|
||||
private Long exp;
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user;
|
||||
package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
@ -8,11 +8,11 @@ import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel("管理后台 - 【开放接口】获得用户基本信息 Response VO")
|
||||
@ApiModel("管理后台 - OAuth2.0 获得用户基本信息 Response VO")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class OAuth2OpenUserInfoRespVO {
|
||||
public class OAuth2UserInfoRespVO {
|
||||
|
||||
@ApiModelProperty(value = "用户编号", required = true, example = "1")
|
||||
private Long id;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user;
|
||||
package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
@ -10,11 +10,11 @@ import org.hibernate.validator.constraints.Length;
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
@ApiModel("管理后台 - 【开放接口】更新用户基本信息 Request VO")
|
||||
@ApiModel("管理后台 - OAuth2.0 更新用户基本信息 Request VO")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class OAuth2OpenUserUpdateReqVO {
|
||||
public class OAuth2UserUpdateReqVO {
|
||||
|
||||
@ApiModelProperty(value = "用户昵称", required = true, example = "芋艿")
|
||||
@Size(max = 30, message = "用户昵称长度不能超过 30 个字符")
|
@ -7,15 +7,9 @@ import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAccessTokenRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAuthorizeInfoRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenCheckTokenRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user.OAuth2OpenUserInfoRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.user.OAuth2OpenUserUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ApproveDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.util.oauth2.OAuth2Utils;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
@ -46,14 +40,6 @@ public interface OAuth2OpenConvert {
|
||||
}
|
||||
OAuth2OpenCheckTokenRespVO convert3(OAuth2AccessTokenDO bean);
|
||||
|
||||
// ============ 用户操作的示例 ============
|
||||
|
||||
OAuth2OpenUserInfoRespVO convert(AdminUserDO bean);
|
||||
OAuth2OpenUserInfoRespVO.Dept convert(DeptDO dept);
|
||||
List<OAuth2OpenUserInfoRespVO.Post> convertList(List<PostDO> list);
|
||||
|
||||
UserProfileUpdateReqVO convert(OAuth2OpenUserUpdateReqVO bean);
|
||||
|
||||
default OAuth2OpenAuthorizeInfoRespVO convert(OAuth2ClientDO client, List<OAuth2ApproveDO> approves) {
|
||||
// 构建 scopes
|
||||
List<KeyValue<String, Boolean>> scopes = new ArrayList<>(client.getScopes().size());
|
||||
|
@ -0,0 +1,25 @@
|
||||
package cn.iocoder.yudao.module.system.convert.oauth2;
|
||||
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user.OAuth2UserInfoRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user.OAuth2UserUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface OAuth2UserConvert {
|
||||
|
||||
OAuth2UserConvert INSTANCE = Mappers.getMapper(OAuth2UserConvert.class);
|
||||
|
||||
OAuth2UserInfoRespVO convert(AdminUserDO bean);
|
||||
OAuth2UserInfoRespVO.Dept convert(DeptDO dept);
|
||||
List<OAuth2UserInfoRespVO.Post> convertList(List<PostDO> list);
|
||||
|
||||
UserProfileUpdateReqVO convert(OAuth2UserUpdateReqVO bean);
|
||||
|
||||
}
|
@ -9,7 +9,6 @@ import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@ -22,11 +21,10 @@ import java.util.List;
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("system_oauth2_access_token")
|
||||
@TableName(value = "system_oauth2_access_token", autoResultMap = true)
|
||||
@KeySequence("system_oauth2_access_token_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class OAuth2AccessTokenDO extends TenantBaseDO {
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,7 @@ import java.util.List;
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName("system_oauth2_refresh_token")
|
||||
@TableName(value = "system_oauth2_refresh_token", autoResultMap = true)
|
||||
// 由于 Oracle 的 SEQ 的名字长度有限制,所以就先用 system_oauth2_access_token_seq 吧,反正也没啥问题
|
||||
@KeySequence("system_oauth2_access_token_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
|
@ -25,7 +25,7 @@ public interface OAuth2AccessTokenMapper extends BaseMapperX<OAuth2AccessTokenDO
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<OAuth2AccessTokenDO>()
|
||||
.eqIfPresent(OAuth2AccessTokenDO::getUserId, reqVO.getUserId())
|
||||
.eqIfPresent(OAuth2AccessTokenDO::getUserType, reqVO.getUserType())
|
||||
.eqIfPresent(OAuth2AccessTokenDO::getClientId, reqVO.getClientId())
|
||||
.likeIfPresent(OAuth2AccessTokenDO::getClientId, reqVO.getClientId())
|
||||
.gt(OAuth2AccessTokenDO::getExpiresTime, new Date())
|
||||
.orderByDesc(OAuth2AccessTokenDO::getId));
|
||||
}
|
||||
|
@ -6,7 +6,9 @@ import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ApproveDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2ApproveMapper;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@ -35,6 +37,7 @@ public class OAuth2ApproveServiceImpl implements OAuth2ApproveService {
|
||||
private OAuth2ApproveMapper oauth2ApproveMapper;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean checkForPreApproval(Long userId, Integer userType, String clientId, Collection<String> requestedScopes) {
|
||||
// 第一步,基于 Client 的自动授权计算,如果 scopes 都在自动授权中,则返回 true 通过
|
||||
OAuth2ClientDO clientDO = oauth2ClientService.validOAuthClientFromCache(clientId);
|
||||
@ -49,14 +52,14 @@ public class OAuth2ApproveServiceImpl implements OAuth2ApproveService {
|
||||
}
|
||||
|
||||
// 第二步,算上用户已经批准的授权。如果 scopes 都包含,则返回 true
|
||||
List<OAuth2ApproveDO> approveDOs = oauth2ApproveMapper.selectListByUserIdAndUserTypeAndClientId(
|
||||
userId, userType, clientId);
|
||||
List<OAuth2ApproveDO> approveDOs = getApproveList(userId, userType, clientId);
|
||||
Set<String> scopes = convertSet(approveDOs, OAuth2ApproveDO::getScope,
|
||||
o -> o.getApproved() && !DateUtils.isExpired(o.getExpiresTime())); // 只保留未过期的
|
||||
OAuth2ApproveDO::getApproved); // 只保留未过期的 + 同意的
|
||||
return CollUtil.containsAll(scopes, requestedScopes);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean updateAfterApproval(Long userId, Integer userType, String clientId, Map<String, Boolean> requestedScopes) {
|
||||
// 如果 requestedScopes 为空,说明没有要求,则返回 true 通过
|
||||
if (CollUtil.isEmpty(requestedScopes)) {
|
||||
@ -83,8 +86,9 @@ public class OAuth2ApproveServiceImpl implements OAuth2ApproveService {
|
||||
return approveDOs;
|
||||
}
|
||||
|
||||
private void saveApprove(Long userId, Integer userType, String clientId,
|
||||
String scope, Boolean approved, Date expireTime) {
|
||||
@VisibleForTesting
|
||||
void saveApprove(Long userId, Integer userType, String clientId,
|
||||
String scope, Boolean approved, Date expireTime) {
|
||||
// 先更新
|
||||
OAuth2ApproveDO approveDO = new OAuth2ApproveDO().setUserId(userId).setUserType(userType)
|
||||
.setClientId(clientId).setScope(scope).setApproved(approved).setExpiresTime(expireTime);
|
||||
|
@ -15,6 +15,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2ClientMapper;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.auth.OAuth2ClientProducer;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -51,7 +52,8 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService {
|
||||
*
|
||||
* 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
|
||||
*/
|
||||
@Getter
|
||||
@Getter // 解决单测
|
||||
@Setter // 解决单测
|
||||
private volatile Map<String, OAuth2ClientDO> clientCache;
|
||||
/**
|
||||
* 缓存角色的最大更新时间,用于后续的增量轮询,判断是否有更新
|
||||
@ -151,7 +153,7 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void validateClientIdExists(Long id, String clientId) {
|
||||
void validateClientIdExists(Long id, String clientId) {
|
||||
OAuth2ClientDO client = oauth2ClientMapper.selectByClientId(clientId);
|
||||
if (client == null) {
|
||||
return;
|
||||
@ -160,7 +162,7 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService {
|
||||
if (id == null) {
|
||||
throw exception(OAUTH2_CLIENT_EXISTS);
|
||||
}
|
||||
if (!client.getClientId().equals(clientId)) {
|
||||
if (!client.getId().equals(id)) {
|
||||
throw exception(OAUTH2_CLIENT_EXISTS);
|
||||
}
|
||||
}
|
||||
@ -189,7 +191,7 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService {
|
||||
|
||||
// 校验客户端密钥
|
||||
if (StrUtil.isNotEmpty(clientSecret) && ObjectUtil.notEqual(client.getSecret(), clientSecret)) {
|
||||
throw exception(OAUTH2_CLIENT_CLIENT_SECRET_ERROR, clientSecret);
|
||||
throw exception(OAUTH2_CLIENT_CLIENT_SECRET_ERROR);
|
||||
}
|
||||
// 校验授权方式
|
||||
if (StrUtil.isNotEmpty(authorizedGrantType) && !CollUtil.contains(client.getAuthorizedGrantTypes(), authorizedGrantType)) {
|
||||
|
@ -26,8 +26,8 @@ public interface OAuth2CodeService {
|
||||
* @param state 状态
|
||||
* @return 授权码的信息
|
||||
*/
|
||||
OAuth2CodeDO createAuthorizationCode(Long userId, Integer userType, String clientId, List<String> scopes,
|
||||
String redirectUri, String state);
|
||||
OAuth2CodeDO createAuthorizationCode(Long userId, Integer userType, String clientId,
|
||||
List<String> scopes, String redirectUri, String state);
|
||||
|
||||
/**
|
||||
* 使用授权码
|
||||
|
@ -33,8 +33,8 @@ public class OAuth2CodeServiceImpl implements OAuth2CodeService {
|
||||
private OAuth2CodeMapper oauth2CodeMapper;
|
||||
|
||||
@Override
|
||||
public OAuth2CodeDO createAuthorizationCode(Long userId, Integer userType, String clientId, List<String> scopes,
|
||||
String redirectUri, String state) {
|
||||
public OAuth2CodeDO createAuthorizationCode(Long userId, Integer userType, String clientId,
|
||||
List<String> scopes, String redirectUri, String state) {
|
||||
OAuth2CodeDO codeDO = new OAuth2CodeDO().setCode(generateCode())
|
||||
.setUserId(userId).setUserType(userType)
|
||||
.setClientId(clientId).setScopes(scopes)
|
||||
|
@ -61,11 +61,13 @@ public class OAuth2Utils {
|
||||
if (CollUtil.isNotEmpty(scopes)) {
|
||||
vars.put("scope", buildScopeStr(scopes));
|
||||
}
|
||||
for (String key : additionalInformation.keySet()) {
|
||||
Object value = additionalInformation.get(key);
|
||||
if (value != null) {
|
||||
keys.put("extra_" + key, key);
|
||||
vars.put("extra_" + key, value);
|
||||
if (CollUtil.isNotEmpty(additionalInformation)) {
|
||||
for (String key : additionalInformation.keySet()) {
|
||||
Object value = additionalInformation.get(key);
|
||||
if (value != null) {
|
||||
keys.put("extra_" + key, key);
|
||||
vars.put("extra_" + key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Do not include the refresh token (even if there is one)
|
||||
|
@ -0,0 +1,330 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.oauth2;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAccessTokenRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAuthorizeInfoRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenCheckTokenRespVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ApproveDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
|
||||
import cn.iocoder.yudao.module.system.enums.auth.OAuth2GrantTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ApproveService;
|
||||
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ClientService;
|
||||
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2GrantService;
|
||||
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.addTime;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link OAuth2OpenController} 的单元测试
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class OAuth2OpenControllerTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private OAuth2OpenController oauth2OpenController;
|
||||
|
||||
@Mock
|
||||
private OAuth2GrantService oauth2GrantService;
|
||||
@Mock
|
||||
private OAuth2ClientService oauth2ClientService;
|
||||
@Mock
|
||||
private OAuth2ApproveService oauth2ApproveService;
|
||||
@Mock
|
||||
private OAuth2TokenService oauth2TokenService;
|
||||
|
||||
@Test
|
||||
public void testPostAccessToken_authorizationCode() {
|
||||
// 准备参数
|
||||
String granType = OAuth2GrantTypeEnum.AUTHORIZATION_CODE.getGrantType();
|
||||
String code = randomString();
|
||||
String redirectUri = randomString();
|
||||
String state = randomString();
|
||||
HttpServletRequest request = mockRequest("test_client_id", "test_client_secret");
|
||||
// mock 方法(client)
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("test_client_id");
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq("test_client_id"), eq("test_client_secret"), eq(granType), eq(new ArrayList<>()), eq(redirectUri))).thenReturn(client);
|
||||
|
||||
// mock 方法(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setExpiresTime(addTime(Duration.ofMillis(30010L))); // 多给 10 毫秒,保证可执行完
|
||||
when(oauth2GrantService.grantAuthorizationCodeForAccessToken(eq("test_client_id"),
|
||||
eq(code), eq(redirectUri), eq(state))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用
|
||||
CommonResult<OAuth2OpenAccessTokenRespVO> result = oauth2OpenController.postAccessToken(request, granType,
|
||||
code, redirectUri, state, null, null, null, null);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertPojoEquals(accessTokenDO, result.getData());
|
||||
assertEquals(30L, result.getData().getExpiresIn()); // 执行过程会过去几毫秒
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostAccessToken_password() {
|
||||
// 准备参数
|
||||
String granType = OAuth2GrantTypeEnum.PASSWORD.getGrantType();
|
||||
String username = randomString();
|
||||
String password = randomString();
|
||||
String scope = "write read";
|
||||
HttpServletRequest request = mockRequest("test_client_id", "test_client_secret");
|
||||
// mock 方法(client)
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("test_client_id");
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq("test_client_id"), eq("test_client_secret"),
|
||||
eq(granType), eq(Lists.newArrayList("write", "read")), isNull())).thenReturn(client);
|
||||
|
||||
// mock 方法(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setExpiresTime(addTime(Duration.ofMillis(30010L))); // 多给 10 毫秒,保证可执行完
|
||||
when(oauth2GrantService.grantPassword(eq(username), eq(password), eq("test_client_id"),
|
||||
eq(Lists.newArrayList("write", "read")))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用
|
||||
CommonResult<OAuth2OpenAccessTokenRespVO> result = oauth2OpenController.postAccessToken(request, granType,
|
||||
null, null, null, username, password, scope, null);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertPojoEquals(accessTokenDO, result.getData());
|
||||
assertEquals(30L, result.getData().getExpiresIn()); // 执行过程会过去几毫秒
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostAccessToken_refreshToken() {
|
||||
// 准备参数
|
||||
String granType = OAuth2GrantTypeEnum.REFRESH_TOKEN.getGrantType();
|
||||
String refreshToken = randomString();
|
||||
String password = randomString();
|
||||
HttpServletRequest request = mockRequest("test_client_id", "test_client_secret");
|
||||
// mock 方法(client)
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("test_client_id");
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq("test_client_id"), eq("test_client_secret"),
|
||||
eq(granType), eq(Lists.newArrayList()), isNull())).thenReturn(client);
|
||||
|
||||
// mock 方法(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setExpiresTime(addTime(Duration.ofMillis(30010L))); // 多给 10 毫秒,保证可执行完
|
||||
when(oauth2GrantService.grantRefreshToken(eq(refreshToken), eq("test_client_id"))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用
|
||||
CommonResult<OAuth2OpenAccessTokenRespVO> result = oauth2OpenController.postAccessToken(request, granType,
|
||||
null, null, null, null, password, null, refreshToken);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertPojoEquals(accessTokenDO, result.getData());
|
||||
assertEquals(30L, result.getData().getExpiresIn()); // 执行过程会过去几毫秒
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostAccessToken_implicit() {
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2OpenController.postAccessToken(null,
|
||||
OAuth2GrantTypeEnum.IMPLICIT.getGrantType(), null, null, null,
|
||||
null, null, null, null),
|
||||
new ErrorCode(400, "Token 接口不支持 implicit 授权模式"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevokeToken() {
|
||||
// 准备参数
|
||||
HttpServletRequest request = mockRequest("demo_client_id", "demo_client_secret");
|
||||
String token = randomString();
|
||||
// mock 方法(client)
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("demo_client_id");
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq("demo_client_id"),
|
||||
eq("demo_client_secret"), isNull(), isNull(), isNull())).thenReturn(client);
|
||||
// mock 方法(移除)
|
||||
when(oauth2GrantService.revokeToken(eq("demo_client_id"), eq(token))).thenReturn(true);
|
||||
|
||||
// 调用
|
||||
CommonResult<Boolean> result = oauth2OpenController.revokeToken(request, token);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertTrue(result.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckToken() {
|
||||
// 准备参数
|
||||
HttpServletRequest request = mockRequest("demo_client_id", "demo_client_secret");
|
||||
String token = randomString();
|
||||
// mock 方法
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class).setUserType(UserTypeEnum.ADMIN.getValue()).setExpiresTime(new Date(1653485731195L));
|
||||
when(oauth2TokenService.checkAccessToken(eq(token))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用
|
||||
CommonResult<OAuth2OpenCheckTokenRespVO> result = oauth2OpenController.checkToken(request, token);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertPojoEquals(accessTokenDO, result.getData());
|
||||
assertEquals(1653485731L, result.getData().getExp()); // 执行过程会过去几毫秒
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthorize() {
|
||||
// 准备参数
|
||||
String clientId = randomString();
|
||||
// mock 方法(client)
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("demo_client_id").setScopes(ListUtil.toList("read", "write", "all"));
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(client);
|
||||
// mock 方法(approve)
|
||||
List<OAuth2ApproveDO> approves = asList(
|
||||
randomPojo(OAuth2ApproveDO.class).setScope("read").setApproved(true),
|
||||
randomPojo(OAuth2ApproveDO.class).setScope("write").setApproved(false));
|
||||
when(oauth2ApproveService.getApproveList(isNull(), eq(UserTypeEnum.ADMIN.getValue()), eq(clientId))).thenReturn(approves);
|
||||
|
||||
// 调用
|
||||
CommonResult<OAuth2OpenAuthorizeInfoRespVO> result = oauth2OpenController.authorize(clientId);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertPojoEquals(client, result.getData().getClient());
|
||||
assertEquals(new KeyValue<>("read", true), result.getData().getScopes().get(0));
|
||||
assertEquals(new KeyValue<>("write", false), result.getData().getScopes().get(1));
|
||||
assertEquals(new KeyValue<>("all", false), result.getData().getScopes().get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApproveOrDeny_grantTypeError() {
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2OpenController.approveOrDeny(randomString(), null,
|
||||
null, null, null, null),
|
||||
new ErrorCode(400, "response_type 参数值只允许 code 和 token"));
|
||||
}
|
||||
|
||||
@Test // autoApprove = true,但是不通过
|
||||
public void testApproveOrDeny_autoApproveNo() {
|
||||
// 准备参数
|
||||
String responseType = "code";
|
||||
String clientId = randomString();
|
||||
String scope = "{\"read\": true, \"write\": false}";
|
||||
String redirectUri = randomString();
|
||||
String state = randomString();
|
||||
// mock 方法
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId), isNull(), eq("authorization_code"),
|
||||
eq(asSet("read", "write")), eq(redirectUri))).thenReturn(client);
|
||||
|
||||
// 调用
|
||||
CommonResult<String> result = oauth2OpenController.approveOrDeny(responseType, clientId,
|
||||
scope, redirectUri, true, state);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertNull(result.getData());
|
||||
}
|
||||
|
||||
@Test // autoApprove = false,但是不通过
|
||||
public void testApproveOrDeny_ApproveNo() {
|
||||
// 准备参数
|
||||
String responseType = "token";
|
||||
String clientId = randomString();
|
||||
String scope = "{\"read\": true, \"write\": false}";
|
||||
String redirectUri = "https://www.iocoder.cn";
|
||||
String state = "test";
|
||||
// mock 方法
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId), isNull(), eq("implicit"),
|
||||
eq(asSet("read", "write")), eq(redirectUri))).thenReturn(client);
|
||||
|
||||
// 调用
|
||||
CommonResult<String> result = oauth2OpenController.approveOrDeny(responseType, clientId,
|
||||
scope, redirectUri, false, state);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertEquals("https://www.iocoder.cn#error=access_denied&error_description=User%20denied%20access&state=test", result.getData());
|
||||
}
|
||||
|
||||
@Test // autoApprove = true,通过 + token
|
||||
public void testApproveOrDeny_autoApproveWithToken() {
|
||||
// 准备参数
|
||||
String responseType = "token";
|
||||
String clientId = randomString();
|
||||
String scope = "{\"read\": true, \"write\": false}";
|
||||
String redirectUri = "https://www.iocoder.cn";
|
||||
String state = "test";
|
||||
// mock 方法(client)
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId(clientId).setAdditionalInformation(null);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId), isNull(), eq("implicit"),
|
||||
eq(asSet("read", "write")), eq(redirectUri))).thenReturn(client);
|
||||
// mock 方法(场景一)
|
||||
when(oauth2ApproveService.checkForPreApproval(isNull(), eq(UserTypeEnum.ADMIN.getValue()),
|
||||
eq(clientId), eq(SetUtils.asSet("read", "write")))).thenReturn(true);
|
||||
// mock 方法(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setAccessToken("test_access_token").setExpiresTime(addTime(Duration.ofMillis(30010L)));
|
||||
when(oauth2GrantService.grantImplicit(isNull(), eq(UserTypeEnum.ADMIN.getValue()),
|
||||
eq(clientId), eq(ListUtil.toList("read")))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用
|
||||
CommonResult<String> result = oauth2OpenController.approveOrDeny(responseType, clientId,
|
||||
scope, redirectUri, true, state);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertEquals("https://www.iocoder.cn#access_token=test_access_token&token_type=bearer&state=test&expires_in=30&scope=read", result.getData());
|
||||
}
|
||||
|
||||
@Test // autoApprove = false,通过 + code
|
||||
public void testApproveOrDeny_approveWithCode() {
|
||||
// 准备参数
|
||||
String responseType = "code";
|
||||
String clientId = randomString();
|
||||
String scope = "{\"read\": true, \"write\": false}";
|
||||
String redirectUri = "https://www.iocoder.cn";
|
||||
String state = "test";
|
||||
// mock 方法(client)
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId(clientId).setAdditionalInformation(null);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId), isNull(), eq("authorization_code"),
|
||||
eq(asSet("read", "write")), eq(redirectUri))).thenReturn(client);
|
||||
// mock 方法(场景二)
|
||||
when(oauth2ApproveService.updateAfterApproval(isNull(), eq(UserTypeEnum.ADMIN.getValue()), eq(clientId),
|
||||
eq(MapUtil.builder(new LinkedHashMap<String, Boolean>()).put("read", true).put("write", false).build())))
|
||||
.thenReturn(true);
|
||||
// mock 方法(访问令牌)
|
||||
String authorizationCode = "test_code";
|
||||
when(oauth2GrantService.grantAuthorizationCodeForCode(isNull(), eq(UserTypeEnum.ADMIN.getValue()),
|
||||
eq(clientId), eq(ListUtil.toList("read")), eq(redirectUri), eq(state))).thenReturn(authorizationCode);
|
||||
|
||||
// 调用
|
||||
CommonResult<String> result = oauth2OpenController.approveOrDeny(responseType, clientId,
|
||||
scope, redirectUri, false, state);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertEquals("https://www.iocoder.cn?code=test_code&state=test", result.getData());
|
||||
}
|
||||
|
||||
private HttpServletRequest mockRequest(String clientId, String secret) {
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
when(request.getParameter(eq("client_id"))).thenReturn(clientId);
|
||||
when(request.getParameter(eq("client_secret"))).thenReturn(secret);
|
||||
return request;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,267 @@
|
||||
package cn.iocoder.yudao.module.system.service.oauth2;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ApproveDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2ApproveMapper;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.*;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.addTime;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link OAuth2ApproveServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(OAuth2ApproveServiceImpl.class)
|
||||
public class OAuth2ApproveServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private OAuth2ApproveServiceImpl oauth2ApproveService;
|
||||
|
||||
@Resource
|
||||
private OAuth2ApproveMapper oauth2ApproveMapper;
|
||||
|
||||
@MockBean
|
||||
private OAuth2ClientService oauth2ClientService;
|
||||
|
||||
@Test
|
||||
public void checkForPreApproval_clientAutoApprove() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
List<String> requestedScopes = Lists.newArrayList("read");
|
||||
// mock 方法
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId)))
|
||||
.thenReturn(randomPojo(OAuth2ClientDO.class).setAutoApproveScopes(requestedScopes));
|
||||
|
||||
// 调用
|
||||
boolean success = oauth2ApproveService.checkForPreApproval(userId, userType,
|
||||
clientId, requestedScopes);
|
||||
// 断言
|
||||
assertTrue(success);
|
||||
List<OAuth2ApproveDO> result = oauth2ApproveMapper.selectList();
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(userId, result.get(0).getUserId());
|
||||
assertEquals(userType, result.get(0).getUserType());
|
||||
assertEquals(clientId, result.get(0).getClientId());
|
||||
assertEquals("read", result.get(0).getScope());
|
||||
assertTrue(result.get(0).getApproved());
|
||||
assertFalse(DateUtils.isExpired(result.get(0).getExpiresTime()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkForPreApproval_approve() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
List<String> requestedScopes = Lists.newArrayList("read");
|
||||
// mock 方法
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId)))
|
||||
.thenReturn(randomPojo(OAuth2ClientDO.class).setAutoApproveScopes(null));
|
||||
// mock 数据
|
||||
OAuth2ApproveDO approve = randomPojo(OAuth2ApproveDO.class).setUserId(userId)
|
||||
.setUserType(userType).setClientId(clientId).setScope("read")
|
||||
.setExpiresTime(addTime(Duration.ofDays(1))).setApproved(true); // 同意
|
||||
oauth2ApproveMapper.insert(approve);
|
||||
|
||||
// 调用
|
||||
boolean success = oauth2ApproveService.checkForPreApproval(userId, userType,
|
||||
clientId, requestedScopes);
|
||||
// 断言
|
||||
assertTrue(success);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkForPreApproval_reject() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
List<String> requestedScopes = Lists.newArrayList("read");
|
||||
// mock 方法
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId)))
|
||||
.thenReturn(randomPojo(OAuth2ClientDO.class).setAutoApproveScopes(null));
|
||||
// mock 数据
|
||||
OAuth2ApproveDO approve = randomPojo(OAuth2ApproveDO.class).setUserId(userId)
|
||||
.setUserType(userType).setClientId(clientId).setScope("read")
|
||||
.setExpiresTime(addTime(Duration.ofDays(1))).setApproved(false); // 拒绝
|
||||
oauth2ApproveMapper.insert(approve);
|
||||
|
||||
// 调用
|
||||
boolean success = oauth2ApproveService.checkForPreApproval(userId, userType,
|
||||
clientId, requestedScopes);
|
||||
// 断言
|
||||
assertFalse(success);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateAfterApproval_none() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
|
||||
// 调用
|
||||
boolean success = oauth2ApproveService.updateAfterApproval(userId, userType, clientId,
|
||||
null);
|
||||
// 断言
|
||||
assertTrue(success);
|
||||
List<OAuth2ApproveDO> result = oauth2ApproveMapper.selectList();
|
||||
assertEquals(0, result.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateAfterApproval_approved() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
Map<String, Boolean> requestedScopes = new LinkedHashMap<>(); // 有序,方便判断
|
||||
requestedScopes.put("read", true);
|
||||
requestedScopes.put("write", false);
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
boolean success = oauth2ApproveService.updateAfterApproval(userId, userType, clientId,
|
||||
requestedScopes);
|
||||
// 断言
|
||||
assertTrue(success);
|
||||
List<OAuth2ApproveDO> result = oauth2ApproveMapper.selectList();
|
||||
assertEquals(2, result.size());
|
||||
// read
|
||||
assertEquals(userId, result.get(0).getUserId());
|
||||
assertEquals(userType, result.get(0).getUserType());
|
||||
assertEquals(clientId, result.get(0).getClientId());
|
||||
assertEquals("read", result.get(0).getScope());
|
||||
assertTrue(result.get(0).getApproved());
|
||||
assertFalse(DateUtils.isExpired(result.get(0).getExpiresTime()));
|
||||
// write
|
||||
assertEquals(userId, result.get(1).getUserId());
|
||||
assertEquals(userType, result.get(1).getUserType());
|
||||
assertEquals(clientId, result.get(1).getClientId());
|
||||
assertEquals("write", result.get(1).getScope());
|
||||
assertFalse(result.get(1).getApproved());
|
||||
assertFalse(DateUtils.isExpired(result.get(1).getExpiresTime()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateAfterApproval_reject() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
Map<String, Boolean> requestedScopes = new LinkedHashMap<>();
|
||||
requestedScopes.put("write", false);
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
boolean success = oauth2ApproveService.updateAfterApproval(userId, userType, clientId,
|
||||
requestedScopes);
|
||||
// 断言
|
||||
assertFalse(success);
|
||||
List<OAuth2ApproveDO> result = oauth2ApproveMapper.selectList();
|
||||
assertEquals(1, result.size());
|
||||
// write
|
||||
assertEquals(userId, result.get(0).getUserId());
|
||||
assertEquals(userType, result.get(0).getUserType());
|
||||
assertEquals(clientId, result.get(0).getClientId());
|
||||
assertEquals("write", result.get(0).getScope());
|
||||
assertFalse(result.get(0).getApproved());
|
||||
assertFalse(DateUtils.isExpired(result.get(0).getExpiresTime()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetApproveList() {
|
||||
// 准备参数
|
||||
Long userId = 10L;
|
||||
Integer userType = UserTypeEnum.ADMIN.getValue();
|
||||
String clientId = randomString();
|
||||
// mock 数据
|
||||
OAuth2ApproveDO approve = randomPojo(OAuth2ApproveDO.class).setUserId(userId)
|
||||
.setUserType(userType).setClientId(clientId).setExpiresTime(addTime(Duration.ofDays(1L)));
|
||||
oauth2ApproveMapper.insert(approve); // 未过期
|
||||
oauth2ApproveMapper.insert(ObjectUtil.clone(approve).setId(null)
|
||||
.setExpiresTime(addTime(Duration.ofDays(-1L)))); // 已过期
|
||||
|
||||
// 调用
|
||||
List<OAuth2ApproveDO> result = oauth2ApproveService.getApproveList(userId, userType, clientId);
|
||||
// 断言
|
||||
assertEquals(1, result.size());
|
||||
assertPojoEquals(approve, result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveApprove_insert() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
String scope = randomString();
|
||||
Boolean approved = randomBoolean();
|
||||
Date expireTime = randomDay(1, 30);
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
oauth2ApproveService.saveApprove(userId, userType, clientId,
|
||||
scope, approved, expireTime);
|
||||
// 断言
|
||||
List<OAuth2ApproveDO> result = oauth2ApproveMapper.selectList();
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(userId, result.get(0).getUserId());
|
||||
assertEquals(userType, result.get(0).getUserType());
|
||||
assertEquals(clientId, result.get(0).getClientId());
|
||||
assertEquals(scope, result.get(0).getScope());
|
||||
assertEquals(approved, result.get(0).getApproved());
|
||||
assertEquals(expireTime, result.get(0).getExpiresTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveApprove_update() {
|
||||
// mock 数据
|
||||
OAuth2ApproveDO approve = randomPojo(OAuth2ApproveDO.class);
|
||||
oauth2ApproveMapper.insert(approve);
|
||||
// 准备参数
|
||||
Long userId = approve.getUserId();
|
||||
Integer userType = approve.getUserType();
|
||||
String clientId = approve.getClientId();
|
||||
String scope = approve.getScope();
|
||||
Boolean approved = randomBoolean();
|
||||
Date expireTime = randomDay(1, 30);
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
oauth2ApproveService.saveApprove(userId, userType, clientId,
|
||||
scope, approved, expireTime);
|
||||
// 断言
|
||||
List<OAuth2ApproveDO> result = oauth2ApproveMapper.selectList();
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(approve.getId(), result.get(0).getId());
|
||||
assertEquals(userId, result.get(0).getUserId());
|
||||
assertEquals(userType, result.get(0).getUserType());
|
||||
assertEquals(clientId, result.get(0).getClientId());
|
||||
assertEquals(scope, result.get(0).getScope());
|
||||
assertEquals(approved, result.get(0).getApproved());
|
||||
assertEquals(expireTime, result.get(0).getExpiresTime());
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.module.system.service.auth;
|
||||
package cn.iocoder.yudao.module.system.service.oauth2;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
@ -9,13 +10,12 @@ import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client.OAuth2Cl
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2ClientMapper;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.auth.OAuth2ClientProducer;
|
||||
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ClientServiceImpl;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
@ -23,7 +23,7 @@ import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.OAUTH2_CLIENT_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@ -132,7 +132,31 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void testValidateClientIdExists_withId() {
|
||||
// mock 数据
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("tudou");
|
||||
oauth2ClientMapper.insert(client);
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String clientId = "tudou";
|
||||
|
||||
// 调用,不会报错
|
||||
assertServiceException(() -> oauth2ClientService.validateClientIdExists(id, clientId), OAUTH2_CLIENT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateClientIdExists_noId() {
|
||||
// mock 数据
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("tudou");
|
||||
oauth2ClientMapper.insert(client);
|
||||
// 准备参数
|
||||
String clientId = "tudou";
|
||||
|
||||
// 调用,不会报错
|
||||
assertServiceException(() -> oauth2ClientService.validateClientIdExists(null, clientId), OAUTH2_CLIENT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOAuth2ClientPage() {
|
||||
// mock 数据
|
||||
OAuth2ClientDO dbOAuth2Client = randomPojo(OAuth2ClientDO.class, o -> { // 等会查询到
|
||||
@ -143,10 +167,10 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
|
||||
// 测试 name 不匹配
|
||||
oauth2ClientMapper.insert(cloneIgnoreId(dbOAuth2Client, o -> o.setName("凤凰")));
|
||||
// 测试 status 不匹配
|
||||
oauth2ClientMapper.insert(cloneIgnoreId(dbOAuth2Client, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())));
|
||||
oauth2ClientMapper.insert(cloneIgnoreId(dbOAuth2Client, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 准备参数
|
||||
OAuth2ClientPageReqVO reqVO = new OAuth2ClientPageReqVO();
|
||||
reqVO.setName("long");
|
||||
reqVO.setName("龙");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
|
||||
// 调用
|
||||
@ -157,4 +181,35 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
|
||||
assertPojoEquals(dbOAuth2Client, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidOAuthClientFromCache() {
|
||||
// mock 方法
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("default")
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
OAuth2ClientDO client02 = randomPojo(OAuth2ClientDO.class).setClientId("disable")
|
||||
.setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
Map<String, OAuth2ClientDO> clientCache = MapUtil.<String, OAuth2ClientDO>builder()
|
||||
.put(client.getClientId(), client)
|
||||
.put(client02.getClientId(), client02).build();
|
||||
oauth2ClientService.setClientCache(clientCache);
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache(randomString(),
|
||||
null, null, null, null), OAUTH2_CLIENT_NOT_EXISTS);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("disable",
|
||||
null, null, null, null), OAUTH2_CLIENT_DISABLE);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
randomString(), null, null, null), OAUTH2_CLIENT_CLIENT_SECRET_ERROR);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
null, randomString(), null, null), OAUTH2_CLIENT_AUTHORIZED_GRANT_TYPE_NOT_EXISTS);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
null, null, Collections.singleton(randomString()), null), OAUTH2_CLIENT_SCOPE_OVER);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
null, null, null, "test"), OAUTH2_CLIENT_REDIRECT_URI_NOT_MATCH, "test");
|
||||
// 成功调用
|
||||
OAuth2ClientDO result = oauth2ClientService.validOAuthClientFromCache(client.getClientId(), client.getSecret(),
|
||||
client.getAuthorizedGrantTypes().get(0), client.getScopes(), client.getRedirectUris().get(0));
|
||||
assertPojoEquals(client, result);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package cn.iocoder.yudao.module.system.service.oauth2;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2CodeDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2CodeMapper;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.addTime;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.OAUTH2_CODE_EXPIRE;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.OAUTH2_CODE_NOT_EXISTS;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link OAuth2CodeServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(OAuth2CodeServiceImpl.class)
|
||||
class OAuth2CodeServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private OAuth2CodeServiceImpl oauth2CodeService;
|
||||
|
||||
@Resource
|
||||
private OAuth2CodeMapper oauth2CodeMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateAuthorizationCode() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = RandomUtil.randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
List<String> scopes = Lists.newArrayList("read", "write");
|
||||
String redirectUri = randomString();
|
||||
String state = randomString();
|
||||
|
||||
// 调用
|
||||
OAuth2CodeDO codeDO = oauth2CodeService.createAuthorizationCode(userId, userType, clientId,
|
||||
scopes, redirectUri, state);
|
||||
// 断言
|
||||
OAuth2CodeDO dbCodeDO = oauth2CodeMapper.selectByCode(codeDO.getCode());
|
||||
assertPojoEquals(codeDO, dbCodeDO, "createTime", "updateTime", "deleted");
|
||||
assertEquals(userId, codeDO.getUserId());
|
||||
assertEquals(userType, codeDO.getUserType());
|
||||
assertEquals(clientId, codeDO.getClientId());
|
||||
assertEquals(scopes, codeDO.getScopes());
|
||||
assertEquals(redirectUri, codeDO.getRedirectUri());
|
||||
assertEquals(state, codeDO.getState());
|
||||
assertFalse(DateUtils.isExpired(codeDO.getExpiresTime()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsumeAuthorizationCode_null() {
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2CodeService.consumeAuthorizationCode(randomString()),
|
||||
OAUTH2_CODE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsumeAuthorizationCode_expired() {
|
||||
// 准备参数
|
||||
String code = "test_code";
|
||||
// mock 数据
|
||||
OAuth2CodeDO codeDO = randomPojo(OAuth2CodeDO.class).setCode(code)
|
||||
.setExpiresTime(addTime(Duration.ofDays(-1)));
|
||||
oauth2CodeMapper.insert(codeDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2CodeService.consumeAuthorizationCode(code),
|
||||
OAUTH2_CODE_EXPIRE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsumeAuthorizationCode_success() {
|
||||
// 准备参数
|
||||
String code = "test_code";
|
||||
// mock 数据
|
||||
OAuth2CodeDO codeDO = randomPojo(OAuth2CodeDO.class).setCode(code)
|
||||
.setExpiresTime(addTime(Duration.ofDays(1)));
|
||||
oauth2CodeMapper.insert(codeDO);
|
||||
|
||||
// 调用
|
||||
OAuth2CodeDO result = oauth2CodeService.consumeAuthorizationCode(code);
|
||||
assertPojoEquals(codeDO, result);
|
||||
assertNull(oauth2CodeMapper.selectByCode(code));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
package cn.iocoder.yudao.module.system.service.oauth2;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2CodeDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.service.auth.AdminAuthService;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link OAuth2GrantServiceImpl} 的单元测试
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class OAuth2GrantServiceImplTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private OAuth2GrantServiceImpl oauth2GrantService;
|
||||
|
||||
@Mock
|
||||
private OAuth2TokenService oauth2TokenService;
|
||||
@Mock
|
||||
private OAuth2CodeService oauth2CodeService;
|
||||
@Mock
|
||||
private AdminAuthService adminAuthService;
|
||||
|
||||
@Test
|
||||
public void testGrantImplicit() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
List<String> scopes = Lists.newArrayList("read", "write");
|
||||
// mock 方法
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
|
||||
when(oauth2TokenService.createAccessToken(eq(userId), eq(userType),
|
||||
eq(clientId), eq(scopes))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertPojoEquals(accessTokenDO, oauth2GrantService.grantImplicit(
|
||||
userId, userType, clientId, scopes));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrantAuthorizationCodeForCode() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
List<String> scopes = Lists.newArrayList("read", "write");
|
||||
String redirectUri = randomString();
|
||||
String state = randomString();
|
||||
// mock 方法
|
||||
OAuth2CodeDO codeDO = randomPojo(OAuth2CodeDO.class);
|
||||
when(oauth2CodeService.createAuthorizationCode(eq(userId), eq(userType),
|
||||
eq(clientId), eq(scopes), eq(redirectUri), eq(state))).thenReturn(codeDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertEquals(codeDO.getCode(), oauth2GrantService.grantAuthorizationCodeForCode(userId, userType,
|
||||
clientId, scopes, redirectUri, state));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrantAuthorizationCodeForAccessToken() {
|
||||
// 准备参数
|
||||
String clientId = randomString();
|
||||
String code = randomString();
|
||||
List<String> scopes = Lists.newArrayList("read", "write");
|
||||
String redirectUri = randomString();
|
||||
String state = randomString();
|
||||
// mock 方法(code)
|
||||
OAuth2CodeDO codeDO = randomPojo(OAuth2CodeDO.class, o -> {
|
||||
o.setClientId(clientId);
|
||||
o.setRedirectUri(redirectUri);
|
||||
o.setState(state);
|
||||
o.setScopes(scopes);
|
||||
});
|
||||
when(oauth2CodeService.consumeAuthorizationCode(eq(code))).thenReturn(codeDO);
|
||||
// mock 方法(创建令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
|
||||
when(oauth2TokenService.createAccessToken(eq(codeDO.getUserId()), eq(codeDO.getUserType()),
|
||||
eq(codeDO.getClientId()), eq(codeDO.getScopes()))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertPojoEquals(accessTokenDO, oauth2GrantService.grantAuthorizationCodeForAccessToken(
|
||||
clientId, code, redirectUri, state));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrantPassword() {
|
||||
// 准备参数
|
||||
String username = randomString();
|
||||
String password = randomString();
|
||||
String clientId = randomString();
|
||||
List<String> scopes = Lists.newArrayList("read", "write");
|
||||
// mock 方法(认证)
|
||||
AdminUserDO user = randomPojo(AdminUserDO.class);
|
||||
when(adminAuthService.authenticate(eq(username), eq(password))).thenReturn(user);
|
||||
// mock 方法(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
|
||||
when(oauth2TokenService.createAccessToken(eq(user.getId()), eq(UserTypeEnum.ADMIN.getValue()),
|
||||
eq(clientId), eq(scopes))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertPojoEquals(accessTokenDO, oauth2GrantService.grantPassword(
|
||||
username, password, clientId, scopes));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrantRefreshToken() {
|
||||
// 准备参数
|
||||
String refreshToken = randomString();
|
||||
String clientId = randomString();
|
||||
// mock 方法
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
|
||||
when(oauth2TokenService.refreshAccessToken(eq(refreshToken), eq(clientId)))
|
||||
.thenReturn(accessTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertPojoEquals(accessTokenDO, oauth2GrantService.grantRefreshToken(
|
||||
refreshToken, clientId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevokeToken_clientIdError() {
|
||||
// 准备参数
|
||||
String clientId = randomString();
|
||||
String accessToken = randomString();
|
||||
// mock 方法
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
|
||||
when(oauth2TokenService.getAccessToken(eq(accessToken))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertFalse(oauth2GrantService.revokeToken(clientId, accessToken));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevokeToken_success() {
|
||||
// 准备参数
|
||||
String clientId = randomString();
|
||||
String accessToken = randomString();
|
||||
// mock 方法(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class).setClientId(clientId);
|
||||
when(oauth2TokenService.getAccessToken(eq(accessToken))).thenReturn(accessTokenDO);
|
||||
// mock 方法(移除)
|
||||
when(oauth2TokenService.removeAccessToken(eq(accessToken))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertTrue(oauth2GrantService.revokeToken(clientId, accessToken));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,289 @@
|
||||
package cn.iocoder.yudao.module.system.service.oauth2;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.token.OAuth2AccessTokenPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2RefreshTokenDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2AccessTokenMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2RefreshTokenMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.redis.oauth2.OAuth2AccessTokenRedisDAO;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.Duration;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.addTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link OAuth2TokenServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import({OAuth2TokenServiceImpl.class, OAuth2AccessTokenRedisDAO.class})
|
||||
public class OAuth2TokenServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
@Resource
|
||||
private OAuth2TokenServiceImpl oauth2TokenService;
|
||||
|
||||
@Resource
|
||||
private OAuth2AccessTokenMapper oauth2AccessTokenMapper;
|
||||
@Resource
|
||||
private OAuth2RefreshTokenMapper oauth2RefreshTokenMapper;
|
||||
|
||||
@Resource
|
||||
private OAuth2AccessTokenRedisDAO oauth2AccessTokenRedisDAO;
|
||||
|
||||
@MockBean
|
||||
private OAuth2ClientService oauth2ClientService;
|
||||
|
||||
@Test
|
||||
public void testCreateAccessToken() {
|
||||
TenantContextHolder.setTenantId(0L);
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = RandomUtil.randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
List<String> scopes = Lists.newArrayList("read", "write");
|
||||
// mock 方法
|
||||
OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class).setClientId(clientId)
|
||||
.setAccessTokenValiditySeconds(30).setRefreshTokenValiditySeconds(60);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(clientDO);
|
||||
|
||||
// 调用
|
||||
OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAccessToken(userId, userType, clientId, scopes);
|
||||
// 断言访问令牌
|
||||
OAuth2AccessTokenDO dbAccessTokenDO = oauth2AccessTokenMapper.selectByAccessToken(accessTokenDO.getAccessToken());
|
||||
assertPojoEquals(accessTokenDO, dbAccessTokenDO, "createTime", "updateTime", "deleted");
|
||||
assertEquals(userId, accessTokenDO.getUserId());
|
||||
assertEquals(userType, accessTokenDO.getUserType());
|
||||
assertEquals(clientId, accessTokenDO.getClientId());
|
||||
assertEquals(scopes, accessTokenDO.getScopes());
|
||||
assertFalse(DateUtils.isExpired(accessTokenDO.getExpiresTime()));
|
||||
// 断言访问令牌的缓存
|
||||
OAuth2AccessTokenDO redisAccessTokenDO = oauth2AccessTokenRedisDAO.get(accessTokenDO.getAccessToken());
|
||||
assertPojoEquals(accessTokenDO, redisAccessTokenDO, "createTime", "updateTime", "deleted");
|
||||
// 断言刷新令牌
|
||||
OAuth2RefreshTokenDO refreshTokenDO = oauth2RefreshTokenMapper.selectList().get(0);
|
||||
assertPojoEquals(accessTokenDO, refreshTokenDO, "id", "expiresTime", "createTime", "updateTime", "deleted");
|
||||
assertFalse(DateUtils.isExpired(refreshTokenDO.getExpiresTime()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshAccessToken_null() {
|
||||
// 准备参数
|
||||
String refreshToken = randomString();
|
||||
String clientId = randomString();
|
||||
// mock 方法
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2TokenService.refreshAccessToken(refreshToken, clientId),
|
||||
new ErrorCode(400, "无效的刷新令牌"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshAccessToken_clientIdError() {
|
||||
// 准备参数
|
||||
String refreshToken = randomString();
|
||||
String clientId = randomString();
|
||||
// mock 方法
|
||||
OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class).setClientId(clientId);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(clientDO);
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class)
|
||||
.setRefreshToken(refreshToken).setClientId("error");
|
||||
oauth2RefreshTokenMapper.insert(refreshTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2TokenService.refreshAccessToken(refreshToken, clientId),
|
||||
new ErrorCode(400, "刷新令牌的客户端编号不正确"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshAccessToken_expired() {
|
||||
// 准备参数
|
||||
String refreshToken = randomString();
|
||||
String clientId = randomString();
|
||||
// mock 方法
|
||||
OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class).setClientId(clientId);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(clientDO);
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class)
|
||||
.setRefreshToken(refreshToken).setClientId(clientId)
|
||||
.setExpiresTime(addTime(Duration.ofDays(-1)));
|
||||
oauth2RefreshTokenMapper.insert(refreshTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2TokenService.refreshAccessToken(refreshToken, clientId),
|
||||
new ErrorCode(401, "刷新令牌已过期"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshAccessToken_success() {
|
||||
TenantContextHolder.setTenantId(0L);
|
||||
// 准备参数
|
||||
String refreshToken = randomString();
|
||||
String clientId = randomString();
|
||||
// mock 方法
|
||||
OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class).setClientId(clientId)
|
||||
.setAccessTokenValiditySeconds(30);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(clientDO);
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class)
|
||||
.setRefreshToken(refreshToken).setClientId(clientId)
|
||||
.setExpiresTime(addTime(Duration.ofDays(1)));
|
||||
oauth2RefreshTokenMapper.insert(refreshTokenDO);
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class).setRefreshToken(refreshToken);
|
||||
oauth2AccessTokenMapper.insert(accessTokenDO);
|
||||
oauth2AccessTokenRedisDAO.set(accessTokenDO);
|
||||
|
||||
// 调用
|
||||
OAuth2AccessTokenDO newAccessTokenDO = oauth2TokenService.refreshAccessToken(refreshToken, clientId);
|
||||
// 断言,老的访问令牌被删除
|
||||
assertNull(oauth2AccessTokenMapper.selectByAccessToken(accessTokenDO.getAccessToken()));
|
||||
assertNull(oauth2AccessTokenRedisDAO.get(accessTokenDO.getAccessToken()));
|
||||
// 断言,新的访问令牌
|
||||
OAuth2AccessTokenDO dbAccessTokenDO = oauth2AccessTokenMapper.selectByAccessToken(newAccessTokenDO.getAccessToken());
|
||||
assertPojoEquals(newAccessTokenDO, dbAccessTokenDO, "createTime", "updateTime", "deleted");
|
||||
assertPojoEquals(newAccessTokenDO, refreshTokenDO, "id", "expiresTime", "createTime", "updateTime", "deleted",
|
||||
"creator", "updater");
|
||||
assertFalse(DateUtils.isExpired(newAccessTokenDO.getExpiresTime()));
|
||||
// 断言,新的访问令牌的缓存
|
||||
OAuth2AccessTokenDO redisAccessTokenDO = oauth2AccessTokenRedisDAO.get(newAccessTokenDO.getAccessToken());
|
||||
assertPojoEquals(newAccessTokenDO, redisAccessTokenDO, "createTime", "updateTime", "deleted");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAccessToken() {
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setExpiresTime(addTime(Duration.ofDays(1)));
|
||||
oauth2AccessTokenMapper.insert(accessTokenDO);
|
||||
// 准备参数
|
||||
String accessToken = accessTokenDO.getAccessToken();
|
||||
|
||||
// 调用
|
||||
OAuth2AccessTokenDO result = oauth2TokenService.getAccessToken(accessToken);
|
||||
// 断言
|
||||
assertPojoEquals(accessTokenDO, result, "createTime", "updateTime", "deleted",
|
||||
"creator", "updater");
|
||||
assertPojoEquals(accessTokenDO, oauth2AccessTokenRedisDAO.get(accessToken), "createTime", "updateTime", "deleted",
|
||||
"creator", "updater");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckAccessToken_null() {
|
||||
// 调研,并断言
|
||||
assertServiceException(() -> oauth2TokenService.checkAccessToken(randomString()),
|
||||
new ErrorCode(401, "访问令牌不存在"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckAccessToken_expired() {
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setExpiresTime(addTime(Duration.ofDays(-1)));
|
||||
oauth2AccessTokenMapper.insert(accessTokenDO);
|
||||
// 准备参数
|
||||
String accessToken = accessTokenDO.getAccessToken();
|
||||
|
||||
// 调研,并断言
|
||||
assertServiceException(() -> oauth2TokenService.checkAccessToken(accessToken),
|
||||
new ErrorCode(401, "访问令牌已过期"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckAccessToken_success() {
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setExpiresTime(addTime(Duration.ofDays(1)));
|
||||
oauth2AccessTokenMapper.insert(accessTokenDO);
|
||||
// 准备参数
|
||||
String accessToken = accessTokenDO.getAccessToken();
|
||||
|
||||
// 调研,并断言
|
||||
OAuth2AccessTokenDO result = oauth2TokenService.getAccessToken(accessToken);
|
||||
// 断言
|
||||
assertPojoEquals(accessTokenDO, result, "createTime", "updateTime", "deleted",
|
||||
"creator", "updater");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveAccessToken_null() {
|
||||
// 调用,并断言
|
||||
assertNull(oauth2TokenService.removeAccessToken(randomString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveAccessToken_success() {
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setExpiresTime(addTime(Duration.ofDays(1)));
|
||||
oauth2AccessTokenMapper.insert(accessTokenDO);
|
||||
// mock 数据(刷新令牌)
|
||||
OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class)
|
||||
.setRefreshToken(accessTokenDO.getRefreshToken());
|
||||
oauth2RefreshTokenMapper.insert(refreshTokenDO);
|
||||
// 调用
|
||||
OAuth2AccessTokenDO result = oauth2TokenService.removeAccessToken(accessTokenDO.getAccessToken());
|
||||
assertPojoEquals(accessTokenDO, result, "createTime", "updateTime", "deleted",
|
||||
"creator", "updater");
|
||||
// 断言数据
|
||||
assertNull(oauth2AccessTokenMapper.selectByAccessToken(accessTokenDO.getAccessToken()));
|
||||
assertNull(oauth2RefreshTokenMapper.selectByRefreshToken(accessTokenDO.getRefreshToken()));
|
||||
assertNull(oauth2AccessTokenRedisDAO.get(accessTokenDO.getAccessToken()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGetAccessTokenPage() {
|
||||
// mock 数据
|
||||
OAuth2AccessTokenDO dbAccessToken = randomPojo(OAuth2AccessTokenDO.class, o -> { // 等会查询到
|
||||
o.setUserId(10L);
|
||||
o.setUserType(1);
|
||||
o.setClientId("test_client");
|
||||
o.setExpiresTime(DateUtils.addTime(Duration.ofDays(1)));
|
||||
});
|
||||
oauth2AccessTokenMapper.insert(dbAccessToken);
|
||||
// 测试 userId 不匹配
|
||||
oauth2AccessTokenMapper.insert(cloneIgnoreId(dbAccessToken, o -> o.setUserId(20L)));
|
||||
// 测试 userType 不匹配
|
||||
oauth2AccessTokenMapper.insert(cloneIgnoreId(dbAccessToken, o -> o.setUserType(2)));
|
||||
// 测试 userType 不匹配
|
||||
oauth2AccessTokenMapper.insert(cloneIgnoreId(dbAccessToken, o -> o.setClientId("it_client")));
|
||||
// 测试 expireTime 不匹配
|
||||
oauth2AccessTokenMapper.insert(cloneIgnoreId(dbAccessToken, o -> o.setExpiresTime(new Date())));
|
||||
// 准备参数
|
||||
OAuth2AccessTokenPageReqVO reqVO = new OAuth2AccessTokenPageReqVO();
|
||||
reqVO.setUserId(10L);
|
||||
reqVO.setUserType(1);
|
||||
reqVO.setClientId("test");
|
||||
|
||||
// 调用
|
||||
PageResult<OAuth2AccessTokenDO> pageResult = oauth2TokenService.getAccessTokenPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbAccessToken, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
}
|
@ -3,15 +3,17 @@ package cn.iocoder.yudao.module.system.service.permission;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleCreateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleExportReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RolePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.permission.RoleProducer;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
@ -20,6 +22,7 @@ import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
@ -155,61 +158,66 @@ public class RoleServiceTest extends BaseDbUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRoles_success() {
|
||||
Map<Long, RoleDO> idRoleMap = new HashMap<>();
|
||||
// 验证查询状态为1的角色
|
||||
RoleDO roleDO1 = createRoleDO("role1", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 1);
|
||||
roleMapper.insert(roleDO1);
|
||||
idRoleMap.put(roleDO1.getId(), roleDO1);
|
||||
|
||||
RoleDO roleDO2 = createRoleDO("role2", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 1);
|
||||
roleMapper.insert(roleDO2);
|
||||
idRoleMap.put(roleDO2.getId(), roleDO2);
|
||||
|
||||
// 以下是排除的角色
|
||||
RoleDO roleDO3 = createRoleDO("role3", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 2);
|
||||
roleMapper.insert(roleDO3);
|
||||
|
||||
//调用
|
||||
List<RoleDO> roles = roleService.getRoles(Arrays.asList(1));
|
||||
|
||||
//断言
|
||||
assertEquals(2, roles.size());
|
||||
roles.stream().forEach(r -> assertPojoEquals(idRoleMap.get(r.getId()), r));
|
||||
public void testGetRoles() {
|
||||
// mock 数据
|
||||
RoleDO dbRole = randomPojo(RoleDO.class, o -> { // 等会查询到
|
||||
o.setName("土豆");
|
||||
o.setCode("tudou");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(DateUtils.buildTime(2022, 2, 8));
|
||||
});
|
||||
roleMapper.insert(dbRole);
|
||||
// 测试 name 不匹配
|
||||
roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setName("红薯")));
|
||||
// 测试 code 不匹配
|
||||
roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setCode("hong")));
|
||||
// 测试 createTime 不匹配
|
||||
roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setCreateTime(DateUtils.buildTime(2022, 2, 16))));
|
||||
// 准备参数
|
||||
RoleExportReqVO reqVO = new RoleExportReqVO();
|
||||
reqVO.setName("土豆");
|
||||
reqVO.setCode("tu");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setBeginTime(DateUtils.buildTime(2022, 2, 1));
|
||||
reqVO.setEndTime(DateUtils.buildTime(2022, 2, 12));
|
||||
|
||||
// 调用
|
||||
List<RoleDO> list = roleService.getRoleList(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbRole, list.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRolePage_success() {
|
||||
Map<Long, RoleDO> idRoleMap = new HashMap<>();
|
||||
// 验证名称包含"role", 状态为1,code为"code"的角色
|
||||
// 第一页
|
||||
RoleDO roleDO = createRoleDO("role1", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 1, "code");
|
||||
roleMapper.insert(roleDO);
|
||||
idRoleMap.put(roleDO.getId(), roleDO);
|
||||
// 第二页
|
||||
roleDO = createRoleDO("role2", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 1, "code");
|
||||
roleMapper.insert(roleDO);
|
||||
|
||||
// 以下是排除的角色
|
||||
roleDO = createRoleDO("role3", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 2, "code");
|
||||
roleMapper.insert(roleDO);
|
||||
roleDO = createRoleDO("role4", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 1, "xxxxx");
|
||||
roleMapper.insert(roleDO);
|
||||
|
||||
//调用
|
||||
RolePageReqVO reqVO = randomPojo(RolePageReqVO.class, o -> {
|
||||
o.setName("role");
|
||||
o.setCode("code");
|
||||
o.setStatus(1);
|
||||
o.setPageNo(1);
|
||||
o.setPageSize(1);
|
||||
o.setBeginTime(null);
|
||||
o.setEndTime(null);
|
||||
public void testGetRolePage() {
|
||||
// mock 数据
|
||||
RoleDO dbRole = randomPojo(RoleDO.class, o -> { // 等会查询到
|
||||
o.setName("土豆");
|
||||
o.setCode("tudou");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(DateUtils.buildTime(2022, 2, 8));
|
||||
});
|
||||
PageResult<RoleDO> result = roleService.getRolePage(reqVO);
|
||||
assertEquals(2, result.getTotal());
|
||||
result.getList().stream().forEach(r -> assertPojoEquals(idRoleMap.get(r.getId()), r));
|
||||
roleMapper.insert(dbRole);
|
||||
// 测试 name 不匹配
|
||||
roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setName("红薯")));
|
||||
// 测试 code 不匹配
|
||||
roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setCode("hong")));
|
||||
// 测试 createTime 不匹配
|
||||
roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setCreateTime(DateUtils.buildTime(2022, 2, 16))));
|
||||
// 准备参数
|
||||
RolePageReqVO reqVO = new RolePageReqVO();
|
||||
reqVO.setName("土豆");
|
||||
reqVO.setCode("tu");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setBeginTime(DateUtils.buildTime(2022, 2, 1));
|
||||
reqVO.setEndTime(DateUtils.buildTime(2022, 2, 12));
|
||||
|
||||
// 调用
|
||||
PageResult<RoleDO> pageResult = roleService.getRolePage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbRole, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -21,3 +21,7 @@ DELETE FROM "system_tenant";
|
||||
DELETE FROM "system_tenant_package";
|
||||
DELETE FROM "system_sensitive_word";
|
||||
DELETE FROM "system_oauth2_client";
|
||||
DELETE FROM "system_oauth2_approve";
|
||||
DELETE FROM "system_oauth2_access_token";
|
||||
DELETE FROM "system_oauth2_refresh_token";
|
||||
DELETE FROM "system_oauth2_code";
|
||||
|
@ -482,9 +482,9 @@ CREATE TABLE IF NOT EXISTS "system_oauth2_client" (
|
||||
"access_token_validity_seconds" int NOT NULL,
|
||||
"refresh_token_validity_seconds" int NOT NULL,
|
||||
"redirect_uris" varchar NOT NULL,
|
||||
"auto_approve" bit NOT NULL DEFAULT FALSE,
|
||||
"authorized_grant_types" varchar NOT NULL,
|
||||
"scopes" varchar NOT NULL DEFAULT '',
|
||||
"auto_approve_scopes" varchar NOT NULL DEFAULT '',
|
||||
"authorities" varchar NOT NULL DEFAULT '',
|
||||
"resource_ids" varchar NOT NULL DEFAULT '',
|
||||
"additional_information" varchar NOT NULL DEFAULT '',
|
||||
@ -495,3 +495,73 @@ CREATE TABLE IF NOT EXISTS "system_oauth2_client" (
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT 'OAuth2 客户端表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_oauth2_approve" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint NOT NULL,
|
||||
"user_type" tinyint NOT NULL,
|
||||
"client_id" varchar NOT NULL,
|
||||
"scope" varchar NOT NULL,
|
||||
"approved" bit NOT NULL DEFAULT FALSE,
|
||||
"expires_time" datetime NOT NULL,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT 'OAuth2 批准表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_oauth2_access_token" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint NOT NULL,
|
||||
"user_type" tinyint NOT NULL,
|
||||
"access_token" varchar NOT NULL,
|
||||
"refresh_token" varchar NOT NULL,
|
||||
"client_id" varchar NOT NULL,
|
||||
"scopes" varchar NOT NULL,
|
||||
"approved" bit NOT NULL DEFAULT FALSE,
|
||||
"expires_time" datetime NOT NULL,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
"tenant_id" bigint NOT NULL,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT 'OAuth2 访问令牌';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_oauth2_refresh_token" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint NOT NULL,
|
||||
"user_type" tinyint NOT NULL,
|
||||
"refresh_token" varchar NOT NULL,
|
||||
"client_id" varchar NOT NULL,
|
||||
"scopes" varchar NOT NULL,
|
||||
"approved" bit NOT NULL DEFAULT FALSE,
|
||||
"expires_time" datetime NOT NULL,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT 'OAuth2 刷新令牌';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_oauth2_code" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint NOT NULL,
|
||||
"user_type" tinyint NOT NULL,
|
||||
"code" varchar NOT NULL,
|
||||
"client_id" varchar NOT NULL,
|
||||
"scopes" varchar NOT NULL,
|
||||
"expires_time" datetime NOT NULL,
|
||||
"redirect_uri" varchar NOT NULL,
|
||||
"state" varchar NOT NULL,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT 'OAuth2 刷新令牌';
|
||||
|
@ -37,7 +37,7 @@
|
||||
<el-form-item style="width:100%;">
|
||||
<el-button :loading="loading" size="medium" type="primary" style="width:60%;"
|
||||
@click.native.prevent="handleAuthorize(true)">
|
||||
<span v-if="!loading">统一授权</span>
|
||||
<span v-if="!loading">同意授权</span>
|
||||
<span v-else>授 权 中...</span>
|
||||
</el-button>
|
||||
<el-button size="medium" style="width:36%"
|
||||
|
@ -103,9 +103,10 @@
|
||||
<el-form-item label="刷新令牌的有效期" prop="refreshTokenValiditySeconds">
|
||||
<el-input-number v-model="form.refreshTokenValiditySeconds" placeholder="单位:秒" />
|
||||
</el-form-item>
|
||||
<el-form-item label="可重定向的 URI 地址" prop="redirectUris">
|
||||
<el-select v-model="form.redirectUris" multiple filterable allow-create placeholder="请输入可重定向的 URI 地址" style="width: 500px" >
|
||||
<el-option v-for="redirectUri in form.redirectUris" :key="redirectUri" :label="redirectUri" :value="redirectUri"/>
|
||||
<el-form-item label="授权类型" prop="authorizedGrantTypes">
|
||||
<el-select v-model="form.authorizedGrantTypes" multiple filterable placeholder="请输入授权类型" style="width: 500px" >
|
||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_OAUTH2_GRANT_TYPE)"
|
||||
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="授权范围" prop="scopes">
|
||||
@ -113,11 +114,16 @@
|
||||
<el-option v-for="scope in form.scopes" :key="scope" :label="scope" :value="scope"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="自动授权" prop="autoApproveScopes">
|
||||
<el-form-item label="自动授权范围" prop="autoApproveScopes">
|
||||
<el-select v-model="form.autoApproveScopes" multiple filterable placeholder="请输入授权范围" style="width: 500px" >
|
||||
<el-option v-for="scope in form.scopes" :key="scope" :label="scope" :value="scope"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="可重定向的 URI 地址" prop="redirectUris">
|
||||
<el-select v-model="form.redirectUris" multiple filterable allow-create placeholder="请输入可重定向的 URI 地址" style="width: 500px" >
|
||||
<el-option v-for="redirectUri in form.redirectUris" :key="redirectUri" :label="redirectUri" :value="redirectUri"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="权限" prop="authorities">
|
||||
<el-select v-model="form.authorities" multiple filterable allow-create placeholder="请输入权限" style="width: 500px" >
|
||||
<el-option v-for="authority in form.authorities" :key="authority" :label="authority" :value="authority"/>
|
||||
|
Loading…
Reference in New Issue
Block a user