use serde::{Serialize, Deserialize};
use crate::{session::SessionStore, request::{RequestType}, wechat::{mp::method::WechatMpMethod}, WechatCommonResponse, WechatMpClient, LabradorResult, LabraError};
use crate::wechat::mp::constants::{ACCESS_TOKEN, APPID, CODE, GRANT_TYPE, LANG, OPENID, REFRESH_TOKEN, SECRET, ZH_CN};
use crate::wechat::mp::method::Oauth2Method;
#[derive(Debug, Clone)]
pub struct WechatMpOauth2<'a, T: SessionStore> {
client: &'a WechatMpClient<T>,
}
#[allow(unused)]
impl<'a, T: SessionStore> WechatMpOauth2<'a, T> {
#[inline]
pub fn new(client: &WechatMpClient<T>) -> WechatMpOauth2<T> {
WechatMpOauth2 {
client,
}
}
pub async fn oauth2_token(&self, code: &str) -> LabradorResult<WechatMpOauth2AccessTokenResponse> {
let v = self.client.get(WechatMpMethod::Oauth2(Oauth2Method::AccessToken), vec![
(GRANT_TYPE.to_string(), "authorization_code".to_string()),
(CODE.to_string(), code.to_string()),
(APPID.to_string(), self.client.appid.to_string()),
(SECRET.to_string(), self.client.secret.to_string()),
], RequestType::Json).await?.json::<serde_json::Value>()?;
let mut result = WechatCommonResponse::from_value(v.clone())?;
if result.is_success() {
Ok(serde_json::from_value::<WechatMpOauth2AccessTokenResponse>(v)?)
} else {
Err(LabraError::ClientError {errcode: result.errcode.to_owned().unwrap_or_default().to_string(), errmsg: result.errmsg.to_owned().unwrap_or_default()})
}
}
pub async fn refresh_token(&self, refresh_token: &str) -> LabradorResult<WechatMpOauth2AccessTokenResponse> {
let v = self.client.get(WechatMpMethod::Oauth2(Oauth2Method::RefreshToken), vec![
(GRANT_TYPE.to_string(), REFRESH_TOKEN.to_string()),
(REFRESH_TOKEN.to_string(), refresh_token.to_string()),
(APPID.to_string(), self.client.appid.to_string()),
], RequestType::Json).await?.json::<serde_json::Value>()?;
let mut result = WechatCommonResponse::from_value(v.to_owned())?;
if result.is_success() {
Ok(serde_json::from_value::<WechatMpOauth2AccessTokenResponse>(v)?)
} else {
Err(LabraError::ClientError {errcode: result.errcode.to_owned().unwrap_or_default().to_string(), errmsg: result.errmsg.to_owned().unwrap_or_default()})
}
}
pub async fn oauth2_userinfo(&self, access_token: &str, openid: &str) -> LabradorResult<WechatMpOauth2UserInfo> {
let v = self.client.get(WechatMpMethod::Oauth2(Oauth2Method::UserInfo), vec![
(ACCESS_TOKEN.to_string(), access_token.to_string()),
(OPENID.to_string(), openid.to_string()),
(LANG.to_string(), ZH_CN.to_string()),
], RequestType::Json).await?.json::<serde_json::Value>()?;
let mut result = WechatCommonResponse::from_value(v.to_owned())?;
if result.is_success() {
Ok(serde_json::from_value::<WechatMpOauth2UserInfo>(v)?)
} else {
Err(LabraError::ClientError {errcode: result.errcode.to_owned().unwrap_or_default().to_string(), errmsg: result.errmsg.to_owned().unwrap_or_default()})
}
}
}
#[allow(unused)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatMpOauth2AccessTokenResponse{
pub access_token: String,
pub refresh_token: Option<String>,
pub openid: String,
pub scope: String,
pub expires_in: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatMpOauth2UserInfo {
pub openid: String,
pub nickname: String,
pub sex: u8,
pub city: String,
pub province: String,
pub country: String,
pub headimgurl: String,
pub unionid: Option<String>,
}