Skip to content

Commit f9edcce

Browse files
Merge pull request #227 from supertokens/fix/session-claims
test: Fix failing tests for django and flask
2 parents 698cc96 + 9eb50a5 commit f9edcce

File tree

4 files changed

+184
-5
lines changed

4 files changed

+184
-5
lines changed

tests/auth-react/django3x/mysite/utils.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
thirdparty,
1313
thirdpartyemailpassword,
1414
thirdpartypasswordless,
15+
userroles,
1516
)
1617
from supertokens_python.recipe.emailpassword import EmailPasswordRecipe
1718
from supertokens_python.recipe.emailpassword.interfaces import (
@@ -81,6 +82,7 @@
8182
from supertokens_python.recipe.thirdpartypasswordless.interfaces import (
8283
APIInterface as ThirdpartyPasswordlessAPIInterface,
8384
)
85+
from supertokens_python.recipe.userroles import UserRolesRecipe
8486
from supertokens_python.types import GeneralErrorResponse
8587
from typing_extensions import Literal
8688

@@ -240,13 +242,15 @@ def custom_init(
240242
None, Literal["USER_INPUT_CODE", "MAGIC_LINK", "USER_INPUT_CODE_AND_MAGIC_LINK"]
241243
] = None,
242244
):
245+
UserRolesRecipe.reset()
243246
PasswordlessRecipe.reset()
244247
ThirdPartyPasswordlessRecipe.reset()
245248
JWTRecipe.reset()
246249
EmailVerificationRecipe.reset()
247250
SessionRecipe.reset()
248251
ThirdPartyRecipe.reset()
249252
EmailPasswordRecipe.reset()
253+
EmailVerificationRecipe.reset()
250254
ThirdPartyEmailPasswordRecipe.reset()
251255
Supertokens.reset()
252256

@@ -849,10 +853,11 @@ async def authorisation_url_get(
849853
)
850854

851855
recipe_list = [
856+
userroles.init(),
852857
session.init(override=session.InputOverrideConfig(apis=override_session_apis)),
853858
emailverification.init(
854859
mode="OPTIONAL",
855-
create_and_send_custom_email=ev_create_and_send_custom_email, # TODO: Is it correct to create a seperate func for this?
860+
create_and_send_custom_email=ev_create_and_send_custom_email,
856861
override=EVInputOverrideConfig(apis=override_email_verification_apis),
857862
),
858863
emailpassword.init(

tests/auth-react/django3x/polls/urls.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import os
2+
13
from django.urls import path
24

35
from . import views
@@ -11,3 +13,18 @@
1113
path("test/featureFlags", views.test_feature_flags, name="featureFlags"),
1214
path("beforeeach", views.before_each, name="beforeeach"),
1315
]
16+
17+
mode = os.environ.get("APP_MODE", "asgi")
18+
19+
if mode == "asgi":
20+
urlpatterns += [
21+
path("unverifyEmail", views.unverify_email_api, name="unverifyEmail"), # type: ignore
22+
path("setRole", views.set_role_api, name="setRole"), # type: ignore
23+
path("checkRole", views.check_role_api, name="checkRole"), # type: ignore
24+
]
25+
else:
26+
urlpatterns += [
27+
path("unverifyEmail", views.sync_unverify_email_api, name="unverifyEmail"),
28+
path("setRole", views.sync_set_role_api, name="setRole"),
29+
path("checkRole", views.sync_check_role_api, name="checkRole"),
30+
]

tests/auth-react/django3x/polls/views.py

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,52 @@
1313
# under the License.
1414
import json
1515
import os
16+
from typing import List, Dict, Any
1617

1718
from django.conf import settings
1819
from django.http import HttpRequest, HttpResponse, JsonResponse
1920
from mysite.store import get_codes, get_url_with_token
2021
from mysite.utils import custom_init
22+
23+
from supertokens_python.recipe.emailverification import EmailVerificationClaim
2124
from supertokens_python.recipe.session import SessionContainer
25+
from supertokens_python.recipe.session.interfaces import SessionClaimValidator
26+
from supertokens_python.recipe.userroles import UserRoleClaim, PermissionClaim
2227

2328
mode = os.environ.get("APP_MODE", "asgi")
2429

30+
31+
async def override_global_claim_validators(
32+
gv: List[SessionClaimValidator],
33+
_session: SessionContainer,
34+
user_context: Dict[str, Any],
35+
):
36+
validators = gv.copy()
37+
req = user_context["_default"]["request"]
38+
body = await req.json()
39+
40+
if body.get("role"):
41+
info = body["role"]
42+
validator = getattr(UserRoleClaim.validators, info["validator"])
43+
validators.append(validator(*info["args"]))
44+
45+
if body.get("permission"):
46+
info = body["permission"]
47+
validator = getattr(PermissionClaim.validators, info["validator"])
48+
validators.append(validator(*info["args"]))
49+
50+
return validators
51+
52+
2553
if mode == "asgi":
2654
from supertokens_python.recipe.session.framework.django.asyncio import (
2755
verify_session,
2856
)
57+
from supertokens_python.recipe.userroles.asyncio import (
58+
create_new_role_or_add_permissions,
59+
add_role_to_user,
60+
)
61+
from supertokens_python.recipe.emailverification.asyncio import unverify_email
2962

3063
@verify_session()
3164
async def session_info(request: HttpRequest): # type: ignore
@@ -39,8 +72,36 @@ async def session_info(request: HttpRequest): # type: ignore
3972
}
4073
)
4174

75+
@verify_session()
76+
async def set_role_api(request: HttpRequest):
77+
session_: SessionContainer = request.supertokens # type: ignore
78+
body = json.loads(request.body)
79+
await create_new_role_or_add_permissions(body["role"], body["permissions"])
80+
await add_role_to_user(session_.get_user_id(), body["role"])
81+
await session_.fetch_and_set_claim(UserRoleClaim)
82+
await session_.fetch_and_set_claim(PermissionClaim)
83+
return JsonResponse({"status": "OK"})
84+
85+
@verify_session()
86+
async def unverify_email_api(request: HttpRequest):
87+
session_: SessionContainer = request.supertokens # type: ignore
88+
await unverify_email(session_.get_user_id())
89+
await session_.fetch_and_set_claim(EmailVerificationClaim)
90+
return JsonResponse({"status": "OK"})
91+
92+
@verify_session(override_global_claim_validators=override_global_claim_validators)
93+
async def check_role_api(): # type: ignore
94+
return JsonResponse({"status": "OK"})
95+
4296
else:
4397
from supertokens_python.recipe.session.framework.django.syncio import verify_session
98+
from supertokens_python.recipe.userroles.syncio import (
99+
create_new_role_or_add_permissions as sync_create_new_role_or_add_permissions,
100+
add_role_to_user as sync_add_role_to_user,
101+
)
102+
from supertokens_python.recipe.emailverification.syncio import (
103+
unverify_email as sync_unverify_email,
104+
)
44105

45106
@verify_session()
46107
def session_info(request: HttpRequest):
@@ -54,6 +115,27 @@ def session_info(request: HttpRequest):
54115
}
55116
)
56117

118+
@verify_session()
119+
def sync_set_role_api(request: HttpRequest):
120+
session_: SessionContainer = request.supertokens # type: ignore
121+
body = json.loads(request.body)
122+
sync_create_new_role_or_add_permissions(body["role"], body["permissions"])
123+
sync_add_role_to_user(session_.get_user_id(), body["role"])
124+
session_.sync_fetch_and_set_claim(UserRoleClaim)
125+
session_.sync_fetch_and_set_claim(PermissionClaim)
126+
return JsonResponse({"status": "OK"})
127+
128+
@verify_session()
129+
def sync_unverify_email_api(request: HttpRequest):
130+
session_: SessionContainer = request.supertokens # type: ignore
131+
sync_unverify_email(session_.get_user_id())
132+
session_.sync_fetch_and_set_claim(EmailVerificationClaim)
133+
return JsonResponse({"status": "OK"})
134+
135+
@verify_session(override_global_claim_validators=override_global_claim_validators)
136+
def sync_check_role_api():
137+
return JsonResponse({"status": "OK"})
138+
57139

58140
def ping(request: HttpRequest):
59141
return HttpResponse("success")
@@ -87,5 +169,12 @@ def before_each(request: HttpRequest):
87169

88170
def test_feature_flags(request: HttpRequest):
89171
return JsonResponse(
90-
{"available": ["passwordless", "thirdpartypasswordless", "generalerror"]}
172+
{
173+
"available": [
174+
"passwordless",
175+
"thirdpartypasswordless",
176+
"generalerror",
177+
"userroles",
178+
]
179+
}
91180
)

tests/auth-react/flask-server/app.py

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from dotenv import load_dotenv
1818
from flask import Flask, g, jsonify, make_response, request
1919
from flask_cors import CORS
20+
2021
from supertokens_python import (
2122
InputAppInfo,
2223
Supertokens,
@@ -34,6 +35,7 @@
3435
thirdparty,
3536
thirdpartyemailpassword,
3637
thirdpartypasswordless,
38+
userroles,
3739
)
3840
from supertokens_python.recipe.emailpassword import EmailPasswordRecipe
3941
from supertokens_python.recipe.emailpassword.interfaces import (
@@ -47,10 +49,14 @@
4749
InputFormField,
4850
User,
4951
)
50-
from supertokens_python.recipe.emailverification import EmailVerificationRecipe
52+
from supertokens_python.recipe.emailverification import (
53+
EmailVerificationRecipe,
54+
EmailVerificationClaim,
55+
)
5156
from supertokens_python.recipe.emailverification import (
5257
InputOverrideConfig as EVInputOverrideConfig,
5358
)
59+
from supertokens_python.recipe.emailverification.asyncio import unverify_email
5460
from supertokens_python.recipe.emailverification.interfaces import (
5561
APIInterface as EmailVerificationAPIInterface,
5662
)
@@ -75,9 +81,10 @@
7581
from supertokens_python.recipe.session.framework.flask import verify_session
7682
from supertokens_python.recipe.session.interfaces import (
7783
APIInterface as SessionAPIInterface,
84+
SessionContainer,
85+
SessionClaimValidator,
7886
)
7987
from supertokens_python.recipe.session.interfaces import APIOptions as SAPIOptions
80-
from supertokens_python.recipe.session.interfaces import SessionContainer
8188
from supertokens_python.recipe.thirdparty import ThirdPartyRecipe
8289
from supertokens_python.recipe.thirdparty.interfaces import (
8390
APIInterface as ThirdpartyAPIInterface,
@@ -105,6 +112,15 @@
105112
from supertokens_python.recipe.thirdpartypasswordless.interfaces import (
106113
APIInterface as ThirdpartyPasswordlessAPIInterface,
107114
)
115+
from supertokens_python.recipe.userroles import (
116+
UserRoleClaim,
117+
PermissionClaim,
118+
UserRolesRecipe,
119+
)
120+
from supertokens_python.recipe.userroles.asyncio import (
121+
create_new_role_or_add_permissions,
122+
add_role_to_user,
123+
)
108124
from supertokens_python.types import GeneralErrorResponse
109125
from typing_extensions import Literal
110126

@@ -264,13 +280,15 @@ def custom_init(
264280
None, Literal["USER_INPUT_CODE", "MAGIC_LINK", "USER_INPUT_CODE_AND_MAGIC_LINK"]
265281
] = None,
266282
):
283+
UserRolesRecipe.reset()
267284
PasswordlessRecipe.reset()
268285
ThirdPartyPasswordlessRecipe.reset()
269286
JWTRecipe.reset()
270287
EmailVerificationRecipe.reset()
271288
SessionRecipe.reset()
272289
ThirdPartyRecipe.reset()
273290
EmailPasswordRecipe.reset()
291+
EmailVerificationRecipe.reset()
274292
ThirdPartyEmailPasswordRecipe.reset()
275293
Supertokens.reset()
276294

@@ -893,6 +911,7 @@ async def authorisation_url_get(
893911
)
894912

895913
recipe_list = [
914+
userroles.init(),
896915
session.init(override=session.InputOverrideConfig(apis=override_session_apis)),
897916
emailverification.init(
898917
mode="OPTIONAL",
@@ -1014,10 +1033,59 @@ def test_get_device():
10141033

10151034
@app.get("/test/featureFlags") # type: ignore
10161035
def test_feature_flags():
1017-
available = ["passwordless", "thirdpartypasswordless", "generalerror"]
1036+
available = ["passwordless", "thirdpartypasswordless", "generalerror", "userroles"]
10181037
return jsonify({"available": available})
10191038

10201039

1040+
@app.get("/unverifyEmail") # type: ignore
1041+
@verify_session()
1042+
async def unverify_email_api():
1043+
session_: SessionContainer = g.supertokens # type: ignore
1044+
await unverify_email(session_.get_user_id())
1045+
await session_.fetch_and_set_claim(EmailVerificationClaim)
1046+
return jsonify({"status": "OK"})
1047+
1048+
1049+
@app.route("/setRole", methods=["POST"]) # type: ignore
1050+
@verify_session()
1051+
async def verify_email_api():
1052+
session_: SessionContainer = g.supertokens # type: ignore
1053+
body: Dict[str, Any] = request.get_json() # type: ignore
1054+
await create_new_role_or_add_permissions(body["role"], body["permissions"])
1055+
await add_role_to_user(session_.get_user_id(), body["role"])
1056+
await session_.fetch_and_set_claim(UserRoleClaim)
1057+
await session_.fetch_and_set_claim(PermissionClaim)
1058+
return jsonify({"status": "OK"})
1059+
1060+
1061+
async def override_global_claim_validators(
1062+
gv: List[SessionClaimValidator],
1063+
_session: SessionContainer,
1064+
user_context: Dict[str, Any],
1065+
):
1066+
validators = gv.copy()
1067+
req = user_context["_default"]["request"]
1068+
body = await req.json()
1069+
1070+
if body.get("role"):
1071+
info = body["role"]
1072+
validator = getattr(UserRoleClaim.validators, info["validator"])
1073+
validators.append(validator(*info["args"]))
1074+
1075+
if body.get("permission"):
1076+
info = body["permission"]
1077+
validator = getattr(PermissionClaim.validators, info["validator"])
1078+
validators.append(validator(*info["args"]))
1079+
1080+
return validators
1081+
1082+
1083+
@app.route("/checkRole", methods=["POST"]) # type: ignore
1084+
@verify_session(override_global_claim_validators=override_global_claim_validators)
1085+
async def check_role_api():
1086+
return jsonify({"status": "OK"})
1087+
1088+
10211089
@app.route("/", defaults={"path": ""}) # type: ignore
10221090
@app.route("/<path:path>") # type: ignore
10231091
def index(_: str):

0 commit comments

Comments
 (0)