21
21
from supertokens_python .framework import BaseRequest , BaseResponse
22
22
from supertokens_python .normalised_url_path import NormalisedURLPath
23
23
from supertokens_python .querier import Querier
24
+ from supertokens_python .recipe .session .asyncio import get_session_information
24
25
from supertokens_python .recipe .userroles .recipe_implementation import (
25
26
RecipeImplementation ,
26
27
)
27
28
from supertokens_python .recipe .userroles .utils import validate_and_normalise_user_input
28
29
from supertokens_python .recipe_module import APIHandled , RecipeModule
29
30
from supertokens_python .supertokens import AppInfo
30
- from supertokens_python .types import RecipeUserId
31
+ from supertokens_python .types import RecipeUserId , User
31
32
32
33
from ...post_init_callbacks import PostSTInitCallbacks
33
34
from ..session import SessionRecipe
34
35
from ..session .claim_base_classes .primitive_array_claim import PrimitiveArrayClaim
35
36
from .exceptions import SuperTokensUserRolesError
36
- from .interfaces import GetPermissionsForRoleOkResult
37
+ from .interfaces import GetPermissionsForRoleOkResult , UnknownRoleError
37
38
from .utils import InputOverrideConfig
38
39
39
40
@@ -49,6 +50,8 @@ def __init__(
49
50
skip_adding_permissions_to_access_token : Optional [bool ] = None ,
50
51
override : Union [InputOverrideConfig , None ] = None ,
51
52
):
53
+ from ..oauth2provider .recipe import OAuth2ProviderRecipe
54
+
52
55
super ().__init__ (recipe_id , app_info )
53
56
self .config = validate_and_normalise_user_input (
54
57
self ,
@@ -72,6 +75,109 @@ def callback():
72
75
PermissionClaim
73
76
)
74
77
78
+ async def token_payload_builder (
79
+ user : User ,
80
+ scopes : List [str ],
81
+ session_handle : str ,
82
+ user_context : Dict [str , Any ],
83
+ ) -> Dict [str , Any ]:
84
+ payload : Dict [str , Any ] = {"roles" : None , "permissions" : None }
85
+
86
+ session_info = await get_session_information (
87
+ session_handle , user_context
88
+ )
89
+
90
+ if session_info is None :
91
+ raise Exception ("should never come here" )
92
+
93
+ user_roles : List [str ] = []
94
+
95
+ if "roles" in scopes or "permissions" in scopes :
96
+ res = await self .recipe_implementation .get_roles_for_user (
97
+ tenant_id = session_info .tenant_id ,
98
+ user_id = user .id ,
99
+ user_context = user_context ,
100
+ )
101
+
102
+ user_roles = res .roles
103
+
104
+ if "roles" in scopes :
105
+ payload ["roles" ] = user_roles
106
+
107
+ if "permissions" in scopes :
108
+ user_permissions : Set [str ] = set ()
109
+ for role in user_roles :
110
+ role_permissions = (
111
+ await self .recipe_implementation .get_permissions_for_role (
112
+ role = role ,
113
+ user_context = user_context ,
114
+ )
115
+ )
116
+
117
+ if isinstance (role_permissions , UnknownRoleError ):
118
+ raise Exception ("Failed to fetch permissions for the role" )
119
+
120
+ for perm in role_permissions .permissions :
121
+ user_permissions .add (perm )
122
+
123
+ payload ["permissions" ] = list (user_permissions )
124
+
125
+ return payload
126
+
127
+ OAuth2ProviderRecipe .get_instance ().add_access_token_builder_from_other_recipe (
128
+ token_payload_builder
129
+ )
130
+ OAuth2ProviderRecipe .get_instance ().add_id_token_builder_from_other_recipe (
131
+ token_payload_builder
132
+ )
133
+
134
+ async def user_info_builder (
135
+ user : User ,
136
+ _access_token_payload : Dict [str , Any ],
137
+ scopes : List [str ],
138
+ tenant_id : str ,
139
+ user_context : Dict [str , Any ],
140
+ ) -> Dict [str , Any ]:
141
+ user_info : Dict [str , Any ] = {"roles" : None , "permissions" : None }
142
+
143
+ user_roles = []
144
+
145
+ if "roles" in scopes or "permissions" in scopes :
146
+ res = await self .recipe_implementation .get_roles_for_user (
147
+ tenant_id = tenant_id ,
148
+ user_id = user .id ,
149
+ user_context = user_context ,
150
+ )
151
+
152
+ user_roles = res .roles
153
+
154
+ if "roles" in scopes :
155
+ user_info ["roles" ] = user_roles
156
+
157
+ if "permissions" in scopes :
158
+ user_permissions : Set [str ] = set ()
159
+ for role in user_roles :
160
+ role_permissions = (
161
+ await self .recipe_implementation .get_permissions_for_role (
162
+ role = role ,
163
+ user_context = user_context ,
164
+ )
165
+ )
166
+
167
+ if isinstance (role_permissions , UnknownRoleError ):
168
+ raise Exception ("Failed to fetch permissions for the role" )
169
+
170
+ for perm in role_permissions .permissions :
171
+ user_permissions .add (perm )
172
+
173
+ user_info ["permissions" ] = list (user_permissions )
174
+
175
+ return user_info
176
+
177
+ OAuth2ProviderRecipe .get_instance ().add_user_info_builder_from_other_recipe (
178
+ user_info_builder
179
+ )
180
+
75
181
PostSTInitCallbacks .add_post_init_callback (callback )
76
182
77
183
def is_error_from_this_recipe_based_on_instance (self , err : Exception ) -> bool :
0 commit comments