Skip to content

Commit f4e4f26

Browse files
Merge pull request #375 from supertokens/fix/user-roles-mt
fix: Userroles recipe multitenancy features
2 parents 2bf2094 + bb00729 commit f4e4f26

File tree

5 files changed

+79
-36
lines changed

5 files changed

+79
-36
lines changed

supertokens_python/recipe/userroles/asyncio/__init__.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Dict, List, Union
1+
from typing import Any, Dict, List, Union, Optional
22

33
from supertokens_python.recipe.userroles.interfaces import (
44
AddRoleToUserOkResult,
@@ -17,44 +17,54 @@
1717

1818

1919
async def add_role_to_user(
20-
user_id: str, role: str, user_context: Union[Dict[str, Any], None] = None
20+
tenant_id: Optional[str],
21+
user_id: str,
22+
role: str,
23+
user_context: Union[Dict[str, Any], None] = None,
2124
) -> Union[AddRoleToUserOkResult, UnknownRoleError]:
2225
if user_context is None:
2326
user_context = {}
2427
return await UserRolesRecipe.get_instance().recipe_implementation.add_role_to_user(
25-
user_id, role, user_context
28+
user_id, role, tenant_id, user_context
2629
)
2730

2831

2932
async def remove_user_role(
30-
user_id: str, role: str, user_context: Union[Dict[str, Any], None] = None
33+
tenant_id: Optional[str],
34+
user_id: str,
35+
role: str,
36+
user_context: Union[Dict[str, Any], None] = None,
3137
) -> Union[RemoveUserRoleOkResult, UnknownRoleError]:
3238
if user_context is None:
3339
user_context = {}
3440
return await UserRolesRecipe.get_instance().recipe_implementation.remove_user_role(
35-
user_id, role, user_context
41+
user_id, role, tenant_id, user_context
3642
)
3743

3844

3945
async def get_roles_for_user(
40-
user_id: str, user_context: Union[Dict[str, Any], None] = None
46+
tenant_id: Optional[str],
47+
user_id: str,
48+
user_context: Union[Dict[str, Any], None] = None,
4149
) -> GetRolesForUserOkResult:
4250
if user_context is None:
4351
user_context = {}
4452
return (
4553
await UserRolesRecipe.get_instance().recipe_implementation.get_roles_for_user(
46-
user_id, user_context
54+
user_id, tenant_id, user_context
4755
)
4856
)
4957

5058

5159
async def get_users_that_have_role(
52-
role: str, user_context: Union[Dict[str, Any], None] = None
60+
tenant_id: Optional[str],
61+
role: str,
62+
user_context: Union[Dict[str, Any], None] = None,
5363
) -> Union[GetUsersThatHaveRoleOkResult, UnknownRoleError]:
5464
if user_context is None:
5565
user_context = {}
5666
return await UserRolesRecipe.get_instance().recipe_implementation.get_users_that_have_role(
57-
role, user_context
67+
role, tenant_id, user_context
5868
)
5969

6070

supertokens_python/recipe/userroles/interfaces.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from abc import ABC, abstractmethod
2-
from typing import Any, Dict, List, Union
2+
from typing import Any, Dict, List, Union, Optional
33

44

55
class AddRoleToUserOkResult:
@@ -58,25 +58,33 @@ def __init__(self, roles: List[str]):
5858
class RecipeInterface(ABC):
5959
@abstractmethod
6060
async def add_role_to_user(
61-
self, user_id: str, role: str, user_context: Dict[str, Any]
61+
self,
62+
user_id: str,
63+
role: str,
64+
tenant_id: Optional[str],
65+
user_context: Dict[str, Any],
6266
) -> Union[AddRoleToUserOkResult, UnknownRoleError]:
6367
pass
6468

6569
@abstractmethod
6670
async def remove_user_role(
67-
self, user_id: str, role: str, user_context: Dict[str, Any]
71+
self,
72+
user_id: str,
73+
role: str,
74+
tenant_id: Optional[str],
75+
user_context: Dict[str, Any],
6876
) -> Union[RemoveUserRoleOkResult, UnknownRoleError]:
6977
pass
7078

7179
@abstractmethod
7280
async def get_roles_for_user(
73-
self, user_id: str, user_context: Dict[str, Any]
81+
self, user_id: str, tenant_id: Optional[str], user_context: Dict[str, Any]
7482
) -> GetRolesForUserOkResult:
7583
pass
7684

7785
@abstractmethod
7886
async def get_users_that_have_role(
79-
self, role: str, user_context: Dict[str, Any]
87+
self, role: str, tenant_id: Optional[str], user_context: Dict[str, Any]
8088
) -> Union[GetUsersThatHaveRoleOkResult, UnknownRoleError]:
8189
pass
8290

supertokens_python/recipe/userroles/recipe.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,12 @@ def __init__(self) -> None:
147147
default_max_age_in_sec = 300
148148

149149
async def fetch_value(
150-
user_id: str, _tenant_id: str, user_context: Dict[str, Any]
150+
user_id: str, tenant_id: str, user_context: Dict[str, Any]
151151
) -> List[str]:
152152
recipe = UserRolesRecipe.get_instance()
153153

154154
user_roles = await recipe.recipe_implementation.get_roles_for_user(
155-
user_id, user_context
155+
tenant_id, user_id, user_context
156156
)
157157

158158
user_permissions: Set[str] = set()
@@ -182,11 +182,11 @@ def __init__(self) -> None:
182182
default_max_age_in_sec = 300
183183

184184
async def fetch_value(
185-
user_id: str, _tenant_id: str, user_context: Dict[str, Any]
185+
user_id: str, tenant_id: str, user_context: Dict[str, Any]
186186
) -> List[str]:
187187
recipe = UserRolesRecipe.get_instance()
188188
res = await recipe.recipe_implementation.get_roles_for_user(
189-
user_id, user_context
189+
tenant_id, user_id, user_context
190190
)
191191
return res.roles
192192

supertokens_python/recipe/userroles/recipe_implementation.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# under the License.
1414

1515

16-
from typing import Any, Dict, List, Union
16+
from typing import Any, Dict, List, Union, Optional
1717

1818
from supertokens_python.normalised_url_path import NormalisedURLPath
1919
from supertokens_python.querier import Querier
@@ -32,6 +32,7 @@
3232
RemoveUserRoleOkResult,
3333
UnknownRoleError,
3434
)
35+
from ..multitenancy.constants import DEFAULT_TENANT_ID
3536

3637

3738
class RecipeImplementation(RecipeInterface):
@@ -40,11 +41,16 @@ def __init__(self, querier: Querier):
4041
self.querier = querier
4142

4243
async def add_role_to_user(
43-
self, user_id: str, role: str, user_context: Dict[str, Any]
44+
self,
45+
user_id: str,
46+
role: str,
47+
tenant_id: Optional[str],
48+
user_context: Dict[str, Any],
4449
) -> Union[AddRoleToUserOkResult, UnknownRoleError]:
4550
params = {"userId": user_id, "role": role}
4651
response = await self.querier.send_put_request(
47-
NormalisedURLPath("/recipe/user/role"), params
52+
NormalisedURLPath(f"{tenant_id or DEFAULT_TENANT_ID}/recipe/user/role"),
53+
params,
4854
)
4955
if response.get("status") == "OK":
5056
return AddRoleToUserOkResult(
@@ -53,11 +59,18 @@ async def add_role_to_user(
5359
return UnknownRoleError()
5460

5561
async def remove_user_role(
56-
self, user_id: str, role: str, user_context: Dict[str, Any]
62+
self,
63+
user_id: str,
64+
role: str,
65+
tenant_id: Optional[str],
66+
user_context: Dict[str, Any],
5767
) -> Union[RemoveUserRoleOkResult, UnknownRoleError]:
5868
params = {"userId": user_id, "role": role}
5969
response = await self.querier.send_post_request(
60-
NormalisedURLPath("/recipe/user/role/remove"), params
70+
NormalisedURLPath(
71+
f"{tenant_id or DEFAULT_TENANT_ID}/recipe/user/role/remove"
72+
),
73+
params,
6174
)
6275
if response["status"] == "OK":
6376
return RemoveUserRoleOkResult(
@@ -66,20 +79,22 @@ async def remove_user_role(
6679
return UnknownRoleError()
6780

6881
async def get_roles_for_user(
69-
self, user_id: str, user_context: Dict[str, Any]
82+
self, user_id: str, tenant_id: Optional[str], user_context: Dict[str, Any]
7083
) -> GetRolesForUserOkResult:
7184
params = {"userId": user_id}
7285
response = await self.querier.send_get_request(
73-
NormalisedURLPath("/recipe/user/roles"), params
86+
NormalisedURLPath(f"{tenant_id or DEFAULT_TENANT_ID}/recipe/user/roles"),
87+
params,
7488
)
7589
return GetRolesForUserOkResult(roles=response["roles"])
7690

7791
async def get_users_that_have_role(
78-
self, role: str, user_context: Dict[str, Any]
92+
self, role: str, tenant_id: Optional[str], user_context: Dict[str, Any]
7993
) -> Union[GetUsersThatHaveRoleOkResult, UnknownRoleError]:
8094
params = {"role": role}
8195
response = await self.querier.send_get_request(
82-
NormalisedURLPath("/recipe/role/users"), params
96+
NormalisedURLPath(f"{tenant_id or DEFAULT_TENANT_ID}/recipe/role/users"),
97+
params,
8398
)
8499
if response.get("status") == "OK":
85100
return GetUsersThatHaveRoleOkResult(users=response["users"])

supertokens_python/recipe/userroles/syncio/__init__.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# License for the specific language governing permissions and limitations
1313
# under the License.
1414

15-
from typing import Any, Dict, List, Union
15+
from typing import Any, Dict, List, Union, Optional
1616

1717
from supertokens_python.async_to_sync_wrapper import sync
1818
from supertokens_python.recipe.userroles.interfaces import (
@@ -31,35 +31,45 @@
3131

3232

3333
def add_role_to_user(
34-
user_id: str, role: str, user_context: Union[Dict[str, Any], None] = None
34+
tenant_id: Optional[str],
35+
user_id: str,
36+
role: str,
37+
user_context: Union[Dict[str, Any], None] = None,
3538
) -> Union[AddRoleToUserOkResult, UnknownRoleError]:
3639
from supertokens_python.recipe.userroles.asyncio import add_role_to_user
3740

38-
return sync(add_role_to_user(user_id, role, user_context))
41+
return sync(add_role_to_user(tenant_id, user_id, role, user_context))
3942

4043

4144
def remove_user_role(
42-
user_id: str, role: str, user_context: Union[Dict[str, Any], None] = None
45+
tenant_id: Optional[str],
46+
user_id: str,
47+
role: str,
48+
user_context: Union[Dict[str, Any], None] = None,
4349
) -> Union[RemoveUserRoleOkResult, UnknownRoleError]:
4450
from supertokens_python.recipe.userroles.asyncio import remove_user_role
4551

46-
return sync(remove_user_role(user_id, role, user_context))
52+
return sync(remove_user_role(tenant_id, user_id, role, user_context))
4753

4854

4955
def get_roles_for_user(
50-
user_id: str, user_context: Union[Dict[str, Any], None] = None
56+
tenant_id: Optional[str],
57+
user_id: str,
58+
user_context: Union[Dict[str, Any], None] = None,
5159
) -> GetRolesForUserOkResult:
5260
from supertokens_python.recipe.userroles.asyncio import get_roles_for_user
5361

54-
return sync(get_roles_for_user(user_id, user_context))
62+
return sync(get_roles_for_user(tenant_id, user_id, user_context))
5563

5664

5765
def get_users_that_have_role(
58-
role: str, user_context: Union[Dict[str, Any], None] = None
66+
tenant_id: Optional[str],
67+
role: str,
68+
user_context: Union[Dict[str, Any], None] = None,
5969
) -> Union[GetUsersThatHaveRoleOkResult, UnknownRoleError]:
6070
from supertokens_python.recipe.userroles.asyncio import get_users_that_have_role
6171

62-
return sync(get_users_that_have_role(role, user_context))
72+
return sync(get_users_that_have_role(tenant_id, role, user_context))
6373

6474

6575
def create_new_role_or_add_permissions(

0 commit comments

Comments
 (0)