diff --git a/imphnen-iam/src/v1/auth/google/google_oauth_controller.rs b/imphnen-iam/src/v1/auth/google/google_oauth_controller.rs index 6213ad4..af0522a 100644 --- a/imphnen-iam/src/v1/auth/google/google_oauth_controller.rs +++ b/imphnen-iam/src/v1/auth/google/google_oauth_controller.rs @@ -19,6 +19,11 @@ pub struct GoogleAuthUrlResponse { pub authorize_url: String, } +#[derive(Debug, Serialize, Deserialize)] +pub struct GoogleLoginRequest { + pub redirect_uri: Option, +} + pub struct GoogleOauthController { google_oauth_service: T, } @@ -49,8 +54,8 @@ where .route( "/login", get( - move |State(controller): State>| async move { - controller.google_oauth_login().await + move |State(controller): State>, Query(params): Query| async move { + controller.google_oauth_login(params).await }, ), ) @@ -66,8 +71,8 @@ where .with_state(Arc::new(self.clone())) } - pub async fn google_oauth_login(&self) -> Result { - let (authorize_url, _csrf_state) = self.google_oauth_service.generate_auth_url(); + pub async fn google_oauth_login(&self, params: GoogleLoginRequest) -> Result { + let (authorize_url, _csrf_state) = self.google_oauth_service.generate_auth_url(params.redirect_uri); Ok(Redirect::to(authorize_url.as_str())) } diff --git a/imphnen-iam/src/v1/auth/google/google_oauth_service.rs b/imphnen-iam/src/v1/auth/google/google_oauth_service.rs index 9b22eba..e3d0581 100644 --- a/imphnen-iam/src/v1/auth/google/google_oauth_service.rs +++ b/imphnen-iam/src/v1/auth/google/google_oauth_service.rs @@ -89,8 +89,8 @@ async fn get_default_role_id(_env: &Env) -> Result { pub trait GoogleOauthService: Send + Sync + 'static { // Removed new() from trait fn with_services(auth_service: A, users_service: U, env: &'static Env) -> Self; - fn google_oauth_client(&self) -> BasicClient; - fn generate_auth_url(&self) -> (Url, CsrfToken); + fn google_oauth_client(&self, custom_redirect_uri: Option) -> BasicClient; + fn generate_auth_url(&self, custom_redirect_uri: Option) -> (Url, CsrfToken); async fn google_oauth_callback(&self, auth_request: AuthRequest, app_state: &AppState) -> Result<(UsersDetailItemDto, TokenDto), Error>; // Changed return type } @@ -103,7 +103,11 @@ pub struct GoogleOauthServiceImpl { } impl GoogleOauthServiceImpl { - // Removed the `new()` method as it will be replaced by `with_services` + /// Generate Google OAuth authorization URL + pub fn get_auth_url(&self, custom_redirect_uri: Option) -> String { + let (auth_url, _csrf_token) = self.generate_auth_url(custom_redirect_uri); + auth_url.to_string() + } } #[async_trait] @@ -120,7 +124,7 @@ where } } - fn google_oauth_client(&self) -> BasicClient { + fn google_oauth_client(&self, custom_redirect_uri: Option) -> BasicClient { let google_client_id = ClientId::new(self.env.google_client_id.clone()); let google_client_secret = ClientSecret::new(self.env.google_client_secret.clone()); let auth_url = AuthUrl::new("https://accounts.google.com/o/oauth2/v2/auth".to_string()) @@ -128,6 +132,8 @@ where let token_url = TokenUrl::new("https://oauth2.googleapis.com/token".to_string()) .expect("Invalid token endpoint URL"); + let redirect_uri = custom_redirect_uri.unwrap_or_else(|| self.env.google_redirect_url.clone()); + BasicClient::new( google_client_id, Some(google_client_secret), @@ -135,13 +141,13 @@ where Some(token_url), ) .set_redirect_uri( - RedirectUrl::new(self.env.google_redirect_url.clone()) + RedirectUrl::new(redirect_uri) .expect("Invalid redirect URL"), ) } - fn generate_auth_url(&self) -> (Url, CsrfToken) { - let client = self.google_oauth_client(); + fn generate_auth_url(&self, custom_redirect_uri: Option) -> (Url, CsrfToken) { + let client = self.google_oauth_client(custom_redirect_uri); let (pkce_code_challenge, pkce_code_verifier) = PkceCodeChallenge::new_random_sha256(); // Generate a signed CSRF token with PKCE verifier for stateless validation @@ -167,7 +173,8 @@ where info!("Starting Google OAuth callback process"); - let client = self.google_oauth_client(); + // Use the default client for the callback + let client = self.google_oauth_client(None); let token_response = client .exchange_code(oauth2::AuthorizationCode::new(auth_request.code))