From ed039ba2aa4fa8bff441a2d7ca4249317bcf6dec Mon Sep 17 00:00:00 2001 From: ZackYoung Date: Thu, 9 Nov 2023 16:52:47 +0800 Subject: [PATCH 1/3] feature_add_token_persistent --- dinky-admin/pom.xml | 5 - .../org/dinky/configure/SaTokenConfigure.java | 5 +- .../org/dinky/controller/TokenController.java | 10 +- .../java/org/dinky/data/model/SysToken.java | 14 + .../org/dinky/service/impl/TokenService.java | 329 ++++++++++++++++++ .../dinky/service/impl/UserServiceImpl.java | 34 +- .../src/main/resources/db/db-h2-ddl.sql | 1 + .../src/main/resources/mapper/TokenMapper.xml | 9 +- dinky-web/src/models/Sse.tsx | 25 +- pom.xml | 12 - script/sql/dinky-mysql.sql | 53 +-- script/sql/dinky-pg.sql | 4 +- .../1.0.0-SNAPSHOT_schema/mysql/dinky_ddl.sql | 31 +- 13 files changed, 449 insertions(+), 83 deletions(-) create mode 100644 dinky-admin/src/main/java/org/dinky/service/impl/TokenService.java diff --git a/dinky-admin/pom.xml b/dinky-admin/pom.xml index 7fd1b2f957..2332938453 100644 --- a/dinky-admin/pom.xml +++ b/dinky-admin/pom.xml @@ -169,11 +169,6 @@ org.springframework.boot spring-boot-starter-actuator - - - org.springframework.boot - spring-boot-starter-data-redis - org.dinky dinky-core diff --git a/dinky-admin/src/main/java/org/dinky/configure/SaTokenConfigure.java b/dinky-admin/src/main/java/org/dinky/configure/SaTokenConfigure.java index ff1c155714..bf61ef83e9 100644 --- a/dinky-admin/src/main/java/org/dinky/configure/SaTokenConfigure.java +++ b/dinky-admin/src/main/java/org/dinky/configure/SaTokenConfigure.java @@ -22,14 +22,15 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import cn.dev33.satoken.jwt.StpLogicJwtForSimple; import cn.dev33.satoken.stp.StpLogic; +import cn.dev33.satoken.util.SaTokenConsts; @Configuration public class SaTokenConfigure { // Sa-Token 整合 jwt (Simple 简单模式) @Bean public StpLogic getStpLogicJwt() { - return new StpLogicJwtForSimple(); + // return new StpLogicJwtForSimple(); + return new StpLogic(SaTokenConsts.TOKEN_STYLE_RANDOM_32); } } diff --git a/dinky-admin/src/main/java/org/dinky/controller/TokenController.java b/dinky-admin/src/main/java/org/dinky/controller/TokenController.java index 93656e4266..432a7b9199 100644 --- a/dinky-admin/src/main/java/org/dinky/controller/TokenController.java +++ b/dinky-admin/src/main/java/org/dinky/controller/TokenController.java @@ -42,14 +42,16 @@ import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaMode; -import cn.hutool.core.lang.UUID; +import cn.dev33.satoken.stp.StpLogic; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -/** TokenController */ +/** + * TokenController + */ @Slf4j @Api(tags = "Token Controller") @RestController @@ -58,6 +60,7 @@ public class TokenController { private final TokenService tokenService; + private final StpLogic stpLogic; /** * get udf template list @@ -113,12 +116,13 @@ public Result deleteToken(@RequestParam Integer id) { /** * delete Token by id + * * @return {@link Result} <{@link Void}> */ @PostMapping("/buildToken") @Log(title = "Build Token", businessType = BusinessType.OTHER) @ApiOperation("Build Token") public Result buildToken() { - return Result.succeed(UUID.fastUUID().toString(true), Status.SUCCESS); + return Result.succeed(stpLogic.createTokenValue(null, null, 1, null), Status.SUCCESS); } } diff --git a/dinky-admin/src/main/java/org/dinky/data/model/SysToken.java b/dinky-admin/src/main/java/org/dinky/data/model/SysToken.java index bebb71527d..101d726ed1 100644 --- a/dinky-admin/src/main/java/org/dinky/data/model/SysToken.java +++ b/dinky-admin/src/main/java/org/dinky/data/model/SysToken.java @@ -24,6 +24,7 @@ import java.util.Date; import java.util.List; +import com.baomidou.mybatisplus.annotation.EnumValue; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; @@ -39,6 +40,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.Getter; import lombok.NoArgsConstructor; @Data @@ -154,4 +156,16 @@ public class SysToken implements Serializable { dataType = "List", notes = "List of timestamps indicating the time range for token expiration") private List expireTimeRange; + + private Source source; + + @Getter + @AllArgsConstructor + public enum Source { + LOGIN(1), + CUSTOM(2); + + @EnumValue + private final int type; + } } diff --git a/dinky-admin/src/main/java/org/dinky/service/impl/TokenService.java b/dinky-admin/src/main/java/org/dinky/service/impl/TokenService.java new file mode 100644 index 0000000000..381f8c14db --- /dev/null +++ b/dinky-admin/src/main/java/org/dinky/service/impl/TokenService.java @@ -0,0 +1,329 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dinky.service.impl; + +import org.dinky.context.UserInfoContextHolder; +import org.dinky.data.dto.UserDTO; +import org.dinky.data.model.SysToken; +import org.dinky.data.model.User; +import org.dinky.mapper.TokenMapper; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitialization; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; + +import cn.dev33.satoken.SaManager; +import cn.dev33.satoken.dao.SaTokenDao; +import cn.dev33.satoken.stp.StpLogic; +import cn.dev33.satoken.util.SaFoxUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@RequiredArgsConstructor +@Slf4j +@Service +@DependsOnDatabaseInitialization +public class TokenService implements SaTokenDao { + + private final TokenMapper tokenMapper; + private final StpLogic stpLogic; + + /** + * 存储数据的集合 + */ + public Map dataMap = new ConcurrentHashMap<>(); + + /** + * 存储数据过期时间的集合(单位: 毫秒), 记录所有 key 的到期时间 (注意存储的是到期时间,不是剩余存活时间) + */ + public Map expireMap = new ConcurrentHashMap<>(); + + // ------------------------ String 读写操作 + + @Override + public String get(String key) { + clearKeyByTimeout(key); + return (String) dataMap.get(key); + } + + @Override + public void set(String key, String value, long timeout) { + if (timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) { + return; + } + dataMap.put(key, value); + expireMap.put( + key, + (timeout == SaTokenDao.NEVER_EXPIRE) + ? (SaTokenDao.NEVER_EXPIRE) + : (System.currentTimeMillis() + timeout * 1000)); + } + + @Override + public void update(String key, String value) { + if (getKeyTimeout(key) == SaTokenDao.NOT_VALUE_EXPIRE) { + return; + } + dataMap.put(key, value); + } + + @Override + public void delete(String key) { + String token = CollUtil.getLast(StrUtil.split(key, ":")); + dataMap.remove(key); + expireMap.remove(key); + tokenMapper.delete(new LambdaQueryWrapper().eq(SysToken::getTokenValue, token)); + } + + @Override + public long getTimeout(String key) { + return getKeyTimeout(key); + } + + @Override + public void updateTimeout(String key, long timeout) { + expireMap.put( + key, + (timeout == SaTokenDao.NEVER_EXPIRE) + ? (SaTokenDao.NEVER_EXPIRE) + : (System.currentTimeMillis() + timeout * 1000)); + } + + // ------------------------ Object 读写操作 + + @Override + public Object getObject(String key) { + clearKeyByTimeout(key); + return dataMap.get(key); + } + + @Override + public void setObject(String key, Object object, long timeout) { + if (timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) { + return; + } + dataMap.put(key, object); + expireMap.put( + key, + (timeout == SaTokenDao.NEVER_EXPIRE) + ? (SaTokenDao.NEVER_EXPIRE) + : (System.currentTimeMillis() + timeout * 1000)); + } + + @Override + public void updateObject(String key, Object object) { + if (getKeyTimeout(key) == SaTokenDao.NOT_VALUE_EXPIRE) { + return; + } + dataMap.put(key, object); + } + + @Override + public void deleteObject(String key) { + delete(key); + } + + @Override + public long getObjectTimeout(String key) { + return getKeyTimeout(key); + } + + @Override + public void updateObjectTimeout(String key, long timeout) { + expireMap.put( + key, + (timeout == SaTokenDao.NEVER_EXPIRE) + ? (SaTokenDao.NEVER_EXPIRE) + : (System.currentTimeMillis() + timeout * 1000)); + } + + // ------------------------ Session 读写操作 + // 使用接口默认实现 + + // --------- 会话管理 + + @Override + public List searchData(String prefix, String keyword, int start, int size, boolean sortType) { + return SaFoxUtil.searchList(expireMap.keySet(), prefix, keyword, start, size, sortType); + } + + // ------------------------ 以下是一个定时缓存的简单实现,采用:惰性检查 + 异步循环扫描 + + // --------- 过期时间相关操作 + + /** + * 如果指定的 key 已经过期,则立即清除它 + * + * @param key 指定 key + */ + void clearKeyByTimeout(String key) { + Long expirationTime = expireMap.get(key); + // 清除条件: + // 1、数据存在。 + // 2、不是 [ 永不过期 ]。 + // 3、已经超过过期时间。 + if (expirationTime != null + && expirationTime != SaTokenDao.NEVER_EXPIRE + && expirationTime < System.currentTimeMillis()) { + delete(key); + } + } + + /** + * 获取指定 key 的剩余存活时间 (单位:秒) + * + * @param key 指定 key + * @return 这个 key 的剩余存活时间 + */ + long getKeyTimeout(String key) { + // 由于数据过期检测属于惰性扫描,很可能此时这个 key 已经是过期状态了,所以这里需要先检查一下 + clearKeyByTimeout(key); + + // 获取这个 key 的过期时间 + Long expire = expireMap.get(key); + + // 如果 expire 数据不存在,说明框架没有存储这个 key,此时返回 NOT_VALUE_EXPIRE + if (expire == null) { + return SaTokenDao.NOT_VALUE_EXPIRE; + } + + // 如果 expire 被标注为永不过期,则返回 NEVER_EXPIRE + if (expire == SaTokenDao.NEVER_EXPIRE) { + return SaTokenDao.NEVER_EXPIRE; + } + + // ---- 代码至此,说明这个 key 是有过期时间的,且未过期,那么: + + // 计算剩余时间并返回 (过期时间戳 - 当前时间戳) / 1000 转秒 + long timeout = (expire - System.currentTimeMillis()) / 1000; + + // 小于零时,视为不存在 + if (timeout < 0) { + dataMap.remove(key); + expireMap.remove(key); + return SaTokenDao.NOT_VALUE_EXPIRE; + } + return timeout; + } + + // --------- 定时清理过期数据 + + /** + * 执行数据清理的线程引用 + */ + public Thread refreshThread; + + /** + * 是否继续执行数据清理的线程标记 + */ + public volatile boolean refreshFlag; + + /** + * 清理所有已经过期的 key + */ + public void refreshDataMap() { + for (String s : expireMap.keySet()) { + clearKeyByTimeout(s); + } + } + + /** + * 初始化定时任务,定时清理过期数据 + */ + public void initRefreshThread() { + + // 如果开发者配置了 <=0 的值,则不启动定时清理 + if (SaManager.getConfig().getDataRefreshPeriod() <= 0) { + return; + } + + // 启动定时刷新 + this.refreshFlag = true; + this.refreshThread = new Thread(() -> { + for (; ; ) { + try { + try { + // 如果已经被标记为结束 + if (!refreshFlag) { + return; + } + // 执行清理 + refreshDataMap(); + } catch (Exception e) { + log.error("", e); + } + // 休眠N秒 + int dataRefreshPeriod = SaManager.getConfig().getDataRefreshPeriod(); + if (dataRefreshPeriod <= 0) { + dataRefreshPeriod = 1; + } + Thread.sleep(dataRefreshPeriod * 1000L); + } catch (Exception e) { + log.error("", e); + } + } + }); + this.refreshThread.start(); + } + + /** + * 组件被安装时,开始刷新数据线程 + */ + @Override + public void init() { + DateTime now = DateUtil.date(); + List sysTokens = tokenMapper.selectList(new LambdaQueryWrapper<>()); + for (SysToken sysToken : sysTokens) { + Integer userId = sysToken.getUserId(); + dataMap.put(stpLogic.splicingKeyTokenValue(sysToken.getTokenValue()), userId.toString()); + dataMap.put(stpLogic.splicingKeyLastActiveTime(sysToken.getTokenValue()), StrUtil.toString(now.getTime())); + UserDTO userInfo = new UserDTO(); + User user = new User(); + user.setId(userId); + userInfo.setUser(user); + UserInfoContextHolder.set(userId, userInfo); + if (sysToken.getExpireType() == 1) { + expireMap.put(stpLogic.splicingKeyTokenValue(sysToken.getTokenValue()), NEVER_EXPIRE); + } else { + expireMap.put( + stpLogic.splicingKeyTokenValue(sysToken.getTokenValue()), + sysToken.getExpireEndTime().getTime()); + } + } + initRefreshThread(); + } + + /** + * 组件被卸载时,结束定时任务,不再定时清理过期数据 + */ + @Override + public void destroy() { + this.refreshFlag = false; + } +} diff --git a/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java b/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java index 5d8f3d49d8..1b930846e3 100644 --- a/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java +++ b/dinky-admin/src/main/java/org/dinky/service/impl/UserServiceImpl.java @@ -33,6 +33,7 @@ import org.dinky.data.model.Role; import org.dinky.data.model.RoleMenu; import org.dinky.data.model.RowPermissions; +import org.dinky.data.model.SysToken; import org.dinky.data.model.SystemConfiguration; import org.dinky.data.model.Tenant; import org.dinky.data.model.User; @@ -42,6 +43,7 @@ import org.dinky.data.params.AssignUserToTenantParams; import org.dinky.data.result.Result; import org.dinky.data.vo.UserVo; +import org.dinky.mapper.TokenMapper; import org.dinky.mapper.UserMapper; import org.dinky.mybatis.service.impl.SuperServiceImpl; import org.dinky.service.MenuService; @@ -66,6 +68,8 @@ import cn.dev33.satoken.secure.SaSecureUtil; import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import lombok.RequiredArgsConstructor; @@ -98,6 +102,8 @@ public class UserServiceImpl extends SuperServiceImpl implemen private final RoleMenuService roleMenuService; private final MenuService menuService; + private final TokenService tokenService; + private final TokenMapper tokenMapper; @Override public Result registerUser(User user) { @@ -156,7 +162,7 @@ public Boolean removeUser(Integer id) { * * @param loginDTO a user based on the provided login credentials. * @return a Result object containing the user information if the login is successful, or an - * appropriate error status if the login fails. + * appropriate error status if the login fails. */ @Override public Result loginUser(LoginDTO loginDTO) { @@ -182,15 +188,37 @@ public Result loginUser(LoginDTO loginDTO) { } // Perform login using StpUtil (Assuming it handles the session management) - StpUtil.login(user.getId(), loginDTO.isAutoLogin()); + Integer userId = user.getId(); + StpUtil.login(userId, loginDTO.isAutoLogin()); // save login log record loginLogService.saveLoginLog(user, Status.LOGIN_SUCCESS); + insertToken(userInfo); + // Return the user information along with a success status return Result.succeed(userInfo, Status.LOGIN_SUCCESS); } + private void insertToken(UserDTO userInfo) { + Integer userId = userInfo.getUser().getId(); + SysToken sysToken = new SysToken(); + String tokenValue = StpUtil.getTokenValueByLoginId(userId); + sysToken.setTokenValue(tokenValue); + sysToken.setUserId(userId); + // todo 权限和租户暂未接入 + sysToken.setRoleId(1); + sysToken.setTenantId(1); + sysToken.setExpireType(3); + DateTime date = DateUtil.date(); + sysToken.setExpireStartTime(date); + sysToken.setExpireEndTime(DateUtil.offsetDay(date, 1)); + sysToken.setCreator(userId); + sysToken.setUpdator(userId); + sysToken.setSource(SysToken.Source.LOGIN); + tokenMapper.insert(sysToken); + } + private User localLogin(LoginDTO loginDTO) throws AuthException { // Get user from local database by username User user = getUserByUsername(loginDTO.getUsername()); @@ -476,7 +504,7 @@ public Result resetPassword(Integer userId) { * @param userId * @return */ - private UserDTO buildUserInfo(Integer userId) { + public UserDTO buildUserInfo(Integer userId) { User user = getById(userId); if (Asserts.isNull(user)) { diff --git a/dinky-admin/src/main/resources/db/db-h2-ddl.sql b/dinky-admin/src/main/resources/db/db-h2-ddl.sql index 698e2ecbb1..708a716e4f 100644 --- a/dinky-admin/src/main/resources/db/db-h2-ddl.sql +++ b/dinky-admin/src/main/resources/db/db-h2-ddl.sql @@ -568,6 +568,7 @@ CREATE TABLE `dinky_sys_token` ( `update_time` datetime NOT NULL COMMENT 'modify time', `creator` bigint DEFAULT NULL COMMENT '创建人', `updator` bigint DEFAULT NULL COMMENT '修改人', + `source` tinyint(2) DEFAULT NULL COMMENT '1:login 2:custom', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COMMENT='token management'; diff --git a/dinky-admin/src/main/resources/mapper/TokenMapper.xml b/dinky-admin/src/main/resources/mapper/TokenMapper.xml index 0b9ee212a6..4eedfee080 100644 --- a/dinky-admin/src/main/resources/mapper/TokenMapper.xml +++ b/dinky-admin/src/main/resources/mapper/TokenMapper.xml @@ -4,10 +4,10 @@ diff --git a/dinky-web/src/models/Sse.tsx b/dinky-web/src/models/Sse.tsx index e15d26823e..8acc603a83 100644 --- a/dinky-web/src/models/Sse.tsx +++ b/dinky-web/src/models/Sse.tsx @@ -1,19 +1,19 @@ /* * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. * */ @@ -41,7 +41,6 @@ export default () => { const para = { sessionKey: uuidRef.current, topics: topics }; await postAll('api/sse/subscribeTopic', para).catch((e) => ErrorMessage(e)); }; - const reconnectSse = () => { const sseUrl = '/api/sse/connect?sessionKey=' + uuidRef.current; eventSource?.close(); diff --git a/pom.xml b/pom.xml index 4055f29150..87d7cb9601 100644 --- a/pom.xml +++ b/pom.xml @@ -372,18 +372,6 @@ sa-token-spring-boot-starter ${sa-token.version} - - - cn.dev33 - sa-token-dao-redis-jackson - ${sa-token.version} - - - redis.clients - jedis - ${jedis.version} - - org.dinky dinky-core diff --git a/script/sql/dinky-mysql.sql b/script/sql/dinky-mysql.sql index 581b430c61..11bd95571c 100644 --- a/script/sql/dinky-mysql.sql +++ b/script/sql/dinky-mysql.sql @@ -1841,29 +1841,6 @@ CREATE TABLE `dinky_sys_role_menu` ( UNIQUE KEY `un_role_menu_inx` (`role_id`,`menu_id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; - --- ---------------------------- --- Table structure dinky_sys_token --- ---------------------------- -drop table if exists `dinky_sys_token`; -CREATE TABLE `dinky_sys_token` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id', - `token_value` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'token value', - `user_id` bigint NOT NULL COMMENT 'user id', - `role_id` bigint NOT NULL COMMENT 'role id', - `tenant_id` bigint NOT NULL COMMENT 'tenant id', - `expire_type` tinyint NOT NULL COMMENT '1: never expire, 2: expire after a period of time, 3: expire at a certain time', - `expire_start_time` datetime DEFAULT NULL COMMENT 'expire start time ,when expire_type = 3 , it is the start time of the period', - `expire_end_time` datetime DEFAULT NULL COMMENT 'expire end time ,when expire_type = 2,3 , it is the end time of the period', - `create_time` datetime NOT NULL COMMENT 'create time', - `update_time` datetime NOT NULL COMMENT 'modify time', - `creator` bigint DEFAULT NULL COMMENT '创建人', - `updator` bigint DEFAULT NULL COMMENT '修改人', - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='token management'; - - - -- ---------------------------- -- Table structure dinky_sys_alert -- ---------------------------- @@ -1918,9 +1895,7 @@ INSERT INTO dinky_alert_template VALUES (1, 'Default', ' [Go toTask Web](http://${taskUrl}) ', 1, null, null); -COMMIT; -SET FOREIGN_KEY_CHECKS = 1; CREATE TABLE `dinky_udf_manage` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL COMMENT 'udf name', @@ -1932,4 +1907,30 @@ CREATE TABLE `dinky_udf_manage` ( `update_time` datetime DEFAULT NULL COMMENT 'update time', PRIMARY KEY (`id`) USING BTREE, KEY `name,resources_id` (`name`,`resources_id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='udf'; \ No newline at end of file +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='udf'; + +-- ---------------------------- +-- Table structure dinky_sys_token +-- ---------------------------- +drop table if exists `dinky_sys_token`; +CREATE TABLE `dinky_sys_token` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', + `token_value` varchar(255) NOT NULL COMMENT 'token value', + `user_id` bigint(20) NOT NULL COMMENT 'user id', + `role_id` bigint(20) NOT NULL COMMENT 'role id', + `tenant_id` bigint(20) NOT NULL COMMENT 'tenant id', + `expire_type` tinyint(4) NOT NULL COMMENT '1: never expire, 2: expire after a period of time, 3: expire at a certain time', + `expire_start_time` datetime DEFAULT NULL COMMENT 'expire start time ,when expire_type = 3 , it is the start time of the period', + `expire_end_time` datetime DEFAULT NULL COMMENT 'expire end time ,when expire_type = 2,3 , it is the end time of the period', + `create_time` datetime NOT NULL COMMENT 'create time', + `update_time` datetime NOT NULL COMMENT 'modify time', + `creator` bigint(20) DEFAULT NULL COMMENT '创建人', + `updator` bigint(20) DEFAULT NULL COMMENT '修改人', + `source` tinyint(2) DEFAULT NULL COMMENT '1:login 2:custom', + PRIMARY KEY (`id`), + UNIQUE KEY `token_value` (`token_value`) USING BTREE, + KEY `source` (`source`) USING HASH +) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4 COMMENT='token management'; + +COMMIT; +SET FOREIGN_KEY_CHECKS = 1; diff --git a/script/sql/dinky-pg.sql b/script/sql/dinky-pg.sql index 7d7bd15134..c17d2b8db7 100644 --- a/script/sql/dinky-pg.sql +++ b/script/sql/dinky-pg.sql @@ -2663,7 +2663,8 @@ create table public.dinky_sys_token ( create_time timestamp without time zone, update_time timestamp without time zone, creator bigint, - updator bigint + updator bigint, + source bigint ); comment on table public.dinky_sys_token is 'token table'; comment on column public.dinky_sys_token.id is 'id'; @@ -2678,6 +2679,7 @@ comment on column public.dinky_sys_token.create_time is 'create time'; comment on column public.dinky_sys_token.update_time is 'modify time'; comment on column public.dinky_sys_token.creator is 'creat user'; comment on column public.dinky_sys_token.updator is 'modify user'; +comment on column public.dinky_sys_token.source is 'source'; -- ---------------------------- diff --git a/script/sql/upgrade/1.0.0-SNAPSHOT_schema/mysql/dinky_ddl.sql b/script/sql/upgrade/1.0.0-SNAPSHOT_schema/mysql/dinky_ddl.sql index f9f90b0ade..076665bdb2 100644 --- a/script/sql/upgrade/1.0.0-SNAPSHOT_schema/mysql/dinky_ddl.sql +++ b/script/sql/upgrade/1.0.0-SNAPSHOT_schema/mysql/dinky_ddl.sql @@ -275,20 +275,23 @@ create table if not exists dinky_alert_rules -- Table structure dinky_sys_token -- ---------------------------- CREATE TABLE `dinky_sys_token` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id', - `token_value` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'token value', - `user_id` bigint NOT NULL COMMENT 'user id', - `role_id` bigint NOT NULL COMMENT 'role id', - `tenant_id` bigint NOT NULL COMMENT 'tenant id', - `expire_type` tinyint NOT NULL COMMENT '1: never expire, 2: expire after a period of time, 3: expire at a certain time', - `expire_start_time` datetime DEFAULT NULL COMMENT 'expire start time ,when expire_type = 3 , it is the start time of the period', - `expire_end_time` datetime DEFAULT NULL COMMENT 'expire end time ,when expire_type = 2,3 , it is the end time of the period', - `create_time` datetime NOT NULL COMMENT 'create time', - `update_time` datetime NOT NULL COMMENT 'modify time', - `creator` bigint DEFAULT NULL COMMENT '创建人', - `updator` bigint DEFAULT NULL COMMENT '修改人', - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='token management'; + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', + `token_value` varchar(255) NOT NULL COMMENT 'token value', + `user_id` bigint(20) NOT NULL COMMENT 'user id', + `role_id` bigint(20) NOT NULL COMMENT 'role id', + `tenant_id` bigint(20) NOT NULL COMMENT 'tenant id', + `expire_type` tinyint(4) NOT NULL COMMENT '1: never expire, 2: expire after a period of time, 3: expire at a certain time', + `expire_start_time` datetime DEFAULT NULL COMMENT 'expire start time ,when expire_type = 3 , it is the start time of the period', + `expire_end_time` datetime DEFAULT NULL COMMENT 'expire end time ,when expire_type = 2,3 , it is the end time of the period', + `create_time` datetime NOT NULL COMMENT 'create time', + `update_time` datetime NOT NULL COMMENT 'modify time', + `creator` bigint(20) DEFAULT NULL COMMENT '创建人', + `updator` bigint(20) DEFAULT NULL COMMENT '修改人', + `source` tinyint(2) DEFAULT NULL COMMENT '1:login 2:custom', + PRIMARY KEY (`id`), + UNIQUE KEY `token_value` (`token_value`) USING BTREE, + KEY `source` (`source`) USING HASH +) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4 COMMENT='token management'; CREATE TABLE `dinky_udf_manage` ( `id` int(11) NOT NULL AUTO_INCREMENT, From fb89081b6e8965f557f2d7719482a33a498d6616 Mon Sep 17 00:00:00 2001 From: ZackYoung Date: Thu, 9 Nov 2023 17:33:45 +0800 Subject: [PATCH 2/3] feature_add_token_persistent --- .../java/org/dinky/configure/CacheConfig.java | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/dinky-admin/src/main/java/org/dinky/configure/CacheConfig.java b/dinky-admin/src/main/java/org/dinky/configure/CacheConfig.java index a0eb4b45a6..58bc54df6b 100644 --- a/dinky-admin/src/main/java/org/dinky/configure/CacheConfig.java +++ b/dinky-admin/src/main/java/org/dinky/configure/CacheConfig.java @@ -20,12 +20,7 @@ package org.dinky.configure; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.cache.RedisCacheConfiguration; -import org.springframework.data.redis.serializer.RedisSerializationContext; -import org.springframework.data.redis.serializer.RedisSerializer; -import org.springframework.data.redis.serializer.StringRedisSerializer; /** * CacheCoonfigure @@ -37,14 +32,14 @@ public class CacheConfig { /** 配置Redis缓存注解的value序列化方式 */ - @Bean - public RedisCacheConfiguration cacheConfiguration() { - return RedisCacheConfiguration.defaultCacheConfig() - // 序列化为json - .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json())) - .serializeKeysWith( - RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())); - } +// @Bean +// public RedisCacheConfiguration cacheConfiguration() { +// return RedisCacheConfiguration.defaultCacheConfig() +// // 序列化为json +// .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json())) +// .serializeKeysWith( +// RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())); +// } // /** // * 配置RedisTemplate的序列化方式 From 38ae431ac04d1327265f08a93a56801f9eb60101 Mon Sep 17 00:00:00 2001 From: ZackYoung Date: Thu, 9 Nov 2023 17:37:55 +0800 Subject: [PATCH 3/3] feature_add_token_persistent --- .../java/org/dinky/configure/CacheConfig.java | 58 ------------------- 1 file changed, 58 deletions(-) delete mode 100644 dinky-admin/src/main/java/org/dinky/configure/CacheConfig.java diff --git a/dinky-admin/src/main/java/org/dinky/configure/CacheConfig.java b/dinky-admin/src/main/java/org/dinky/configure/CacheConfig.java deleted file mode 100644 index 58bc54df6b..0000000000 --- a/dinky-admin/src/main/java/org/dinky/configure/CacheConfig.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.dinky.configure; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Configuration; - -/** - * CacheCoonfigure - * - * @since 2022/09/24 11:23 - */ -@Configuration -@ConditionalOnProperty(prefix = "spring.cache", name = "type", havingValue = "REDIS") -public class CacheConfig { - - /** 配置Redis缓存注解的value序列化方式 */ -// @Bean -// public RedisCacheConfiguration cacheConfiguration() { -// return RedisCacheConfiguration.defaultCacheConfig() -// // 序列化为json -// .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json())) -// .serializeKeysWith( -// RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())); -// } - - // /** - // * 配置RedisTemplate的序列化方式 - // */ - // @Bean - // public RedisTemplate redisTemplate(RedisConnectionFactory factory) { - // RedisTemplate redisTemplate = new RedisTemplate(); - // redisTemplate.setConnectionFactory(factory); - // // 指定key的序列化方式:string - // redisTemplate.setKeySerializer(RedisSerializer.string()); - // // 指定value的序列化方式:json - // redisTemplate.setValueSerializer(RedisSerializer.json()); - // return redisTemplate; - // } - -}