From 5cf109f8cfc774b681662d099bf6bf2207a925cb Mon Sep 17 00:00:00 2001 From: KShivendu Date: Fri, 1 Sep 2023 14:09:05 +0530 Subject: [PATCH 1/3] fix: Failing tests in the CI --- tests/auth-react/django3x/polls/urls.py | 1 + tests/auth-react/django3x/polls/views.py | 13 ++++++ tests/auth-react/fastapi-server/app.py | 14 +++++++ tests/auth-react/flask-server/app.py | 14 +++++++ .../django2x/polls/views.py | 41 +++++++++++++++++- .../django3x/polls/views.py | 38 ++++++++++++++++- .../frontendIntegration/fastapi-server/app.py | 37 +++++++++++++++- tests/frontendIntegration/flask-server/app.py | 42 +++++++++++++++++-- 8 files changed, 191 insertions(+), 9 deletions(-) diff --git a/tests/auth-react/django3x/polls/urls.py b/tests/auth-react/django3x/polls/urls.py index 0d4d64575..0be864c80 100644 --- a/tests/auth-react/django3x/polls/urls.py +++ b/tests/auth-react/django3x/polls/urls.py @@ -8,6 +8,7 @@ path("ping", views.ping, name="ping"), path("sessionInfo", views.session_info, name="sessionInfo"), path("token", views.token, name="token"), + path("deleteUser", views.delete_user_api, name="token"), path("test/setFlow", views.test_set_flow, name="setFlow"), path("test/getDevice", views.test_get_device, name="getDevice"), path("test/featureFlags", views.test_feature_flags, name="featureFlags"), diff --git a/tests/auth-react/django3x/polls/views.py b/tests/auth-react/django3x/polls/views.py index aa17fbcde..d822adf26 100644 --- a/tests/auth-react/django3x/polls/views.py +++ b/tests/auth-react/django3x/polls/views.py @@ -24,6 +24,8 @@ from supertokens_python.recipe.session import SessionContainer from supertokens_python.recipe.session.interfaces import SessionClaimValidator from supertokens_python.recipe.userroles import UserRoleClaim, PermissionClaim +from supertokens_python.syncio import delete_user +from supertokens_python.recipe.emailpassword.syncio import get_user_by_email mode = os.environ.get("APP_MODE", "asgi") @@ -146,6 +148,17 @@ def token(request: HttpRequest): return JsonResponse({"latestURLWithToken": latest_url_with_token}) +def delete_user_api(request: HttpRequest): + body = json.loads(request.body) + if body["rid"] != "emailpassword": + return JsonResponse({"message": "Not implemented"}, status_code=400) + + user = get_user_by_email(body["email"]) + assert user is not None + delete_user(user.user_id) + return HttpResponse("") + + def test_get_device(request: HttpRequest): pre_auth_session_id = request.GET.get("preAuthSessionId", None) if pre_auth_session_id is None: diff --git a/tests/auth-react/fastapi-server/app.py b/tests/auth-react/fastapi-server/app.py index eb928bdc2..5dc81cd05 100644 --- a/tests/auth-react/fastapi-server/app.py +++ b/tests/auth-react/fastapi-server/app.py @@ -46,6 +46,8 @@ thirdpartypasswordless, userroles, ) +from supertokens_python.asyncio import delete_user +from supertokens_python.recipe.emailpassword.asyncio import get_user_by_email from supertokens_python.recipe.dashboard import DashboardRecipe from supertokens_python.recipe.emailpassword import EmailPasswordRecipe from supertokens_python.recipe.emailpassword.interfaces import ( @@ -1036,6 +1038,18 @@ async def get_token(): return JSONResponse({"latestURLWithToken": latest_url_with_token}) +@app.post("/deleteUser") +async def delete_user_api(request: Request): + body = await request.json() + if body["rid"] != "emailpassword": + return JSONResponse({"message": "Not implemented"}, status_code=400) + + user = await get_user_by_email(body["email"]) + assert user is not None + await delete_user(user.user_id) + return PlainTextResponse() + + @app.get("/unverifyEmail") async def unverify_email_api(session_: SessionContainer = Depends(verify_session())): await unverify_email(session_.get_user_id()) diff --git a/tests/auth-react/flask-server/app.py b/tests/auth-react/flask-server/app.py index 012c0b400..b610bd6c0 100644 --- a/tests/auth-react/flask-server/app.py +++ b/tests/auth-react/flask-server/app.py @@ -38,6 +38,8 @@ thirdpartypasswordless, userroles, ) +from supertokens_python.syncio import delete_user +from supertokens_python.recipe.emailpassword.syncio import get_user_by_email from supertokens_python.recipe.dashboard import DashboardRecipe from supertokens_python.recipe.emailpassword import EmailPasswordRecipe from supertokens_python.recipe.emailpassword.interfaces import ( @@ -1041,6 +1043,18 @@ def test_feature_flags(): return jsonify({"available": available}) +@app.post("/deleteUser") # type: ignore +def delete_user_api(): + body = request.get_json() or {} + if body["rid"] != "emailpassword": + return jsonify({"message": "Not implemented"}), 400 + + user = get_user_by_email(body["email"]) + assert user is not None + delete_user(user.user_id) + return "" + + @app.get("/unverifyEmail") # type: ignore @verify_session() def unverify_email_api(): diff --git a/tests/frontendIntegration/django2x/polls/views.py b/tests/frontendIntegration/django2x/polls/views.py index fe33804ab..830e0588c 100644 --- a/tests/frontendIntegration/django2x/polls/views.py +++ b/tests/frontendIntegration/django2x/polls/views.py @@ -24,6 +24,10 @@ from supertokens_python import get_all_cors_headers from supertokens_python import InputAppInfo, Supertokens, SupertokensConfig, init from supertokens_python.framework import BaseRequest, BaseResponse +from base64 import b64encode +from supertokens_python.utils import get_timestamp_ms +from supertokens_python.async_to_sync_wrapper import sync +from supertokens_python.querier import Querier, NormalisedURLPath from supertokens_python.recipe import session from supertokens_python.recipe.session import ( InputErrorHandlers, @@ -338,12 +342,45 @@ def login(request: HttpRequest): def login_2_18(request: HttpRequest): if request.method == "POST": + # This CDI version is no longer supported by this SDK, but + # we want to ensure that sessions keep working after the upgrade + # We can hard-code the structure of the request&response, since + # this is a fixed CDI version and it's not going to change + + Querier.api_version = "2.18" + body = json.loads(request.body) user_id = body["userId"] payload = body["payload"] - session_ = create_new_session(request, user_id, payload) - return HttpResponse(session_.get_user_id()) + legacy_session_res = sync( + Querier.get_instance().send_post_request( + NormalisedURLPath("/recipe/session"), + { + "userId": user_id, + "enableAntiCsrf": False, + "userDataInJWT": payload, + "userDataInDatabase": {}, + }, + ) + ) + Querier.api_version = None + + legacy_access_token = legacy_session_res["accessToken"]["token"] + legacy_refresh_token = legacy_session_res["refreshToken"]["token"] + + front_token = json.dumps( + {"uid": user_id, "ate": get_timestamp_ms() + 3600000, "up": payload} + ) + + return JsonResponse( + {}, + headers={ + "st-access-token": legacy_access_token, + "st-refresh-token": legacy_refresh_token, + "front-token": b64encode(front_token.encode()), + }, + ) else: return send_options_api_response() diff --git a/tests/frontendIntegration/django3x/polls/views.py b/tests/frontendIntegration/django3x/polls/views.py index a7b67d737..8aceade22 100644 --- a/tests/frontendIntegration/django3x/polls/views.py +++ b/tests/frontendIntegration/django3x/polls/views.py @@ -29,6 +29,9 @@ from supertokens_python import get_all_cors_headers from supertokens_python import InputAppInfo, Supertokens, SupertokensConfig, init from supertokens_python.framework import BaseRequest, BaseResponse +from base64 import b64encode +from supertokens_python.utils import get_timestamp_ms +from supertokens_python.querier import Querier, NormalisedURLPath from supertokens_python.recipe import session from supertokens_python.recipe.session import ( InputErrorHandlers, @@ -345,12 +348,43 @@ async def login(request: HttpRequest): async def login_2_18(request: HttpRequest): if request.method == "POST": + # This CDI version is no longer supported by this SDK, but + # we want to ensure that sessions keep working after the upgrade + # We can hard-code the structure of the request&response, since + # this is a fixed CDI version and it's not going to change + + Querier.api_version = "2.18" + body = json.loads(request.body) user_id = body["userId"] payload = body["payload"] - session_ = await create_new_session(request, user_id, payload) - return HttpResponse(session_.get_user_id()) + legacy_session_res = await Querier.get_instance().send_post_request( + NormalisedURLPath("/recipe/session"), + { + "userId": user_id, + "enableAntiCsrf": False, + "userDataInJWT": payload, + "userDataInDatabase": {}, + }, + ) + Querier.api_version = None + + legacy_access_token = legacy_session_res["accessToken"]["token"] + legacy_refresh_token = legacy_session_res["refreshToken"]["token"] + + front_token = json.dumps( + {"uid": user_id, "ate": get_timestamp_ms() + 3600000, "up": payload} + ) + + return JsonResponse( + {}, + headers={ + "st-access-token": legacy_access_token, + "st-refresh-token": legacy_refresh_token, + "front-token": b64encode(front_token.encode()), + }, + ) else: return send_options_api_response() diff --git a/tests/frontendIntegration/fastapi-server/app.py b/tests/frontendIntegration/fastapi-server/app.py index 6fe3d8302..420f7ae28 100644 --- a/tests/frontendIntegration/fastapi-server/app.py +++ b/tests/frontendIntegration/fastapi-server/app.py @@ -29,6 +29,9 @@ get_all_cors_headers, init, ) +from base64 import b64encode +from supertokens_python.utils import get_timestamp_ms +from supertokens_python.querier import Querier, NormalisedURLPath from supertokens_python.framework import BaseRequest, BaseResponse from supertokens_python.framework.fastapi import get_middleware from supertokens_python.recipe import session @@ -221,11 +224,41 @@ async def login(request: Request): @app.post("/login-2.18") async def login_2_18(request: Request): + # This CDI version is no longer supported by this SDK, but we want to ensure that sessions keep working after the upgrade + # We can hard-code the structure of the request&response, since this is a fixed CDI version and it's not going to change + + Querier.api_version = "2.18" + body = await request.json() user_id = body["userId"] payload = body["payload"] - _session = await create_new_session(request, user_id, payload) - return PlainTextResponse(content=_session.get_user_id()) + + legacy_session_res = await Querier.get_instance().send_post_request( + NormalisedURLPath("/recipe/session"), + { + "userId": user_id, + "enableAntiCsrf": False, + "userDataInJWT": payload, + "userDataInDatabase": {}, + }, + ) + Querier.api_version = None + + legacy_access_token = legacy_session_res["accessToken"]["token"] + legacy_refresh_token = legacy_session_res["refreshToken"]["token"] + + front_token = json.dumps( + {"uid": user_id, "ate": get_timestamp_ms() + 3600000, "up": payload} + ) + + return JSONResponse( + {}, + headers={ + "st-access-token": legacy_access_token, + "st-refresh-token": legacy_refresh_token, + "front-token": b64encode(front_token.encode()), + }, + ) @app.options("/beforeeach") diff --git a/tests/frontendIntegration/flask-server/app.py b/tests/frontendIntegration/flask-server/app.py index dc47fe9d3..78b2e7b54 100644 --- a/tests/frontendIntegration/flask-server/app.py +++ b/tests/frontendIntegration/flask-server/app.py @@ -28,6 +28,10 @@ from flask_cors import CORS from supertokens_python import InputAppInfo, Supertokens, SupertokensConfig, init from supertokens_python.framework.flask.flask_middleware import Middleware +from base64 import b64encode +from supertokens_python.utils import get_timestamp_ms +from supertokens_python.async_to_sync_wrapper import sync +from supertokens_python.querier import Querier, NormalisedURLPath from supertokens_python.recipe import session from supertokens_python.recipe.session import ( InputErrorHandlers, @@ -247,11 +251,43 @@ def login(): @app.route("/login-2.18", methods=["POST"]) # type: ignore def login_2_18(): - body: Dict[str, Any] = request.get_json() # type: ignore + # This CDI version is no longer supported by this SDK, but we want to ensure that sessions keep working after the upgrade + # We can hard-code the structure of the request&response, since this is a fixed CDI version and it's not going to change + + Querier.api_version = "2.18" + + body = request.json or {} user_id = body["userId"] payload = body["payload"] - _session = create_new_session(request, user_id, payload) - return _session.get_user_id() + + legacy_session_res = sync( + Querier.get_instance().send_post_request( + NormalisedURLPath("/recipe/session"), + { + "userId": user_id, + "enableAntiCsrf": False, + "userDataInJWT": payload, + "userDataInDatabase": {}, + }, + ) + ) + Querier.api_version = None + + legacy_access_token = legacy_session_res["accessToken"]["token"] + legacy_refresh_token = legacy_session_res["refreshToken"]["token"] + + front_token = json.dumps( + {"uid": user_id, "ate": get_timestamp_ms() + 3600000, "up": payload} + ) + + return Response( + "{}", + headers={ + "st-access-token": legacy_access_token, + "st-refresh-token": legacy_refresh_token, + "front-token": b64encode(front_token.encode()), + }, + ) @app.route("/beforeeach", methods=["OPTIONS"]) # type: ignore From ead46788ad821abe5ef6b96c4bbbb0a0f2d8631e Mon Sep 17 00:00:00 2001 From: KShivendu Date: Fri, 1 Sep 2023 17:25:18 +0530 Subject: [PATCH 2/3] fix: Failing website tests --- tests/frontendIntegration/django2x/polls/views.py | 2 +- tests/frontendIntegration/django3x/polls/views.py | 2 +- tests/frontendIntegration/fastapi-server/app.py | 4 ++-- tests/frontendIntegration/flask-server/app.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/frontendIntegration/django2x/polls/views.py b/tests/frontendIntegration/django2x/polls/views.py index 830e0588c..efba5ee66 100644 --- a/tests/frontendIntegration/django2x/polls/views.py +++ b/tests/frontendIntegration/django2x/polls/views.py @@ -378,7 +378,7 @@ def login_2_18(request: HttpRequest): headers={ "st-access-token": legacy_access_token, "st-refresh-token": legacy_refresh_token, - "front-token": b64encode(front_token.encode()), + "front-token": b64encode(front_token.encode()).decode(), }, ) else: diff --git a/tests/frontendIntegration/django3x/polls/views.py b/tests/frontendIntegration/django3x/polls/views.py index 8aceade22..a60e0a8ce 100644 --- a/tests/frontendIntegration/django3x/polls/views.py +++ b/tests/frontendIntegration/django3x/polls/views.py @@ -382,7 +382,7 @@ async def login_2_18(request: HttpRequest): headers={ "st-access-token": legacy_access_token, "st-refresh-token": legacy_refresh_token, - "front-token": b64encode(front_token.encode()), + "front-token": b64encode(front_token.encode()).decode(), }, ) else: diff --git a/tests/frontendIntegration/fastapi-server/app.py b/tests/frontendIntegration/fastapi-server/app.py index 420f7ae28..372f152eb 100644 --- a/tests/frontendIntegration/fastapi-server/app.py +++ b/tests/frontendIntegration/fastapi-server/app.py @@ -252,11 +252,11 @@ async def login_2_18(request: Request): ) return JSONResponse( - {}, + content={}, headers={ "st-access-token": legacy_access_token, "st-refresh-token": legacy_refresh_token, - "front-token": b64encode(front_token.encode()), + "front-token": b64encode(front_token.encode()).decode(), }, ) diff --git a/tests/frontendIntegration/flask-server/app.py b/tests/frontendIntegration/flask-server/app.py index 78b2e7b54..e90144362 100644 --- a/tests/frontendIntegration/flask-server/app.py +++ b/tests/frontendIntegration/flask-server/app.py @@ -285,7 +285,7 @@ def login_2_18(): headers={ "st-access-token": legacy_access_token, "st-refresh-token": legacy_refresh_token, - "front-token": b64encode(front_token.encode()), + "front-token": b64encode(front_token.encode()).decode(), }, ) From 9a6ba4bf82f02ca7bb4c145de2ed2dd1c09e53bc Mon Sep 17 00:00:00 2001 From: KShivendu Date: Wed, 6 Sep 2023 15:39:26 +0530 Subject: [PATCH 3/3] fix: Django website tests --- tests/frontendIntegration/django2x/polls/urls.py | 2 +- tests/frontendIntegration/django3x/polls/urls.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/frontendIntegration/django2x/polls/urls.py b/tests/frontendIntegration/django2x/polls/urls.py index 12e1496be..ffb93937c 100644 --- a/tests/frontendIntegration/django2x/polls/urls.py +++ b/tests/frontendIntegration/django2x/polls/urls.py @@ -6,7 +6,7 @@ urlpatterns = [ # type: ignore path("index.html", views.send_file, name="index.html"), # type: ignore path("login", views.login, name="login"), # type: ignore - path("login-2.18", views.login_2_18, name="login"), # type: ignore + path("login-2.18", views.login_2_18, name="login_218"), # type: ignore path("beforeeach", views.before_each, name="beforeeach"), # type: ignore path("testUserConfig", views.test_config, name="testUserConfig"), # type: ignore path( diff --git a/tests/frontendIntegration/django3x/polls/urls.py b/tests/frontendIntegration/django3x/polls/urls.py index f81f723be..ffb93937c 100644 --- a/tests/frontendIntegration/django3x/polls/urls.py +++ b/tests/frontendIntegration/django3x/polls/urls.py @@ -6,7 +6,7 @@ urlpatterns = [ # type: ignore path("index.html", views.send_file, name="index.html"), # type: ignore path("login", views.login, name="login"), # type: ignore - path("login-2.18", views.login, name="login"), # type: ignore + path("login-2.18", views.login_2_18, name="login_218"), # type: ignore path("beforeeach", views.before_each, name="beforeeach"), # type: ignore path("testUserConfig", views.test_config, name="testUserConfig"), # type: ignore path(