wx_rust_open/config/wx_open_config_storage.rs
1//! 开放平台(第三方平台)配置存储接口。
2//!
3//! 对应 Java `me.chanjar.weixin.open.api.WxOpenConfigStorage`。
4//!
5//! 与 mp/ma 不同:Java 的 `WxOpenConfigStorage` 是独立接口(不继承
6//! common `WxConfigStorage`),其核心是第三方平台的 component 凭据链
7//! (appid/secret/token/aesKey/verify_ticket → component_access_token)
8//! 与按 authorizer appId 分桶的 token/ticket 缓存。Rust trait 以只读
9//! 方法 + 可变方法表达同一契约(`&self` 可变性由内部锁保证)。
10
11use std::sync::Arc;
12use tokio::sync::Mutex as AsyncMutex;
13
14use wx_rust_common::config::WxConfigStorage;
15
16use crate::bean::{WxOpenAuthorizerAccessToken, WxOpenComponentAccessToken};
17use crate::config::WxOpenHostConfig;
18
19/// 开放平台(第三方平台)配置存储。
20///
21/// 全部方法对应 Java `WxOpenConfigStorage` 同名 getter/setter:
22/// component 三凭证 + verify_ticket + component_access_token 缓存、
23/// 按 appId 分桶的授权方 token/jsapi/card ticket、代理、重试与锁。
24pub trait WxOpenConfigStorage: Send + Sync {
25 // ---- 第三方平台 component 基础信息(对应 Java get/setComponentAppId 等) ----
26
27 /// 第三方平台 appid(对应 Java `getComponentAppId()`)。
28 fn component_app_id(&self) -> Option<String>;
29
30 /// 设置第三方平台 appid(对应 Java `setComponentAppId(String)`)。
31 fn set_component_app_id(&self, component_app_id: &str);
32
33 /// 第三方平台 appsecret(对应 Java `getComponentAppSecret()`)。
34 fn component_app_secret(&self) -> Option<String>;
35
36 /// 设置第三方平台 appsecret(对应 Java `setComponentAppSecret(String)`)。
37 fn set_component_app_secret(&self, component_app_secret: &str);
38
39 /// 消息校验 Token(对应 Java `getComponentToken()`)。
40 fn component_token(&self) -> Option<String>;
41
42 /// 设置消息校验 Token(对应 Java `setComponentToken(String)`)。
43 fn set_component_token(&self, component_token: &str);
44
45 /// 消息加解密 Key(对应 Java `getComponentAesKey()`)。
46 fn component_aes_key(&self) -> Option<String>;
47
48 /// 设置消息加解密 Key(对应 Java `setComponentAesKey(String)`)。
49 fn set_component_aes_key(&self, component_aes_key: &str);
50
51 /// 推送的 verify ticket(对应 Java `getComponentVerifyTicket()`)。
52 fn component_verify_ticket(&self) -> Option<String>;
53
54 /// 设置推送的 verify ticket(对应 Java `setComponentVerifyTicket(String)`)。
55 fn set_component_verify_ticket(&self, component_verify_ticket: &str);
56
57 /// 设置第三方平台基础信息(对应 Java `setWxOpenInfo` 四参便捷方法)。
58 fn set_wx_open_info(
59 &self,
60 component_app_id: &str,
61 component_app_secret: &str,
62 component_token: &str,
63 component_aes_key: &str,
64 ) {
65 self.set_component_app_id(component_app_id);
66 self.set_component_app_secret(component_app_secret);
67 self.set_component_token(component_token);
68 self.set_component_aes_key(component_aes_key);
69 }
70
71 // ---- component_access_token 缓存(对应 Java get/isExpired/expire/update) ----
72
73 /// 当前缓存的 component_access_token(对应 Java `getComponentAccessToken()`)。
74 fn component_access_token(&self) -> Option<String>;
75
76 /// component_access_token 是否已过期(对应 Java `isComponentAccessTokenExpired()`)。
77 fn is_component_access_token_expired(&self) -> bool;
78
79 /// 强制将 component_access_token 过期(对应 Java `expireComponentAccessToken()`)。
80 fn expire_component_access_token(&self);
81
82 /// 线程安全地更新 component_access_token(对应 Java
83 /// `updateComponentAccessToken(WxOpenComponentAccessToken)`)。
84 fn update_component_access_token(&self, component_access_token: &WxOpenComponentAccessToken) {
85 self.update_component_access_token_with_expiry(
86 component_access_token.component_access_token(),
87 component_access_token.expires_in(),
88 );
89 }
90
91 /// 线程安全地更新 component_access_token(对应 Java
92 /// `updateComponentAccessToken(String, int)` 重载)。
93 fn update_component_access_token_with_expiry(
94 &self,
95 component_access_token: &str,
96 expires_in_seconds: i32,
97 );
98
99 /// component_access_token 锁(对应 Java `getComponentAccessTokenLock()`)。
100 fn component_access_token_lock(&self) -> Arc<AsyncMutex<()>>;
101
102 /// 按 key 取锁(对应 Java `getLockByKey(String)`,并发仅刷新一次语义)。
103 fn lock_by_key(&self, key: &str) -> Arc<AsyncMutex<()>>;
104
105 /// token 过期时是否自动刷新(对应 Java `autoRefreshToken()`,默认 true)。
106 fn auto_refresh_token(&self) -> bool {
107 true
108 }
109
110 // ---- 授权方(authorizer)token/ticket 缓存(按 appId 分桶) ----
111
112 /// 授权方 refresh_token(对应 Java `getAuthorizerRefreshToken(String)`)。
113 fn authorizer_refresh_token(&self, app_id: &str) -> Option<String>;
114
115 /// 设置授权方 refresh_token(对应 Java `setAuthorizerRefreshToken(String, String)`)。
116 fn set_authorizer_refresh_token(&self, app_id: &str, authorizer_refresh_token: &str);
117
118 /// 更新授权方 refresh_token(对应 Java `updateAuthorizerRefreshToken(String, String)`
119 /// 重载方法,Java 语义与 set 相同)。
120 fn update_authorizer_refresh_token(&self, app_id: &str, authorizer_refresh_token: &str) {
121 self.set_authorizer_refresh_token(app_id, authorizer_refresh_token);
122 }
123
124 /// 授权方 access_token(对应 Java `getAuthorizerAccessToken(String)`)。
125 fn authorizer_access_token(&self, app_id: &str) -> Option<String>;
126
127 /// 授权方 access_token 是否过期(对应 Java `isAuthorizerAccessTokenExpired(String)`)。
128 fn is_authorizer_access_token_expired(&self, app_id: &str) -> bool;
129
130 /// 强制将授权方 access_token 过期(对应 Java `expireAuthorizerAccessToken(String)`)。
131 fn expire_authorizer_access_token(&self, app_id: &str);
132
133 /// 线程安全地更新授权方 access_token(对应 Java
134 /// `updateAuthorizerAccessToken(String, WxOpenAuthorizerAccessToken)`)。
135 fn update_authorizer_access_token(
136 &self,
137 app_id: &str,
138 authorizer_access_token: &WxOpenAuthorizerAccessToken,
139 ) {
140 self.update_authorizer_access_token_with_expiry(
141 app_id,
142 authorizer_access_token.authorizer_access_token(),
143 authorizer_access_token.expires_in(),
144 );
145 }
146
147 /// 线程安全地更新授权方 access_token(对应 Java
148 /// `updateAuthorizerAccessToken(String, String, int)` 重载)。
149 fn update_authorizer_access_token_with_expiry(
150 &self,
151 app_id: &str,
152 authorizer_access_token: &str,
153 expires_in_seconds: i32,
154 );
155
156 /// 授权方 jsapi ticket(对应 Java `getJsapiTicket(String)`)。
157 fn jsapi_ticket(&self, app_id: &str) -> Option<String>;
158
159 /// 授权方 jsapi ticket 是否过期(对应 Java `isJsapiTicketExpired(String)`)。
160 fn is_jsapi_ticket_expired(&self, app_id: &str) -> bool;
161
162 /// 强制将授权方 jsapi ticket 过期(对应 Java `expireJsapiTicket(String)`)。
163 fn expire_jsapi_ticket(&self, app_id: &str);
164
165 /// 线程安全地更新授权方 jsapi ticket(对应 Java
166 /// `updateJsapiTicket(String, String, int)`)。
167 fn update_jsapi_ticket(&self, app_id: &str, jsapi_ticket: &str, expires_in_seconds: i32);
168
169 /// 授权方卡券 api ticket(对应 Java `getCardApiTicket(String)`)。
170 fn card_api_ticket(&self, app_id: &str) -> Option<String>;
171
172 /// 授权方卡券 api ticket 是否过期(对应 Java `isCardApiTicketExpired(String)`)。
173 fn is_card_api_ticket_expired(&self, app_id: &str) -> bool;
174
175 /// 强制将授权方卡券 api ticket 过期(对应 Java `expireCardApiTicket(String)`)。
176 fn expire_card_api_ticket(&self, app_id: &str);
177
178 /// 线程安全地更新授权方卡券 api ticket(对应 Java
179 /// `updateCardApiTicket(String, String, int)`)。
180 fn update_card_api_ticket(&self, app_id: &str, card_api_ticket: &str, expires_in_seconds: i32);
181
182 // ---- 授权方代 mp/ma 配置桥接 ----
183
184 /// 按 appId 取代公众号配置存储(对应 Java `getWxMpConfigStorage(String)`)。
185 ///
186 /// Wave 0 占位:Java 返回 `WxMpConfigStorage`(`WxOpenInnerConfigStorage`
187 /// 内层桥接实现),Rust 侧待代 mp 桥接波次接入 `wx-rust-mp` 后返回其
188 /// `WxMpConfigStorage` trait 对象,当前统一以 common `WxConfigStorage`
189 /// 表达并返回 `None`。
190 fn wx_mp_config_storage(&self, _app_id: &str) -> Option<Arc<dyn WxConfigStorage>> {
191 None
192 }
193
194 /// 按 appId 取代小程序配置存储(对应 Java `getWxMaConfig(String)`)。
195 ///
196 /// 占位说明同 [`Self::wx_mp_config_storage`]。
197 fn wx_ma_config(&self, _app_id: &str) -> Option<Arc<dyn WxConfigStorage>> {
198 None
199 }
200
201 /// 自定义域名配置(对应 mp/ma 的 host config 语义)。
202 ///
203 /// Java `WxOpenConfigStorage` 无此方法,以 `WxOpenInMemoryConfigStorage`
204 /// 的 `apiHostUrl` 表达同一能力;Rust 侧统一为 host 配置结构,默认
205 /// 返回 `None`(使用 `https://api.weixin.qq.com`),默认实现返回
206 /// 含自定义 apiHostUrl 的配置。
207 fn wx_open_host_config(&self) -> Option<WxOpenHostConfig> {
208 None
209 }
210
211 // ---- HTTP 代理与重试 ----
212
213 /// HTTP 代理主机(对应 Java `getHttpProxyHost()`)。
214 fn http_proxy_host(&self) -> Option<String>;
215
216 /// HTTP 代理端口(对应 Java `getHttpProxyPort()`)。
217 fn http_proxy_port(&self) -> i32;
218
219 /// HTTP 代理用户名(对应 Java `getHttpProxyUsername()`)。
220 fn http_proxy_username(&self) -> Option<String>;
221
222 /// HTTP 代理密码(对应 Java `getHttpProxyPassword()`)。
223 fn http_proxy_password(&self) -> Option<String>;
224
225 /// HTTP 请求重试间隔(毫秒,对应 Java `getRetrySleepMillis()`,默认 1000)。
226 fn retry_sleep_millis(&self) -> i32 {
227 1000
228 }
229
230 /// HTTP 请求最大重试次数(对应 Java `getMaxRetryTimes()`,默认 5)。
231 fn max_retry_times(&self) -> i32 {
232 5
233 }
234
235 // ---- 服务端 API 签名(RSA/AES 私钥与序号) ----
236
237 /// 第三方平台设置 API 签名 RSA 私钥(对应 Java
238 /// `getComponentApiSignatureRsaPrivateKey()`)。
239 fn component_api_signature_rsa_private_key(&self) -> Option<String>;
240
241 /// 设置 API 签名 RSA 私钥(对应 Java
242 /// `setComponentApiSignatureRsaPrivateKey(String)`)。
243 fn set_component_api_signature_rsa_private_key(&self, api_signature_rsa_private_key: &str);
244
245 /// API 签名 AES KEY(对应 Java `getComponentApiSignatureAesKey()`)。
246 fn component_api_signature_aes_key(&self) -> Option<String>;
247
248 /// 设置 API 签名 AES KEY(对应 Java `setComponentApiSignatureAesKey(String)`)。
249 fn set_component_api_signature_aes_key(&self, api_signature_aes_key: &str);
250
251 /// API 签名 RSA 私钥序号(对应 Java `getComponentApiSignatureRsaPrivateKeySn()`)。
252 fn component_api_signature_rsa_private_key_sn(&self) -> Option<String>;
253
254 /// 设置 API 签名 RSA 私钥序号(对应 Java
255 /// `setComponentApiSignatureRsaPrivateKeySn(String)`)。
256 fn set_component_api_signature_rsa_private_key_sn(
257 &self,
258 api_signature_rsa_private_key_sn: &str,
259 );
260
261 /// API 签名 AES key 序号(对应 Java `getComponentApiSignatureAesKeySn()`)。
262 fn component_api_signature_aes_key_sn(&self) -> Option<String>;
263
264 /// 设置 API 签名 AES key 序号(对应 Java
265 /// `setComponentApiSignatureAesKeySn(String)`)。
266 fn set_component_api_signature_aes_key_sn(&self, api_signature_aes_key_sn: &str);
267}