Skip to content

Commit 11a2feb

Browse files
authored
Merge pull request #290 from supertokens/interface-changes
Feat: Interface and routing for email-password login
2 parents 8beebf4 + e7a0567 commit 11a2feb

File tree

7 files changed

+92
-8
lines changed

7 files changed

+92
-8
lines changed

supertokens_python/recipe/dashboard/api/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
# under the License.
1414
from .api_key_protector import api_key_protector
1515
from .dashboard import handle_dashboard_api
16+
from .signin import handle_sign_in_api
17+
from .signout import handle_signout
1618
from .userdetails.user_delete import handle_user_delete
1719
from .userdetails.user_email_verify_get import handle_user_email_verify_get
1820
from .userdetails.user_email_verify_put import handle_user_email_verify_put
@@ -45,4 +47,6 @@
4547
"handle_user_sessions_post",
4648
"handle_user_password_put",
4749
"handle_email_verify_token_post",
50+
"handle_sign_in_api",
51+
"handle_signout",
4852
]
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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
17+
18+
if TYPE_CHECKING:
19+
from supertokens_python.recipe.dashboard.interfaces import APIInterface, APIOptions
20+
21+
# pylint: disable=unused-argument
22+
async def handle_sign_in_api(api_implementation: APIInterface, api_options: APIOptions):
23+
pass
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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
17+
18+
if TYPE_CHECKING:
19+
from supertokens_python.recipe.dashboard.interfaces import APIInterface, APIOptions
20+
21+
from ..interfaces import SignOutOK
22+
23+
24+
# pylint: disable=unused-argument
25+
async def handle_signout(
26+
api_implementation: APIInterface, api_options: APIOptions
27+
) -> SignOutOK:
28+
return SignOutOK()

supertokens_python/recipe/dashboard/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@
88
USER_SESSION_API = "/api/user/sessions"
99
USER_PASSWORD_API = "/api/user/password"
1010
USER_EMAIL_VERIFY_TOKEN_API = "/api/user/email/verify/token"
11+
EMAIL_PASSWORD_SIGN_IN = "/api/signin"
12+
EMAIL_PASSSWORD_SIGNOUT = "/api/signout"

supertokens_python/recipe/dashboard/interfaces.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,3 +285,8 @@ def __init__(self, error: str) -> None:
285285

286286
def to_json(self) -> Dict[str, Any]:
287287
return {"status": self.status, "error": self.error}
288+
289+
290+
class SignOutOK(APIResponse):
291+
def to_json(self):
292+
return {"status": "OK"}

supertokens_python/recipe/dashboard/recipe.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
handle_metadata_get,
2727
handle_metadata_put,
2828
handle_sessions_get,
29+
handle_sign_in_api,
30+
handle_signout,
2931
handle_user_delete,
3032
handle_user_email_verify_get,
3133
handle_user_email_verify_put,
@@ -52,6 +54,8 @@
5254

5355
from .constants import (
5456
DASHBOARD_API,
57+
EMAIL_PASSSWORD_SIGNOUT,
58+
EMAIL_PASSWORD_SIGN_IN,
5559
USER_API,
5660
USER_EMAIL_VERIFY_API,
5761
USER_EMAIL_VERIFY_TOKEN_API,
@@ -78,7 +82,7 @@ def __init__(
7882
self,
7983
recipe_id: str,
8084
app_info: AppInfo,
81-
api_key: str,
85+
api_key: Union[str, None],
8286
override: Union[InputOverrideConfig, None] = None,
8387
):
8488
super().__init__(recipe_id, app_info)
@@ -136,6 +140,8 @@ async def handle_api_request(
136140
return await handle_dashboard_api(self.api_implementation, api_options)
137141
if request_id == VALIDATE_KEY_API:
138142
return await handle_validate_key_api(self.api_implementation, api_options)
143+
if request_id == EMAIL_PASSWORD_SIGN_IN:
144+
return await handle_sign_in_api(self.api_implementation, api_options)
139145

140146
# Do API key validation for the remaining APIs
141147
api_function: Optional[
@@ -171,6 +177,8 @@ async def handle_api_request(
171177
api_function = handle_user_password_put
172178
elif request_id == USER_EMAIL_VERIFY_TOKEN_API:
173179
api_function = handle_email_verify_token_post
180+
elif request_id == EMAIL_PASSSWORD_SIGNOUT:
181+
api_function = handle_signout
174182

175183
if api_function is not None:
176184
return await api_key_protector(
@@ -189,7 +197,7 @@ def get_all_cors_headers(self) -> List[str]:
189197

190198
@staticmethod
191199
def init(
192-
api_key: str,
200+
api_key: Union[str, None],
193201
override: Union[InputOverrideConfig, None] = None,
194202
):
195203
def func(app_info: AppInfo):

supertokens_python/recipe/dashboard/utils.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515

1616
from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Union
1717

18+
if TYPE_CHECKING:
19+
from supertokens_python.framework.request import BaseRequest
20+
1821
from supertokens_python.recipe.emailpassword import EmailPasswordRecipe
1922
from supertokens_python.recipe.emailpassword.asyncio import (
2023
get_user_by_id as ep_get_user_by_id,
@@ -46,6 +49,8 @@
4649
from ...supertokens import AppInfo
4750
from .constants import (
4851
DASHBOARD_API,
52+
EMAIL_PASSSWORD_SIGNOUT,
53+
EMAIL_PASSWORD_SIGN_IN,
4954
USER_API,
5055
USER_EMAIL_VERIFY_API,
5156
USER_EMAIL_VERIFY_TOKEN_API,
@@ -162,21 +167,18 @@ def __init__(
162167

163168
class DashboardConfig:
164169
def __init__(
165-
self,
166-
api_key: str,
167-
override: OverrideConfig,
170+
self, api_key: Union[str, None], override: OverrideConfig, auth_mode: str
168171
):
169172
self.api_key = api_key
170173
self.override = override
174+
self.auth_mode = auth_mode
171175

172176

173177
def validate_and_normalise_user_input(
174178
# app_info: AppInfo,
175-
api_key: str,
179+
api_key: Union[str, None],
176180
override: Optional[InputOverrideConfig] = None,
177181
) -> DashboardConfig:
178-
if api_key.strip() == "":
179-
raise Exception("apiKey provided to Dashboard recipe cannot be empty")
180182

181183
if override is None:
182184
override = InputOverrideConfig()
@@ -187,6 +189,7 @@ def validate_and_normalise_user_input(
187189
functions=override.functions,
188190
apis=override.apis,
189191
),
192+
"api-key" if api_key else "email-password",
190193
)
191194

192195

@@ -230,6 +233,10 @@ def get_api_if_matched(path: NormalisedURLPath, method: str) -> Optional[str]:
230233
return USER_PASSWORD_API
231234
if path_str.endswith(USER_EMAIL_VERIFY_TOKEN_API) and method == "post":
232235
return USER_EMAIL_VERIFY_TOKEN_API
236+
if path_str.endswith(EMAIL_PASSWORD_SIGN_IN) and method == "post":
237+
return EMAIL_PASSWORD_SIGN_IN
238+
if path_str.endswith(EMAIL_PASSSWORD_SIGNOUT) and method == "post":
239+
return EMAIL_PASSSWORD_SIGNOUT
233240

234241
return None
235242

@@ -385,3 +392,10 @@ def is_recipe_initialised(recipeId: str) -> bool:
385392
pass
386393

387394
return isRecipeInitialised
395+
396+
397+
def validate_APIKey(req: BaseRequest, config: DashboardConfig) -> bool:
398+
apiKeyHeaderValue = req.get_header("authorization")
399+
if not apiKeyHeaderValue:
400+
return False
401+
return apiKeyHeaderValue == config.api_key

0 commit comments

Comments
 (0)