parent
5d473ba537
commit
199452d3b7
|
|
@ -212,7 +212,7 @@ impl From<crate::gotrue::GoTrueError> for AppError {
|
||||||
(400, m) if m.starts_with("User already registered") => {
|
(400, m) if m.starts_with("User already registered") => {
|
||||||
AppError::UserAlreadyRegistered(err.msg)
|
AppError::UserAlreadyRegistered(err.msg)
|
||||||
},
|
},
|
||||||
(401, _) => AppError::UserUnAuthorized(err.msg),
|
(401, _) => AppError::UserUnAuthorized(format!("{}:{}", err.code, err.msg)),
|
||||||
(422, _) => AppError::InvalidRequest(err.msg),
|
(422, _) => AppError::InvalidRequest(err.msg),
|
||||||
_ => AppError::OAuthError(err.to_string()),
|
_ => AppError::OAuthError(err.to_string()),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ use shared_entity::response::{AppResponse, AppResponseError};
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tracing::{event, instrument, trace, warn};
|
use tracing::{error, event, instrument, trace, warn};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use gotrue_entity::dto::SignUpResponse::{Authenticated, NotAuthenticated};
|
use gotrue_entity::dto::SignUpResponse::{Authenticated, NotAuthenticated};
|
||||||
|
|
@ -215,8 +215,11 @@ impl Client {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let access_token = access_token.ok_or(url_missing_param("access_token"))?;
|
let access_token = access_token.ok_or(url_missing_param("access_token"))?;
|
||||||
let (user, new) = self.verify_token(&access_token).await?;
|
if access_token.is_empty() {
|
||||||
|
return Err(AppError::OAuthError("Empty access token".to_string()).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let (user, new) = self.verify_token(&access_token).await?;
|
||||||
self.token.write().set(GotrueTokenResponse {
|
self.token.write().set(GotrueTokenResponse {
|
||||||
access_token,
|
access_token,
|
||||||
token_type: token_type.ok_or(url_missing_param("token_type"))?,
|
token_type: token_type.ok_or(url_missing_param("token_type"))?,
|
||||||
|
|
@ -336,6 +339,7 @@ impl Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[instrument(level = "debug", skip_all, err)]
|
||||||
async fn verify_token(&self, access_token: &str) -> Result<(User, bool), AppResponseError> {
|
async fn verify_token(&self, access_token: &str) -> Result<(User, bool), AppResponseError> {
|
||||||
let user = self.gotrue_client.user_info(access_token).await?;
|
let user = self.gotrue_client.user_info(access_token).await?;
|
||||||
let is_new = self.verify_token_cloud(access_token).await?;
|
let is_new = self.verify_token_cloud(access_token).await?;
|
||||||
|
|
@ -451,15 +455,20 @@ impl Client {
|
||||||
pub fn access_token(&self) -> Result<String, AppResponseError> {
|
pub fn access_token(&self) -> Result<String, AppResponseError> {
|
||||||
match &self.token.try_read_for(Duration::from_secs(2)) {
|
match &self.token.try_read_for(Duration::from_secs(2)) {
|
||||||
None => Err(AppError::Unhandled("Failed to read token".to_string()).into()),
|
None => Err(AppError::Unhandled("Failed to read token".to_string()).into()),
|
||||||
Some(token) => Ok(
|
Some(token) => {
|
||||||
token
|
let access_token = token
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(AppResponseError::from(AppError::NotLoggedIn(
|
.ok_or(AppResponseError::from(AppError::NotLoggedIn(
|
||||||
"fail to get access token. Token is empty".to_string(),
|
"fail to get access token. Token is empty".to_string(),
|
||||||
)))?
|
)))?
|
||||||
.access_token
|
.access_token
|
||||||
.clone(),
|
.clone();
|
||||||
),
|
|
||||||
|
if access_token.is_empty() {
|
||||||
|
error!("Unexpected empty access token");
|
||||||
|
}
|
||||||
|
Ok(access_token)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ use gotrue_entity::dto::{
|
||||||
use gotrue_entity::error::{GoTrueError, GoTrueErrorSerde, GotrueClientError};
|
use gotrue_entity::error::{GoTrueError, GoTrueErrorSerde, GotrueClientError};
|
||||||
use gotrue_entity::sso::{SSOProvider, SSOProviders};
|
use gotrue_entity::sso::{SSOProvider, SSOProviders};
|
||||||
use infra::reqwest::{check_response, from_body, from_response};
|
use infra::reqwest::{check_response, from_body, from_response};
|
||||||
|
use reqwest::{Method, RequestBuilder};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
|
|
@ -97,10 +98,9 @@ impl Client {
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, err)]
|
#[tracing::instrument(skip_all, err)]
|
||||||
pub async fn logout(&self, access_token: &str) -> Result<(), GoTrueError> {
|
pub async fn logout(&self, access_token: &str) -> Result<(), GoTrueError> {
|
||||||
|
let url = format!("{}/logout", self.base_url);
|
||||||
let resp = self
|
let resp = self
|
||||||
.client
|
.http_client_with_auth(Method::POST, &url, access_token)
|
||||||
.post(format!("{}/logout", self.base_url))
|
|
||||||
.header("Authorization", format!("Bearer {}", access_token))
|
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
Ok(check_response(resp).await?)
|
Ok(check_response(resp).await?)
|
||||||
|
|
@ -110,9 +110,7 @@ impl Client {
|
||||||
pub async fn user_info(&self, access_token: &str) -> Result<User, GoTrueError> {
|
pub async fn user_info(&self, access_token: &str) -> Result<User, GoTrueError> {
|
||||||
let url = format!("{}/user", self.base_url);
|
let url = format!("{}/user", self.base_url);
|
||||||
let resp = self
|
let resp = self
|
||||||
.client
|
.http_client_with_auth(Method::GET, &url, access_token)
|
||||||
.get(&url)
|
|
||||||
.header("Authorization", format!("Bearer {}", access_token))
|
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
to_gotrue_result(resp).await
|
to_gotrue_result(resp).await
|
||||||
|
|
@ -123,10 +121,9 @@ impl Client {
|
||||||
access_token: &str,
|
access_token: &str,
|
||||||
update_user_params: &UpdateGotrueUserParams,
|
update_user_params: &UpdateGotrueUserParams,
|
||||||
) -> Result<User, GoTrueError> {
|
) -> Result<User, GoTrueError> {
|
||||||
|
let url = format!("{}/user", self.base_url);
|
||||||
let resp = self
|
let resp = self
|
||||||
.client
|
.http_client_with_auth(Method::PUT, &url, access_token)
|
||||||
.put(format!("{}/user", self.base_url))
|
|
||||||
.header("Authorization", format!("Bearer {}", access_token))
|
|
||||||
.json(update_user_params)
|
.json(update_user_params)
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
@ -138,10 +135,9 @@ impl Client {
|
||||||
&self,
|
&self,
|
||||||
access_token: &str,
|
access_token: &str,
|
||||||
) -> Result<AdminListUsersResponse, GoTrueError> {
|
) -> Result<AdminListUsersResponse, GoTrueError> {
|
||||||
|
let url = format!("{}/admin/users", self.base_url);
|
||||||
let resp = self
|
let resp = self
|
||||||
.client
|
.http_client_with_auth(Method::GET, &url, access_token)
|
||||||
.get(format!("{}/admin/users", self.base_url))
|
|
||||||
.header("Authorization", format!("Bearer {}", access_token))
|
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
to_gotrue_result(resp).await
|
to_gotrue_result(resp).await
|
||||||
|
|
@ -152,10 +148,9 @@ impl Client {
|
||||||
access_token: &str,
|
access_token: &str,
|
||||||
user_id: &str, // uuid
|
user_id: &str, // uuid
|
||||||
) -> Result<User, GoTrueError> {
|
) -> Result<User, GoTrueError> {
|
||||||
|
let url = format!("{}/admin/users/{}", self.base_url, user_id);
|
||||||
let resp = self
|
let resp = self
|
||||||
.client
|
.http_client_with_auth(Method::GET, &url, access_token)
|
||||||
.get(format!("{}/admin/users/{}", self.base_url, user_id))
|
|
||||||
.header("Authorization", format!("Bearer {}", access_token))
|
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
to_gotrue_result(resp).await
|
to_gotrue_result(resp).await
|
||||||
|
|
@ -167,10 +162,9 @@ impl Client {
|
||||||
user_uuid: &str,
|
user_uuid: &str,
|
||||||
delete_user_params: &AdminDeleteUserParams,
|
delete_user_params: &AdminDeleteUserParams,
|
||||||
) -> Result<(), GoTrueError> {
|
) -> Result<(), GoTrueError> {
|
||||||
|
let url = format!("{}/admin/users/{}", self.base_url, user_uuid);
|
||||||
let resp = self
|
let resp = self
|
||||||
.client
|
.http_client_with_auth(Method::DELETE, &url, access_token)
|
||||||
.delete(format!("{}/admin/users/{}", self.base_url, user_uuid))
|
|
||||||
.header("Authorization", format!("Bearer {}", access_token))
|
|
||||||
.json(&delete_user_params)
|
.json(&delete_user_params)
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
@ -183,10 +177,9 @@ impl Client {
|
||||||
user_uuid: &str,
|
user_uuid: &str,
|
||||||
admin_user_params: &AdminUserParams,
|
admin_user_params: &AdminUserParams,
|
||||||
) -> Result<User, GoTrueError> {
|
) -> Result<User, GoTrueError> {
|
||||||
|
let url = format!("{}/admin/users/{}", self.base_url, user_uuid);
|
||||||
let resp = self
|
let resp = self
|
||||||
.client
|
.http_client_with_auth(Method::PUT, &url, access_token)
|
||||||
.put(format!("{}/admin/users/{}", self.base_url, user_uuid))
|
|
||||||
.header("Authorization", format!("Bearer {}", access_token))
|
|
||||||
.json(&admin_user_params)
|
.json(&admin_user_params)
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
@ -198,10 +191,9 @@ impl Client {
|
||||||
access_token: &str,
|
access_token: &str,
|
||||||
admin_user_params: &AdminUserParams,
|
admin_user_params: &AdminUserParams,
|
||||||
) -> Result<User, GoTrueError> {
|
) -> Result<User, GoTrueError> {
|
||||||
|
let url = format!("{}/admin/users", self.base_url);
|
||||||
let resp = self
|
let resp = self
|
||||||
.client
|
.http_client_with_auth(Method::POST, &url, access_token)
|
||||||
.post(format!("{}/admin/users", self.base_url))
|
|
||||||
.header("Authorization", format!("Bearer {}", access_token))
|
|
||||||
.json(&admin_user_params)
|
.json(&admin_user_params)
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
@ -213,10 +205,9 @@ impl Client {
|
||||||
access_token: &str,
|
access_token: &str,
|
||||||
generate_link_params: &GenerateLinkParams,
|
generate_link_params: &GenerateLinkParams,
|
||||||
) -> Result<GenerateLinkResponse, GoTrueError> {
|
) -> Result<GenerateLinkResponse, GoTrueError> {
|
||||||
|
let url = format!("{}/admin/generate_link", self.base_url);
|
||||||
let resp = self
|
let resp = self
|
||||||
.client
|
.http_client_with_auth(Method::POST, &url, access_token)
|
||||||
.post(format!("{}/admin/generate_link", self.base_url))
|
|
||||||
.header("Authorization", format!("Bearer {}", access_token))
|
|
||||||
.json(&generate_link_params)
|
.json(&generate_link_params)
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
@ -228,10 +219,9 @@ impl Client {
|
||||||
access_token: &str,
|
access_token: &str,
|
||||||
magic_link_params: &MagicLinkParams,
|
magic_link_params: &MagicLinkParams,
|
||||||
) -> Result<(), GoTrueError> {
|
) -> Result<(), GoTrueError> {
|
||||||
|
let url = format!("{}/magiclink", self.base_url);
|
||||||
let resp = self
|
let resp = self
|
||||||
.client
|
.http_client_with_auth(Method::POST, &url, access_token)
|
||||||
.post(format!("{}/magiclink", self.base_url))
|
|
||||||
.header("Authorization", format!("Bearer {}", access_token))
|
|
||||||
.json(&magic_link_params)
|
.json(&magic_link_params)
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
@ -242,10 +232,9 @@ impl Client {
|
||||||
&self,
|
&self,
|
||||||
access_token: &str,
|
access_token: &str,
|
||||||
) -> Result<SSOProviders, GoTrueError> {
|
) -> Result<SSOProviders, GoTrueError> {
|
||||||
|
let url = format!("{}/admin/sso/providers", self.base_url);
|
||||||
let resp = self
|
let resp = self
|
||||||
.client
|
.http_client_with_auth(Method::GET, &url, access_token)
|
||||||
.get(format!("{}/admin/sso/providers", self.base_url))
|
|
||||||
.header("Authorization", format!("Bearer {}", access_token))
|
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
to_gotrue_result(resp).await
|
to_gotrue_result(resp).await
|
||||||
|
|
@ -256,10 +245,9 @@ impl Client {
|
||||||
access_token: &str,
|
access_token: &str,
|
||||||
create_sso_provider_params: &CreateSSOProviderParams,
|
create_sso_provider_params: &CreateSSOProviderParams,
|
||||||
) -> Result<SSOProvider, GoTrueError> {
|
) -> Result<SSOProvider, GoTrueError> {
|
||||||
|
let url = format!("{}/admin/sso/providers", self.base_url);
|
||||||
let resp = self
|
let resp = self
|
||||||
.client
|
.http_client_with_auth(Method::POST, &url, access_token)
|
||||||
.post(format!("{}/admin/sso/providers", self.base_url))
|
|
||||||
.header("Authorization", format!("Bearer {}", access_token))
|
|
||||||
.json(create_sso_provider_params)
|
.json(create_sso_provider_params)
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
@ -271,10 +259,9 @@ impl Client {
|
||||||
access_token: &str,
|
access_token: &str,
|
||||||
idp_id: &str,
|
idp_id: &str,
|
||||||
) -> Result<SSOProvider, GoTrueError> {
|
) -> Result<SSOProvider, GoTrueError> {
|
||||||
|
let url = format!("{}/admin/sso/providers/{}", self.base_url, idp_id);
|
||||||
let resp = self
|
let resp = self
|
||||||
.client
|
.http_client_with_auth(Method::GET, &url, access_token)
|
||||||
.get(format!("{}/admin/sso/providers/{}", self.base_url, idp_id))
|
|
||||||
.header("Authorization", format!("Bearer {}", access_token))
|
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
to_gotrue_result(resp).await
|
to_gotrue_result(resp).await
|
||||||
|
|
@ -286,10 +273,9 @@ impl Client {
|
||||||
idp_id: &str,
|
idp_id: &str,
|
||||||
create_sso_provider_params: &CreateSSOProviderParams,
|
create_sso_provider_params: &CreateSSOProviderParams,
|
||||||
) -> Result<SSOProvider, GoTrueError> {
|
) -> Result<SSOProvider, GoTrueError> {
|
||||||
|
let url = format!("{}/admin/sso/providers/{}", self.base_url, idp_id);
|
||||||
let resp = self
|
let resp = self
|
||||||
.client
|
.http_client_with_auth(Method::PUT, &url, access_token)
|
||||||
.put(format!("{}/admin/sso/providers/{}", self.base_url, idp_id))
|
|
||||||
.header("Authorization", format!("Bearer {}", access_token))
|
|
||||||
.json(create_sso_provider_params)
|
.json(create_sso_provider_params)
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
@ -301,14 +287,22 @@ impl Client {
|
||||||
access_token: &str,
|
access_token: &str,
|
||||||
idp_id: &str,
|
idp_id: &str,
|
||||||
) -> Result<SSOProvider, GoTrueError> {
|
) -> Result<SSOProvider, GoTrueError> {
|
||||||
|
let url = format!("{}/admin/sso/providers/{}", self.base_url, idp_id);
|
||||||
let resp = self
|
let resp = self
|
||||||
.client
|
.http_client_with_auth(Method::DELETE, &url, access_token)
|
||||||
.delete(format!("{}/admin/sso/providers/{}", self.base_url, idp_id))
|
|
||||||
.header("Authorization", format!("Bearer {}", access_token))
|
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
to_gotrue_result(resp).await
|
to_gotrue_result(resp).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn http_client_with_auth(
|
||||||
|
&self,
|
||||||
|
method: Method,
|
||||||
|
url: &str,
|
||||||
|
access_token: &str,
|
||||||
|
) -> RequestBuilder {
|
||||||
|
self.client.request(method, url).bearer_auth(access_token)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn to_gotrue_result<T>(resp: reqwest::Response) -> Result<T, GoTrueError>
|
async fn to_gotrue_result<T>(resp: reqwest::Response) -> Result<T, GoTrueError>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue