diff --git a/continew-common/src/main/java/top/continew/admin/common/util/SecureUtils.java b/continew-common/src/main/java/top/continew/admin/common/util/SecureUtils.java index a7edaa29..28f0b5db 100644 --- a/continew-common/src/main/java/top/continew/admin/common/util/SecureUtils.java +++ b/continew-common/src/main/java/top/continew/admin/common/util/SecureUtils.java @@ -26,6 +26,7 @@ import top.continew.starter.core.util.validate.ValidationUtils; import top.continew.starter.security.crypto.autoconfigure.CryptoProperties; import top.continew.starter.security.crypto.encryptor.AesEncryptor; import top.continew.starter.security.crypto.encryptor.IEncryptor; + import java.util.List; import java.util.stream.Collectors; @@ -40,6 +41,18 @@ public class SecureUtils { private SecureUtils() { } + /** + * 公钥加密 + * + * @param data 要加密的内容 + * @return 加密后的内容 + */ + public static String encryptByRsaPublicKey(String data) { + String publicKey = RsaProperties.PUBLIC_KEY; + ValidationUtils.throwIfBlank(publicKey, "请配置 RSA 公钥"); + return encryptByRsaPublicKey(data, publicKey); + } + /** * 私钥解密 * @@ -52,6 +65,17 @@ public class SecureUtils { return decryptByRsaPrivateKey(data, privateKey); } + /** + * 公钥加密 + * + * @param data 要加密的内容 + * @param publicKey 公钥 + * @return 加密后的内容 + */ + public static String encryptByRsaPublicKey(String data, String publicKey) { + return new String(SecureUtil.rsa(null, publicKey).encrypt(data, KeyType.PublicKey)); + } + /** * 私钥解密 * diff --git a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/entity/AppDO.java b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/entity/AppDO.java index 6e11eca5..171a4a27 100644 --- a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/entity/AppDO.java +++ b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/entity/AppDO.java @@ -16,19 +16,20 @@ package top.continew.admin.open.model.entity; -import java.io.Serial; -import java.time.*; - -import lombok.Data; - import com.baomidou.mybatisplus.annotation.TableName; - +import lombok.Data; +import top.continew.admin.common.enums.DisEnableStatusEnum; import top.continew.starter.extension.crud.model.entity.BaseDO; +import top.continew.starter.security.crypto.annotation.FieldEncrypt; + +import java.io.Serial; +import java.time.LocalDateTime; /** * 应用实体 * * @author chengzi + * @author Charles7c * @since 2024/10/17 16:03 */ @Data @@ -39,42 +40,34 @@ public class AppDO extends BaseDO { private static final long serialVersionUID = 1L; /** - * ID - */ - private Long id; - - /** - * 应用名称 + * 名称 */ private String name; /** - * APPKEY + * Access Key(访问密钥) */ - private String appKey; + @FieldEncrypt + private String accessKey; /** - * APPSECRET + * Secret Key(私有密钥) */ - private String appSecret; - - /** - * 应用状态 - */ - private String status; + @FieldEncrypt + private String secretKey; /** * 失效时间 */ - private LocalDateTime expirationTime; + private LocalDateTime expireTime; /** - * 应用描述 + * 描述 */ - private String appDesc; + private String description; /** - * secret查看状态 + * 状态 */ - private String secretStatus; + private DisEnableStatusEnum status; } \ No newline at end of file diff --git a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/query/AppQuery.java b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/query/AppQuery.java index 0c843751..3508c875 100644 --- a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/query/AppQuery.java +++ b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/query/AppQuery.java @@ -16,20 +16,19 @@ package top.continew.admin.open.model.query; -import java.io.Serial; -import java.io.Serializable; - -import lombok.Data; - import io.swagger.v3.oas.annotations.media.Schema; - +import lombok.Data; import top.continew.starter.data.core.annotation.Query; import top.continew.starter.data.core.enums.QueryType; +import java.io.Serial; +import java.io.Serializable; + /** * 应用查询条件 * * @author chengzi + * @author Charles7c * @since 2024/10/17 16:03 */ @Data @@ -40,16 +39,9 @@ public class AppQuery implements Serializable { private static final long serialVersionUID = 1L; /** - * 应用名称 + * 关键词 */ - @Schema(description = "应用名称") - @Query(type = QueryType.LIKE) - private String name; - - /** - * APPKEY - */ - @Schema(description = "APPKEY") - @Query(type = QueryType.LIKE) - private String appKey; + @Schema(description = "关键词", example = "应用1") + @Query(columns = {"name", "description"}, type = QueryType.LIKE) + private String description; } \ No newline at end of file diff --git a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/req/AppReq.java b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/req/AppReq.java index de21a2b6..3ef55632 100644 --- a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/req/AppReq.java +++ b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/req/AppReq.java @@ -16,67 +16,68 @@ package top.continew.admin.open.model.req; -import java.io.Serial; -import java.time.*; - -import jakarta.validation.constraints.*; - -import lombok.Data; - import io.swagger.v3.oas.annotations.media.Schema; - +import jakarta.validation.constraints.Future; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; import org.hibernate.validator.constraints.Length; - +import top.continew.admin.common.enums.DisEnableStatusEnum; import top.continew.starter.extension.crud.model.req.BaseReq; +import java.io.Serial; +import java.time.LocalDateTime; + /** - * 创建或修改应用信息 + * 创建或修改应用参数 * * @author chengzi + * @author Charles7c * @since 2024/10/17 16:03 */ @Data -@Schema(description = "创建或修改应用信息") +@Schema(description = "创建或修改应用参数") public class AppReq extends BaseReq { @Serial private static final long serialVersionUID = 1L; /** - * 应用名称 + * 名称 */ - @Schema(description = "应用名称") - @NotBlank(message = "应用名称不能为空") - @Length(max = 255, message = "应用名称长度不能超过 {max} 个字符") + @Schema(description = "名称", example = "应用1") + @NotBlank(message = "名称不能为空") + @Length(max = 100, message = "名称长度不能超过 {max} 个字符") private String name; - /** - * APPKEY - */ - @Schema(description = "应用密钥") - @NotBlank(message = "应用密钥不能为空") - @Length(max = 255, message = "应用密钥长度不能超过 {max} 个字符") - private String appKey; - - /** - * 应用状态 - */ - @Schema(description = "应用状态") - @NotBlank(message = "应用状态不能为空") - @Length(max = 255, message = "应用状态长度不能超过 {max} 个字符") - private String status; - /** * 失效时间 */ - @Schema(description = "失效时间") - @NotNull(message = "失效时间不能为空") - private LocalDateTime expirationTime; + @Schema(description = "失效时间", example = "2023-08-08 23:59:59", type = "string") + @Future(message = "失效时间必须是未来时间") + private LocalDateTime expireTime; /** - * 应用描述 + * 描述 */ - @Schema(description = "应用描述") - @Length(max = 255, message = "应用描述长度不能超过 {max} 个字符") - private String appDesc; + @Schema(description = "描述", example = "应用1描述信息") + @Length(max = 200, message = "描述长度不能超过 {max} 个字符") + private String description; + + /** + * 状态 + */ + @Schema(description = "状态", example = "1") + private DisEnableStatusEnum status; + + /** + * Access Key(访问密钥) + */ + @Schema(hidden = true) + private String accessKey; + + /** + * Secret Key(密钥) + */ + @Schema(hidden = true) + private String secretKey; } \ No newline at end of file diff --git a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/resp/AppDetailResp.java b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/resp/AppDetailResp.java index 7a3342d8..70627d65 100644 --- a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/resp/AppDetailResp.java +++ b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/resp/AppDetailResp.java @@ -16,22 +16,22 @@ package top.continew.admin.open.model.resp; -import java.io.Serial; -import java.time.*; - -import lombok.Data; - -import io.swagger.v3.oas.annotations.media.Schema; - import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; - +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import top.continew.admin.common.enums.DisEnableStatusEnum; import top.continew.starter.extension.crud.model.resp.BaseDetailResp; +import top.continew.starter.file.excel.converter.ExcelBaseEnumConverter; + +import java.io.Serial; +import java.time.LocalDateTime; /** * 应用详情信息 * * @author chengzi + * @author Charles7c * @since 2024/10/17 16:03 */ @Data @@ -43,37 +43,37 @@ public class AppDetailResp extends BaseDetailResp { private static final long serialVersionUID = 1L; /** - * 应用名称 + * 名称 */ - @Schema(description = "应用名称") - @ExcelProperty(value = "应用名称") + @Schema(description = "名称", example = "应用1") + @ExcelProperty(value = "名称", order = 2) private String name; /** - * 应用密钥 + * Access Key(访问密钥) */ - @Schema(description = "应用密钥") - @ExcelProperty(value = "应用密钥") - private String appKey; - - /** - * 应用状态 - */ - @Schema(description = "应用状态") - @ExcelProperty(value = "应用状态") - private String status; + @Schema(description = "Access Key(访问密钥)", example = "YjUyMGJjYjIxNTE0NDAxMWE1NmRiY2") + @ExcelProperty(value = "Access Key", order = 3) + private String accessKey; /** * 失效时间 */ - @Schema(description = "失效时间") - @ExcelProperty(value = "失效时间") - private LocalDateTime expirationTime; + @Schema(description = "失效时间", example = "2023-08-08 08:08:08", type = "string") + @ExcelProperty(value = "失效时间", order = 4) + private LocalDateTime expireTime; /** - * 应用描述 + * 状态 */ - @Schema(description = "应用描述") - @ExcelProperty(value = "应用描述") - private String appDesc; + @Schema(description = "状态", example = "1") + @ExcelProperty(value = "状态", converter = ExcelBaseEnumConverter.class, order = 5) + private DisEnableStatusEnum status; + + /** + * 描述 + */ + @Schema(description = "描述", example = "应用1描述信息") + @ExcelProperty(value = "描述", order = 6) + private String description; } \ No newline at end of file diff --git a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/resp/AppResp.java b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/resp/AppResp.java index 8457ef90..637d067d 100644 --- a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/resp/AppResp.java +++ b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/resp/AppResp.java @@ -16,56 +16,55 @@ package top.continew.admin.open.model.resp; -import java.io.Serial; -import java.time.*; - -import lombok.Data; - import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import top.continew.admin.common.enums.DisEnableStatusEnum; +import top.continew.starter.extension.crud.model.resp.BaseDetailResp; -import top.continew.starter.extension.crud.model.resp.BaseResp; +import java.io.Serial; +import java.time.LocalDateTime; /** * 应用信息 * * @author chengzi + * @author Charles7c * @since 2024/10/17 16:03 */ @Data @Schema(description = "应用信息") -public class AppResp extends BaseResp { +public class AppResp extends BaseDetailResp { @Serial private static final long serialVersionUID = 1L; /** - * 应用名称 + * 名称 */ - @Schema(description = "应用名称") + @Schema(description = "名称", example = "应用1") private String name; /** - * APPKEY + * Access Key(访问密钥) */ - @Schema(description = "应用密钥") - private String appKey; - - /** - * 应用状态 - */ - @Schema(description = "应用状态") - private String status; + @Schema(description = "Access Key(访问密钥)", example = "YjUyMGJjYjIxNTE0NDAxMWE1NmRiY2") + private String accessKey; /** * 失效时间 */ - @Schema(description = "失效时间") - private LocalDateTime expirationTime; + @Schema(description = "失效时间", example = "2023-08-08 08:08:08", type = "string") + private LocalDateTime expireTime; /** - * 应用描述 + * 状态 */ - @Schema(description = "应用描述") - private String appDesc; + @Schema(description = "状态", example = "1") + private DisEnableStatusEnum status; + /** + * 描述 + */ + @Schema(description = "描述", example = "应用1描述信息") + private String description; } \ No newline at end of file diff --git a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/resp/AppSecretGetResp.java b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/resp/AppSecretResp.java similarity index 66% rename from continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/resp/AppSecretGetResp.java rename to continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/resp/AppSecretResp.java index cb04f07d..6baff6ca 100644 --- a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/resp/AppSecretGetResp.java +++ b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/model/resp/AppSecretResp.java @@ -20,28 +20,31 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serial; +import java.io.Serializable; /** - * 应用密钥/密码信息 + * 应用密钥信息 * * @author chengzi + * @author Charles7c * @since 2024/10/17 16:03 */ @Data -@Schema(description = "应用密钥/密码信息") -public class AppSecretGetResp { +@Schema(description = "应用密钥信息") +public class AppSecretResp implements Serializable { + @Serial private static final long serialVersionUID = 1L; /** - * 应用密钥 + * Access Key(访问密钥) */ - @Schema(description = "应用密钥") - private String appKey; + @Schema(description = "Access Key(访问密钥)", example = "YjUyMGJjYjIxNTE0NDAxMWE1NmRiY2") + private String accessKey; /** - * 应用密码 + * Secret Key(私有密钥) */ - @Schema(description = "应用密码") - private String appSecret; + @Schema(description = "Secret Key(私有密钥)", example = "") + private String secretKey; } diff --git a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/service/AppService.java b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/service/AppService.java index 7ef07137..7a1e707f 100644 --- a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/service/AppService.java +++ b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/service/AppService.java @@ -16,71 +16,58 @@ package top.continew.admin.open.service; -import top.continew.admin.open.model.resp.AppSecretGetResp; -import top.continew.starter.extension.crud.service.BaseService; import top.continew.admin.open.model.query.AppQuery; import top.continew.admin.open.model.req.AppReq; import top.continew.admin.open.model.resp.AppDetailResp; import top.continew.admin.open.model.resp.AppResp; +import top.continew.admin.open.model.resp.AppSecretResp; +import top.continew.starter.extension.crud.service.BaseService; /** * 应用业务接口 * * @author chengzi + * @author Charles7c * @since 2024/10/17 16:03 */ public interface AppService extends BaseService { - /** - * 根据ID查询应用密码 - * - * @param id ID - * @return 应用密码 - */ - AppSecretGetResp getAppSecretById(Long id); /** - * 根据ID重置应用密码查看状态 + * 获取密钥 + * + * @param id ID + * @return 密钥信息 + */ + AppSecretResp getSecret(Long id); + + /** + * 重置密钥 * * @param id ID */ - void resetAppSecretStatusById(Long id, String status); + void resetSecret(Long id); /** - * 根据应用密钥重置应用密码查看状态 + * 根据 Access Key 获取 Secret Key * - * @param appKey 应用密钥 + * @param accessKey Access Key + * @return Secret Key */ - void resetAppSecretStatusByAppkey(String appKey, String status); + String getSecretKeyByAccessKey(String accessKey); /** - * 根据ID刷新应用密码 + * 判断应用是否存在 * - * @param id ID - */ - void refreshAppSecretByID(Long id); - - /** - * 根据应用密钥获取应用密码 - * - * @param appKey 应用密钥 - * @return 应用密码 - */ - String getAppSecretByAppKey(String appKey); - - /** - * 判断应用密钥是否存在 - * - * @param appKey 应用密钥 + * @param accessKey Access Key * @return 是否存在(true:存在;false:不存在) */ - boolean isExistAppKey(String appKey); + boolean isAppExists(String accessKey); /** * 判断应用密钥是否过期 * - * @param appKey 应用密钥 + * @param accessKey Access Key * @return 是否过期(true:已过期;false:未过期) */ - boolean isExpireAppKey(String appKey); - + boolean isAppSecretExpired(String accessKey); } \ No newline at end of file diff --git a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/service/impl/AppServiceImpl.java b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/service/impl/AppServiceImpl.java index 1a25b16e..f6f60e3f 100644 --- a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/service/impl/AppServiceImpl.java +++ b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/service/impl/AppServiceImpl.java @@ -16,22 +16,22 @@ package top.continew.admin.open.service.impl; +import cn.hutool.core.codec.Base64; import cn.hutool.core.date.DateUtil; -import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.util.IdUtil; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; - import org.springframework.stereotype.Service; - -import top.continew.admin.open.model.resp.AppSecretGetResp; -import top.continew.starter.extension.crud.service.impl.BaseServiceImpl; import top.continew.admin.open.mapper.AppMapper; import top.continew.admin.open.model.entity.AppDO; import top.continew.admin.open.model.query.AppQuery; import top.continew.admin.open.model.req.AppReq; import top.continew.admin.open.model.resp.AppDetailResp; import top.continew.admin.open.model.resp.AppResp; +import top.continew.admin.open.model.resp.AppSecretResp; import top.continew.admin.open.service.AppService; +import top.continew.starter.core.constant.StringConstants; +import top.continew.starter.extension.crud.service.impl.BaseServiceImpl; import java.time.LocalDateTime; @@ -39,64 +39,76 @@ import java.time.LocalDateTime; * 应用业务实现 * * @author chengzi + * @author Charles7c * @since 2024/10/17 16:03 */ @Service @RequiredArgsConstructor public class AppServiceImpl extends BaseServiceImpl implements AppService { - // 已激活 - private final static String APP_ENABLED_KEY = "1"; - // 未激活 - private final static String APP_DISABLED_KEY = "0"; + @Override + public void beforeAdd(AppReq req) { + req.setAccessKey(Base64.encode(IdUtil.fastSimpleUUID()) + .replace(StringConstants.SLASH, StringConstants.EMPTY) + .replace("+", StringConstants.EMPTY) + .substring(0, 30)); + req.setSecretKey(this.generateSecret()); + } @Override - public AppSecretGetResp getAppSecretById(Long id) { - AppDO app = baseMapper.lambdaQuery().eq(AppDO::getId, id).one(); - String appSecret = "********"; - if (app.getSecretStatus().equals(APP_DISABLED_KEY)) { - appSecret = app.getAppSecret(); - this.resetAppSecretStatusById(id, APP_ENABLED_KEY); + public AppSecretResp getSecret(Long id) { + AppDO app = super.getById(id); + AppSecretResp appSecretResp = new AppSecretResp(); + appSecretResp.setAccessKey(app.getAccessKey()); + appSecretResp.setSecretKey(app.getSecretKey()); + return appSecretResp; + } + + @Override + public void resetSecret(Long id) { + super.getById(id); + AppDO app = new AppDO(); + app.setSecretKey(this.generateSecret()); + baseMapper.update(app, Wrappers.lambdaQuery(AppDO.class).eq(AppDO::getId, id)); + } + + @Override + public String getSecretKeyByAccessKey(String accessKey) { + return baseMapper.lambdaQuery() + .select(AppDO::getSecretKey) + .eq(AppDO::getAccessKey, accessKey) + .oneOpt() + .map(AppDO::getSecretKey) + .orElse(null); + } + + @Override + public boolean isAppExists(String accessKey) { + return baseMapper.lambdaQuery().eq(AppDO::getAccessKey, accessKey).exists(); + } + + @Override + public boolean isAppSecretExpired(String accessKey) { + LocalDateTime expireTime = baseMapper.lambdaQuery() + .select(AppDO::getExpireTime) + .eq(AppDO::getAccessKey, accessKey) + .oneOpt() + .map(AppDO::getExpireTime) + .orElse(null); + if (expireTime == null) { + return false; } - AppSecretGetResp appSecretGetResp = new AppSecretGetResp(); - appSecretGetResp.setAppKey(app.getAppKey()); - appSecretGetResp.setAppSecret(appSecret); - return appSecretGetResp; + return expireTime.isBefore(DateUtil.date().toLocalDateTime()); } - @Override - public void resetAppSecretStatusById(Long id, String status) { - baseMapper.lambdaUpdate().set(AppDO::getSecretStatus, status).eq(AppDO::getId, id).update(); - } - - @Override - public void resetAppSecretStatusByAppkey(String appKey, String status) { - baseMapper.lambdaUpdate().set(AppDO::getSecretStatus, status).eq(AppDO::getAppKey, appKey).update(); - } - - @Override - public void refreshAppSecretByID(Long id) { - baseMapper.lambdaUpdate().set(AppDO::getAppSecret, IdUtil.simpleUUID()).eq(AppDO::getId, id).update(); - this.resetAppSecretStatusById(id, APP_DISABLED_KEY); - } - - @Override - public String getAppSecretByAppKey(String appKey) { - return baseMapper.lambdaQuery().select(AppDO::getAppSecret).eq(AppDO::getAppKey, appKey).one().getAppSecret(); - } - - @Override - public boolean isExistAppKey(String appKey) { - return baseMapper.lambdaQuery().eq(AppDO::getAppKey, appKey).exists(); - } - - @Override - public boolean isExpireAppKey(String appKey) { - LocalDateTime expirationTime = baseMapper.lambdaQuery() - .select(AppDO::getExpirationTime) - .eq(AppDO::getAppKey, appKey) - .one() - .getExpirationTime(); - return expirationTime.isBefore(LocalDateTimeUtil.of(DateUtil.date())); + /** + * 生成密钥 + * + * @return 密钥 + */ + private String generateSecret() { + return Base64.encode(IdUtil.fastSimpleUUID()) + .replace(StringConstants.SLASH, StringConstants.EMPTY) + .replace("+", StringConstants.EMPTY); } } \ No newline at end of file diff --git a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/sign/OpenSignTemplate.java b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/sign/OpenSignTemplate.java index ad6984dd..f1e54fa0 100644 --- a/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/sign/OpenSignTemplate.java +++ b/continew-plugin/continew-plugin-open/src/main/java/top/continew/admin/open/sign/OpenSignTemplate.java @@ -28,12 +28,18 @@ import java.util.TreeMap; import static cn.dev33.satoken.SaManager.log; +/** + * API 参数签名算法 + * + * @author chengzi + * @since 2024/10/17 16:03 + */ @Component @RequiredArgsConstructor public class OpenSignTemplate extends SaSignTemplate { private final AppService appService; - public static String appKey = "appkey"; + public static final String ACCESS_KEY = "accessKey"; @Override public void checkParamMap(Map paramMap) { @@ -41,19 +47,19 @@ public class OpenSignTemplate extends SaSignTemplate { String timestampValue = paramMap.get(timestamp); String nonceValue = paramMap.get(nonce); String signValue = paramMap.get(sign); - String appKeyValue = paramMap.get(appKey); + String accessKeyValue = paramMap.get(ACCESS_KEY); // 参数非空校验 SaSignException.notEmpty(timestampValue, "缺少 timestamp 字段"); SaSignException.notEmpty(nonceValue, "缺少 nonce 字段"); SaSignException.notEmpty(signValue, "缺少 sign 字段"); - SaSignException.notEmpty(appKeyValue, "缺少 appkey 字段"); + SaSignException.notEmpty(accessKeyValue, "缺少 accessKey 字段"); // 应用存在性校验 - SaSignException.notTrue(!appService.isExistAppKey(appKeyValue), "应用不存在"); + SaSignException.notTrue(!appService.isAppExists(ACCESS_KEY), "应用不存在"); // 应用是否过期校验 - SaSignException.notTrue(appService.isExpireAppKey(appKeyValue), "应用已过期"); + SaSignException.notTrue(appService.isAppSecretExpired(ACCESS_KEY), "应用已过期"); // 依次校验三个参数 checkTimestamp(Long.parseLong(timestampValue)); @@ -67,7 +73,7 @@ public class OpenSignTemplate extends SaSignTemplate { public String createSign(Map paramsMap) { // 根据应用密钥获取对应的应用密码 String appKey = (String)((Map)paramsMap).get("appkey"); - String secretKey = this.appService.getAppSecretByAppKey(appKey); + String secretKey = this.appService.getSecretKeyByAccessKey(appKey); SaSignException.notEmpty(secretKey, "参与参数签名的秘钥不可为空", SaErrorCode.CODE_12201); // 如果调用者不小心传入了 sign 参数,则此处需要将 sign 参数排除在外 diff --git a/continew-webapi/pom.xml b/continew-webapi/pom.xml index 1677302c..dacd0d13 100644 --- a/continew-webapi/pom.xml +++ b/continew-webapi/pom.xml @@ -41,10 +41,9 @@ top.continew continew-plugin-schedule - ${revision} - + top.continew continew-plugin-open diff --git a/continew-webapi/src/main/java/top/continew/admin/controller/open/AppController.java b/continew-webapi/src/main/java/top/continew/admin/controller/open/AppController.java index 8989f9b9..38d3d150 100644 --- a/continew-webapi/src/main/java/top/continew/admin/controller/open/AppController.java +++ b/continew-webapi/src/main/java/top/continew/admin/controller/open/AppController.java @@ -20,27 +20,27 @@ import cn.dev33.satoken.annotation.SaCheckPermission; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.enums.ParameterIn; -import lombok.RequiredArgsConstructor; -import top.continew.admin.open.model.resp.AppSecretGetResp; -import top.continew.starter.extension.crud.enums.Api; - import io.swagger.v3.oas.annotations.tags.Tag; - -import org.springframework.web.bind.annotation.*; - -import top.continew.starter.extension.crud.annotation.CrudRequestMapping; -import top.continew.starter.extension.crud.controller.BaseController; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; import top.continew.admin.open.model.query.AppQuery; import top.continew.admin.open.model.req.AppReq; import top.continew.admin.open.model.resp.AppDetailResp; import top.continew.admin.open.model.resp.AppResp; +import top.continew.admin.open.model.resp.AppSecretResp; import top.continew.admin.open.service.AppService; -import top.continew.starter.extension.crud.model.resp.BaseIdResp; +import top.continew.starter.extension.crud.annotation.CrudRequestMapping; +import top.continew.starter.extension.crud.controller.BaseController; +import top.continew.starter.extension.crud.enums.Api; /** * 应用管理 API * * @author chengzi + * @author Charles7c * @since 2024/10/17 16:03 */ @Tag(name = "应用管理 API") @@ -49,31 +49,19 @@ import top.continew.starter.extension.crud.model.resp.BaseIdResp; @CrudRequestMapping(value = "/open/app", api = {Api.PAGE, Api.DETAIL, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT}) public class AppController extends BaseController { - private final AppService appService; - private final static String APP_DISABLED_KEY = "0"; - - @Operation(summary = "刷新应用密码", description = "刷新应用密码") - @Parameter(name = "id", description = "ID", example = "test", in = ParameterIn.PATH) - @SaCheckPermission("open:app:refreshas") - @GetMapping(value = "/{id}/refreshas") - public void refreshAppSecret(@PathVariable Long id) { - appService.refreshAppSecretByID(id); + @Operation(summary = "获取密钥", description = "获取应用密钥") + @Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH) + @SaCheckPermission("open:app:secret") + @GetMapping("/{id}/secret") + public AppSecretResp getSecret(@PathVariable Long id) { + return baseService.getSecret(id); } - @Operation(summary = "获取应用密码", description = "获取应用密码") - @Parameter(name = "appKey", description = "应用密钥", example = "test", in = ParameterIn.PATH) - @SaCheckPermission("open:app:getas") - @GetMapping("/{id}/appsecret") - public AppSecretGetResp getAppSecret(@PathVariable Long id) { - return appService.getAppSecretById(id); - } - - @Override - public BaseIdResp add(AppReq req) { - BaseIdResp baseIdResp = super.add(req); - Long appId = baseIdResp.getId(); - appService.refreshAppSecretByID(appId); - appService.resetAppSecretStatusById(appId, APP_DISABLED_KEY); - return baseIdResp; + @Operation(summary = "重置密钥", description = "重置应用密钥") + @Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH) + @SaCheckPermission("open:app:resetSecret") + @PatchMapping("/{id}/secret") + public void resetSecret(@PathVariable Long id) { + baseService.resetSecret(id); } } \ No newline at end of file diff --git a/continew-webapi/src/main/resources/db/changelog/db.changelog-master.yaml b/continew-webapi/src/main/resources/db/changelog/db.changelog-master.yaml index e435bc79..feefa21e 100644 --- a/continew-webapi/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/continew-webapi/src/main/resources/db/changelog/db.changelog-master.yaml @@ -7,8 +7,8 @@ databaseChangeLog: file: db/changelog/mysql/main_data.sql - include: file: db/changelog/mysql/plugin/plugin_schedule.sql -# - include: -# file: db/changelog/mysql/plugin/plugin_open.sql + - include: + file: db/changelog/mysql/plugin/plugin_open.sql - include: file: db/changelog/mysql/plugin/plugin_generator.sql # PostgreSQL diff --git a/continew-webapi/src/main/resources/db/changelog/mysql/plugin/plugin_open.sql b/continew-webapi/src/main/resources/db/changelog/mysql/plugin/plugin_open.sql index 3e4ff198..97831c3c 100644 --- a/continew-webapi/src/main/resources/db/changelog/mysql/plugin/plugin_open.sql +++ b/continew-webapi/src/main/resources/db/changelog/mysql/plugin/plugin_open.sql @@ -4,19 +4,19 @@ -- comment 初始化能力开放插件 -- 初始化表结构 CREATE TABLE IF NOT EXISTS `sys_app` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', - `name` varchar(255) DEFAULT NULL COMMENT '应用名称', - `app_key` varchar(255) DEFAULT NULL COMMENT '应用密钥', - `app_secret` varchar(255) DEFAULT NULL COMMENT '应用密码', - `status` varchar(255) DEFAULT NULL COMMENT '应用状态 (0: 未激活;1: 激活)', - `expiration_time` datetime DEFAULT NULL COMMENT '失效时间', - `app_desc` varchar(255) DEFAULT NULL COMMENT '应用描述', - `secret_status` varchar(255) DEFAULT NULL COMMENT '应用密码查看状态 (0: 未查看;1: 已查看)', - `create_user` bigint(20) NOT NULL COMMENT '创建人', - `create_time` datetime NOT NULL COMMENT '创建时间', - `update_user` bigint(20) DEFAULT NULL COMMENT '修改人', - `update_time` datetime DEFAULT NULL COMMENT '修改时间', + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', + `name` varchar(100) NOT NULL COMMENT '名称', + `access_key` varchar(255) NOT NULL COMMENT 'Access Key(访问密钥)', + `secret_key` varchar(255) NOT NULL COMMENT 'Secret Key(私有密钥)', + `expire_time` datetime DEFAULT NULL COMMENT '失效时间', + `description` varchar(200) DEFAULT NULL COMMENT '描述', + `status` tinyint(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '状态(1:启用;2:禁用)', + `create_user` bigint(20) NOT NULL COMMENT '创建人', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_user` bigint(20) DEFAULT NULL COMMENT '修改人', + `update_time` datetime DEFAULT NULL COMMENT '修改时间', PRIMARY KEY (`id`), + UNIQUE INDEX `uk_access_key`(`access_key`), INDEX `idx_create_user`(`create_user`), INDEX `idx_update_user`(`update_user`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='应用表'; @@ -32,5 +32,6 @@ VALUES (7013, '新增', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:add', 3, 1, 1, NOW(), NULL, NULL), (7014, '修改', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:update', 4, 1, 1, NOW(), NULL, NULL), (7015, '删除', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:delete', 5, 1, 1, NOW(), NULL, NULL), -(7016, '导出', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:export', 6, 1, 1, NOW(), NULL, NULL); - +(7016, '导出', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:export', 6, 1, 1, NOW(), NULL, NULL), +(7017, '查看密钥', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:secret', 7, 1, 1, NOW(), NULL, NULL), +(7018, '重置密钥', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:resetSecret', 8, 1, 1, NOW(), NULL, NULL); diff --git a/continew-webapi/src/main/resources/db/changelog/postgresql/plugin/plugin_open.sql b/continew-webapi/src/main/resources/db/changelog/postgresql/plugin/plugin_open.sql index 97b76a60..d5c4ff7f 100644 --- a/continew-webapi/src/main/resources/db/changelog/postgresql/plugin/plugin_open.sql +++ b/continew-webapi/src/main/resources/db/changelog/postgresql/plugin/plugin_open.sql @@ -4,30 +4,29 @@ -- comment 初始化能力开放插件 -- 初始化表结构 CREATE TABLE IF NOT EXISTS "sys_app" ( - "id" int8 DEFAULT NULL, - "name" varchar(255) DEFAULT NULL, - "app_key" varchar(255) DEFAULT NULL, - "app_secret" varchar(255) DEFAULT NULL, - "status" varchar(255) DEFAULT NULL, - "expiration_time" timestamp DEFAULT NULL, - "app_desc" varchar(255) DEFAULT NULL, - "secret_status" varchar(255) DEFAULT NULL, - "create_user" int8 NOT NULL, - "create_time" timestamp NOT NULL, - "update_user" int8 NOT NULL, - "update_time" timestamp NOT NULL, + "id" int8 NOT NULL, + "name" varchar(100) NOT NULL, + "access_key" varchar(255) NOT NULL, + "secret_key" varchar(255) NOT NULL, + "expire_time" timestamp DEFAULT NULL, + "description" varchar(200) DEFAULT NULL, + "status" int2 NOT NULL DEFAULT 1, + "create_user" int8 NOT NULL, + "create_time" timestamp NOT NULL, + "update_user" int8 DEFAULT NULL, + "update_time" timestamp DEFAULT NULL, PRIMARY KEY ("id") ); +CREATE UNIQUE INDEX "uk_app_access_key" ON "sys_app" ("access_key"); CREATE INDEX "idx_app_create_user" ON "sys_app" ("create_user"); CREATE INDEX "idx_app_update_user" ON "sys_app" ("update_user"); COMMENT ON COLUMN "sys_app"."id" IS 'ID'; COMMENT ON COLUMN "sys_app"."name" IS '名称'; -COMMENT ON COLUMN "sys_app"."app_key" IS '应用密钥'; -COMMENT ON COLUMN "sys_app"."app_secret" IS '应用密码'; -COMMENT ON COLUMN "sys_app"."status" IS '应用状态 (0: 未激活;1: 激活)'; -COMMENT ON COLUMN "sys_app"."expiration_time" IS '失效时间'; -COMMENT ON COLUMN "sys_app"."app_desc" IS '应用描述'; -COMMENT ON COLUMN "sys_app"."secret_status" IS '应用密码查看状态 (0: 未查看;1: 已查看)'; +COMMENT ON COLUMN "sys_app"."access_key" IS 'Access Key(访问密钥)'; +COMMENT ON COLUMN "sys_app"."secret_key" IS 'Secret Key(私有密钥)'; +COMMENT ON COLUMN "sys_app"."expire_time" IS '失效时间'; +COMMENT ON COLUMN "sys_app"."description" IS '描述'; +COMMENT ON COLUMN "sys_app"."status" IS '状态(1:启用;2:禁用)'; COMMENT ON COLUMN "sys_app"."create_user" IS '创建人'; COMMENT ON COLUMN "sys_app"."create_time" IS '创建时间'; COMMENT ON COLUMN "sys_app"."update_user" IS '修改人'; @@ -45,5 +44,6 @@ VALUES (7013, '新增', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:add', 3, 1, 1, NOW(), NULL, NULL), (7014, '修改', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:update', 4, 1, 1, NOW(), NULL, NULL), (7015, '删除', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:delete', 5, 1, 1, NOW(), NULL, NULL), -(7016, '导出', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:export', 6, 1, 1, NOW(), NULL, NULL); - +(7016, '导出', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:export', 6, 1, 1, NOW(), NULL, NULL), +(7017, '查看密钥', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:secret', 7, 1, 1, NOW(), NULL, NULL), +(7018, '重置密钥', 7010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'open:app:resetSecret', 8, 1, 1, NOW(), NULL, NULL);