bios_iam/basic/serv/oauth2_spi/
iam_cert_oauth2_spi_github.rs1use crate::basic::serv::iam_cert_oauth2_serv::{IamCertOAuth2Spi, IamCertOAuth2TokenInfo};
2use async_trait::async_trait;
3use ldap3::log::trace;
4use tardis::basic::result::TardisResult;
5use tardis::serde_json::Value;
6use tardis::{TardisFuns, TardisFunsInst};
7
8pub struct IamCertOAuth2SpiGithub;
9const OAUTH2_GITHUB_USER_INFO_CACHE_KEY: &str = "OAUTH2_GITHUB_USER_INFO_CACHE_KEY:";
10#[async_trait]
11impl IamCertOAuth2Spi for IamCertOAuth2SpiGithub {
12 async fn get_access_token(&self, code: &str, ak: &str, sk: &str, funs: &TardisFunsInst) -> TardisResult<IamCertOAuth2TokenInfo> {
13 let headers = vec![("Accept".to_string(), "application/json".to_string())];
15 let result = funs
16 .web_client()
17 .post_to_obj::<Value>(
18 &format!("https://github.com/login/oauth/access_token?client_id={ak}&client_secret={sk}&code={code}"),
19 "",
20 headers,
21 )
22 .await?;
23 if result.code != 200 {
24 return Err(funs.err().not_found(
25 "oauth_spi_github",
26 "get_access_token",
27 "oauth get access token error",
28 "500-iam-cert-oauth-get-access-token-error",
29 ));
30 }
31 let result = result.body.unwrap_or_default();
32 trace!("iam oauth2 spi [Github] get access token response: {}", result);
33 if let Some(access_token) = result.get("access_token") {
34 let access_token = access_token.as_str().unwrap_or("");
35 let headers = vec![
36 ("Authorization".to_string(), format!("Bearer {access_token}")),
37 ("Accept".to_string(), "application/json".to_string()),
38 ("User-Agent".to_string(), "BIOS".to_string()),
39 ];
40 let result = funs.web_client().get_to_str("https://api.github.com/user", headers).await?;
42 trace!("iam oauth2 spi [Github] get user info response: {:?}", result);
43 if result.code != 200 {
44 return Err(funs.err().not_found(
45 "oauth_spi_github",
46 "get_access_token",
47 "oauth get user info error",
48 "500-iam-cert-oauth-get-user-info-error",
49 ));
50 }
51 let user_info = result.body.unwrap_or_default();
52 let user_info = TardisFuns::json.str_to_obj::<Value>(&user_info)?;
53 funs.cache().set_ex(&format!("{OAUTH2_GITHUB_USER_INFO_CACHE_KEY}{access_token}"), &user_info.to_string(), 5).await?;
54 if let Some(id) = user_info.get("id") {
55 Ok(IamCertOAuth2TokenInfo {
56 open_id: id.to_string(),
57 access_token: access_token.to_string(),
58 refresh_token: None,
59 token_expires_ms: None,
60 union_id: None,
61 })
62 } else {
63 Err(funs.err().not_found(
64 "oauth_spi_github",
65 "get_access_token",
66 "oauth get user info error",
67 "500-iam-cert-oauth-get-user-info-error",
68 ))
69 }
70 } else {
71 let mut v_error = "";
72 if let Some(error) = result.get("error") {
73 v_error = error.as_str().unwrap_or("");
74 }
75 Err(funs.err().not_found(
76 "oauth_spi_github",
77 "get_access_token",
78 &format!("oauth get access token error:{v_error}"),
79 "500-iam-cert-oauth-get-access-token-error",
80 ))
81 }
82 }
83
84 async fn get_account_name(&self, oauth2_info: IamCertOAuth2TokenInfo, funs: &TardisFunsInst) -> TardisResult<String> {
85 let user_info = funs.cache().get(&format!("{}{}", OAUTH2_GITHUB_USER_INFO_CACHE_KEY, oauth2_info.access_token.clone())).await?;
86 if let Some(user_info) = user_info {
87 let result = TardisFuns::json.str_to_obj::<Value>(&user_info)?;
88 Ok(result.get("name").unwrap_or(&Value::Null).as_str().unwrap_or("").to_string())
89 } else {
90 Err(funs.err().not_found(
91 "oauth_spi_github",
92 "get_account_name",
93 "oauth get account name error",
94 "500-iam-cert-oauth-get-account-name-error",
95 ))
96 }
97 }
98}