Skip to content

Commit

Permalink
Merge pull request #403 from supertokens/handle-tenant-not-found
Browse files Browse the repository at this point in the history
fix: handle tenant not found error
  • Loading branch information
rishabhpoddar authored Aug 14, 2023
2 parents 87b74e7 + 01b87ec commit f95a9d1
Show file tree
Hide file tree
Showing 18 changed files with 77 additions and 111 deletions.
34 changes: 18 additions & 16 deletions supertokens_python/recipe/multitenancy/api/implementation.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,16 @@ async def login_methods_get(
api_options: APIOptions,
user_context: Dict[str, Any],
) -> Union[LoginMethodsGetOkResult, GeneralErrorResponse]:
tenant_config_res = await api_options.recipe_implementation.get_tenant(

tenant_config = await api_options.recipe_implementation.get_tenant(
tenant_id, user_context
)

if tenant_config is None:
raise Exception("Tenant not found")

provider_inputs_from_static = api_options.static_third_party_providers
provider_configs_from_core = tenant_config_res.third_party.providers
provider_configs_from_core = tenant_config.third_party.providers

merged_providers = merge_providers_from_core_and_static(
provider_configs_from_core, provider_inputs_from_static
Expand All @@ -61,24 +65,22 @@ async def login_methods_get(
client_type,
user_context,
)
final_provider_list.append(
ThirdPartyProvider(
provider_instance.id, provider_instance.config.name
)
)
except Exception as e:
if isinstance(e, ClientTypeNotFoundError):
continue
raise e

if provider_instance is None:
raise Exception("Should never come here")

except ClientTypeNotFoundError:
continue
final_provider_list.append(
ThirdPartyProvider(provider_instance.id, provider_instance.config.name)
)

return LoginMethodsGetOkResult(
email_password=LoginMethodEmailPassword(
tenant_config_res.emailpassword.enabled
),
passwordless=LoginMethodPasswordless(
tenant_config_res.passwordless.enabled
tenant_config.emailpassword.enabled
),
passwordless=LoginMethodPasswordless(tenant_config.passwordless.enabled),
third_party=LoginMethodThirdParty(
tenant_config_res.third_party.enabled, final_provider_list
tenant_config.third_party.enabled, final_provider_list
),
)
2 changes: 1 addition & 1 deletion supertokens_python/recipe/multitenancy/asyncio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ async def delete_tenant(

async def get_tenant(
tenant_id: str, user_context: Optional[Dict[str, Any]] = None
) -> GetTenantOkResult:
) -> Optional[GetTenantOkResult]:
if user_context is None:
user_context = {}
recipe = MultitenancyRecipe.get_instance()
Expand Down
2 changes: 1 addition & 1 deletion supertokens_python/recipe/multitenancy/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ async def delete_tenant(
@abstractmethod
async def get_tenant(
self, tenant_id: str, user_context: Dict[str, Any]
) -> GetTenantOkResult:
) -> Optional[GetTenantOkResult]:
pass

@abstractmethod
Expand Down
62 changes: 1 addition & 61 deletions supertokens_python/recipe/multitenancy/recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
from ...post_init_callbacks import PostSTInitCallbacks

from .interfaces import (
APIInterface,
APIOptions,
TypeGetAllowedDomainsForTenantId,
)
Expand All @@ -42,19 +41,12 @@

from supertokens_python.normalised_url_path import NormalisedURLPath
from supertokens_python.querier import Querier
from supertokens_python.types import GeneralErrorResponse
from supertokens_python.recipe.multitenancy.api.implementation import APIImplementation


from .api import handle_login_methods_api
from .constants import LOGIN_METHODS
from .exceptions import MultitenancyError
from .interfaces import (
LoginMethodsGetOkResult,
ThirdPartyProvider,
LoginMethodEmailPassword,
LoginMethodPasswordless,
LoginMethodThirdParty,
)
from .utils import (
InputOverrideConfig,
validate_and_normalise_user_input,
Expand Down Expand Up @@ -196,58 +188,6 @@ def reset():
MultitenancyRecipe.__instance = None


class APIImplementation(APIInterface):
async def login_methods_get(
self,
tenant_id: str,
client_type: Optional[str],
api_options: APIOptions,
user_context: Dict[str, Any],
) -> Union[LoginMethodsGetOkResult, GeneralErrorResponse]:
from supertokens_python.recipe.thirdparty.providers.config_utils import (
find_and_create_provider_instance,
merge_providers_from_core_and_static,
)
from supertokens_python.recipe.thirdparty.exceptions import (
ClientTypeNotFoundError,
)

tenant_config = await api_options.recipe_implementation.get_tenant(
tenant_id, user_context
)

provider_inputs_from_static = api_options.static_third_party_providers
provider_configs_from_core = tenant_config.third_party.providers

merged_providers = merge_providers_from_core_and_static(
provider_configs_from_core, provider_inputs_from_static
)

final_provider_list: List[ThirdPartyProvider] = []

for provider_input in merged_providers:
try:
provider_instance = await find_and_create_provider_instance(
merged_providers,
provider_input.config.third_party_id,
client_type,
user_context,
)
except ClientTypeNotFoundError:
continue
final_provider_list.append(
ThirdPartyProvider(provider_instance.id, provider_instance.config.name)
)

return LoginMethodsGetOkResult(
LoginMethodEmailPassword(tenant_config.emailpassword.enabled),
LoginMethodPasswordless(tenant_config.passwordless.enabled),
LoginMethodThirdParty(
tenant_config.third_party.enabled, final_provider_list
),
)


class AllowedDomainsClaimClass(PrimitiveArrayClaim[List[str]]):
def __init__(self):
default_max_age_in_sec = 60 * 60
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,16 @@ async def delete_tenant(

async def get_tenant(
self, tenant_id: Optional[str], user_context: Dict[str, Any]
) -> GetTenantOkResult:
) -> Optional[GetTenantOkResult]:
res = await self.querier.send_get_request(
NormalisedURLPath(
f"{tenant_id or DEFAULT_TENANT_ID}/recipe/multitenancy/tenant"
),
)

if res["status"] == "TENANT_NOT_FOUND_ERROR":
return None

tenant_config = parse_tenant_config(res)

return GetTenantOkResult(
Expand Down
9 changes: 7 additions & 2 deletions supertokens_python/recipe/thirdparty/api/authorisation_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
if TYPE_CHECKING:
from supertokens_python.recipe.thirdparty.interfaces import APIOptions, APIInterface

from supertokens_python.exceptions import raise_bad_input_exception
from supertokens_python.exceptions import raise_bad_input_exception, BadInputError
from supertokens_python.utils import send_200_response


Expand Down Expand Up @@ -53,7 +53,12 @@ async def handle_authorisation_url_api(
user_context=user_context,
)

provider = provider_response.provider
if provider_response is None:
raise BadInputError(
f"the provider {third_party_id} could not be found in the configuration"
)

provider = provider_response
result = await api_implementation.authorisation_url_get(
provider=provider,
redirect_uri_on_provider_dashboard=redirect_uri_on_provider_dashboard,
Expand Down
9 changes: 7 additions & 2 deletions supertokens_python/recipe/thirdparty/api/signinup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
if TYPE_CHECKING:
from supertokens_python.recipe.thirdparty.interfaces import APIOptions, APIInterface

from supertokens_python.exceptions import raise_bad_input_exception
from supertokens_python.exceptions import raise_bad_input_exception, BadInputError
from supertokens_python.utils import send_200_response


Expand Down Expand Up @@ -64,7 +64,12 @@ async def handle_sign_in_up_api(
user_context=user_context,
)

provider = provider_response.provider
if provider_response is None:
raise BadInputError(
f"the provider {third_party_id} could not be found in the configuration"
)

provider = provider_response

result = await api_implementation.sign_in_up_post(
provider=provider,
Expand Down
2 changes: 1 addition & 1 deletion supertokens_python/recipe/thirdparty/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ async def get_provider(
client_type: Optional[str],
tenant_id: str,
user_context: Dict[str, Any],
) -> GetProviderOkResult:
) -> Optional[Provider]:
pass


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,13 +262,11 @@ async def find_and_create_provider_instance(
third_party_id: str,
client_type: Optional[str],
user_context: Dict[str, Any],
) -> Provider:
) -> Optional[Provider]:
for provider_input in providers:
if provider_input.config.third_party_id == third_party_id:
provider_instance = create_provider(provider_input)
await fetch_and_set_config(provider_instance, client_type, user_context)
return provider_instance

raise Exception(
f"the provider {third_party_id} could not be found in the configuration"
)
return None
8 changes: 4 additions & 4 deletions supertokens_python/recipe/thirdparty/recipe_implementation.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
from supertokens_python.querier import Querier

from .interfaces import (
GetProviderOkResult,
ManuallyCreateOrUpdateUserOkResult,
RecipeInterface,
SignInUpOkResult,
Expand Down Expand Up @@ -189,6 +188,9 @@ async def get_provider(
user_context=user_context,
)

if tenant_config is None:
raise Exception("Tenant not found")

merged_providers = merge_providers_from_core_and_static(
provider_configs_from_core=tenant_config.third_party.providers,
provider_inputs_from_static=self.providers,
Expand All @@ -198,6 +200,4 @@ async def get_provider(
merged_providers, third_party_id, client_type, user_context
)

return GetProviderOkResult(
provider,
)
return provider
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ async def thirdparty_get_provider(
client_type: Optional[str],
tenant_id: str,
user_context: Dict[str, Any],
) -> ThirdPartyInterfaces.GetProviderOkResult:
) -> Optional[ThirdPartyInterfaces.Provider]:
pass

@abstractmethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
from typing import TYPE_CHECKING, Any, Dict, List, Union, Callable, Optional

import supertokens_python.recipe.emailpassword.interfaces as EPInterfaces
from supertokens_python.recipe.thirdparty.interfaces import GetProviderOkResult
from supertokens_python.recipe.thirdparty.provider import ProviderInput
from supertokens_python.recipe.thirdparty.provider import ProviderInput, Provider
from supertokens_python.recipe.thirdparty.types import RawUserInfoFromProvider
from supertokens_python.recipe.emailpassword.utils import EmailPasswordConfig

Expand Down Expand Up @@ -276,7 +275,7 @@ async def thirdparty_get_provider(
client_type: Optional[str],
tenant_id: str,
user_context: Dict[str, Any],
) -> GetProviderOkResult:
) -> Optional[Provider]:
if self.tp_get_provider is None:
raise Exception("No thirdparty provider configured")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
from typing import Any, Dict, List, Optional, Union

from supertokens_python.recipe.thirdparty.interfaces import (
GetProviderOkResult,
ManuallyCreateOrUpdateUserOkResult,
RecipeInterface,
SignInUpOkResult,
)
from supertokens_python.recipe.thirdparty.provider import Provider
from supertokens_python.recipe.thirdparty.types import RawUserInfoFromProvider, User
from supertokens_python.recipe.thirdpartyemailpassword.interfaces import (
RecipeInterface as ThirdPartyEmailPasswordRecipeInterface,
Expand Down Expand Up @@ -164,7 +164,7 @@ async def get_provider(
client_type: Optional[str],
tenant_id: str,
user_context: Dict[str, Any],
) -> GetProviderOkResult:
) -> Optional[Provider]:
return await self.recipe_implementation.thirdparty_get_provider(
third_party_id,
client_type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ async def thirdparty_get_provider(
client_type: Optional[str],
tenant_id: str,
user_context: Dict[str, Any],
) -> ThirdPartyInterfaces.GetProviderOkResult:
) -> Optional[ThirdPartyInterfaces.Provider]:
pass

@abstractmethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union

from supertokens_python.recipe.thirdparty.provider import ProviderInput
from supertokens_python.recipe.thirdparty.provider import ProviderInput, Provider
from supertokens_python.recipe.thirdparty.types import RawUserInfoFromProvider

from ...passwordless.interfaces import (
Expand All @@ -42,7 +42,6 @@
UpdateUserUnknownUserIdError,
)
from ...thirdparty.interfaces import (
GetProviderOkResult,
ManuallyCreateOrUpdateUserOkResult,
SignInUpOkResult,
)
Expand Down Expand Up @@ -296,7 +295,7 @@ async def thirdparty_get_provider(
client_type: Optional[str],
tenant_id: str,
user_context: Dict[str, Any],
) -> GetProviderOkResult:
) -> Optional[Provider]:
if self.tp_get_provider is None:
raise Exception("No thirdparty provider configured")
return await self.tp_get_provider(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
from typing import Any, Dict, List, Optional, Union

from supertokens_python.recipe.thirdparty.interfaces import (
GetProviderOkResult,
ManuallyCreateOrUpdateUserOkResult,
RecipeInterface,
SignInUpOkResult,
)
from supertokens_python.recipe.thirdparty.types import RawUserInfoFromProvider, User

from ..interfaces import RecipeInterface as ThirdPartyPasswordlessRecipeInterface
from ...thirdparty.provider import Provider


class RecipeImplementation(RecipeInterface):
Expand Down Expand Up @@ -138,7 +138,7 @@ async def get_provider(
client_type: Optional[str],
tenant_id: str,
user_context: Dict[str, Any],
) -> GetProviderOkResult:
) -> Optional[Provider]:
return await self.recipe_implementation.thirdparty_get_provider(
third_party_id, client_type, tenant_id, user_context
)
Loading

0 comments on commit f95a9d1

Please sign in to comment.