diff --git a/packages/asgardeo-ai/src/asgardeo_ai/agent_auth_manager.py b/packages/asgardeo-ai/src/asgardeo_ai/agent_auth_manager.py index 7af0f48..e010841 100644 --- a/packages/asgardeo-ai/src/asgardeo_ai/agent_auth_manager.py +++ b/packages/asgardeo-ai/src/asgardeo_ai/agent_auth_manager.py @@ -388,6 +388,41 @@ async def get_obo_token_with_ciba( logger.error(f"CIBA OBO token exchange failed: {e}") raise TokenError(f"CIBA OBO token exchange failed: {e}") + async def switch_token_to_organization( + self, + token: str, + switching_organization: str, + scopes: Optional[List[str]] = None + ) -> OAuthToken: + """Switch token to a sub-organization. + + :param token: The current access token to be switched. + :param switching_organization: The ID or UUID of the target organization. + :param scopes: Optional list of scopes to request. + :return: OAuth token for the switched organization. + """ + if not token: + raise ValidationError("Token is required for organization switch.") + if not switching_organization: + raise ValidationError("switching_organization is required.") + + scope_str = ' '.join(scopes) if scopes else "add" + + try: + switched_token = await self.token_client.get_token( + 'organization_switch', + token=token, + switching_organization=switching_organization, + scope=scope_str + ) + return switched_token + + except (TokenError, ValidationError): + raise + except Exception as e: + logger.error(f"Organization switch failed: {e}") + raise TokenError(f"Organization switch failed: {e}") + async def revoke_token( self, token: str, diff --git a/packages/asgardeo/src/asgardeo/auth/client.py b/packages/asgardeo/src/asgardeo/auth/client.py index 780c9ad..9601f7e 100644 --- a/packages/asgardeo/src/asgardeo/auth/client.py +++ b/packages/asgardeo/src/asgardeo/auth/client.py @@ -327,6 +327,18 @@ async def get_token(self, grant_type: str, **kwargs: Any) -> OAuthToken: scope = kwargs.get("scope") if scope: data["scope"] = scope + elif grant_type == "organization_switch": + token = kwargs.get("token") + switching_organization = kwargs.get("switching_organization") + if not token or not switching_organization: + raise ValidationError( + "token and switching_organization are required for 'organization_switch' grant type.", + ) + data["token"] = token + data["switching_organization"] = switching_organization + scope = kwargs.get("scope") + if scope: + data["scope"] = scope else: raise ValidationError(f"Unsupported grant type: {grant_type}")