mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-10-31 10:57:13 +08:00 
			
		
		
		
	refactor: 优化项目模块命名(简化、分类、统一)
This commit is contained in:
		
							
								
								
									
										14
									
								
								continew-plugin/continew-plugin-open/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								continew-plugin/continew-plugin-open/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||||
|          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <parent> | ||||
|         <groupId>top.continew</groupId> | ||||
|         <artifactId>continew-plugin</artifactId> | ||||
|         <version>${revision}</version> | ||||
|     </parent> | ||||
|  | ||||
|     <artifactId>continew-plugin-open</artifactId> | ||||
|     <description>能力开放插件(包括应用管理、API开放授权、API开发等)</description> | ||||
| </project> | ||||
| @@ -0,0 +1,49 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed 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 top.continew.admin.open.handler; | ||||
|  | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import cn.dev33.satoken.annotation.handler.SaAnnotationHandlerInterface; | ||||
| import org.springframework.stereotype.Component; | ||||
| import top.continew.admin.open.util.ApiSignCheckUtils; | ||||
|  | ||||
| import java.lang.reflect.Method; | ||||
|  | ||||
| import static cn.dev33.satoken.annotation.handler.SaCheckPermissionHandler._checkMethod; | ||||
|  | ||||
| /** | ||||
|  * 重定义注解 SaCheckPermission 的处理器 | ||||
|  * | ||||
|  * @author chengzi | ||||
|  * @since 2024/10/25 12:03 | ||||
|  */ | ||||
| @Component | ||||
| public class SaCheckPermissionHandler implements SaAnnotationHandlerInterface<SaCheckPermission> { | ||||
|  | ||||
|     @Override | ||||
|     public Class<SaCheckPermission> getHandlerAnnotationClass() { | ||||
|         return SaCheckPermission.class; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void checkMethod(SaCheckPermission at, Method method) { | ||||
|         if (!ApiSignCheckUtils.isExistSignParam()) { | ||||
|             _checkMethod(at.type(), at.value(), at.mode(), at.orRole()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,28 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed 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 top.continew.admin.open.mapper; | ||||
|  | ||||
| import top.continew.starter.data.mp.base.BaseMapper; | ||||
| import top.continew.admin.open.model.entity.AppDO; | ||||
|  | ||||
| /** | ||||
|  * 应用 Mapper | ||||
|  * | ||||
|  * @author chengzi | ||||
|  * @since 2024/10/17 16:03 | ||||
|  */ | ||||
| public interface AppMapper extends BaseMapper<AppDO> {} | ||||
| @@ -0,0 +1,80 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed 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 top.continew.admin.open.model.entity; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.time.*; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
|  | ||||
| import top.continew.starter.extension.crud.model.entity.BaseDO; | ||||
|  | ||||
| /** | ||||
|  * 应用实体 | ||||
|  * | ||||
|  * @author chengzi | ||||
|  * @since 2024/10/17 16:03 | ||||
|  */ | ||||
| @Data | ||||
| @TableName("sys_app") | ||||
| public class AppDO extends BaseDO { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * ID | ||||
|      */ | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 应用名称 | ||||
|      */ | ||||
|     private String name; | ||||
|  | ||||
|     /** | ||||
|      * APPKEY | ||||
|      */ | ||||
|     private String appKey; | ||||
|  | ||||
|     /** | ||||
|      * APPSECRET | ||||
|      */ | ||||
|     private String appSecret; | ||||
|  | ||||
|     /** | ||||
|      * 应用状态 | ||||
|      */ | ||||
|     private String status; | ||||
|  | ||||
|     /** | ||||
|      * 失效时间 | ||||
|      */ | ||||
|     private LocalDateTime expirationTime; | ||||
|  | ||||
|     /** | ||||
|      * 应用描述 | ||||
|      */ | ||||
|     private String appDesc; | ||||
|  | ||||
|     /** | ||||
|      * secret查看状态 | ||||
|      */ | ||||
|     private String secretStatus; | ||||
| } | ||||
| @@ -0,0 +1,55 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed 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 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 top.continew.starter.data.core.annotation.Query; | ||||
| import top.continew.starter.data.core.enums.QueryType; | ||||
|  | ||||
| /** | ||||
|  * 应用查询条件 | ||||
|  * | ||||
|  * @author chengzi | ||||
|  * @since 2024/10/17 16:03 | ||||
|  */ | ||||
| @Data | ||||
| @Schema(description = "应用查询条件") | ||||
| public class AppQuery implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     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; | ||||
| } | ||||
| @@ -0,0 +1,82 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed 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 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 org.hibernate.validator.constraints.Length; | ||||
|  | ||||
| import top.continew.starter.extension.crud.model.req.BaseReq; | ||||
|  | ||||
| /** | ||||
|  * 创建或修改应用信息 | ||||
|  * | ||||
|  * @author chengzi | ||||
|  * @since 2024/10/17 16:03 | ||||
|  */ | ||||
| @Data | ||||
| @Schema(description = "创建或修改应用信息") | ||||
| public class AppReq extends BaseReq { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 应用名称 | ||||
|      */ | ||||
|     @Schema(description = "应用名称") | ||||
|     @NotBlank(message = "应用名称不能为空") | ||||
|     @Length(max = 255, 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 = "应用描述") | ||||
|     @Length(max = 255, message = "应用描述长度不能超过 {max} 个字符") | ||||
|     private String appDesc; | ||||
| } | ||||
| @@ -0,0 +1,79 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed 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 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 top.continew.starter.extension.crud.model.resp.BaseDetailResp; | ||||
|  | ||||
| /** | ||||
|  * 应用详情信息 | ||||
|  * | ||||
|  * @author chengzi | ||||
|  * @since 2024/10/17 16:03 | ||||
|  */ | ||||
| @Data | ||||
| @ExcelIgnoreUnannotated | ||||
| @Schema(description = "应用详情信息") | ||||
| public class AppDetailResp extends BaseDetailResp { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 应用名称 | ||||
|      */ | ||||
|     @Schema(description = "应用名称") | ||||
|     @ExcelProperty(value = "应用名称") | ||||
|     private String name; | ||||
|  | ||||
|     /** | ||||
|      * 应用密钥 | ||||
|      */ | ||||
|     @Schema(description = "应用密钥") | ||||
|     @ExcelProperty(value = "应用密钥") | ||||
|     private String appKey; | ||||
|  | ||||
|     /** | ||||
|      * 应用状态 | ||||
|      */ | ||||
|     @Schema(description = "应用状态") | ||||
|     @ExcelProperty(value = "应用状态") | ||||
|     private String status; | ||||
|  | ||||
|     /** | ||||
|      * 失效时间 | ||||
|      */ | ||||
|     @Schema(description = "失效时间") | ||||
|     @ExcelProperty(value = "失效时间") | ||||
|     private LocalDateTime expirationTime; | ||||
|  | ||||
|     /** | ||||
|      * 应用描述 | ||||
|      */ | ||||
|     @Schema(description = "应用描述") | ||||
|     @ExcelProperty(value = "应用描述") | ||||
|     private String appDesc; | ||||
| } | ||||
| @@ -0,0 +1,71 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed 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 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 top.continew.starter.extension.crud.model.resp.BaseResp; | ||||
|  | ||||
| /** | ||||
|  * 应用信息 | ||||
|  * | ||||
|  * @author chengzi | ||||
|  * @since 2024/10/17 16:03 | ||||
|  */ | ||||
| @Data | ||||
| @Schema(description = "应用信息") | ||||
| public class AppResp extends BaseResp { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 应用名称 | ||||
|      */ | ||||
|     @Schema(description = "应用名称") | ||||
|     private String name; | ||||
|  | ||||
|     /** | ||||
|      * APPKEY | ||||
|      */ | ||||
|     @Schema(description = "应用密钥") | ||||
|     private String appKey; | ||||
|  | ||||
|     /** | ||||
|      * 应用状态 | ||||
|      */ | ||||
|     @Schema(description = "应用状态") | ||||
|     private String status; | ||||
|  | ||||
|     /** | ||||
|      * 失效时间 | ||||
|      */ | ||||
|     @Schema(description = "失效时间") | ||||
|     private LocalDateTime expirationTime; | ||||
|  | ||||
|     /** | ||||
|      * 应用描述 | ||||
|      */ | ||||
|     @Schema(description = "应用描述") | ||||
|     private String appDesc; | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,47 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed 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 top.continew.admin.open.model.resp; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.io.Serial; | ||||
|  | ||||
| /** | ||||
|  * 应用密钥/密码信息 | ||||
|  * | ||||
|  * @author chengzi | ||||
|  * @since 2024/10/17 16:03 | ||||
|  */ | ||||
| @Data | ||||
| @Schema(description = "应用密钥/密码信息") | ||||
| public class AppSecretGetResp { | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 应用密钥 | ||||
|      */ | ||||
|     @Schema(description = "应用密钥") | ||||
|     private String appKey; | ||||
|  | ||||
|     /** | ||||
|      * 应用密码 | ||||
|      */ | ||||
|     @Schema(description = "应用密码") | ||||
|     private String appSecret; | ||||
| } | ||||
| @@ -0,0 +1,86 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed 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 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; | ||||
|  | ||||
| /** | ||||
|  * 应用业务接口 | ||||
|  * | ||||
|  * @author chengzi | ||||
|  * @since 2024/10/17 16:03 | ||||
|  */ | ||||
| public interface AppService extends BaseService<AppResp, AppDetailResp, AppQuery, AppReq> { | ||||
|     /** | ||||
|      * 根据ID查询应用密码 | ||||
|      * | ||||
|      * @param id ID | ||||
|      * @return 应用密码 | ||||
|      */ | ||||
|     AppSecretGetResp getAppSecretById(Long id); | ||||
|  | ||||
|     /** | ||||
|      * 根据ID重置应用密码查看状态 | ||||
|      * | ||||
|      * @param id ID | ||||
|      */ | ||||
|     void resetAppSecretStatusById(Long id, String status); | ||||
|  | ||||
|     /** | ||||
|      * 根据应用密钥重置应用密码查看状态 | ||||
|      * | ||||
|      * @param appKey 应用密钥 | ||||
|      */ | ||||
|     void resetAppSecretStatusByAppkey(String appKey, String status); | ||||
|  | ||||
|     /** | ||||
|      * 根据ID刷新应用密码 | ||||
|      * | ||||
|      * @param id ID | ||||
|      */ | ||||
|     void refreshAppSecretByID(Long id); | ||||
|  | ||||
|     /** | ||||
|      * 根据应用密钥获取应用密码 | ||||
|      * | ||||
|      * @param appKey 应用密钥 | ||||
|      * @return 应用密码 | ||||
|      */ | ||||
|     String getAppSecretByAppKey(String appKey); | ||||
|  | ||||
|     /** | ||||
|      * 判断应用密钥是否存在 | ||||
|      * | ||||
|      * @param appKey 应用密钥 | ||||
|      * @return 是否存在(true:存在;false:不存在) | ||||
|      */ | ||||
|     boolean isExistAppKey(String appKey); | ||||
|  | ||||
|     /** | ||||
|      * 判断应用密钥是否过期 | ||||
|      * | ||||
|      * @param appKey 应用密钥 | ||||
|      * @return 是否过期(true:已过期;false:未过期) | ||||
|      */ | ||||
|     boolean isExpireAppKey(String appKey); | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,102 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed 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 top.continew.admin.open.service.impl; | ||||
|  | ||||
| import cn.hutool.core.date.DateUtil; | ||||
| import cn.hutool.core.date.LocalDateTimeUtil; | ||||
| import cn.hutool.core.util.IdUtil; | ||||
| 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.service.AppService; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
|  | ||||
| /** | ||||
|  * 应用业务实现 | ||||
|  * | ||||
|  * @author chengzi | ||||
|  * @since 2024/10/17 16:03 | ||||
|  */ | ||||
| @Service | ||||
| @RequiredArgsConstructor | ||||
| public class AppServiceImpl extends BaseServiceImpl<AppMapper, AppDO, AppResp, AppDetailResp, AppQuery, AppReq> implements AppService { | ||||
|  | ||||
|     // 已激活 | ||||
|     private final static String APP_ENABLED_KEY = "1"; | ||||
|     // 未激活 | ||||
|     private final static String APP_DISABLED_KEY = "0"; | ||||
|  | ||||
|     @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); | ||||
|         } | ||||
|         AppSecretGetResp appSecretGetResp = new AppSecretGetResp(); | ||||
|         appSecretGetResp.setAppKey(app.getAppKey()); | ||||
|         appSecretGetResp.setAppSecret(appSecret); | ||||
|         return appSecretGetResp; | ||||
|     } | ||||
|  | ||||
|     @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())); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,92 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed 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 top.continew.admin.open.sign; | ||||
|  | ||||
| import cn.dev33.satoken.error.SaErrorCode; | ||||
| import cn.dev33.satoken.exception.SaSignException; | ||||
| import cn.dev33.satoken.sign.SaSignTemplate; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.springframework.stereotype.Component; | ||||
| import top.continew.admin.open.service.AppService; | ||||
|  | ||||
| import java.util.Map; | ||||
| import java.util.TreeMap; | ||||
|  | ||||
| import static cn.dev33.satoken.SaManager.log; | ||||
|  | ||||
| @Component | ||||
| @RequiredArgsConstructor | ||||
| public class OpenSignTemplate extends SaSignTemplate { | ||||
|  | ||||
|     private final AppService appService; | ||||
|     public static String appKey = "appkey"; | ||||
|  | ||||
|     @Override | ||||
|     public void checkParamMap(Map<String, String> paramMap) { | ||||
|         // 获取必须的参数 | ||||
|         String timestampValue = paramMap.get(timestamp); | ||||
|         String nonceValue = paramMap.get(nonce); | ||||
|         String signValue = paramMap.get(sign); | ||||
|         String appKeyValue = paramMap.get(appKey); | ||||
|  | ||||
|         // 参数非空校验 | ||||
|         SaSignException.notEmpty(timestampValue, "缺少 timestamp 字段"); | ||||
|         SaSignException.notEmpty(nonceValue, "缺少 nonce 字段"); | ||||
|         SaSignException.notEmpty(signValue, "缺少 sign 字段"); | ||||
|         SaSignException.notEmpty(appKeyValue, "缺少 appkey 字段"); | ||||
|  | ||||
|         // 应用存在性校验 | ||||
|         SaSignException.notTrue(!appService.isExistAppKey(appKeyValue), "应用不存在"); | ||||
|  | ||||
|         // 应用是否过期校验 | ||||
|         SaSignException.notTrue(appService.isExpireAppKey(appKeyValue), "应用已过期"); | ||||
|  | ||||
|         // 依次校验三个参数 | ||||
|         checkTimestamp(Long.parseLong(timestampValue)); | ||||
|         checkNonce(nonceValue); | ||||
|         checkSign(paramMap, signValue); | ||||
|  | ||||
|         // 通过 √ | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String createSign(Map<String, ?> paramsMap) { | ||||
|         // 根据应用密钥获取对应的应用密码 | ||||
|         String appKey = (String)((Map)paramsMap).get("appkey"); | ||||
|         String secretKey = this.appService.getAppSecretByAppKey(appKey); | ||||
|         SaSignException.notEmpty(secretKey, "参与参数签名的秘钥不可为空", SaErrorCode.CODE_12201); | ||||
|  | ||||
|         // 如果调用者不小心传入了 sign 参数,则此处需要将 sign 参数排除在外 | ||||
|         if (paramsMap.containsKey(sign)) { | ||||
|             // 为了保证不影响原有的 paramsMap,此处需要再复制一份 | ||||
|             paramsMap = new TreeMap<>(paramsMap); | ||||
|             paramsMap.remove(sign); | ||||
|         } | ||||
|  | ||||
|         // 计算签名 | ||||
|         String paramsStr = joinParamsDictSort(paramsMap); | ||||
|         String fullStr = paramsStr + "&" + key + "=" + secretKey; | ||||
|         String signStr = abstractStr(fullStr); | ||||
|  | ||||
|         // 输入日志,方便调试 | ||||
|         log.debug("fullStr:{}", fullStr); | ||||
|         log.debug("signStr:{}", signStr); | ||||
|  | ||||
|         // 返回 | ||||
|         return signStr; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,46 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * | ||||
|  * Licensed 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 top.continew.admin.open.util; | ||||
|  | ||||
| import cn.dev33.satoken.context.SaHolder; | ||||
| import cn.dev33.satoken.context.model.SaRequest; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * API签名验证工具类 | ||||
|  * | ||||
|  * @author chengzi | ||||
|  * @since 2024/10/25 15:31 | ||||
|  */ | ||||
| public class ApiSignCheckUtils { | ||||
|  | ||||
|     private ApiSignCheckUtils() { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 判断请求是否包含sign参数 | ||||
|      * | ||||
|      * @return 是否包含sign参数(true:包含;false:不包含) | ||||
|      */ | ||||
|     public static boolean isExistSignParam() { | ||||
|         SaRequest saRequest = SaHolder.getRequest(); | ||||
|         List<String> paramNames = saRequest.getParamNames(); | ||||
|         return paramNames.stream().anyMatch(paramName -> paramName.equals("sign")); | ||||
|     } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user