@@ -239,3 +239,73 @@ class DogsController(ControllerBase):
239
239
240
240
!!! info
241
241
It's important to note that ` ExecutionContext ` becomes available when there is route handler found to handle the current request.
242
+
243
+ To access the route's role(s) (custom metadata), we'll use the ` Reflector ` helper class, which is provided out of the box by the framework.
244
+ ` Reflector ` can be injected into a class in the normal way:
245
+
246
+ ``` python
247
+ # project_name/apps/dogs/guards.py
248
+ from ellar.di import injectable
249
+ from ellar.core import GuardCanActivate, IExecutionContext
250
+ from ellar.services import Reflector
251
+
252
+
253
+ @injectable ()
254
+ class RoleGuard (GuardCanActivate ):
255
+ def __init__ (self , reflector : Reflector):
256
+ self .reflector = reflector
257
+
258
+ async def can_activate (self , context : IExecutionContext) -> bool :
259
+ roles = self .reflector.get(' roles' , context.get_handler())
260
+ # request = context.switch_to_http_connection().get_request()
261
+ # check if user in request object has role
262
+ return ' user' in roles
263
+ ```
264
+
265
+ Next, we apply the ` RoleGuard ` to ` DogsController `
266
+
267
+ ``` python
268
+ # project_name/apps/dogs/controllers.py
269
+ import typing
270
+ from ellar.common import Body, Controller, post, set_metadata
271
+ from ellar.core import ControllerBase
272
+ from .schemas import CreateDogSerializer, DogListFilter
273
+ from .guards import RoleGuard
274
+
275
+ def roles (* _roles : str ) -> typing.Callable:
276
+ return set_metadata(' roles' , list (_roles))
277
+
278
+
279
+ @Controller (' /dogs' , guards = [RoleGuard, ])
280
+ class DogsController (ControllerBase ):
281
+ @post ()
282
+ @roles (' admin' , ' is_staff' )
283
+ async def create (self , payload : CreateDogSerializer = Body()):
284
+ result = payload.dict()
285
+ result.update(message = ' This action adds a new dog' )
286
+ return result
287
+ ```
288
+
289
+ Also, since ` RoleGuard ` depends on ` Reflector ` , it has to be registered as a provider. And we do that in ` DogsModule ` :
290
+
291
+ ``` python
292
+ # project_name/apps/dogs/module.py
293
+
294
+ from ellar.common import Module
295
+ from ellar.core import ModuleBase
296
+ from ellar.di import Container
297
+
298
+ from .controllers import DogsController
299
+ from .guards import RoleGuard
300
+
301
+
302
+ @Module (
303
+ controllers = [DogsController],
304
+ providers = [RoleGuard],
305
+ )
306
+ class DogsModule (ModuleBase ):
307
+ def register_providers (self , container : Container) -> None :
308
+ # for more complicated provider registrations
309
+ # container.register_instance(...)
310
+ pass
311
+ ```
0 commit comments