Skip to content

Commit cfe84f5

Browse files
Merge pull request #528 from supertokens/auto-transpiling-e2e-tests
auto transpile: pr 1
2 parents 8e3a7b2 + 91dcf57 commit cfe84f5

33 files changed

+790
-148
lines changed

.pylintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ disable=raw-checker-failed,
123123
consider-using-in,
124124
no-else-return,
125125
no-self-use,
126-
no-else-raise
126+
no-else-raise,
127+
too-many-nested-blocks,
127128

128129

129130
# Enable the message, report, category or checker with the given id(s). You can

.vscode/launch.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,21 @@
1515
"FLASK_DEBUG": "1"
1616
},
1717
"jinja": true
18+
},
19+
{
20+
"name": "Python: Flask, supertokens-auth-react tests",
21+
"type": "python",
22+
"request": "launch",
23+
"program": "${workspaceFolder}/tests/auth-react/flask-server/app.py",
24+
"args": [
25+
"--port",
26+
"8083"
27+
],
28+
"cwd": "${workspaceFolder}/tests/auth-react/flask-server",
29+
"env": {
30+
"FLASK_DEBUG": "1"
31+
},
32+
"jinja": true
1833
}
1934
]
2035
}

supertokens_python/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from typing_extensions import Literal
1818

1919
from supertokens_python.framework.request import BaseRequest
20+
from supertokens_python.types import RecipeUserId
2021

2122
from . import supertokens
2223
from .recipe_module import RecipeModule
@@ -49,3 +50,7 @@ def get_request_from_user_context(
4950
user_context: Optional[Dict[str, Any]],
5051
) -> Optional[BaseRequest]:
5152
return Supertokens.get_instance().get_request_from_user_context(user_context)
53+
54+
55+
def convert_to_recipe_user_id(user_id: str) -> RecipeUserId:
56+
return RecipeUserId(user_id)

supertokens_python/auth_utils.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -912,19 +912,22 @@ async def filter_out_invalid_second_factors_or_throw_if_all_are_invalid(
912912
factors_set_up_for_user_prom: Optional[List[str]] = None
913913
mfa_info_prom = None
914914

915-
async def get_factors_set_up_for_user():
915+
async def get_factors_set_up_for_user() -> List[str]:
916916
nonlocal factors_set_up_for_user_prom
917917
if factors_set_up_for_user_prom is None:
918918
factors_set_up_for_user_prom = await mfa_instance.recipe_implementation.get_factors_setup_for_user(
919919
user=session_user, user_context=user_context
920920
)
921+
assert factors_set_up_for_user_prom is not None
921922
return factors_set_up_for_user_prom
922923

923924
async def get_mfa_requirements_for_auth():
924925
nonlocal mfa_info_prom
925926
if mfa_info_prom is None:
927+
926928
mfa_info_prom = await update_and_get_mfa_related_info_in_session(
927-
input_session=session, user_context=user_context
929+
input_session=session,
930+
user_context=user_context,
928931
)
929932
return mfa_info_prom.mfa_requirements_for_auth
930933

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
2+
#
3+
# This software is licensed under the Apache License, Version 2.0 (the
4+
# "License") as published by the Apache Software Foundation.
5+
#
6+
# You may not use this file except in compliance with the License. You may
7+
# obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
from __future__ import annotations
15+
16+
from typing import TYPE_CHECKING, Callable, List, Optional, Union
17+
18+
from supertokens_python.recipe.multifactorauth.types import OverrideConfig
19+
20+
from .recipe import MultiFactorAuthRecipe
21+
22+
if TYPE_CHECKING:
23+
from supertokens_python.supertokens import AppInfo
24+
25+
from ...recipe_module import RecipeModule
26+
27+
28+
def init(
29+
first_factors: Optional[List[str]] = None,
30+
override: Union[OverrideConfig, None] = None,
31+
) -> Callable[[AppInfo], RecipeModule]:
32+
return MultiFactorAuthRecipe.init(
33+
first_factors,
34+
override,
35+
)

supertokens_python/recipe/multifactorauth/api/implementation.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,22 @@
1212
# License for the specific language governing permissions and limitations
1313
# under the License.
1414
from __future__ import annotations
15+
import importlib
1516

16-
from typing import TYPE_CHECKING, Any, Dict, List, Union
17+
from typing import Any, Dict, List, Union
18+
from supertokens_python.recipe.multifactorauth.multi_factor_auth_claim import (
19+
MultiFactorAuthClaim,
20+
)
1721

1822
from supertokens_python.recipe.session import SessionContainer
19-
from supertokens_python.recipe.multifactorauth.utils import (
20-
update_and_get_mfa_related_info_in_session,
21-
)
2223
from supertokens_python.recipe.multitenancy.asyncio import get_tenant
23-
from ..multi_factor_auth_claim import MultiFactorAuthClaim
2424
from supertokens_python.asyncio import get_user
2525
from supertokens_python.recipe.session.exceptions import (
2626
InvalidClaimsError,
2727
SuperTokensSessionError,
2828
UnauthorisedError,
2929
)
3030

31-
if TYPE_CHECKING:
32-
from supertokens_python.recipe.multifactorauth.interfaces import (
33-
APIInterface,
34-
APIOptions,
35-
)
36-
3731
from supertokens_python.types import GeneralErrorResponse
3832
from ..interfaces import (
3933
APIInterface,
@@ -50,14 +44,19 @@ async def resync_session_and_fetch_mfa_info_put(
5044
session: SessionContainer,
5145
user_context: Dict[str, Any],
5246
) -> Union[ResyncSessionAndFetchMFAInfoPUTOkResult, GeneralErrorResponse]:
47+
48+
module = importlib.import_module(
49+
"supertokens_python.recipe.multifactorauth.utils"
50+
)
51+
5352
session_user = await get_user(session.get_user_id(), user_context)
5453

5554
if session_user is None:
5655
raise UnauthorisedError(
5756
"Session user not found",
5857
)
5958

60-
mfa_info = await update_and_get_mfa_related_info_in_session(
59+
mfa_info = await module.update_and_get_mfa_related_info_in_session(
6160
input_session=session,
6261
user_context=user_context,
6362
)
@@ -144,7 +143,7 @@ async def get_mfa_requirements_for_auth():
144143
)
145144
return ResyncSessionAndFetchMFAInfoPUTOkResult(
146145
factors=NextFactors(
147-
next=next_factors,
146+
next_=next_factors,
148147
already_setup=factors_setup_for_user,
149148
allowed_to_setup=factors_allowed_to_setup,
150149
),

supertokens_python/recipe/multifactorauth/api/resync_session_and_fetch_mfa_info.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828

2929
async def handle_resync_session_and_fetch_mfa_info_api(
30-
tenant_id: str,
30+
_tenant_id: str,
3131
api_implementation: APIInterface,
3232
api_options: APIOptions,
3333
user_context: Dict[str, Any],

supertokens_python/recipe/multifactorauth/asyncio/__init__.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
from ..types import (
2222
MFARequirementList,
2323
)
24-
from ..recipe import MultiFactorAuthRecipe
2524
from ..utils import update_and_get_mfa_related_info_in_session
2625
from supertokens_python.recipe.accountlinking.asyncio import get_user
2726

@@ -41,6 +40,7 @@ async def assert_allowed_to_setup_factor_else_throw_invalid_claim_error(
4140
factors_set_up_for_user = await get_factors_setup_for_user(
4241
session.get_user_id(), user_context
4342
)
43+
from ..recipe import MultiFactorAuthRecipe
4444

4545
recipe = MultiFactorAuthRecipe.get_instance_or_throw_error()
4646

@@ -81,6 +81,7 @@ async def mark_factor_as_complete_in_session(
8181
) -> None:
8282
if user_context is None:
8383
user_context = {}
84+
from ..recipe import MultiFactorAuthRecipe
8485

8586
recipe = MultiFactorAuthRecipe.get_instance_or_throw_error()
8687
await recipe.recipe_implementation.mark_factor_as_complete_in_session(
@@ -100,6 +101,7 @@ async def get_factors_setup_for_user(
100101
user = await get_user(user_id, user_context)
101102
if user is None:
102103
raise Exception("Unknown user id")
104+
from ..recipe import MultiFactorAuthRecipe
103105

104106
recipe = MultiFactorAuthRecipe.get_instance_or_throw_error()
105107
return await recipe.recipe_implementation.get_factors_setup_for_user(
@@ -114,6 +116,7 @@ async def get_required_secondary_factors_for_user(
114116
) -> List[str]:
115117
if user_context is None:
116118
user_context = {}
119+
from ..recipe import MultiFactorAuthRecipe
117120

118121
recipe = MultiFactorAuthRecipe.get_instance_or_throw_error()
119122
return await recipe.recipe_implementation.get_required_secondary_factors_for_user(
@@ -129,6 +132,7 @@ async def add_to_required_secondary_factors_for_user(
129132
) -> None:
130133
if user_context is None:
131134
user_context = {}
135+
from ..recipe import MultiFactorAuthRecipe
132136

133137
recipe = MultiFactorAuthRecipe.get_instance_or_throw_error()
134138
await recipe.recipe_implementation.add_to_required_secondary_factors_for_user(
@@ -145,13 +149,11 @@ async def remove_from_required_secondary_factors_for_user(
145149
) -> None:
146150
if user_context is None:
147151
user_context = {}
152+
from ..recipe import MultiFactorAuthRecipe
148153

149154
recipe = MultiFactorAuthRecipe.get_instance_or_throw_error()
150155
await recipe.recipe_implementation.remove_from_required_secondary_factors_for_user(
151156
user_id=user_id,
152157
factor_id=factor_id,
153158
user_context=user_context,
154159
)
155-
156-
157-
init = MultiFactorAuthRecipe.init

supertokens_python/recipe/multifactorauth/interfaces.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,15 @@ async def resync_session_and_fetch_mfa_info_put(
123123

124124
class NextFactors:
125125
def __init__(
126-
self, next: List[str], already_setup: List[str], allowed_to_setup: List[str]
126+
self, next_: List[str], already_setup: List[str], allowed_to_setup: List[str]
127127
):
128-
self.next = next
128+
self.next_ = next_
129129
self.already_setup = already_setup
130130
self.allowed_to_setup = allowed_to_setup
131131

132132
def to_json(self) -> Dict[str, Any]:
133133
return {
134-
"next": self.next,
134+
"next": self.next_,
135135
"alreadySetup": self.already_setup,
136136
"allowedToSetup": self.allowed_to_setup,
137137
}

supertokens_python/recipe/multifactorauth/multi_factor_auth_claim.py

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
1+
# Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved.
2+
#
3+
# This software is licensed under the Apache License, Version 2.0 (the
4+
# "License") as published by the Apache Software Foundation.
5+
#
6+
# You may not use this file except in compliance with the License. You may
7+
# obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
115
from __future__ import annotations
16+
import importlib
217

318
from typing import Any, Dict, Optional, Set
419

@@ -15,7 +30,6 @@
1530
MFAClaimValue,
1631
MFARequirementList,
1732
)
18-
from .utils import update_and_get_mfa_related_info_in_session
1933

2034

2135
class HasCompletedRequirementListSCV(SessionClaimValidator):
@@ -29,14 +43,10 @@ def __init__(
2943
self.claim: MultiFactorAuthClaimClass = claim
3044
self.requirement_list = requirement_list
3145

32-
async def should_refetch(
46+
def should_refetch(
3347
self, payload: Dict[str, Any], user_context: Dict[str, Any]
3448
) -> bool:
35-
return (
36-
True
37-
if self.claim.key not in payload or not payload[self.claim.key]
38-
else False
39-
)
49+
return bool(self.claim.key not in payload or not payload[self.claim.key])
4050

4151
async def validate(
4252
self, payload: JSONObject, user_context: Dict[str, Any]
@@ -65,7 +75,7 @@ async def validate(
6575

6676
factor_ids = next_set_of_unsatisfied_factors.factor_ids
6777

68-
if next_set_of_unsatisfied_factors.type == "string":
78+
if next_set_of_unsatisfied_factors.type_ == "string":
6979
return ClaimValidationResult(
7080
is_valid=False,
7181
reason={
@@ -74,7 +84,7 @@ async def validate(
7484
},
7585
)
7686

77-
elif next_set_of_unsatisfied_factors.type == "oneOf":
87+
elif next_set_of_unsatisfied_factors.type_ == "oneOf":
7888
return ClaimValidationResult(
7989
is_valid=False,
8090
reason={
@@ -101,15 +111,11 @@ def __init__(
101111
super().__init__(id_)
102112
self.claim = claim
103113

104-
async def should_refetch(
114+
def should_refetch(
105115
self, payload: Dict[str, Any], user_context: Dict[str, Any]
106116
) -> bool:
107117
assert self.claim is not None
108-
return (
109-
True
110-
if self.claim.key not in payload or not payload[self.claim.key]
111-
else False
112-
)
118+
return bool(self.claim.key not in payload or not payload[self.claim.key])
113119

114120
async def validate(
115121
self, payload: JSONObject, user_context: Dict[str, Any]
@@ -161,13 +167,17 @@ def __init__(self, key: Optional[str] = None):
161167
key = key or "st-mfa"
162168

163169
async def fetch_value(
164-
user_id: str,
170+
_user_id: str,
165171
recipe_user_id: RecipeUserId,
166172
tenant_id: str,
167173
current_payload: Dict[str, Any],
168174
user_context: Dict[str, Any],
169175
) -> MFAClaimValue:
170-
mfa_info = await update_and_get_mfa_related_info_in_session(
176+
module = importlib.import_module(
177+
"supertokens_python.recipe.multifactorauth.utils"
178+
)
179+
180+
mfa_info = await module.update_and_get_mfa_related_info_in_session(
171181
input_session_recipe_user_id=recipe_user_id,
172182
input_tenant_id=tenant_id,
173183
input_access_token_payload=current_payload,
@@ -209,9 +219,11 @@ def get_next_set_of_unsatisfied_factors(
209219
)
210220

211221
if len(next_factors) > 0:
212-
return FactorIdsAndType(factor_ids=list(next_factors), type=factor_type)
222+
return FactorIdsAndType(
223+
factor_ids=list(next_factors), type_=factor_type
224+
)
213225

214-
return FactorIdsAndType(factor_ids=[], type="string")
226+
return FactorIdsAndType(factor_ids=[], type_="string")
215227

216228
def add_to_payload_(
217229
self,

0 commit comments

Comments
 (0)