diff --git a/chsm-common/src/main/java/com/sunyard/chsm/enums/Padding.java b/chsm-common/src/main/java/com/sunyard/chsm/enums/Padding.java index b5788fd..d699421 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/enums/Padding.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/enums/Padding.java @@ -8,15 +8,16 @@ import java.util.Objects; /** * 数据的填充模式 + * * @author Cheney */ @Getter @AllArgsConstructor public enum Padding { NOPadding("NoPadding", "NoPadding"), - PCKS5Padding( "PKCS5Padding", "PKCS5Padding"), - PCKS7Padding( "PKCS7Padding", "PKCS7Padding"), - ; + PCKS5Padding("PKCS5Padding", "PKCS5Padding"), + PCKS7Padding("PKCS7Padding", "PKCS7Padding"), + ; private final String code; private final String desc; diff --git a/chsm-common/src/main/java/com/sunyard/chsm/service/KeyInfoService.java b/chsm-common/src/main/java/com/sunyard/chsm/service/KeyInfoService.java index 9fcbd40..9af08ff 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/service/KeyInfoService.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/service/KeyInfoService.java @@ -14,6 +14,8 @@ public interface KeyInfoService { Page selectPageList(KeyInfoDTO.Query query); + KeyInfoDTO.KeyView selectById(Long id); + Long save(KeyInfoDTO.KeySave save); void update(KeyInfoDTO.KeyUpdate update); diff --git a/chsm-common/src/main/java/com/sunyard/chsm/service/impl/KeyInfoServiceImpl.java b/chsm-common/src/main/java/com/sunyard/chsm/service/impl/KeyInfoServiceImpl.java index 27675c3..e8930d9 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/service/impl/KeyInfoServiceImpl.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/service/impl/KeyInfoServiceImpl.java @@ -158,6 +158,35 @@ public class KeyInfoServiceImpl implements KeyInfoService { return new Page(page.getCurrent(), page.getSize(), page.getTotal()).setRecords(viewList); } + @Override + public KeyInfoDTO.KeyView selectById(Long id) { + KeyInfo keyInfo = keyInfoMapper.selectById(id); + Assert.notNull(keyInfo, "密钥ID不存在"); + LocalDateTime now = LocalDateTime.now(); + KeyInfoDTO.KeyView view = new KeyInfoDTO.KeyView(); + BeanUtils.copyProperties(keyInfo, view); + Optional.of(keyInfo.getKeyType()).map(KeyCategory::of).map(KeyCategory::getDesc).ifPresent(view::setKeyTypeText); + Map usageMap = KeyUsage.getUsage(keyInfo.getKeyUsage()) + .stream() + .collect(Collectors.toMap(KeyUsage::getCode, KeyUsage::getDesc)); + view.setKeyUsages(new ArrayList<>(usageMap.keySet())); + view.setKeyUsageText(String.join(",", usageMap.values())); + KeyStatus keyStatus = KeyStatus.of(keyInfo.getStatus()); + if (KeyStatus.ENABLED == keyStatus) { + if (now.isBefore(keyInfo.getEffectiveTime())) { + view.setStatus(KeyStatus.WAIT_ENABLED.getCode()); + view.setStatusText(KeyStatus.WAIT_ENABLED.getDesc()); + } else if (now.isAfter(keyInfo.getExpiredTime())) { + view.setStatus(KeyStatus.EXPIRED.getCode()); + view.setStatusText(KeyStatus.EXPIRED.getDesc()); + } + } + if (ObjectUtils.isEmpty(view.getStatusText())) { + view.setStatusText(keyStatus.getDesc()); + } + return view; + } + @Override public Long save(KeyInfoDTO.KeySave save) { @@ -218,7 +247,7 @@ public class KeyInfoServiceImpl implements KeyInfoService { List keyInfos = keyInfoMapper.selectBatchIds(ids); if (CollectionUtils.isEmpty(keyInfos)) { - log.warn("enableKey no exist key with ids: {}", ids.stream().map(String::valueOf).collect(Collectors.joining(","))); + log.warn("updateKey no exist key with ids: {}", ids.stream().map(String::valueOf).collect(Collectors.joining(","))); return; } List unNormalCodes = keyInfos.stream() diff --git a/chsm-params/src/main/java/com/sunyard/chsm/param/KeyCreateReq.java b/chsm-params/src/main/java/com/sunyard/chsm/param/KeyCreateReq.java new file mode 100644 index 0000000..b5dd112 --- /dev/null +++ b/chsm-params/src/main/java/com/sunyard/chsm/param/KeyCreateReq.java @@ -0,0 +1,26 @@ +package com.sunyard.chsm.param; + +import lombok.Data; + +import javax.validation.constraints.Max; +import javax.validation.constraints.NotNull; + +/** + * @author liulu + * @since 2024/12/17 + */ +@Data +public class KeyCreateReq { + + /** + * 密钥模版编码 + */ + @NotNull(message = "密钥模版不能为空") + private String keyTemplateCode; + /** + * 生成数量 + */ + @NotNull(message = "生成数量不能为空") + @Max(value = 100, message = "一次最多生成100个密钥") + private Integer genNumber; +} diff --git a/chsm-params/src/main/java/com/sunyard/chsm/param/KeyInfoQuery.java b/chsm-params/src/main/java/com/sunyard/chsm/param/KeyInfoQuery.java new file mode 100644 index 0000000..1a47074 --- /dev/null +++ b/chsm-params/src/main/java/com/sunyard/chsm/param/KeyInfoQuery.java @@ -0,0 +1,30 @@ +package com.sunyard.chsm.param; + +import lombok.Data; + +/** + * @author liulu + * @since 2024/12/17 + */ +@Data +public class KeyInfoQuery { + + /** + * 当前页 + */ + private int pageNumber = 1; + /** + * 每页大小 + */ + private int pageSize = 10; + /** + * 密钥状态 + */ + private String status; + /** + * 密钥类型: sym_key 对称密钥, asym_key 非对称密钥 + */ + private String keyType; + + +} diff --git a/chsm-params/src/main/java/com/sunyard/chsm/param/KeyInfoResp.java b/chsm-params/src/main/java/com/sunyard/chsm/param/KeyInfoResp.java new file mode 100644 index 0000000..c33f54d --- /dev/null +++ b/chsm-params/src/main/java/com/sunyard/chsm/param/KeyInfoResp.java @@ -0,0 +1,56 @@ +package com.sunyard.chsm.param; + +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * @author liulu + * @since 2024/12/17 + */ +@Data +public class KeyInfoResp { + + /** + * 密钥ID + */ + private String KeyId; + /** + * 密钥算法 + */ + private String keyAlg; + /** + * 密钥类型 + */ + private String keyType; + private String keyTypeText; + /** + * 密钥用途 + */ + private List keyUsages; + private String keyUsageText; + /** + * 校验算法 + */ + private String checkAlg; + /** + * 校验值 + */ + private String checkValue; + /** + * 密钥状态 + */ + private String status; + private String statusText; + /** + * 生效时间 + */ + private LocalDateTime effectiveTime; + /** + * 过期时间 + */ + private LocalDateTime expiredTime; + private LocalDateTime createTime; + +} diff --git a/chsm-params/src/main/java/com/sunyard/chsm/param/KeyManageReq.java b/chsm-params/src/main/java/com/sunyard/chsm/param/KeyManageReq.java new file mode 100644 index 0000000..c3f0f36 --- /dev/null +++ b/chsm-params/src/main/java/com/sunyard/chsm/param/KeyManageReq.java @@ -0,0 +1,22 @@ +package com.sunyard.chsm.param; + +import lombok.Data; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @author liulu + * @since 2024/12/17 + */ +@Data +public class KeyManageReq { + + /** + * 密钥id列表 + */ + @Size(min = 1, max = 100, message = "密钥id列表长度在1-100之间") + @NotNull(message = "密钥id列表不能为空") + private List ids; +} diff --git a/chsm-params/src/main/java/com/sunyard/chsm/param/KeyUpdateReq.java b/chsm-params/src/main/java/com/sunyard/chsm/param/KeyUpdateReq.java new file mode 100644 index 0000000..ddc169b --- /dev/null +++ b/chsm-params/src/main/java/com/sunyard/chsm/param/KeyUpdateReq.java @@ -0,0 +1,28 @@ +package com.sunyard.chsm.param; + +import lombok.Data; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.time.LocalDate; +import java.util.List; + +/** + * @author liulu + * @since 2024/12/17 + */ +@Data +public class KeyUpdateReq { + + /** + * 密钥id列表 + */ + @Size(min = 1, max = 100, message = "密钥id列表长度在1-100之间") + @NotNull(message = "密钥id列表不能为空") + private List ids; + + /** + * 新密钥生效时间 yyyy-MM-dd + */ + private LocalDate effectiveTime; +} diff --git a/chsm-web-manage/src/main/java/com/sunyard/config/WebConfig.java b/chsm-web-manage/src/main/java/com/sunyard/config/WebConfig.java index f9d7cf3..0b0cd16 100644 --- a/chsm-web-manage/src/main/java/com/sunyard/config/WebConfig.java +++ b/chsm-web-manage/src/main/java/com/sunyard/config/WebConfig.java @@ -1,7 +1,6 @@ package com.sunyard.config; import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; @@ -62,7 +61,6 @@ public class WebConfig { javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateFormat.DATE)); javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateFormat.DATE_TIME)); builder.modules(javaTimeModule); - builder.serializerByType(Long.class, ToStringSerializer.instance); builder.serializationInclusion(JsonInclude.Include.NON_NULL); builder.failOnUnknownProperties(false); }; diff --git a/chsm-web-server/pom.xml b/chsm-web-server/pom.xml index 749e3c6..cf45222 100644 --- a/chsm-web-server/pom.xml +++ b/chsm-web-server/pom.xml @@ -19,21 +19,6 @@ - - - - org.junit.jupiter - junit-jupiter-api - 5.8.0 - test - - - - org.springframework.boot - spring-boot-starter-test - test - - com.sunyard.chsm chsm-common @@ -54,6 +39,13 @@ io.jsonwebtoken jjwt + + + + org.springframework.boot + spring-boot-starter-test + test + diff --git a/chsm-web-server/src/main/java/com/sunyard/chsm/auth/UserContext.java b/chsm-web-server/src/main/java/com/sunyard/chsm/auth/UserContext.java index 660ed2d..44ef003 100644 --- a/chsm-web-server/src/main/java/com/sunyard/chsm/auth/UserContext.java +++ b/chsm-web-server/src/main/java/com/sunyard/chsm/auth/UserContext.java @@ -17,5 +17,9 @@ public class UserContext { return (AppUser) requestAttributes.getAttribute(ATTRIBUTE_APP_USER, RequestAttributes.SCOPE_REQUEST); } + public static Long getCurrentAppId() { + return getCurrentUser().getAppId(); + } + } diff --git a/chsm-web-server/src/main/java/com/sunyard/chsm/controller/KeyManageController.java b/chsm-web-server/src/main/java/com/sunyard/chsm/controller/KeyManageController.java index 6c8d6aa..dbc44ea 100644 --- a/chsm-web-server/src/main/java/com/sunyard/chsm/controller/KeyManageController.java +++ b/chsm-web-server/src/main/java/com/sunyard/chsm/controller/KeyManageController.java @@ -1,17 +1,23 @@ package com.sunyard.chsm.controller; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.sunyard.chsm.auth.AuthCode; import com.sunyard.chsm.constant.AuthCodeConst; import com.sunyard.chsm.model.R; -import com.sunyard.chsm.model.dto.KeyInfoDTO; -import com.sunyard.chsm.service.KeyInfoService; -import org.springframework.validation.annotation.Validated; +import com.sunyard.chsm.param.KeyCreateReq; +import com.sunyard.chsm.param.KeyInfoQuery; +import com.sunyard.chsm.param.KeyInfoResp; +import com.sunyard.chsm.param.KeyManageReq; +import com.sunyard.chsm.param.KeyUpdateReq; +import com.sunyard.chsm.service.KeyManageService; +import org.springframework.util.Assert; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import javax.validation.Valid; /** * 密钥管理类接口 @@ -20,22 +26,106 @@ import javax.annotation.Resource; * @since 2024/12/6 */ @RestController -@RequestMapping("/key/manage") +@RequestMapping("/key") public class KeyManageController { @Resource - private KeyInfoService keyInfoService; + private KeyManageService keyManageService; + + /** + * 查询密钥列表 + * + * @param query 查询条件 + * @return 分页列表 + */ + @PostMapping("/pageList") + public R> queryPageList(@RequestBody KeyInfoQuery query) { + Page page = keyManageService.queryPageList(query); + return R.data(page); + } + + /** + * 查询密钥详情 + * + * @param id 查询条件 + * @return 分页列表 + */ + @PostMapping("/info") + public R queryInfo(Long id) { + Assert.notNull(id, "密钥id不能为空"); + KeyInfoResp resp = keyManageService.queryInfo(id); + return R.data(resp); + } + + /** + * 创建密钥 + * + * @return id + */ + @PostMapping("/gen") + public R save(@Valid @RequestBody KeyCreateReq req) { + Long id = keyManageService.create(req); + return R.data(id); + } + + /** + * 更新密钥 + * + * @param req 参数 + * @return id + */ + @PostMapping("/update") + public R update(@Valid @RequestBody KeyUpdateReq req) { + keyManageService.update(req); + return R.ok(); + } /** * 启用密钥 * - * @param param 密钥id + * @param req 密钥ids * @return id */ @PostMapping("/enable") @AuthCode(AuthCodeConst.key_enable) - public R enableKey(@Validated @RequestBody KeyInfoDTO.IDs param) { - keyInfoService.enableKey(param.getIds()); + public R enableKey(@Valid @RequestBody KeyManageReq req) { + keyManageService.enableKey(req.getIds()); + return R.ok(); + } + + /** + * 停用密钥 + * + * @param req 密钥id + * @return id + */ + @PostMapping("/disable") + public R disableKey(@Valid @RequestBody KeyManageReq req) { + keyManageService.disableKey(req.getIds()); + return R.ok(); + } + + /** + * 归档密钥 + * + * @param req 密钥id + * @return id + */ + @PostMapping("/archive") + public R archiveKey(@Valid @RequestBody KeyManageReq req) { + keyManageService.archiveKey(req.getIds()); + return R.ok(); + } + + /** + * 销毁密钥 + * + * @param req 密钥id + * @return id + */ + @PostMapping("/destroy") + public R destroyKey(@Valid @RequestBody KeyManageReq req) { + keyManageService.destroyKey(req.getIds()); return R.ok(); } diff --git a/chsm-web-server/src/main/java/com/sunyard/chsm/service/KeyManageService.java b/chsm-web-server/src/main/java/com/sunyard/chsm/service/KeyManageService.java index bf59fe2..4373756 100644 --- a/chsm-web-server/src/main/java/com/sunyard/chsm/service/KeyManageService.java +++ b/chsm-web-server/src/main/java/com/sunyard/chsm/service/KeyManageService.java @@ -1,8 +1,121 @@ package com.sunyard.chsm.service; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.sunyard.chsm.auth.AppUser; +import com.sunyard.chsm.auth.UserContext; +import com.sunyard.chsm.mapper.KeyInfoMapper; +import com.sunyard.chsm.model.dto.KeyInfoDTO; +import com.sunyard.chsm.model.entity.KeyInfo; +import com.sunyard.chsm.param.KeyCreateReq; +import com.sunyard.chsm.param.KeyInfoQuery; +import com.sunyard.chsm.param.KeyInfoResp; +import com.sunyard.chsm.param.KeyUpdateReq; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import javax.annotation.Resource; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + /** * @author liulu * @since 2024/12/16 */ -public interface KeyManageService { +@Slf4j +@Service +@Transactional +public class KeyManageService { + + @Resource + private KeyInfoMapper keyInfoMapper; + @Resource + private KeyInfoService keyInfoService; + + public Page queryPageList(KeyInfoQuery query) { + KeyInfoDTO.Query nq = new KeyInfoDTO.Query(); + BeanUtils.copyProperties(query, nq); + nq.setAppId(UserContext.getCurrentAppId()); + Page page = keyInfoService.selectPageList(nq); + List records = page.getRecords(); + if (CollectionUtils.isEmpty(records)) { + return new Page<>(page.getCurrent(), page.getSize(), page.getTotal()); + } + List viewList = records.stream() + .map(it -> { + KeyInfoResp resp = new KeyInfoResp(); + BeanUtils.copyProperties(it, resp); + resp.setKeyId(it.getCode()); + return resp; + }) + .collect(Collectors.toList()); + + return new Page(page.getCurrent(), page.getSize(), page.getTotal()).setRecords(viewList); + } + + public KeyInfoResp queryInfo(Long id) { + checkIds(Collections.singletonList(id)); + KeyInfoDTO.KeyView view = keyInfoService.selectById(id); + KeyInfoResp resp = new KeyInfoResp(); + BeanUtils.copyProperties(view, resp); + resp.setKeyId(view.getCode()); + return resp; + } + + public Long create(KeyCreateReq req) { + KeyInfoDTO.KeySave save = new KeyInfoDTO.KeySave(); + save.setApplicationId(UserContext.getCurrentAppId()); + save.setKeyTemplateCode(req.getKeyTemplateCode()); + save.setGenNumber(req.getGenNumber()); + return keyInfoService.save(save); + } + + + public void update(KeyUpdateReq req) { + Assert.notNull(req.getEffectiveTime(), "新密钥生效时间不能为空"); + checkIds(req.getIds()); + KeyInfoDTO.KeyUpdate update = new KeyInfoDTO.KeyUpdate(); + update.setIds(req.getIds()); + update.setEffectiveTime(req.getEffectiveTime()); + keyInfoService.update(update); + } + + public void enableKey(List ids) { + checkIds(ids); + keyInfoService.enableKey(ids); + } + + public void disableKey(List ids) { + checkIds(ids); + keyInfoService.disableKey(ids); + } + + public void archiveKey(List ids) { + checkIds(ids); + keyInfoService.archiveKey(ids); + } + + public void destroyKey(List ids) { + checkIds(ids); + keyInfoService.destroyKey(ids); + } + + + private void checkIds(List ids) { + AppUser appUser = UserContext.getCurrentUser(); + List keyInfos = keyInfoMapper.selectBatchIds(ids); + Assert.notEmpty(keyInfos, "密钥ID不正确"); + String msg = keyInfos.stream() + .filter(it -> !Objects.equals(it.getApplicationId(), appUser.getAppId())) + .map(KeyInfo::getCode) + .collect(Collectors.joining(", ")); + Assert.isTrue(ObjectUtils.isEmpty(msg), "密钥ID:" + msg + "不属于当前应用, 无权操作"); + } + } diff --git a/chsm-web-server/src/main/java/com/sunyard/chsm/service/impl/KeyManageServiceImpl.java b/chsm-web-server/src/main/java/com/sunyard/chsm/service/impl/KeyManageServiceImpl.java deleted file mode 100644 index e7ff757..0000000 --- a/chsm-web-server/src/main/java/com/sunyard/chsm/service/impl/KeyManageServiceImpl.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.sunyard.chsm.service.impl; - -import com.sunyard.chsm.service.KeyManageService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * @author liulu - * @since 2024/12/16 - */ -@Slf4j -@Service -@Transactional -public class KeyManageServiceImpl implements KeyManageService { -} diff --git a/chsm-web-server/src/test/java/com/sunyard/chsm/sdf/SdfApiAdapterTest.java b/chsm-web-server/src/test/java/sdf/SdfApiAdapterTest.java similarity index 99% rename from chsm-web-server/src/test/java/com/sunyard/chsm/sdf/SdfApiAdapterTest.java rename to chsm-web-server/src/test/java/sdf/SdfApiAdapterTest.java index 51c385c..72179fa 100644 --- a/chsm-web-server/src/test/java/com/sunyard/chsm/sdf/SdfApiAdapterTest.java +++ b/chsm-web-server/src/test/java/sdf/SdfApiAdapterTest.java @@ -1,4 +1,4 @@ -package com.sunyard.chsm.sdf; +package sdf; import com.sunyard.chsm.enums.ManufacturerModelEnum; import com.sunyard.chsm.sdf.adapter.SdfApiAdapter; diff --git a/pom.xml b/pom.xml index 1b45f69..84b4997 100644 --- a/pom.xml +++ b/pom.xml @@ -37,9 +37,11 @@ lombok provided + - junit - junit + org.junit.jupiter + junit-jupiter-api + 5.8.0 test