mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2026-03-10 00:13:40 +08:00
🆕 #3703 【企业微信】第三方应用基础接口实现
This commit is contained in:
@@ -793,4 +793,6 @@ public class WxCpTpXmlMessage implements Serializable {
|
||||
log.debug("解密后的原始xml消息内容:{}", plainText);
|
||||
return fromXml(plainText);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ public interface WxCpTpConfigStorage {
|
||||
* @return the aes key
|
||||
*/
|
||||
//第三方应用的EncodingAESKey,用来检查签名
|
||||
String getAesKey();
|
||||
String getEncodingAESKey();
|
||||
|
||||
/**
|
||||
* 企微服务商企业ID & 企业secret
|
||||
|
||||
@@ -0,0 +1,431 @@
|
||||
package me.chanjar.weixin.cp.config.impl;
|
||||
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
import me.chanjar.weixin.common.bean.WxAccessToken;
|
||||
import me.chanjar.weixin.common.redis.RedissonWxRedisOps;
|
||||
import me.chanjar.weixin.common.redis.WxRedisOps;
|
||||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
|
||||
import me.chanjar.weixin.cp.bean.WxCpProviderToken;
|
||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.redisson.api.RedissonClient;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
/**
|
||||
* 企业微信各种固定、授权配置的Redisson存储实现
|
||||
*/
|
||||
public abstract class AbstractWxCpTpInRedisConfigImpl extends WxCpTpDefaultConfigImpl implements Serializable {
|
||||
private static final long serialVersionUID = -5385639031981770319L;
|
||||
|
||||
public AbstractWxCpTpInRedisConfigImpl(@NonNull WxRedisOps wxRedisOps) {
|
||||
this(wxRedisOps, null);
|
||||
}
|
||||
|
||||
public AbstractWxCpTpInRedisConfigImpl(@NonNull WxRedisOps wxRedisOps, String keyPrefix) {
|
||||
this.wxRedisOps = wxRedisOps;
|
||||
this.keyPrefix = keyPrefix;
|
||||
}
|
||||
/**
|
||||
* The constant LOCK_KEY.
|
||||
*/
|
||||
// lock key
|
||||
protected static final String LOCK_KEY = "wechat_tp_lock:";
|
||||
/**
|
||||
* The constant LOCKER_PROVIDER_ACCESS_TOKEN.
|
||||
*/
|
||||
protected static final String LOCKER_PROVIDER_ACCESS_TOKEN = "providerAccessTokenLock";
|
||||
/**
|
||||
* The constant LOCKER_SUITE_ACCESS_TOKEN.
|
||||
*/
|
||||
protected static final String LOCKER_SUITE_ACCESS_TOKEN = "suiteAccessTokenLock";
|
||||
/**
|
||||
* The constant LOCKER_ACCESS_TOKEN.
|
||||
*/
|
||||
protected static final String LOCKER_ACCESS_TOKEN = "accessTokenLock";
|
||||
/**
|
||||
* The constant LOCKER_CORP_JSAPI_TICKET.
|
||||
*/
|
||||
protected static final String LOCKER_CORP_JSAPI_TICKET = "corpJsapiTicketLock";
|
||||
/**
|
||||
* The constant LOCKER_SUITE_JSAPI_TICKET.
|
||||
*/
|
||||
protected static final String LOCKER_SUITE_JSAPI_TICKET = "suiteJsapiTicketLock";
|
||||
@NonNull
|
||||
private final WxRedisOps wxRedisOps;
|
||||
private final String suiteAccessTokenKey = ":suiteAccessTokenKey:";
|
||||
private final String suiteTicketKey = ":suiteTicketKey:";
|
||||
private final String accessTokenKey = ":accessTokenKey:";
|
||||
private final String authCorpJsApiTicketKey = ":authCorpJsApiTicketKey:";
|
||||
private final String authSuiteJsApiTicketKey = ":authSuiteJsApiTicketKey:";
|
||||
private final String providerTokenKey = ":providerTokenKey:";
|
||||
/**
|
||||
* redis里面key的统一前缀
|
||||
*/
|
||||
@Setter
|
||||
private String keyPrefix = "";
|
||||
private volatile String baseApiUrl;
|
||||
private volatile String httpProxyHost;
|
||||
private volatile int httpProxyPort;
|
||||
private volatile String httpProxyUsername;
|
||||
private volatile String httpProxyPassword;
|
||||
private volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
|
||||
private volatile File tmpDirFile;
|
||||
|
||||
|
||||
@Override
|
||||
public void setBaseApiUrl(String baseUrl) {
|
||||
this.baseApiUrl = baseUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getApiUrl(String path) {
|
||||
if (baseApiUrl == null) {
|
||||
baseApiUrl = "https://qyapi.weixin.qq.com";
|
||||
}
|
||||
return baseApiUrl + path;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 第三方应用的suite access token相关
|
||||
*/
|
||||
@Override
|
||||
public String getSuiteAccessToken() {
|
||||
return wxRedisOps.getValue(keyWithPrefix(suiteAccessTokenKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxAccessToken getSuiteAccessTokenEntity() {
|
||||
String suiteAccessToken = wxRedisOps.getValue(keyWithPrefix(suiteAccessTokenKey));
|
||||
Long expireIn = wxRedisOps.getExpire(keyWithPrefix(suiteAccessTokenKey));
|
||||
if (StringUtils.isBlank(suiteAccessToken) || expireIn == null || expireIn == 0 || expireIn == -2) {
|
||||
return new WxAccessToken();
|
||||
}
|
||||
|
||||
WxAccessToken suiteAccessTokenEntity = new WxAccessToken();
|
||||
suiteAccessTokenEntity.setAccessToken(suiteAccessToken);
|
||||
suiteAccessTokenEntity.setExpiresIn(Math.max(Math.toIntExact(expireIn), 0));
|
||||
return suiteAccessTokenEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuiteAccessTokenExpired() {
|
||||
//remain time to live in seconds, or key not exist
|
||||
return wxRedisOps.getExpire(keyWithPrefix(suiteAccessTokenKey)) == 0L || wxRedisOps.getExpire(keyWithPrefix(suiteAccessTokenKey)) == -2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireSuiteAccessToken() {
|
||||
wxRedisOps.expire(keyWithPrefix(suiteAccessTokenKey), 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSuiteAccessToken(WxAccessToken suiteAccessToken) {
|
||||
updateSuiteAccessToken(suiteAccessToken.getAccessToken(), suiteAccessToken.getExpiresIn());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSuiteAccessToken(String suiteAccessToken, int expiresInSeconds) {
|
||||
wxRedisOps.setValue(keyWithPrefix(suiteAccessTokenKey), suiteAccessToken, expiresInSeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方应用的suite ticket相关
|
||||
*/
|
||||
@Override
|
||||
public String getSuiteTicket() {
|
||||
return wxRedisOps.getValue(keyWithPrefix(suiteTicketKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuiteTicketExpired() {
|
||||
//remain time to live in seconds, or key not exist
|
||||
return wxRedisOps.getExpire(keyWithPrefix(suiteTicketKey)) == 0L || wxRedisOps.getExpire(keyWithPrefix(suiteTicketKey)) == -2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireSuiteTicket() {
|
||||
wxRedisOps.expire(keyWithPrefix(suiteTicketKey), 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSuiteTicket(String suiteTicket, int expiresInSeconds) {
|
||||
wxRedisOps.setValue(keyWithPrefix(suiteTicketKey), suiteTicket, expiresInSeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方应用的其他配置,来自于企微配置
|
||||
*/
|
||||
@Override
|
||||
public String getSuiteId() {
|
||||
return suiteId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSuiteSecret() {
|
||||
return suiteSecret;
|
||||
}
|
||||
|
||||
// 第三方应用的token,用来检查应用的签名
|
||||
@Override
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
//第三方应用的EncodingAESKey,用来检查签名
|
||||
@Override
|
||||
public String getEncodingAESKey() {
|
||||
return encodingAESKey;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 企微服务商企业ID & 企业secret, 来自于企微配置
|
||||
*/
|
||||
@Override
|
||||
public String getCorpId() {
|
||||
return corpId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProviderSecret() {
|
||||
return providerSecret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProviderSecret(String providerSecret) {
|
||||
this.providerSecret = providerSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权企业的access token相关
|
||||
*/
|
||||
@Override
|
||||
public String getAccessToken(String authCorpId) {
|
||||
return wxRedisOps.getValue(keyWithPrefix(authCorpId) + accessTokenKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxAccessToken getAccessTokenEntity(String authCorpId) {
|
||||
String accessToken = wxRedisOps.getValue(keyWithPrefix(authCorpId) + accessTokenKey);
|
||||
Long expire = wxRedisOps.getExpire(keyWithPrefix(authCorpId) + accessTokenKey);
|
||||
if (StringUtils.isBlank(accessToken) || expire == null || expire == 0 || expire == -2) {
|
||||
return new WxAccessToken();
|
||||
}
|
||||
|
||||
WxAccessToken accessTokenEntity = new WxAccessToken();
|
||||
accessTokenEntity.setAccessToken(accessToken);
|
||||
accessTokenEntity.setExpiresIn((int) ((expire - System.currentTimeMillis()) / 1000 + 200));
|
||||
return accessTokenEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccessTokenExpired(String authCorpId) {
|
||||
//没有设置或者TTL为0,都是过期
|
||||
return wxRedisOps.getExpire(keyWithPrefix(authCorpId) + accessTokenKey) == 0L
|
||||
|| wxRedisOps.getExpire(keyWithPrefix(authCorpId) + accessTokenKey) == -2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireAccessToken(String authCorpId) {
|
||||
wxRedisOps.expire(keyWithPrefix(authCorpId) + accessTokenKey, 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAccessToken(String authCorpId, String accessToken, int expiredInSeconds) {
|
||||
wxRedisOps.setValue(keyWithPrefix(authCorpId) + accessTokenKey, accessToken, expiredInSeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 授权企业的js api ticket相关
|
||||
*/
|
||||
@Override
|
||||
public String getAuthCorpJsApiTicket(String authCorpId) {
|
||||
return wxRedisOps.getValue(keyWithPrefix(authCorpId) + authCorpJsApiTicketKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthCorpJsApiTicketExpired(String authCorpId) {
|
||||
//没有设置或TTL为0,都是过期
|
||||
return wxRedisOps.getExpire(keyWithPrefix(authCorpId) + authCorpJsApiTicketKey) == 0L
|
||||
|| wxRedisOps.getExpire(keyWithPrefix(authCorpId) + authCorpJsApiTicketKey) == -2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireAuthCorpJsApiTicket(String authCorpId) {
|
||||
wxRedisOps.expire(keyWithPrefix(authCorpId) + authCorpJsApiTicketKey, 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAuthCorpJsApiTicket(String authCorpId, String jsApiTicket, int expiredInSeconds) {
|
||||
wxRedisOps.setValue(keyWithPrefix(authCorpId) + authCorpJsApiTicketKey, jsApiTicket, expiredInSeconds,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 授权企业的第三方应用js api ticket相关
|
||||
*/
|
||||
@Override
|
||||
public String getAuthSuiteJsApiTicket(String authCorpId) {
|
||||
return wxRedisOps.getValue(keyWithPrefix(authCorpId) + authSuiteJsApiTicketKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthSuiteJsApiTicketExpired(String authCorpId) {
|
||||
//没有设置或者TTL为0,都是过期
|
||||
return wxRedisOps.getExpire(keyWithPrefix(authCorpId) + authSuiteJsApiTicketKey) == 0L
|
||||
|| wxRedisOps.getExpire(keyWithPrefix(authCorpId) + authSuiteJsApiTicketKey) == -2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireAuthSuiteJsApiTicket(String authCorpId) {
|
||||
wxRedisOps.expire(keyWithPrefix(authCorpId) + authSuiteJsApiTicketKey, 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAuthSuiteJsApiTicket(String authCorpId, String jsApiTicket, int expiredInSeconds) {
|
||||
wxRedisOps.setValue(keyWithPrefix(authCorpId) + authSuiteJsApiTicketKey, jsApiTicket, expiredInSeconds,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProviderTokenExpired() {
|
||||
//remain time to live in seconds, or key not exist
|
||||
return wxRedisOps.getExpire(providerKeyWithPrefix(providerTokenKey)) == 0L || wxRedisOps.getExpire(providerKeyWithPrefix(providerTokenKey)) == -2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProviderToken(String providerToken, int expiredInSeconds) {
|
||||
wxRedisOps.setValue(providerKeyWithPrefix(providerTokenKey), providerToken, expiredInSeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProviderToken() {
|
||||
return wxRedisOps.getValue(providerKeyWithPrefix(providerTokenKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpProviderToken getProviderTokenEntity() {
|
||||
String providerToken = wxRedisOps.getValue(providerKeyWithPrefix(providerTokenKey));
|
||||
Long expire = wxRedisOps.getExpire(providerKeyWithPrefix(providerTokenKey));
|
||||
|
||||
if (StringUtils.isBlank(providerToken) || expire == null || expire == 0 || expire == -2) {
|
||||
return new WxCpProviderToken();
|
||||
}
|
||||
|
||||
WxCpProviderToken wxCpProviderToken = new WxCpProviderToken();
|
||||
wxCpProviderToken.setProviderAccessToken(providerToken);
|
||||
wxCpProviderToken.setExpiresIn(Math.max(Math.toIntExact(expire), 0));
|
||||
return wxCpProviderToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireProviderToken() {
|
||||
wxRedisOps.expire(providerKeyWithPrefix(providerTokenKey), 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 网络代理相关
|
||||
*/
|
||||
@Override
|
||||
public String getHttpProxyHost() {
|
||||
return this.httpProxyHost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHttpProxyPort() {
|
||||
return this.httpProxyPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHttpProxyUsername() {
|
||||
return this.httpProxyUsername;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHttpProxyPassword() {
|
||||
return this.httpProxyPassword;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getTmpDirFile() {
|
||||
return tmpDirFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lock getProviderAccessTokenLock() {
|
||||
return getProviderLockByKey(String.join(":", this.corpId, LOCKER_PROVIDER_ACCESS_TOKEN));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lock getSuiteAccessTokenLock() {
|
||||
return getLockByKey(LOCKER_SUITE_ACCESS_TOKEN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lock getAccessTokenLock(String authCorpId) {
|
||||
return getLockByKey(String.join(":", authCorpId, LOCKER_ACCESS_TOKEN));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lock getAuthCorpJsapiTicketLock(String authCorpId) {
|
||||
return getLockByKey(String.join(":", authCorpId, LOCKER_CORP_JSAPI_TICKET));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lock getSuiteJsapiTicketLock(String authCorpId) {
|
||||
return getLockByKey(String.join(":", authCorpId, LOCKER_SUITE_JSAPI_TICKET));
|
||||
}
|
||||
|
||||
private Lock getLockByKey(String key) {
|
||||
// 最终key的模式:(keyPrefix:)wechat_tp_lock:suiteId:(authCorpId):lockKey
|
||||
// 其中keyPrefix目前不支持外部配置,authCorpId只有涉及到corpAccessToken, suiteJsapiTicket, authCorpJsapiTicket时才会拼上
|
||||
return this.wxRedisOps.getLock(String.join(":", keyWithPrefix(LOCK_KEY + this.suiteId), key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 单独处理provider,且不应和suite 有关系
|
||||
*/
|
||||
private Lock getProviderLockByKey(String key) {
|
||||
return this.wxRedisOps.getLock(String.join(":", providerKeyWithPrefix(LOCK_KEY), key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApacheHttpClientBuilder getApacheHttpClientBuilder() {
|
||||
return this.apacheHttpClientBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean autoRefreshToken() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return WxCpGsonBuilder.create().toJson(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 一个provider 会有多个suite,需要唯一标识作为前缀
|
||||
*/
|
||||
private String keyWithPrefix(String key) {
|
||||
return keyPrefix + ":" + suiteId + ":" + key;
|
||||
}
|
||||
|
||||
/**
|
||||
* provider 应该独享一个key,且不和任何suite关联
|
||||
* 一个provider 会有多个suite,不同的suite 都应该指向同一个provider 的数据
|
||||
*/
|
||||
private String providerKeyWithPrefix(String key) {
|
||||
return keyPrefix + ":" + corpId + ":" + key;
|
||||
}
|
||||
}
|
||||
@@ -28,20 +28,32 @@ public class WxCpTpDefaultConfigImpl implements WxCpTpConfigStorage, Serializabl
|
||||
private final transient Map<String, Lock> accessTokenLocker = new ConcurrentHashMap<>();
|
||||
private final transient Map<String, Lock> authCorpJsapiTicketLocker = new ConcurrentHashMap<>();
|
||||
private final transient Map<String, Lock> authSuiteJsapiTicketLocker = new ConcurrentHashMap<>();
|
||||
private volatile String corpId;
|
||||
private volatile String corpSecret;
|
||||
/**
|
||||
* 企微服务商企业ID & 企业secret,来自于企微配置
|
||||
*/
|
||||
protected volatile String corpId;
|
||||
/**
|
||||
* 服务商secret
|
||||
*/
|
||||
private volatile String providerSecret;
|
||||
protected volatile String providerSecret;
|
||||
private volatile String providerToken;
|
||||
private volatile long providerTokenExpiresTime;
|
||||
private volatile String suiteId;
|
||||
private volatile String suiteSecret;
|
||||
private volatile String token;
|
||||
/**
|
||||
* 第三方应用的其他配置,来自于企微配置
|
||||
*/
|
||||
protected volatile String suiteId;
|
||||
|
||||
protected volatile String suiteSecret;
|
||||
/**
|
||||
* 第三方应用的token,用来检查应用的签名
|
||||
*/
|
||||
protected volatile String token;
|
||||
private volatile String suiteAccessToken;
|
||||
private volatile long suiteAccessTokenExpiresTime;
|
||||
private volatile String aesKey;
|
||||
/**
|
||||
* 第三方应用的EncodingAESKey,用来检查签名
|
||||
*/
|
||||
protected volatile String encodingAESKey;
|
||||
private volatile String suiteTicket;
|
||||
private volatile long suiteTicketExpiresTime;
|
||||
private volatile String oauth2redirectUri;
|
||||
@@ -186,11 +198,10 @@ public class WxCpTpDefaultConfigImpl implements WxCpTpConfigStorage, Serializabl
|
||||
/**
|
||||
* Sets suite id.
|
||||
*
|
||||
* @param corpId the corp id
|
||||
* @param suiteId
|
||||
*/
|
||||
@Deprecated
|
||||
public void setSuiteId(String corpId) {
|
||||
this.suiteId = corpId;
|
||||
public void setSuiteId(String suiteId) {
|
||||
this.suiteId = suiteId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -200,10 +211,7 @@ public class WxCpTpDefaultConfigImpl implements WxCpTpConfigStorage, Serializabl
|
||||
|
||||
/**
|
||||
* Sets suite secret.
|
||||
*
|
||||
* @param corpSecret the corp secret
|
||||
*/
|
||||
@Deprecated
|
||||
public void setSuiteSecret(String corpSecret) {
|
||||
this.suiteSecret = corpSecret;
|
||||
}
|
||||
@@ -218,24 +226,22 @@ public class WxCpTpDefaultConfigImpl implements WxCpTpConfigStorage, Serializabl
|
||||
*
|
||||
* @param token the token
|
||||
*/
|
||||
@Deprecated
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAesKey() {
|
||||
return this.aesKey;
|
||||
public String getEncodingAESKey() {
|
||||
return this.encodingAESKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets aes key.
|
||||
* Sets aes key. encodingAESKey
|
||||
*
|
||||
* @param aesKey the aes key
|
||||
* @param encodingAESKey the aes key
|
||||
*/
|
||||
@Deprecated
|
||||
public void setAesKey(String aesKey) {
|
||||
this.aesKey = aesKey;
|
||||
public void setEncodingAESKey(String encodingAESKey) {
|
||||
this.encodingAESKey = encodingAESKey;
|
||||
}
|
||||
|
||||
|
||||
@@ -249,25 +255,15 @@ public class WxCpTpDefaultConfigImpl implements WxCpTpConfigStorage, Serializabl
|
||||
*
|
||||
* @param corpId the corp id
|
||||
*/
|
||||
@Deprecated
|
||||
public void setCorpId(String corpId) {
|
||||
this.corpId = corpId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCorpSecret() {
|
||||
return this.corpSecret;
|
||||
return this.providerSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets corp secret.
|
||||
*
|
||||
* @param corpSecret the corp secret
|
||||
*/
|
||||
@Deprecated
|
||||
public void setCorpSecret(String corpSecret) {
|
||||
this.corpSecret = corpSecret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProviderSecret(String providerSecret) {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package me.chanjar.weixin.cp.config.impl;
|
||||
|
||||
import lombok.NonNull;
|
||||
import me.chanjar.weixin.common.redis.JedisWxRedisOps;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.util.Pool;
|
||||
|
||||
/**
|
||||
* 基于 jedis 的实现
|
||||
*
|
||||
* @author yl
|
||||
* created on 2023/04/23
|
||||
*/
|
||||
public class WxCpTpJedisConfigImpl extends AbstractWxCpTpInRedisConfigImpl {
|
||||
private static final long serialVersionUID = -1869372247414407433L;
|
||||
|
||||
public WxCpTpJedisConfigImpl(Pool<Jedis> jedisPool) {
|
||||
this(jedisPool, null);
|
||||
}
|
||||
|
||||
public WxCpTpJedisConfigImpl(@NonNull Pool<Jedis> jedisPool, String keyPrefix) {
|
||||
super(new JedisWxRedisOps(jedisPool), keyPrefix);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package me.chanjar.weixin.cp.config.impl;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.NonNull;
|
||||
import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
|
||||
/**
|
||||
* 基于 RedisTemplate 的实现
|
||||
*
|
||||
* @author yl
|
||||
* created on 2023/04/23
|
||||
*/
|
||||
public class WxCpTpRedisTemplateConfigImpl extends AbstractWxCpTpInRedisConfigImpl {
|
||||
private static final long serialVersionUID = -1660004125413310620L;
|
||||
|
||||
public WxCpTpRedisTemplateConfigImpl(@NonNull StringRedisTemplate stringRedisTemplate) {
|
||||
this(stringRedisTemplate, null);
|
||||
}
|
||||
|
||||
public WxCpTpRedisTemplateConfigImpl(@NonNull StringRedisTemplate stringRedisTemplate, String keyPrefix) {
|
||||
super(new RedisTemplateWxRedisOps(stringRedisTemplate), keyPrefix);
|
||||
}
|
||||
}
|
||||
@@ -1,449 +1,25 @@
|
||||
package me.chanjar.weixin.cp.config.impl;
|
||||
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
import me.chanjar.weixin.common.bean.WxAccessToken;
|
||||
import me.chanjar.weixin.common.redis.WxRedisOps;
|
||||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
|
||||
import me.chanjar.weixin.cp.bean.WxCpProviderToken;
|
||||
import me.chanjar.weixin.cp.config.WxCpTpConfigStorage;
|
||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import me.chanjar.weixin.common.redis.RedissonWxRedisOps;
|
||||
import org.redisson.api.RedissonClient;
|
||||
|
||||
/**
|
||||
* 企业微信各种固定、授权配置的Redisson存储实现
|
||||
* 基于Redisson的实现
|
||||
*
|
||||
* @author yuanqixun created on 2020 /5/13
|
||||
* @author yl
|
||||
*/
|
||||
@Builder
|
||||
public class WxCpTpRedissonConfigImpl implements WxCpTpConfigStorage, Serializable {
|
||||
private static final long serialVersionUID = -5385639031981770319L;
|
||||
public class WxCpTpRedissonConfigImpl extends AbstractWxCpTpInRedisConfigImpl {
|
||||
private static final long serialVersionUID = -5674792341070783967L;
|
||||
|
||||
/**
|
||||
* The constant LOCK_KEY.
|
||||
*/
|
||||
// lock key
|
||||
protected static final String LOCK_KEY = "wechat_tp_lock:";
|
||||
/**
|
||||
* The constant LOCKER_PROVIDER_ACCESS_TOKEN.
|
||||
*/
|
||||
protected static final String LOCKER_PROVIDER_ACCESS_TOKEN = "providerAccessTokenLock";
|
||||
/**
|
||||
* The constant LOCKER_SUITE_ACCESS_TOKEN.
|
||||
*/
|
||||
protected static final String LOCKER_SUITE_ACCESS_TOKEN = "suiteAccessTokenLock";
|
||||
/**
|
||||
* The constant LOCKER_ACCESS_TOKEN.
|
||||
*/
|
||||
protected static final String LOCKER_ACCESS_TOKEN = "accessTokenLock";
|
||||
/**
|
||||
* The constant LOCKER_CORP_JSAPI_TICKET.
|
||||
*/
|
||||
protected static final String LOCKER_CORP_JSAPI_TICKET = "corpJsapiTicketLock";
|
||||
/**
|
||||
* The constant LOCKER_SUITE_JSAPI_TICKET.
|
||||
*/
|
||||
protected static final String LOCKER_SUITE_JSAPI_TICKET = "suiteJsapiTicketLock";
|
||||
@NonNull
|
||||
private final WxRedisOps wxRedisOps;
|
||||
private final String suiteAccessTokenKey = ":suiteAccessTokenKey:";
|
||||
private final String suiteTicketKey = ":suiteTicketKey:";
|
||||
private final String accessTokenKey = ":accessTokenKey:";
|
||||
private final String authCorpJsApiTicketKey = ":authCorpJsApiTicketKey:";
|
||||
private final String authSuiteJsApiTicketKey = ":authSuiteJsApiTicketKey:";
|
||||
private final String providerTokenKey = ":providerTokenKey:";
|
||||
/**
|
||||
* redis里面key的统一前缀
|
||||
*/
|
||||
@Setter
|
||||
private String keyPrefix = "";
|
||||
private volatile String baseApiUrl;
|
||||
private volatile String httpProxyHost;
|
||||
private volatile int httpProxyPort;
|
||||
private volatile String httpProxyUsername;
|
||||
private volatile String httpProxyPassword;
|
||||
private volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
|
||||
private volatile File tmpDirFile;
|
||||
/**
|
||||
* 第三方应用的其他配置,来自于企微配置
|
||||
*/
|
||||
private volatile String suiteId;
|
||||
private volatile String suiteSecret;
|
||||
/**
|
||||
* 第三方应用的token,用来检查应用的签名
|
||||
*/
|
||||
private volatile String token;
|
||||
/**
|
||||
* 第三方应用的EncodingAESKey,用来检查签名
|
||||
*/
|
||||
private volatile String aesKey;
|
||||
/**
|
||||
* 企微服务商企业ID & 企业secret,来自于企微配置
|
||||
*/
|
||||
private volatile String corpId;
|
||||
private volatile String corpSecret;
|
||||
/**
|
||||
* 服务商secret
|
||||
*/
|
||||
private volatile String providerSecret;
|
||||
|
||||
@Override
|
||||
public void setBaseApiUrl(String baseUrl) {
|
||||
this.baseApiUrl = baseUrl;
|
||||
public WxCpTpRedissonConfigImpl(@NonNull RedissonClient redissonClient) {
|
||||
this(redissonClient, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getApiUrl(String path) {
|
||||
if (baseApiUrl == null) {
|
||||
baseApiUrl = "https://qyapi.weixin.qq.com";
|
||||
}
|
||||
return baseApiUrl + path;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 第三方应用的suite access token相关
|
||||
*/
|
||||
@Override
|
||||
public String getSuiteAccessToken() {
|
||||
return wxRedisOps.getValue(keyWithPrefix(suiteAccessTokenKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxAccessToken getSuiteAccessTokenEntity() {
|
||||
String suiteAccessToken = wxRedisOps.getValue(keyWithPrefix(suiteAccessTokenKey));
|
||||
Long expireIn = wxRedisOps.getExpire(keyWithPrefix(suiteAccessTokenKey));
|
||||
if (StringUtils.isBlank(suiteAccessToken) || expireIn == null || expireIn == 0 || expireIn == -2) {
|
||||
return new WxAccessToken();
|
||||
}
|
||||
|
||||
WxAccessToken suiteAccessTokenEntity = new WxAccessToken();
|
||||
suiteAccessTokenEntity.setAccessToken(suiteAccessToken);
|
||||
suiteAccessTokenEntity.setExpiresIn(Math.max(Math.toIntExact(expireIn), 0));
|
||||
return suiteAccessTokenEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuiteAccessTokenExpired() {
|
||||
//remain time to live in seconds, or key not exist
|
||||
return wxRedisOps.getExpire(keyWithPrefix(suiteAccessTokenKey)) == 0L || wxRedisOps.getExpire(keyWithPrefix(suiteAccessTokenKey)) == -2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireSuiteAccessToken() {
|
||||
wxRedisOps.expire(keyWithPrefix(suiteAccessTokenKey), 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSuiteAccessToken(WxAccessToken suiteAccessToken) {
|
||||
updateSuiteAccessToken(suiteAccessToken.getAccessToken(), suiteAccessToken.getExpiresIn());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSuiteAccessToken(String suiteAccessToken, int expiresInSeconds) {
|
||||
wxRedisOps.setValue(keyWithPrefix(suiteAccessTokenKey), suiteAccessToken, expiresInSeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方应用的suite ticket相关
|
||||
*/
|
||||
@Override
|
||||
public String getSuiteTicket() {
|
||||
return wxRedisOps.getValue(keyWithPrefix(suiteTicketKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuiteTicketExpired() {
|
||||
//remain time to live in seconds, or key not exist
|
||||
return wxRedisOps.getExpire(keyWithPrefix(suiteTicketKey)) == 0L || wxRedisOps.getExpire(keyWithPrefix(suiteTicketKey)) == -2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireSuiteTicket() {
|
||||
wxRedisOps.expire(keyWithPrefix(suiteTicketKey), 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSuiteTicket(String suiteTicket, int expiresInSeconds) {
|
||||
wxRedisOps.setValue(keyWithPrefix(suiteTicketKey), suiteTicket, expiresInSeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方应用的其他配置,来自于企微配置
|
||||
*/
|
||||
@Override
|
||||
public String getSuiteId() {
|
||||
return suiteId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSuiteSecret() {
|
||||
return suiteSecret;
|
||||
}
|
||||
|
||||
// 第三方应用的token,用来检查应用的签名
|
||||
@Override
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
//第三方应用的EncodingAESKey,用来检查签名
|
||||
@Override
|
||||
public String getAesKey() {
|
||||
return aesKey;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 企微服务商企业ID & 企业secret, 来自于企微配置
|
||||
*/
|
||||
@Override
|
||||
public String getCorpId() {
|
||||
return corpId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCorpSecret() {
|
||||
return corpSecret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProviderSecret(String providerSecret) {
|
||||
this.providerSecret = providerSecret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProviderSecret() {
|
||||
return providerSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权企业的access token相关
|
||||
*/
|
||||
@Override
|
||||
public String getAccessToken(String authCorpId) {
|
||||
return wxRedisOps.getValue(keyWithPrefix(authCorpId) + accessTokenKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxAccessToken getAccessTokenEntity(String authCorpId) {
|
||||
String accessToken = wxRedisOps.getValue(keyWithPrefix(authCorpId) + accessTokenKey);
|
||||
Long expire = wxRedisOps.getExpire(keyWithPrefix(authCorpId) + accessTokenKey);
|
||||
if (StringUtils.isBlank(accessToken) || expire == null || expire == 0 || expire == -2) {
|
||||
return new WxAccessToken();
|
||||
}
|
||||
|
||||
WxAccessToken accessTokenEntity = new WxAccessToken();
|
||||
accessTokenEntity.setAccessToken(accessToken);
|
||||
accessTokenEntity.setExpiresIn((int) ((expire - System.currentTimeMillis()) / 1000 + 200));
|
||||
return accessTokenEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccessTokenExpired(String authCorpId) {
|
||||
//没有设置或者TTL为0,都是过期
|
||||
return wxRedisOps.getExpire(keyWithPrefix(authCorpId) + accessTokenKey) == 0L
|
||||
|| wxRedisOps.getExpire(keyWithPrefix(authCorpId) + accessTokenKey) == -2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireAccessToken(String authCorpId) {
|
||||
wxRedisOps.expire(keyWithPrefix(authCorpId) + accessTokenKey, 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAccessToken(String authCorpId, String accessToken, int expiredInSeconds) {
|
||||
wxRedisOps.setValue(keyWithPrefix(authCorpId) + accessTokenKey, accessToken, expiredInSeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 授权企业的js api ticket相关
|
||||
*/
|
||||
@Override
|
||||
public String getAuthCorpJsApiTicket(String authCorpId) {
|
||||
return wxRedisOps.getValue(keyWithPrefix(authCorpId) + authCorpJsApiTicketKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthCorpJsApiTicketExpired(String authCorpId) {
|
||||
//没有设置或TTL为0,都是过期
|
||||
return wxRedisOps.getExpire(keyWithPrefix(authCorpId) + authCorpJsApiTicketKey) == 0L
|
||||
|| wxRedisOps.getExpire(keyWithPrefix(authCorpId) + authCorpJsApiTicketKey) == -2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireAuthCorpJsApiTicket(String authCorpId) {
|
||||
wxRedisOps.expire(keyWithPrefix(authCorpId) + authCorpJsApiTicketKey, 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAuthCorpJsApiTicket(String authCorpId, String jsApiTicket, int expiredInSeconds) {
|
||||
wxRedisOps.setValue(keyWithPrefix(authCorpId) + authCorpJsApiTicketKey, jsApiTicket, expiredInSeconds,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 授权企业的第三方应用js api ticket相关
|
||||
*/
|
||||
@Override
|
||||
public String getAuthSuiteJsApiTicket(String authCorpId) {
|
||||
return wxRedisOps.getValue(keyWithPrefix(authCorpId) + authSuiteJsApiTicketKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthSuiteJsApiTicketExpired(String authCorpId) {
|
||||
//没有设置或者TTL为0,都是过期
|
||||
return wxRedisOps.getExpire(keyWithPrefix(authCorpId) + authSuiteJsApiTicketKey) == 0L
|
||||
|| wxRedisOps.getExpire(keyWithPrefix(authCorpId) + authSuiteJsApiTicketKey) == -2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireAuthSuiteJsApiTicket(String authCorpId) {
|
||||
wxRedisOps.expire(keyWithPrefix(authCorpId) + authSuiteJsApiTicketKey, 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAuthSuiteJsApiTicket(String authCorpId, String jsApiTicket, int expiredInSeconds) {
|
||||
wxRedisOps.setValue(keyWithPrefix(authCorpId) + authSuiteJsApiTicketKey, jsApiTicket, expiredInSeconds,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProviderTokenExpired() {
|
||||
//remain time to live in seconds, or key not exist
|
||||
return wxRedisOps.getExpire(providerKeyWithPrefix(providerTokenKey)) == 0L || wxRedisOps.getExpire(providerKeyWithPrefix(providerTokenKey)) == -2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProviderToken(String providerToken, int expiredInSeconds) {
|
||||
wxRedisOps.setValue(providerKeyWithPrefix(providerTokenKey), providerToken, expiredInSeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProviderToken() {
|
||||
return wxRedisOps.getValue(providerKeyWithPrefix(providerTokenKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpProviderToken getProviderTokenEntity() {
|
||||
String providerToken = wxRedisOps.getValue(providerKeyWithPrefix(providerTokenKey));
|
||||
Long expire = wxRedisOps.getExpire(providerKeyWithPrefix(providerTokenKey));
|
||||
|
||||
if (StringUtils.isBlank(providerToken) || expire == null || expire == 0 || expire == -2) {
|
||||
return new WxCpProviderToken();
|
||||
}
|
||||
|
||||
WxCpProviderToken wxCpProviderToken = new WxCpProviderToken();
|
||||
wxCpProviderToken.setProviderAccessToken(providerToken);
|
||||
wxCpProviderToken.setExpiresIn(Math.max(Math.toIntExact(expire), 0));
|
||||
return wxCpProviderToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireProviderToken() {
|
||||
wxRedisOps.expire(providerKeyWithPrefix(providerTokenKey), 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 网络代理相关
|
||||
*/
|
||||
@Override
|
||||
public String getHttpProxyHost() {
|
||||
return this.httpProxyHost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHttpProxyPort() {
|
||||
return this.httpProxyPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHttpProxyUsername() {
|
||||
return this.httpProxyUsername;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHttpProxyPassword() {
|
||||
return this.httpProxyPassword;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getTmpDirFile() {
|
||||
return tmpDirFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lock getProviderAccessTokenLock() {
|
||||
return getProviderLockByKey(String.join(":", this.corpId, LOCKER_PROVIDER_ACCESS_TOKEN));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lock getSuiteAccessTokenLock() {
|
||||
return getLockByKey(LOCKER_SUITE_ACCESS_TOKEN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lock getAccessTokenLock(String authCorpId) {
|
||||
return getLockByKey(String.join(":", authCorpId, LOCKER_ACCESS_TOKEN));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lock getAuthCorpJsapiTicketLock(String authCorpId) {
|
||||
return getLockByKey(String.join(":", authCorpId, LOCKER_CORP_JSAPI_TICKET));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lock getSuiteJsapiTicketLock(String authCorpId) {
|
||||
return getLockByKey(String.join(":", authCorpId, LOCKER_SUITE_JSAPI_TICKET));
|
||||
}
|
||||
|
||||
private Lock getLockByKey(String key) {
|
||||
// 最终key的模式:(keyPrefix:)wechat_tp_lock:suiteId:(authCorpId):lockKey
|
||||
// 其中keyPrefix目前不支持外部配置,authCorpId只有涉及到corpAccessToken, suiteJsapiTicket, authCorpJsapiTicket时才会拼上
|
||||
return this.wxRedisOps.getLock(String.join(":", keyWithPrefix(LOCK_KEY + this.suiteId), key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 单独处理provider,且不应和suite 有关系
|
||||
*/
|
||||
private Lock getProviderLockByKey(String key) {
|
||||
return this.wxRedisOps.getLock(String.join(":", providerKeyWithPrefix(LOCK_KEY), key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApacheHttpClientBuilder getApacheHttpClientBuilder() {
|
||||
return this.apacheHttpClientBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean autoRefreshToken() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return WxCpGsonBuilder.create().toJson(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 一个provider 会有多个suite,需要唯一标识作为前缀
|
||||
*/
|
||||
private String keyWithPrefix(String key) {
|
||||
return keyPrefix + ":" + suiteId + ":" + key;
|
||||
}
|
||||
|
||||
/**
|
||||
* provider 应该独享一个key,且不和任何suite关联
|
||||
* 一个provider 会有多个suite,不同的suite 都应该指向同一个provider 的数据
|
||||
*/
|
||||
private String providerKeyWithPrefix(String key) {
|
||||
return keyPrefix + ":" + corpId + ":" + key;
|
||||
public WxCpTpRedissonConfigImpl(@NonNull RedissonClient redissonClient, String keyPrefix) {
|
||||
super(new RedissonWxRedisOps(redissonClient), keyPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -855,6 +855,10 @@ public interface WxCpApiPathConsts {
|
||||
* The constant GET_PERMANENT_CODE.
|
||||
*/
|
||||
String GET_PERMANENT_CODE = "/cgi-bin/service/get_permanent_code";
|
||||
/**
|
||||
* The constant GET_V2_PERMANENT_CODE.
|
||||
*/
|
||||
String GET_V2_PERMANENT_CODE = "/cgi-bin/service/v2/get_permanent_code";
|
||||
/**
|
||||
* The constant GET_SUITE_TOKEN.
|
||||
*/
|
||||
|
||||
@@ -8,6 +8,7 @@ import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
|
||||
import me.chanjar.weixin.common.util.http.RequestExecutor;
|
||||
import me.chanjar.weixin.common.util.http.RequestHttp;
|
||||
import me.chanjar.weixin.cp.bean.*;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage;
|
||||
import me.chanjar.weixin.cp.config.WxCpTpConfigStorage;
|
||||
|
||||
import java.util.List;
|
||||
@@ -186,6 +187,8 @@ public interface WxCpTpService {
|
||||
@Deprecated
|
||||
WxCpTpCorp getPermanentCode(String authCode) throws WxErrorException;
|
||||
|
||||
WxCpTpCorp getV2PermanentCode(String authCode) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* 获取企业永久授权码信息
|
||||
* <pre>
|
||||
@@ -200,6 +203,8 @@ public interface WxCpTpService {
|
||||
*/
|
||||
WxCpTpPermanentCodeInfo getPermanentCodeInfo(String authCode) throws WxErrorException;
|
||||
|
||||
WxCpTpPermanentCodeInfo getV2PermanentCodeInfo(String authCode) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 获取预授权链接
|
||||
@@ -343,9 +348,7 @@ public interface WxCpTpService {
|
||||
* 获取WxCpTpConfigStorage 对象.
|
||||
*
|
||||
* @return WxCpTpConfigStorage wx cp tp config storage
|
||||
* @deprecated storage应该在service内部使用 ,提供这个接口,容易破坏这个封装
|
||||
*/
|
||||
@Deprecated
|
||||
WxCpTpConfigStorage getWxCpTpConfigStorage();
|
||||
|
||||
/**
|
||||
@@ -527,6 +530,11 @@ public interface WxCpTpService {
|
||||
*/
|
||||
WxCpTpLicenseService getWxCpTpLicenseService();
|
||||
|
||||
WxCpTpXmlMessage fromEncryptedXml(String encryptedXml,
|
||||
String timestamp, String nonce, String msgSignature);
|
||||
|
||||
String getVerifyDecrypt(String sVerifyEchoStr);
|
||||
|
||||
/**
|
||||
* 获取应用的管理员列表
|
||||
*
|
||||
|
||||
@@ -25,8 +25,10 @@ import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
|
||||
import me.chanjar.weixin.common.util.json.GsonParser;
|
||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
|
||||
import me.chanjar.weixin.cp.bean.*;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage;
|
||||
import me.chanjar.weixin.cp.config.WxCpTpConfigStorage;
|
||||
import me.chanjar.weixin.cp.tp.service.*;
|
||||
import me.chanjar.weixin.cp.util.crypto.WxCpTpCryptUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
@@ -91,6 +93,7 @@ public abstract class BaseWxCpTpServiceImpl<H, P> implements WxCpTpService, Requ
|
||||
|
||||
private final WxSessionManager sessionManager = new StandardSessionManager();
|
||||
|
||||
|
||||
/**
|
||||
* 临时文件目录.
|
||||
*/
|
||||
@@ -259,6 +262,18 @@ public abstract class BaseWxCpTpServiceImpl<H, P> implements WxCpTpService, Requ
|
||||
return wxCpTpCorp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpTpCorp getV2PermanentCode(String authCode) throws WxErrorException {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("auth_code", authCode);
|
||||
|
||||
String result = post(configStorage.getApiUrl(GET_V2_PERMANENT_CODE), jsonObject.toString());
|
||||
jsonObject = GsonParser.parse(result);
|
||||
WxCpTpCorp wxCpTpCorp = WxCpTpCorp.fromJson(jsonObject.get("auth_corp_info").getAsJsonObject().toString());
|
||||
wxCpTpCorp.setPermanentCode(jsonObject.get("permanent_code").getAsString());
|
||||
return wxCpTpCorp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpTpPermanentCodeInfo getPermanentCodeInfo(String authCode) throws WxErrorException {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
@@ -267,6 +282,14 @@ public abstract class BaseWxCpTpServiceImpl<H, P> implements WxCpTpService, Requ
|
||||
return WxCpTpPermanentCodeInfo.fromJson(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpTpPermanentCodeInfo getV2PermanentCodeInfo(String authCode) throws WxErrorException {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("auth_code", authCode);
|
||||
String result = post(configStorage.getApiUrl(GET_V2_PERMANENT_CODE), jsonObject.toString());
|
||||
return WxCpTpPermanentCodeInfo.fromJson(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public String getPreAuthUrl(String redirectUri, String state) throws WxErrorException {
|
||||
@@ -452,7 +475,7 @@ public abstract class BaseWxCpTpServiceImpl<H, P> implements WxCpTpService, Requ
|
||||
if (error.getErrorCode() == WxCpErrorMsgEnum.CODE_42009.getCode()) {
|
||||
// 强制设置wxCpTpConfigStorage它的suite access token过期了,这样在下一次请求里就会刷新suite access token
|
||||
this.configStorage.expireSuiteAccessToken();
|
||||
if (this.getWxCpTpConfigStorage().autoRefreshToken()) {
|
||||
if (this.configStorage.autoRefreshToken()) {
|
||||
log.warn("即将重新获取新的access_token,错误代码:{},错误信息:{}", error.getErrorCode(), error.getErrorMsg());
|
||||
return this.execute(executor, uri, data);
|
||||
}
|
||||
@@ -646,6 +669,27 @@ public abstract class BaseWxCpTpServiceImpl<H, P> implements WxCpTpService, Requ
|
||||
this.wxCpTpUserService = wxCpTpUserService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param encryptedXml the encrypted xml
|
||||
* @param timestamp the timestamp
|
||||
* @param nonce the nonce
|
||||
* @param msgSignature the msg signature
|
||||
* @return the wx cp tp xml message
|
||||
*/
|
||||
@Override
|
||||
public WxCpTpXmlMessage fromEncryptedXml(String encryptedXml,
|
||||
String timestamp, String nonce, String msgSignature) {
|
||||
return WxCpTpXmlMessage.fromEncryptedXml(encryptedXml,this.configStorage,timestamp,nonce,msgSignature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVerifyDecrypt(String sVerifyEchoStr) {
|
||||
WxCpTpCryptUtil cryptUtil = new WxCpTpCryptUtil(this.configStorage);
|
||||
return cryptUtil.decrypt(sVerifyEchoStr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpTpAdmin getAdminList(String authCorpId, Integer agentId) throws WxErrorException {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
@@ -764,4 +808,9 @@ public abstract class BaseWxCpTpServiceImpl<H, P> implements WxCpTpService, Requ
|
||||
public void setWxCpTpOAuth2Service(WxCpTpOAuth2Service wxCpTpOAuth2Service) {
|
||||
this.wxCpTpOAuth2Service = wxCpTpOAuth2Service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpTpConfigStorage getWxCpTpConfigStorage() {
|
||||
return this.configStorage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,9 +101,9 @@ public class WxCpTpServiceApacheHttpClientImpl extends BaseWxCpTpServiceImpl<Clo
|
||||
this.httpClient = apacheHttpClientBuilder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpTpConfigStorage getWxCpTpConfigStorage() {
|
||||
return this.configStorage;
|
||||
}
|
||||
// @Override
|
||||
// public WxCpTpConfigStorage getWxCpTpConfigStorage() {
|
||||
// return this.configStorage;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -98,9 +98,9 @@ public class WxCpTpServiceHttpComponentsImpl extends BaseWxCpTpServiceImpl<Close
|
||||
this.httpClient = apacheHttpClientBuilder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpTpConfigStorage getWxCpTpConfigStorage() {
|
||||
return this.configStorage;
|
||||
}
|
||||
// @Override
|
||||
// public WxCpTpConfigStorage getWxCpTpConfigStorage() {
|
||||
// return this.configStorage;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
package me.chanjar.weixin.cp.tp.service.impl;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import jodd.http.HttpConnectionProvider;
|
||||
import jodd.http.HttpRequest;
|
||||
import jodd.http.HttpResponse;
|
||||
import jodd.http.ProxyInfo;
|
||||
import jodd.http.net.SocketHttpConnectionProvider;
|
||||
import me.chanjar.weixin.common.bean.WxAccessToken;
|
||||
import me.chanjar.weixin.common.enums.WxType;
|
||||
import me.chanjar.weixin.common.error.WxError;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.util.http.HttpClientType;
|
||||
import me.chanjar.weixin.common.util.json.GsonParser;
|
||||
import me.chanjar.weixin.cp.api.impl.BaseWxCpServiceImpl;
|
||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
|
||||
import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
|
||||
|
||||
/**
|
||||
* The type Wx cp service jodd http.
|
||||
*
|
||||
* @author someone
|
||||
*/
|
||||
public class WxCpTpServiceJoddHttpImpl extends BaseWxCpTpServiceImpl<HttpConnectionProvider, ProxyInfo> {
|
||||
private HttpConnectionProvider httpClient;
|
||||
private ProxyInfo httpProxy;
|
||||
|
||||
@Override
|
||||
public HttpConnectionProvider getRequestHttpClient() {
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProxyInfo getRequestHttpProxy() {
|
||||
return httpProxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpClientType getRequestType() {
|
||||
return HttpClientType.JODD_HTTP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSuiteAccessToken(boolean forceRefresh) throws WxErrorException {
|
||||
if (!this.configStorage.isSuiteAccessTokenExpired() && !forceRefresh) {
|
||||
return this.configStorage.getSuiteAccessToken();
|
||||
}
|
||||
|
||||
synchronized (this.globalSuiteAccessTokenRefreshLock) {
|
||||
// 构建请求 URL
|
||||
String url = this.configStorage.getApiUrl(WxCpApiPathConsts.Tp.GET_SUITE_TOKEN);
|
||||
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("suite_id", this.configStorage.getSuiteId());
|
||||
jsonObject.addProperty("suite_secret", this.configStorage.getSuiteSecret());
|
||||
jsonObject.addProperty("suite_ticket", this.getSuiteTicket());
|
||||
String jsonBody = jsonObject.toString();
|
||||
|
||||
if (this.httpProxy != null) {
|
||||
httpClient.useProxy(this.httpProxy);
|
||||
}
|
||||
// 创建 POST 请求
|
||||
HttpRequest request = HttpRequest
|
||||
.post(url)
|
||||
.contentType("application/json")
|
||||
.body(jsonBody); // 使用 .body() 设置请求体
|
||||
|
||||
request.withConnectionProvider(httpClient);
|
||||
|
||||
// 发送请求
|
||||
HttpResponse response = request.send();
|
||||
|
||||
// 解析响应
|
||||
String resultContent = response.bodyText();
|
||||
WxError error = WxError.fromJson(resultContent, WxType.CP);
|
||||
if (error.getErrorCode() != 0) {
|
||||
throw new WxErrorException(error);
|
||||
}
|
||||
|
||||
// 更新 access token
|
||||
jsonObject = GsonParser.parse(resultContent);
|
||||
String suiteAccussToken = jsonObject.get("suite_access_token").getAsString();
|
||||
int expiresIn = jsonObject.get("expires_in").getAsInt();
|
||||
this.configStorage.updateSuiteAccessToken(suiteAccussToken, expiresIn);
|
||||
}
|
||||
|
||||
return this.configStorage.getSuiteAccessToken();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initHttp() {
|
||||
if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) {
|
||||
httpProxy = new ProxyInfo(ProxyInfo.ProxyType.HTTP, configStorage.getHttpProxyHost(),
|
||||
configStorage.getHttpProxyPort(), configStorage.getHttpProxyUsername(), configStorage.getHttpProxyPassword());
|
||||
}
|
||||
|
||||
httpClient = new SocketHttpConnectionProvider();
|
||||
}
|
||||
//
|
||||
// @Override
|
||||
// public WxCpConfigStorage getWxCpConfigStorage() {
|
||||
// return this.configStorage;
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package me.chanjar.weixin.cp.tp.service.impl;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.bean.WxAccessToken;
|
||||
import me.chanjar.weixin.common.enums.WxType;
|
||||
import me.chanjar.weixin.common.error.WxError;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.error.WxRuntimeException;
|
||||
import me.chanjar.weixin.common.util.http.HttpClientType;
|
||||
import me.chanjar.weixin.common.util.http.okhttp.DefaultOkHttpClientBuilder;
|
||||
import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo;
|
||||
import me.chanjar.weixin.common.util.json.GsonParser;
|
||||
import me.chanjar.weixin.cp.api.impl.BaseWxCpServiceImpl;
|
||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
|
||||
import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
|
||||
import okhttp3.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.GET_TOKEN;
|
||||
|
||||
/**
|
||||
* The type Wx cp service ok http.
|
||||
*
|
||||
* @author someone
|
||||
*/
|
||||
@Slf4j
|
||||
public class WxCpTpServiceOkHttpImpl extends BaseWxCpTpServiceImpl<OkHttpClient, OkHttpProxyInfo> {
|
||||
private OkHttpClient httpClient;
|
||||
private OkHttpProxyInfo httpProxy;
|
||||
|
||||
@Override
|
||||
public OkHttpClient getRequestHttpClient() {
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OkHttpProxyInfo getRequestHttpProxy() {
|
||||
return httpProxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpClientType getRequestType() {
|
||||
return HttpClientType.OK_HTTP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSuiteAccessToken(boolean forceRefresh) throws WxErrorException {
|
||||
if (!this.configStorage.isSuiteAccessTokenExpired() && !forceRefresh) {
|
||||
return this.configStorage.getSuiteAccessToken();
|
||||
}
|
||||
|
||||
synchronized (this.globalSuiteAccessTokenRefreshLock) {
|
||||
// 得到 httpClient
|
||||
OkHttpClient client = getRequestHttpClient();
|
||||
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("suite_id", this.configStorage.getSuiteId());
|
||||
jsonObject.addProperty("suite_secret", this.configStorage.getSuiteSecret());
|
||||
jsonObject.addProperty("suite_ticket", this.getSuiteTicket());
|
||||
String jsonBody = jsonObject.toString();
|
||||
|
||||
RequestBody requestBody = RequestBody.create(
|
||||
MediaType.get("application/json; charset=utf-8"),
|
||||
jsonBody
|
||||
);
|
||||
|
||||
// 构建 POST 请求
|
||||
Request request = new Request.Builder()
|
||||
.url(this.configStorage.getApiUrl(WxCpApiPathConsts.Tp.GET_SUITE_TOKEN)) // URL 不包含查询参数
|
||||
.post(requestBody) // 使用 POST 方法
|
||||
.build();
|
||||
|
||||
String resultContent = null;
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
if (!response.isSuccessful()) {
|
||||
throw new IOException("Unexpected response code: " + response);
|
||||
}
|
||||
resultContent = response.body().string();
|
||||
} catch (IOException e) {
|
||||
log.error("获取 suite token 失败: {}", e.getMessage(), e);
|
||||
throw new WxRuntimeException("获取 suite token 失败", e);
|
||||
}
|
||||
|
||||
WxError error = WxError.fromJson(resultContent, WxType.CP);
|
||||
if (error.getErrorCode() != 0) {
|
||||
throw new WxErrorException(error);
|
||||
}
|
||||
|
||||
jsonObject = GsonParser.parse(resultContent);
|
||||
String suiteAccussToken = jsonObject.get("suite_access_token").getAsString();
|
||||
int expiresIn = jsonObject.get("expires_in").getAsInt();
|
||||
this.configStorage.updateSuiteAccessToken(suiteAccussToken, expiresIn);
|
||||
}
|
||||
return this.configStorage.getSuiteAccessToken();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initHttp() {
|
||||
log.debug("WxCpServiceOkHttpImpl initHttp");
|
||||
//设置代理
|
||||
if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) {
|
||||
httpProxy = OkHttpProxyInfo.httpProxy(configStorage.getHttpProxyHost(),
|
||||
configStorage.getHttpProxyPort(),
|
||||
configStorage.getHttpProxyUsername(),
|
||||
configStorage.getHttpProxyPassword());
|
||||
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
|
||||
clientBuilder.proxy(getRequestHttpProxy().getProxy());
|
||||
//设置授权
|
||||
clientBuilder.authenticator(new Authenticator() {
|
||||
@Override
|
||||
public Request authenticate(Route route, Response response) throws IOException {
|
||||
String credential = Credentials.basic(httpProxy.getProxyUsername(), httpProxy.getProxyPassword());
|
||||
return response.request().newBuilder()
|
||||
.header("Authorization", credential)
|
||||
.build();
|
||||
}
|
||||
});
|
||||
httpClient = clientBuilder.build();
|
||||
} else {
|
||||
httpClient = DefaultOkHttpClientBuilder.get().build();
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public WxCpConfigStorage getWxCpConfigStorage() {
|
||||
// return this.configStorage;
|
||||
// }
|
||||
}
|
||||
@@ -23,7 +23,7 @@ public class WxCpTpCryptUtil extends WxCryptUtil {
|
||||
* @param encodingAesKey 公众平台上,开发者设置的EncodingAESKey
|
||||
* @param appidOrCorpid 公众平台corpId
|
||||
*/
|
||||
String encodingAesKey = wxCpTpConfigStorage.getAesKey();
|
||||
String encodingAesKey = wxCpTpConfigStorage.getEncodingAESKey();
|
||||
String token = wxCpTpConfigStorage.getToken();
|
||||
String corpId = wxCpTpConfigStorage.getCorpId();
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ import me.chanjar.weixin.cp.bean.WxCpTpPermanentCodeInfo;
|
||||
import me.chanjar.weixin.cp.bean.WxTpCustomizedAuthUrl;
|
||||
import me.chanjar.weixin.cp.config.WxCpTpConfigStorage;
|
||||
import me.chanjar.weixin.cp.config.impl.WxCpTpDefaultConfigImpl;
|
||||
import me.chanjar.weixin.cp.config.impl.AbstractWxCpTpInRedisConfigImpl;
|
||||
import me.chanjar.weixin.cp.config.impl.WxCpTpRedisTemplateConfigImpl;
|
||||
import me.chanjar.weixin.cp.config.impl.WxCpTpRedissonConfigImpl;
|
||||
import me.chanjar.weixin.cp.tp.service.WxCpTpService;
|
||||
import org.mockito.Mockito;
|
||||
@@ -69,7 +71,10 @@ public class BaseWxCpTpServiceImplTest {
|
||||
* @return the wx cp tp config storage
|
||||
*/
|
||||
public WxCpTpConfigStorage wxCpTpConfigStorage() {
|
||||
return WxCpTpRedissonConfigImpl.builder().corpId(PROVIDER_CORP_ID).providerSecret(PROVIDER_SECRET).wxRedisOps(new RedissonWxRedisOps(redissonClient())).build();
|
||||
WxCpTpRedissonConfigImpl wxCpTpRedissonConfig=new WxCpTpRedissonConfigImpl(redissonClient(),"");
|
||||
wxCpTpRedissonConfig.setCorpId(PROVIDER_CORP_ID);
|
||||
wxCpTpRedissonConfig.setProviderSecret(PROVIDER_SECRET);
|
||||
return wxCpTpRedissonConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,6 +6,8 @@ import me.chanjar.weixin.common.redis.RedissonWxRedisOps;
|
||||
import me.chanjar.weixin.cp.bean.WxCpProviderToken;
|
||||
import me.chanjar.weixin.cp.bean.WxCpTpCorpId2OpenCorpId;
|
||||
import me.chanjar.weixin.cp.config.WxCpTpConfigStorage;
|
||||
import me.chanjar.weixin.cp.config.impl.AbstractWxCpTpInRedisConfigImpl;
|
||||
import me.chanjar.weixin.cp.config.impl.WxCpTpRedisTemplateConfigImpl;
|
||||
import me.chanjar.weixin.cp.config.impl.WxCpTpRedissonConfigImpl;
|
||||
import me.chanjar.weixin.cp.tp.service.WxCpTpService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -48,14 +50,10 @@ public class WxCpTpServiceApacheHttpClientImplTest {
|
||||
* The constant PROVIDER_CORP_ID.
|
||||
*/
|
||||
public static final String PROVIDER_CORP_ID = "xxxxxx";
|
||||
/**
|
||||
* The constant CORP_SECRET.
|
||||
*/
|
||||
public static final String CORP_SECRET = "xxxxxx";
|
||||
/**
|
||||
* The constant PROVIDER_SECRET.
|
||||
*/
|
||||
public static final String PROVIDER_SECRET = CORP_SECRET;
|
||||
public static final String PROVIDER_SECRET = "xxxxxx";
|
||||
/**
|
||||
* The constant REDIS_ADDR.
|
||||
*/
|
||||
@@ -85,9 +83,15 @@ public class WxCpTpServiceApacheHttpClientImplTest {
|
||||
* @return the wx cp tp config storage
|
||||
*/
|
||||
public WxCpTpConfigStorage wxCpTpConfigStorage() {
|
||||
return WxCpTpRedissonConfigImpl.builder().baseApiUrl(API_URL).suiteId(SUITE_ID).suiteSecret(SUITE_SECRET)
|
||||
.token(TOKEN).aesKey(AES_KEY).corpId(PROVIDER_CORP_ID).corpSecret(CORP_SECRET).providerSecret(PROVIDER_SECRET)
|
||||
.wxRedisOps(new RedissonWxRedisOps(redissonClient())).build();
|
||||
WxCpTpRedissonConfigImpl wxCpTpRedissonConfig=new WxCpTpRedissonConfigImpl(redissonClient(),"");
|
||||
wxCpTpRedissonConfig.setBaseApiUrl(API_URL);
|
||||
wxCpTpRedissonConfig.setSuiteId(SUITE_ID);
|
||||
wxCpTpRedissonConfig.setSuiteSecret(SUITE_SECRET);
|
||||
wxCpTpRedissonConfig.setToken(TOKEN);
|
||||
wxCpTpRedissonConfig.setEncodingAESKey(AES_KEY);
|
||||
wxCpTpRedissonConfig.setCorpId(PROVIDER_CORP_ID);
|
||||
wxCpTpRedissonConfig.setProviderSecret(PROVIDER_SECRET);
|
||||
return wxCpTpRedissonConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user