mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 21:02:08 +08:00
1、系统登录改造:首页移除机构、新用户用手机号登录(机构新增组织管理员移除账号密码、新增用户移除账号密码)、需要验证码的部分(首页忘记密码、修改密保手机);2、组织权限菜单树增加visiable属性过滤;3、支持钉钉、阿里云短信配置加密、对接系统发送短信;
This commit is contained in:
+5
-2
@@ -2,7 +2,9 @@ package com.cf.imes.framework.sms.config;
|
||||
|
||||
import com.cf.imes.framework.sms.core.client.SmsClientFactory;
|
||||
import com.cf.imes.framework.sms.core.client.impl.SmsClientFactoryImpl;
|
||||
import com.cf.imes.framework.sms.core.property.SmsProperties;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
/**
|
||||
@@ -11,11 +13,12 @@ import org.springframework.context.annotation.Bean;
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@EnableConfigurationProperties(SmsProperties.class)
|
||||
public class ChenfengSmsAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public SmsClientFactory smsClientFactory() {
|
||||
return new SmsClientFactoryImpl();
|
||||
public SmsClientFactory smsClientFactory(SmsProperties smsProperties) {
|
||||
return new SmsClientFactoryImpl(smsProperties);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-8
@@ -14,14 +14,6 @@ import java.util.List;
|
||||
* @since 2021/1/25 14:14
|
||||
*/
|
||||
public interface SmsClient {
|
||||
|
||||
/**
|
||||
* 获得渠道编号
|
||||
*
|
||||
* @return 渠道编号
|
||||
*/
|
||||
Long getId();
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
|
||||
+5
-13
@@ -1,6 +1,6 @@
|
||||
package com.cf.imes.framework.sms.core.client;
|
||||
|
||||
import com.cf.imes.framework.sms.core.property.SmsChannelProperties;
|
||||
import com.cf.imes.framework.sms.core.property.SmsProperties;
|
||||
|
||||
/**
|
||||
* 短信客户端的工厂接口
|
||||
@@ -9,15 +9,6 @@ import com.cf.imes.framework.sms.core.property.SmsChannelProperties;
|
||||
* @since 2021/1/28 14:01
|
||||
*/
|
||||
public interface SmsClientFactory {
|
||||
|
||||
/**
|
||||
* 获得短信 Client
|
||||
*
|
||||
* @param channelId 渠道编号
|
||||
* @return 短信 Client
|
||||
*/
|
||||
SmsClient getSmsClient(Long channelId);
|
||||
|
||||
/**
|
||||
* 获得短信 Client
|
||||
*
|
||||
@@ -27,10 +18,11 @@ public interface SmsClientFactory {
|
||||
SmsClient getSmsClient(String channelCode);
|
||||
|
||||
/**
|
||||
* 创建短信 Client
|
||||
* 获得短信 Client
|
||||
*
|
||||
* @param properties 配置对象
|
||||
* @param smsProperties 短信配置
|
||||
* @return 短信 Client
|
||||
*/
|
||||
void createOrUpdateSmsClient(SmsChannelProperties properties);
|
||||
SmsClient getSmsClient(SmsProperties smsProperties);
|
||||
|
||||
}
|
||||
|
||||
+9
@@ -40,4 +40,13 @@ public class SmsSendRespDTO {
|
||||
*/
|
||||
private String apiMsg;
|
||||
|
||||
/**
|
||||
* 短信发送的目标手机号
|
||||
*/
|
||||
private String mobile;
|
||||
|
||||
/**
|
||||
* 渠道编码
|
||||
*/
|
||||
private String channelCode;
|
||||
}
|
||||
|
||||
+12
-9
@@ -1,7 +1,7 @@
|
||||
package com.cf.imes.framework.sms.core.client.impl;
|
||||
|
||||
import com.cf.imes.framework.sms.core.client.SmsClient;
|
||||
import com.cf.imes.framework.sms.core.property.SmsChannelProperties;
|
||||
import com.cf.imes.framework.sms.core.property.SmsProperties;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
@@ -16,9 +16,9 @@ public abstract class AbstractSmsClient implements SmsClient {
|
||||
/**
|
||||
* 短信渠道配置
|
||||
*/
|
||||
protected volatile SmsChannelProperties properties;
|
||||
protected volatile SmsProperties properties;
|
||||
|
||||
public AbstractSmsClient(SmsChannelProperties properties) {
|
||||
public AbstractSmsClient(SmsProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,15 @@ public abstract class AbstractSmsClient implements SmsClient {
|
||||
*/
|
||||
protected abstract void doInit();
|
||||
|
||||
public final void refresh(SmsChannelProperties properties) {
|
||||
/**
|
||||
* 配置是否发生改变
|
||||
*
|
||||
* @param properties
|
||||
* @return
|
||||
*/
|
||||
protected abstract boolean propChanged(SmsProperties properties);
|
||||
|
||||
public final void refresh(SmsProperties properties) {
|
||||
// 判断是否更新
|
||||
if (properties.equals(this.properties)) {
|
||||
return;
|
||||
@@ -46,9 +54,4 @@ public abstract class AbstractSmsClient implements SmsClient {
|
||||
this.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return properties.getId();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+28
-39
@@ -1,5 +1,6 @@
|
||||
package com.cf.imes.framework.sms.core.client.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.cf.imes.framework.sms.core.client.SmsClient;
|
||||
import com.cf.imes.framework.sms.core.client.SmsClientFactory;
|
||||
import com.cf.imes.framework.sms.core.client.impl.aliyun.AliyunSmsClient;
|
||||
@@ -7,11 +8,12 @@ import com.cf.imes.framework.sms.core.client.impl.debug.DebugDingTalkSmsClient;
|
||||
import com.cf.imes.framework.sms.core.client.impl.tencent.TencentSmsClient;
|
||||
import com.cf.imes.framework.sms.core.enums.SmsChannelEnum;
|
||||
import com.cf.imes.framework.sms.core.property.SmsChannelProperties;
|
||||
import com.cf.imes.framework.sms.core.property.SmsProperties;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
@@ -22,14 +24,9 @@ import java.util.concurrent.ConcurrentMap;
|
||||
*/
|
||||
@Validated
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SmsClientFactoryImpl implements SmsClientFactory {
|
||||
|
||||
/**
|
||||
* 短信客户端 Map
|
||||
* key:渠道编号,使用 {@link SmsChannelProperties#getId()}
|
||||
*/
|
||||
private final ConcurrentMap<Long, AbstractSmsClient> channelIdClients = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 短信客户端 Map
|
||||
* key:渠道编码,使用 {@link SmsChannelProperties#getCode()} ()}
|
||||
@@ -39,21 +36,24 @@ public class SmsClientFactoryImpl implements SmsClientFactory {
|
||||
*/
|
||||
private final ConcurrentMap<String, AbstractSmsClient> channelCodeClients = new ConcurrentHashMap<>();
|
||||
|
||||
public SmsClientFactoryImpl() {
|
||||
// 初始化 channelCodeClients 集合
|
||||
Arrays.stream(SmsChannelEnum.values()).forEach(channel -> {
|
||||
// 创建一个空的 SmsChannelProperties 对象
|
||||
SmsChannelProperties properties = new SmsChannelProperties().setCode(channel.getCode())
|
||||
.setApiKey("default default").setApiSecret("default");
|
||||
// 创建 Sms 客户端
|
||||
AbstractSmsClient smsClient = createSmsClient(properties);
|
||||
channelCodeClients.put(channel.getCode(), smsClient);
|
||||
});
|
||||
public SmsClientFactoryImpl(SmsProperties smsProperties) {
|
||||
// 从配置初始化对应的client客户端
|
||||
AbstractSmsClient client = createSmsClient(smsProperties);
|
||||
client.init();
|
||||
channelCodeClients.put(smsProperties.getChannel(), client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsClient getSmsClient(Long channelId) {
|
||||
return channelIdClients.get(channelId);
|
||||
public SmsClient getSmsClient(SmsProperties smsProperties) {
|
||||
String channel = smsProperties.getChannel();
|
||||
AbstractSmsClient client = channelCodeClients.get(channel);
|
||||
// 1、新的短信类型;2、配置改变
|
||||
if (ObjectUtil.isNull(client) || client.propChanged(smsProperties)) {
|
||||
client = this.createSmsClient(smsProperties);
|
||||
client.init();
|
||||
channelCodeClients.put(channel, client);
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,30 +61,19 @@ public class SmsClientFactoryImpl implements SmsClientFactory {
|
||||
return channelCodeClients.get(channelCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createOrUpdateSmsClient(SmsChannelProperties properties) {
|
||||
AbstractSmsClient client = channelIdClients.get(properties.getId());
|
||||
if (client == null) {
|
||||
client = this.createSmsClient(properties);
|
||||
client.init();
|
||||
channelIdClients.put(client.getId(), client);
|
||||
} else {
|
||||
client.refresh(properties);
|
||||
}
|
||||
}
|
||||
|
||||
private AbstractSmsClient createSmsClient(SmsChannelProperties properties) {
|
||||
SmsChannelEnum channelEnum = SmsChannelEnum.getByCode(properties.getCode());
|
||||
Assert.notNull(channelEnum, String.format("渠道类型(%s) 为空", channelEnum));
|
||||
private AbstractSmsClient createSmsClient(SmsProperties smsProperties) {
|
||||
String channel = smsProperties.getChannel();
|
||||
SmsChannelEnum channelEnum = SmsChannelEnum.getByCode(channel);
|
||||
Assert.notNull(channelEnum, String.format("渠道类型(%s) 为空", channel));
|
||||
// 创建客户端
|
||||
switch (channelEnum) {
|
||||
case ALIYUN: return new AliyunSmsClient(properties);
|
||||
case DEBUG_DING_TALK: return new DebugDingTalkSmsClient(properties);
|
||||
case TENCENT: return new TencentSmsClient(properties);
|
||||
case ALIYUN: return new AliyunSmsClient(smsProperties);
|
||||
case DEBUG_DING_TALK: return new DebugDingTalkSmsClient(smsProperties);
|
||||
case TENCENT: return new TencentSmsClient(smsProperties);
|
||||
}
|
||||
// 创建失败,错误日志 + 抛出异常
|
||||
log.error("[createSmsClient][配置({}) 找不到合适的客户端实现]", properties);
|
||||
throw new IllegalArgumentException(String.format("配置(%s) 找不到合适的客户端实现", properties));
|
||||
log.error("[createSmsClient][配置({}) 找不到合适的客户端实现]", smsProperties);
|
||||
throw new IllegalArgumentException(String.format("配置(%s) 找不到合适的客户端实现", smsProperties));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+22
-3
@@ -1,6 +1,8 @@
|
||||
package com.cf.imes.framework.sms.core.client.impl.aliyun;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.aliyuncs.auth.Credential;
|
||||
import com.cf.imes.framework.common.core.KeyValue;
|
||||
import com.cf.imes.framework.common.util.collection.MapUtils;
|
||||
import com.cf.imes.framework.common.util.json.JsonUtils;
|
||||
@@ -9,7 +11,6 @@ import com.cf.imes.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||
import com.cf.imes.framework.sms.core.client.dto.SmsTemplateRespDTO;
|
||||
import com.cf.imes.framework.sms.core.client.impl.AbstractSmsClient;
|
||||
import com.cf.imes.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
|
||||
import com.cf.imes.framework.sms.core.property.SmsChannelProperties;
|
||||
import com.aliyuncs.DefaultAcsClient;
|
||||
import com.aliyuncs.IAcsClient;
|
||||
import com.aliyuncs.dysmsapi.model.v20170525.QuerySmsTemplateRequest;
|
||||
@@ -18,6 +19,7 @@ import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
|
||||
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
|
||||
import com.aliyuncs.profile.DefaultProfile;
|
||||
import com.aliyuncs.profile.IClientProfile;
|
||||
import com.cf.imes.framework.sms.core.property.SmsProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
@@ -56,7 +58,7 @@ public class AliyunSmsClient extends AbstractSmsClient {
|
||||
*/
|
||||
private volatile IAcsClient client;
|
||||
|
||||
public AliyunSmsClient(SmsChannelProperties properties) {
|
||||
public AliyunSmsClient(SmsProperties properties) {
|
||||
super(properties);
|
||||
Assert.notEmpty(properties.getApiKey(), "apiKey 不能为空");
|
||||
Assert.notEmpty(properties.getApiSecret(), "apiSecret 不能为空");
|
||||
@@ -68,6 +70,23 @@ public class AliyunSmsClient extends AbstractSmsClient {
|
||||
client = new DefaultAcsClient(profile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean propChanged(SmsProperties properties) {
|
||||
DefaultAcsClient defaultAcsClient = (DefaultAcsClient) client;
|
||||
if (ObjectUtil.isNotNull(defaultAcsClient)) {
|
||||
Credential credential = defaultAcsClient.getProfile().getCredential();
|
||||
String accessKeyId = credential.getAccessKeyId();
|
||||
if (ObjectUtil.notEqual(properties.getApiKey(), accessKeyId)) {
|
||||
return true;
|
||||
}
|
||||
String accessSecret = credential.getAccessSecret();
|
||||
if (ObjectUtil.notEqual(properties.getApiSecret(), accessSecret)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsSendRespDTO sendSms(Long sendLogId, String mobile, String apiTemplateId,
|
||||
List<KeyValue<String, Object>> templateParams) throws Throwable {
|
||||
@@ -81,7 +100,7 @@ public class AliyunSmsClient extends AbstractSmsClient {
|
||||
// 执行请求
|
||||
SendSmsResponse response = client.getAcsResponse(request);
|
||||
return new SmsSendRespDTO().setSuccess(Objects.equals(response.getCode(), API_CODE_SUCCESS)).setSerialNo(response.getBizId())
|
||||
.setApiRequestId(response.getRequestId()).setApiCode(response.getCode()).setApiMsg(response.getMessage());
|
||||
.setApiRequestId(response.getRequestId()).setApiCode(response.getCode()).setApiMsg(response.getMessage()).setChannelCode(properties.getChannel());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+10
-4
@@ -3,6 +3,7 @@ package com.cf.imes.framework.sms.core.client.impl.debug;
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.digest.DigestUtil;
|
||||
import cn.hutool.crypto.digest.HmacAlgorithm;
|
||||
@@ -15,7 +16,7 @@ import com.cf.imes.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||
import com.cf.imes.framework.sms.core.client.dto.SmsTemplateRespDTO;
|
||||
import com.cf.imes.framework.sms.core.client.impl.AbstractSmsClient;
|
||||
import com.cf.imes.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
|
||||
import com.cf.imes.framework.sms.core.property.SmsChannelProperties;
|
||||
import com.cf.imes.framework.sms.core.property.SmsProperties;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -31,7 +32,7 @@ import java.util.Objects;
|
||||
*/
|
||||
public class DebugDingTalkSmsClient extends AbstractSmsClient {
|
||||
|
||||
public DebugDingTalkSmsClient(SmsChannelProperties properties) {
|
||||
public DebugDingTalkSmsClient(SmsProperties properties) {
|
||||
super(properties);
|
||||
Assert.notEmpty(properties.getApiKey(), "apiKey 不能为空");
|
||||
Assert.notEmpty(properties.getApiSecret(), "apiSecret 不能为空");
|
||||
@@ -41,6 +42,11 @@ public class DebugDingTalkSmsClient extends AbstractSmsClient {
|
||||
protected void doInit() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean propChanged(SmsProperties properties) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsSendRespDTO sendSms(Long sendLogId, String mobile,
|
||||
String apiTemplateId, List<KeyValue<String, Object>> templateParams) throws Throwable {
|
||||
@@ -57,7 +63,7 @@ public class DebugDingTalkSmsClient extends AbstractSmsClient {
|
||||
Map<?, ?> responseObj = JsonUtils.parseObject(responseText, Map.class);
|
||||
String errorCode = MapUtil.getStr(responseObj, "errcode");
|
||||
return new SmsSendRespDTO().setSuccess(Objects.equals(errorCode, "0")).setSerialNo(StrUtil.uuid())
|
||||
.setApiCode(errorCode).setApiMsg(MapUtil.getStr(responseObj, "errorMsg"));
|
||||
.setApiCode(errorCode).setApiMsg(MapUtil.getStr(responseObj, "errorMsg")).setMobile(mobile).setChannelCode(properties.getChannel());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +81,7 @@ public class DebugDingTalkSmsClient extends AbstractSmsClient {
|
||||
// 生成 sign
|
||||
String secret = properties.getApiSecret();
|
||||
String stringToSign = timestamp + "\n" + secret;
|
||||
byte[] signData = DigestUtil.hmac(HmacAlgorithm.HmacSHA256, StrUtil.bytes(secret)).digest(stringToSign);
|
||||
byte[] signData = DigestUtil.hmac(HmacAlgorithm.HmacSHA256, CharSequenceUtil.bytes(secret)).digest(stringToSign);
|
||||
String sign = Base64.encode(signData);
|
||||
// 构建最终 URL
|
||||
return String.format("https://oapi.dingtalk.com/%s?access_token=%s×tamp=%d&sign=%s",
|
||||
|
||||
+9
-4
@@ -10,7 +10,7 @@ import com.cf.imes.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||
import com.cf.imes.framework.sms.core.client.dto.SmsTemplateRespDTO;
|
||||
import com.cf.imes.framework.sms.core.client.impl.AbstractSmsClient;
|
||||
import com.cf.imes.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
|
||||
import com.cf.imes.framework.sms.core.property.SmsChannelProperties;
|
||||
import com.cf.imes.framework.sms.core.property.SmsProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
@@ -56,7 +56,7 @@ public class TencentSmsClient extends AbstractSmsClient {
|
||||
|
||||
private SmsClient client;
|
||||
|
||||
public TencentSmsClient(SmsChannelProperties properties) {
|
||||
public TencentSmsClient(SmsProperties properties) {
|
||||
super(properties);
|
||||
Assert.notEmpty(properties.getApiSecret(), "apiSecret 不能为空");
|
||||
validateSdkAppId(properties);
|
||||
@@ -69,6 +69,11 @@ public class TencentSmsClient extends AbstractSmsClient {
|
||||
client = new SmsClient(credential, ENDPOINT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean propChanged(SmsProperties properties) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数校验腾讯云的 SDK AppId
|
||||
*
|
||||
@@ -78,7 +83,7 @@ public class TencentSmsClient extends AbstractSmsClient {
|
||||
*
|
||||
* @param properties 配置
|
||||
*/
|
||||
private static void validateSdkAppId(SmsChannelProperties properties) {
|
||||
private static void validateSdkAppId(SmsProperties properties) {
|
||||
String combineKey = properties.getApiKey();
|
||||
Assert.notEmpty(combineKey, "apiKey 不能为空");
|
||||
String[] keys = combineKey.trim().split(" ");
|
||||
@@ -108,7 +113,7 @@ public class TencentSmsClient extends AbstractSmsClient {
|
||||
SendSmsResponse response = client.SendSms(request);
|
||||
SendStatus status = response.getSendStatusSet()[0];
|
||||
return new SmsSendRespDTO().setSuccess(Objects.equals(status.getCode(), API_CODE_SUCCESS)).setSerialNo(status.getSerialNo())
|
||||
.setApiRequestId(response.getRequestId()).setApiCode(status.getCode()).setApiMsg(status.getMessage());
|
||||
.setApiRequestId(response.getRequestId()).setApiCode(status.getCode()).setApiMsg(status.getMessage()).setChannelCode(properties.getChannel());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package com.cf.imes.framework.sms.core.property;
|
||||
|
||||
import com.cf.imes.framework.common.util.encrypt.AesUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
/**
|
||||
* @author Gqr
|
||||
* @since 2024/8/23 10:51
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "chenfeng.sms")
|
||||
@Validated
|
||||
public class SmsProperties {
|
||||
|
||||
@Value("${chenfeng.encrypt.publicKey:}")
|
||||
private String publicKey;
|
||||
|
||||
/**
|
||||
* 短信渠道
|
||||
*/
|
||||
@NotEmpty(message = "短信渠道不能为空")
|
||||
private String channel;
|
||||
/**
|
||||
* 短信签名
|
||||
*/
|
||||
private String signature;
|
||||
/**
|
||||
* 短信 API 的账号
|
||||
*/
|
||||
@NotEmpty(message = "短信apiKey不能为空")
|
||||
private String apiKey;
|
||||
/**
|
||||
* 短信 API 的密钥
|
||||
*/
|
||||
@NotEmpty(message = "短信apiSecret不能为空")
|
||||
private String apiSecret;
|
||||
|
||||
public String getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public void setChannel(String channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
public SmsProperties setSignature(String signature) {
|
||||
this.signature = AesUtils.decrypt(signature, publicKey);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getApiKey() {
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
|
||||
public SmsProperties setApiKey(String apiKey) {
|
||||
this.apiKey = AesUtils.decrypt(apiKey, publicKey);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getApiSecret() {
|
||||
return apiSecret;
|
||||
}
|
||||
|
||||
public SmsProperties setApiSecret(String apiSecret) {
|
||||
this.apiSecret = AesUtils.decrypt(apiSecret, publicKey);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -7,7 +7,7 @@ import com.cf.imes.framework.sms.core.client.dto.SmsReceiveRespDTO;
|
||||
import com.cf.imes.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||
import com.cf.imes.framework.sms.core.client.dto.SmsTemplateRespDTO;
|
||||
import com.cf.imes.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
|
||||
import com.cf.imes.framework.sms.core.property.SmsChannelProperties;
|
||||
import com.cf.imes.framework.sms.core.property.SmsProperties;
|
||||
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import com.aliyuncs.IAcsClient;
|
||||
import com.aliyuncs.dysmsapi.model.v20170525.QuerySmsTemplateRequest;
|
||||
@@ -37,7 +37,7 @@ import static org.mockito.Mockito.when;
|
||||
*/
|
||||
public class AliyunSmsClientTest extends BaseMockitoUnitTest {
|
||||
|
||||
private final SmsChannelProperties properties = new SmsChannelProperties()
|
||||
private final SmsProperties properties = new SmsProperties()
|
||||
.setApiKey(randomString()) // 随机一个 apiKey,避免构建报错
|
||||
.setApiSecret(randomString()) // 随机一个 apiSecret,避免构建报错
|
||||
.setSignature("晨丰科技");
|
||||
|
||||
+3
-3
@@ -9,7 +9,7 @@ import com.cf.imes.framework.sms.core.client.dto.SmsReceiveRespDTO;
|
||||
import com.cf.imes.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||
import com.cf.imes.framework.sms.core.client.dto.SmsTemplateRespDTO;
|
||||
import com.cf.imes.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
|
||||
import com.cf.imes.framework.sms.core.property.SmsChannelProperties;
|
||||
import com.cf.imes.framework.sms.core.property.SmsProperties;
|
||||
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencentcloudapi.sms.v20210111.SmsClient;
|
||||
@@ -39,7 +39,7 @@ import static org.mockito.Mockito.when;
|
||||
*/
|
||||
public class TencentSmsClientTest extends BaseMockitoUnitTest {
|
||||
|
||||
private final SmsChannelProperties properties = new SmsChannelProperties()
|
||||
private final SmsProperties properties = new SmsProperties()
|
||||
.setApiKey(randomString() + " " + randomString()) // 随机一个 apiKey,避免构建报错
|
||||
.setApiSecret(randomString()) // 随机一个 apiSecret,避免构建报错
|
||||
.setSignature("晨丰科技");
|
||||
@@ -64,7 +64,7 @@ public class TencentSmsClientTest extends BaseMockitoUnitTest {
|
||||
@Test
|
||||
public void testRefresh() {
|
||||
// 准备参数
|
||||
SmsChannelProperties p = new SmsChannelProperties()
|
||||
SmsProperties p = new SmsProperties()
|
||||
.setApiKey(randomString() + " " + randomString()) // 随机一个 apiKey,避免构建报错
|
||||
.setApiSecret(randomString()) // 随机一个 apiSecret,避免构建报错
|
||||
.setSignature("晨丰科技");
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.cf.imes.framework.datasource.config;
|
||||
|
||||
import com.baomidou.dynamic.datasource.event.DataSourceInitEvent;
|
||||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration;
|
||||
import com.cf.imes.framework.mybatis.core.event.ChenfengDataSourceEncryptInitEvent;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
|
||||
/**
|
||||
* @author Gqr
|
||||
* @since 2024/8/26 18:20
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@AutoConfigureBefore(DynamicDataSourceAutoConfiguration.class)
|
||||
public class ChenfengDataSourceEncryptConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "chenfeng.encrypt.enable", havingValue = "true")
|
||||
public DataSourceInitEvent getDataSourceInitEvent() {
|
||||
return new ChenfengDataSourceEncryptInitEvent();
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.cf.imes.framework.mybatis.core.event;
|
||||
|
||||
import com.baomidou.dynamic.datasource.creator.DataSourceProperty;
|
||||
import com.baomidou.dynamic.datasource.event.DataSourceInitEvent;
|
||||
import com.cf.imes.framework.common.util.encrypt.AesUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* @author Gqr
|
||||
* @since 2024/8/27 9:09
|
||||
*/
|
||||
public class ChenfengDataSourceEncryptInitEvent implements DataSourceInitEvent {
|
||||
@Value("${chenfeng.encrypt.publicKey:}")
|
||||
private String publicKey;
|
||||
|
||||
/**
|
||||
* 数据源创建前
|
||||
*
|
||||
* @param dataSourceProperty 数据源基础信息
|
||||
*/
|
||||
@Override
|
||||
public void beforeCreate(DataSourceProperty dataSourceProperty) {
|
||||
if (StringUtils.isNotEmpty(publicKey)) {
|
||||
dataSourceProperty.setUsername(AesUtils.decrypt(dataSourceProperty.getUsername(), publicKey));
|
||||
dataSourceProperty.setPassword(AesUtils.decrypt(dataSourceProperty.getPassword(), publicKey));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据源创建后
|
||||
*
|
||||
* @param dataSource 连接池
|
||||
*/
|
||||
@Override
|
||||
public void afterCreate(DataSource dataSource) {
|
||||
|
||||
}
|
||||
}
|
||||
+1
@@ -1,2 +1,3 @@
|
||||
com.cf.imes.framework.datasource.config.ChenfengDataSourceEncryptConfiguration
|
||||
com.cf.imes.framework.datasource.config.ChenfengDataSourceAutoConfiguration
|
||||
com.cf.imes.framework.mybatis.config.ChenfengMybatisAutoConfiguration
|
||||
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package com.cf.imes.framework.redis.config;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.cf.imes.framework.common.util.encrypt.AesUtils;
|
||||
import org.redisson.config.ClusterServersConfig;
|
||||
import org.redisson.config.Config;
|
||||
import org.redisson.config.MasterSlaveServersConfig;
|
||||
import org.redisson.config.ReplicatedServersConfig;
|
||||
import org.redisson.config.SentinelServersConfig;
|
||||
import org.redisson.config.SingleServerConfig;
|
||||
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Gqr
|
||||
* @since 2024/8/27 9:46
|
||||
*/
|
||||
@AutoConfiguration
|
||||
public class ChenfengRedisEncryptAutoConfiguration {
|
||||
|
||||
@Value("${chenfeng.encrypt.publicKey:}")
|
||||
private String publicKey;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "chenfeng.encrypt.enable", havingValue = "true")
|
||||
public RedissonAutoConfigurationCustomizer redissonAutoConfigurationCustomizer() {
|
||||
return configuration -> {
|
||||
Config redissonConfig = new Config();
|
||||
BeanUtil.copyProperties(configuration, redissonConfig);
|
||||
|
||||
String password;
|
||||
SingleServerConfig singleServerConfig = redissonConfig.useSingleServer();
|
||||
if (singleServerConfig != null) {
|
||||
|
||||
password = singleServerConfig.getPassword();
|
||||
singleServerConfig.setPassword(
|
||||
StringUtils.isEmpty(password) ? null : AesUtils.decrypt(password, publicKey));
|
||||
return;
|
||||
}
|
||||
|
||||
MasterSlaveServersConfig masterSlaveServersConfig = redissonConfig.useMasterSlaveServers();
|
||||
if (masterSlaveServersConfig != null) {
|
||||
password = masterSlaveServersConfig.getPassword();
|
||||
masterSlaveServersConfig.setPassword(
|
||||
StringUtils.isEmpty(password) ? null : AesUtils.decrypt(password, publicKey));
|
||||
return;
|
||||
}
|
||||
|
||||
SentinelServersConfig sentinelServersConfig = redissonConfig.useSentinelServers();
|
||||
if (sentinelServersConfig != null) {
|
||||
password = sentinelServersConfig.getPassword();
|
||||
sentinelServersConfig.setPassword(
|
||||
StringUtils.isEmpty(password) ? null : AesUtils.decrypt(password, publicKey));
|
||||
return;
|
||||
}
|
||||
|
||||
ClusterServersConfig clusterServersConfig = redissonConfig.useClusterServers();
|
||||
if (clusterServersConfig != null) {
|
||||
password = clusterServersConfig.getPassword();
|
||||
clusterServersConfig.setPassword(
|
||||
StringUtils.isEmpty(password) ? null : AesUtils.decrypt(password, publicKey));
|
||||
return;
|
||||
}
|
||||
|
||||
ReplicatedServersConfig replicatedServersConfig = redissonConfig.useReplicatedServers();
|
||||
if (replicatedServersConfig != null) {
|
||||
password = replicatedServersConfig.getPassword();
|
||||
replicatedServersConfig.setPassword(
|
||||
StringUtils.isEmpty(password) ? null : AesUtils.decrypt(password, publicKey));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+1
@@ -1,2 +1,3 @@
|
||||
com.cf.imes.framework.redis.config.ChenfengRedisAutoConfiguration
|
||||
com.cf.imes.framework.redis.config.ChenfengRedisEncryptAutoConfiguration
|
||||
com.cf.imes.framework.redis.config.ChenfengCacheAutoConfiguration
|
||||
|
||||
Reference in New Issue
Block a user