113 lines
3.5 KiB
Rust
113 lines
3.5 KiB
Rust
use std::sync::Arc;
|
|
|
|
use chrono::Utc;
|
|
use domain::dto::account::AuthenticateGooleAccountReq;
|
|
use domain::entities::account::Account;
|
|
use domain::vo::account::{LoginAccount, RefreshTokenResult};
|
|
use i18n::message;
|
|
use i18n::message_ids::{ACCOUNT_DISABLED, INVALID_TOKEN};
|
|
use library::cache::account_cache::{CacheAccount, LOGIN_CACHE};
|
|
use library::context::{Context, WhiteContext};
|
|
use library::model::response::ResErr::ErrPerm;
|
|
use library::model::response::{ResErr, ResResult};
|
|
use library::social::google::GOOGLE_SOCIAL;
|
|
use library::token::{generate_refresh_token, generate_token};
|
|
use library::{db, token};
|
|
|
|
pub async fn authenticate_google(
|
|
context: WhiteContext,
|
|
req: AuthenticateGooleAccountReq,
|
|
) -> ResResult<LoginAccount> {
|
|
let verify_result = GOOGLE_SOCIAL
|
|
.verify_id_token(&req.id_token.unwrap())
|
|
.await
|
|
.map_err(|err| {
|
|
tracing::error!(error = ?err, "校验Google Token失败");
|
|
ErrPerm(None)
|
|
})?;
|
|
|
|
let account = Account::find_by_google_id(&verify_result.aud, db!()).await?;
|
|
let account = match account {
|
|
None => {
|
|
tracing::info!("账户不存在, {:?}", verify_result);
|
|
Account::save_google_account(
|
|
&Account {
|
|
username: verify_result.name,
|
|
google_id: Some(verify_result.aud),
|
|
email: Some(verify_result.email),
|
|
display_name: Some(verify_result.given_name),
|
|
avatar_url: Some(verify_result.picture),
|
|
..Default::default()
|
|
},
|
|
db!(),
|
|
)
|
|
.await?
|
|
}
|
|
Some(account) => {
|
|
tracing::info!("账户已存在, {:?}", account);
|
|
if let Some(disable_time) = account.disable_time {
|
|
if disable_time > Utc::now() {
|
|
tracing::error!("账户已禁用");
|
|
return Err(ResErr::service(message!(context.get_lang_tag(), ACCOUNT_DISABLED)));
|
|
}
|
|
}
|
|
|
|
account
|
|
}
|
|
};
|
|
|
|
let token = token::generate_token(&account.id);
|
|
let refresh_token = token::generate_refresh_token(&account.id);
|
|
|
|
LOGIN_CACHE
|
|
.insert(
|
|
account.id.to_owned(),
|
|
Arc::new(CacheAccount {
|
|
account: Arc::new(account.to_owned()),
|
|
token: Arc::new(token.to_owned()),
|
|
}),
|
|
)
|
|
.await;
|
|
|
|
let login_account = LoginAccount {
|
|
username: account.username,
|
|
display_name: account.display_name,
|
|
avatar_url: account.avatar_url,
|
|
metadata: account.metadata,
|
|
wallet: account.wallet,
|
|
email: account.email,
|
|
token,
|
|
refresh_token,
|
|
};
|
|
return Ok(login_account);
|
|
}
|
|
|
|
pub async fn refresh_token(
|
|
context: Context,
|
|
refresh_token: String,
|
|
) -> ResResult<RefreshTokenResult> {
|
|
let account = context.account.clone();
|
|
|
|
if token::verify_refresh_token(&refresh_token).is_err() {
|
|
return Err(ResErr::params(message!(context.get_lang_tag(), INVALID_TOKEN)));
|
|
}
|
|
|
|
let refresh_token = RefreshTokenResult {
|
|
token: generate_token(&account.id),
|
|
refresh_token: generate_refresh_token(&account.id),
|
|
};
|
|
|
|
LOGIN_CACHE.remove(&account.id).await;
|
|
LOGIN_CACHE
|
|
.insert(
|
|
account.id.to_owned(),
|
|
Arc::new(CacheAccount {
|
|
account,
|
|
token: Arc::new(refresh_token.token.to_owned()),
|
|
}),
|
|
)
|
|
.await;
|
|
|
|
Ok(refresh_token)
|
|
}
|