On Aug 20, 2014, at 2:43 PM, Pendergrass, Eric <eric.pendergr...@hp.com> wrote:
> Hi Ryan, > > We tried globally applying the hook but could not get execution to enter the > hook class. > > Perhaps we made a mistake, but we concluded the Controller still had to > inherit from HookController using the project-wide method. Otherwise we > would have been satisfied applying it project-wide. Ceilometer already has a couple of other hooks installed (for example, to provide the database handle) and those do work. I assume you followed them as examples? Doug > > Thanks, > Eric > >> Eric, > >> >> Doug's correct - this looks like a bug in pecan that occurs when you > subclass both rest.RestController and hooks.HookController. I'm working on > a bug fix as we speak. In the meantime, have you tried applying hooks at a > global application level? This approach should still work. >> >> On 08/14/14 04:38 PM, Pendergrass, Eric wrote: >>> Sure, Doug. We want the ability to selectively apply policies to >>> certain Ceilometer API methods based on user/tenant roles. >>> >>> For example, we want to restrict the ability to execute Alarm deletes >>> to admins and user/tenants who have a special role, say "domainadmin". >>> >>> The policy file might look like this: >>> { >>> "context_is_admin": [["role:admin"]], >>> "admin_and_matching_project_domain_id": [["role:domainadmin"]], >>> "admin_or_cloud_admin": [["rule:context_is_admin"], >>> ["rule:admin_and_matching_project_domain_id"]], >>> "telemetry:delete_alarms": [["rule:admin_or_cloud_admin"]] } >>> >>> The current acl.py and _query_to_kwargs access control setup either >>> sets project_id scope to None (do everything) or to the project_id in >>> the request header 'X-Project-Id'. This allows for admin or project >>> scope, but nothing in between. >>> >>> We tried hooks. Unfortunately we can't seem to turn the API >>> controllers into HookControllers just by adding HookController to the >>> Controller class definition. It causes infinite recursion on API >>> startup. For example, this doesn't work because ceilometer-api will >>> not start with it: >>> class MetersController(rest.RestController, HookController): >>> >>> If there was a way to use hooks with the v2. API controllers that >>> might work really well. >>> >>> So we are left using the @secure decorator and deriving the method >>> name from the request environ PATH_INFO and REQUEST_METHOD values. >>> This is how we determine the wrapped method within the class >>> (REQUEST_METHOD + PATH_INFO = "telemetry:delete_alarms" with some >>> munging). We need the method name in order to selectively apply acces >>> control to certain methods. >>> >>> Deriving the method this way isn't ideal but it's the only thing we've >>> gotten working between hooks, @secure, and regular decorators. >>> >>> I submitted a WIP BP here: https://review.openstack.org/#/c/112137/3. >>> It is slightly out of date but should give you a beter idea of our > goals. >>> >>> Thanks >>> >>>> Eric, >>>> >>>> If you can give us some more information about your end goal, >>>> independent >>> of the implementation, maybe we can propose an alternate technique to >>> achieve the same thing. >>>> >>>> Doug >>>> >>>> On Aug 12, 2014, at 6:21 PM, Ryan Petrello >>>> <ryan.petre...@dreamhost.com> >>> wrote: >>>> >>>>> Yep, you're right, this doesn't seem to work. The issue is that >>>>> security is enforced at routing time (while the controller is >>>>> still actually being discovered). In order to do this sort of >>>>> thing with the `check_permissions`, we'd probably need to add a > feature to pecan. >>>>> >>>>> On 08/12/14 06:38 PM, Pendergrass, Eric wrote: >>>>>> Sure, here's the decorated method from v2.py: >>>>>> >>>>>> class MetersController(rest.RestController): >>>>>> """Works on meters.""" >>>>>> >>>>>> @pecan.expose() >>>>>> def _lookup(self, meter_name, *remainder): >>>>>> return MeterController(meter_name), remainder >>>>>> >>>>>> @wsme_pecan.wsexpose([Meter], [Query]) >>>>>> @secure(RBACController.check_permissions) >>>>>> def get_all(self, q=None): >>>>>> >>>>>> and here's the decorator called by the secure tag: >>>>>> >>>>>> class RBACController(object): >>>>>> global _ENFORCER >>>>>> if not _ENFORCER: >>>>>> _ENFORCER = policy.Enforcer() >>>>>> >>>>>> >>>>>> @classmethod >>>>>> def check_permissions(cls): >>>>>> # do some stuff >>>>>> >>>>>> In check_permissions I'd like to know the class and method with >>>>>> the >>> @secure tag that caused check_permissions to be invoked. In this >>> case, that would be MetersController.get_all. >>>>>> >>>>>> Thanks >>>>>> >>>>>> >>>>>>> Can you share some code? What do you mean by, "is there a way >>>>>>> for the >>> decorator code to know it was called by MetersController.get_all" >>>>>>> >>>>>>> On 08/12/14 04:46 PM, Pendergrass, Eric wrote: >>>>>>>> Thanks Ryan, but for some reason the controller attribute is > None: >>>>>>>> >>>>>>>> (Pdb) from pecan.core import state >>>>>>>> (Pdb) state.__dict__ >>>>>>>> {'hooks': [<ceilometer.api.hooks.ConfigHook object at >>>>>>>> 0x31894d0>, <ceilometer.api.hooks.DBHook object at 0x3189650>, > >>>>>>>> <ceilometer.api.hooks.PipelineHook object at 0x39871d0>, >>>>>>>> <ceilometer.api.hooks.TranslationHook object at 0x3aa5510>], > 'app': >>>>>>>> <pecan.core.Pecan object at 0x2e76390>, 'request': <Request at >>>>>>>> 0x3ed7390 GET http://localhost:8777/v2/meters>, 'controller': >>>>>>>> None, >>>>>>>> 'response': <Response at 0x3ed74d0 200 OK>} >>>>>>>> >>>>>>>>> -----Original Message----- >>>>>>>>> From: Ryan Petrello [mailto:ryan.petre...@dreamhost.com] >>>>>>>>> Sent: Tuesday, August 12, 2014 10:34 AM >>>>>>>>> To: OpenStack Development Mailing List (not for usage >>>>>>>>> questions) >>>>>>>>> Subject: Re: [openstack-dev] [Ceilometer] Way to get wrapped >>> method's name/class using Pecan secure decorators? >>>>>>>>> >>>>>>>>> This should give you what you need: >>>>>>>>> >>>>>>>>> from pecan.core import state >>>>>>>>> state.controller >>>>>>>>> >>>>>>>>> On 08/12/14 04:08 PM, Pendergrass, Eric wrote: >>>>>>>>>> Hi, I'm trying to use the built in secure decorator in > Pecan >>>>>>>>>> for >>> access control, and I'ld like to get the name of the method that is >>> wrapped from within the decorator. >>>>>>>>>> >>>>>>>>>> For instance, if I'm wrapping MetersController.get_all > with >>>>>>>>>> an >>> @secure decorator, is there a way for the decorator code to know it >>> was called by MetersController.get_all? >>>>>>>>>> >>>>>>>>>> I don't see any global objects that provide this > information. >>>>>>>>>> I >>> can get the endpoint, v2/meters, with pecan.request.path, but that's >>> not as elegant. >>>>>>>>>> >>>>>>>>>> Is there a way to derive the caller or otherwise pass this >>> information to the decorator? >>>>>>>>>> >>>>>>>>>> Thanks >>>>>>>>>> Eric Pendergrass >>>>>>>>> >>>>>>>>>> _______________________________________________ >>>>>>>>>> OpenStack-dev mailing list >>>>>>>>>> OpenStack-dev@lists.openstack.org >>>>>>>>>> > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack >>>>>>>>>> -dev >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Ryan Petrello >>>>>>>>> Senior Developer, DreamHost >>>>>>>>> ryan.petre...@dreamhost.com >>>>>> >>>>>> _______________________________________________ >>>>>> OpenStack-dev mailing list >>>>>> OpenStack-dev@lists.openstack.org >>>>>> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev >>>>> >>>>> -- >>>>> Ryan Petrello >>>>> Senior Developer, DreamHost >>>>> ryan.petre...@dreamhost.com >>>>> >>>>> _______________________________________________ >>>>> OpenStack-dev mailing list >>>>> OpenStack-dev@lists.openstack.org >>>>> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev >>>> >>>> >>>> _______________________________________________ >>>> OpenStack-dev mailing list >>>> OpenStack-dev@lists.openstack.org >>>> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev >> >> >> >>> _______________________________________________ >>> OpenStack-dev mailing list >>> OpenStack-dev@lists.openstack.org >>> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev >> >> >> -- >> Ryan Petrello >> Senior Developer, DreamHost >> ryan.petre...@dreamhost.com >> >> _______________________________________________ >> OpenStack-dev mailing list >> OpenStack-dev@lists.openstack.org >> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev > _______________________________________________ > OpenStack-dev mailing list > OpenStack-dev@lists.openstack.org > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev _______________________________________________ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev