How can I programmatically get the registration information of a view?

How can I programmatically get the registration information of a view?

In my example (see below) I get the overview-controlpanel view from plone.app.customerize.registration.getViews(IBrowserRequest) into my obj variable.

From it I can get the name, the configure.zcml file and the position of the declaration in it (obj.name and obj.info)

I assume that obj.required gives me a tuple with the for attribute in its first element. Is this right?

But how can I get the class and the permission?

obj.factory gives a hint to Products.Five.browser.metaconfigure.OverviewControlPanel but not to Products.CMFPlone.controlpanel.browser.overview.OverviewControlPanel as defined in configure.zcml.

>>> from plone.app.customerize import registration
>>> from zope.publisher.interfaces.browser import IBrowserRequest
>>> import pprint

>>> obj = [view
...           for view
...           in registration.getViews(IBrowserRequest)
...           if view.name.lower() in ['overview-controlpanel']
...           ][0]

>>> with open(obj.info.file, 'r') as f:
...     zcml_string = f.readlines()[obj.info.line-1:obj.info.eline]
>>> obj.name
'overview-controlpanel'
>>> obj.info.file
'/home/Plone-6.0.0b3/lib/python3.9/site-packages/Products/CMFPlone/controlpanel/browser/configure.zcml'
>>> zcml_string
<browser:page
    name="overview-controlpanel"
    for="plone.base.interfaces.IPloneSiteRoot"
    class=".overview.OverviewControlPanel"
    permission="plone.app.controlpanel.Overview"
    />
>>> obj.required
(<InterfaceClass plone.base.interfaces.siteroot.IPloneSiteRoot>,
    <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
>>> obj.factory
<class 'Products.Five.browser.metaconfigure.OverviewControlPanel'>

Check obj.factory.__bases__ or obj.factory.__mro__ (when you customize a view using plone.app.customerize, it generates a subclass of the original view class).

The permissions end up on the view class's __ac_permissions__ attribute, if I recall correctly.

neither obj.__mro__ nor obj.__bases__ give me Products.CMFPlone.controlpanel.browser.overview.OverviewControlPanel :

>>> obj.factory.__mro__
(<class 'Products.Five.browser.metaconfigure.SiteControlPanel'>,
 <class 'Products.CMFPlone.controlpanel.browser.site.SiteControlPanel'>,
 <class 'plone.app.registry.browser.controlpanel.ControlPanelFormWrapper'>,
 <class 'plone.z3cform.layout.FormWrapper'>,
 <class 'Products.Five.browser.BrowserView'>,
 <class 'Products.Five.browser.metaconfigure.simple'>,
 <class 'zope.browserpage.metaconfigure.simple'>,
 <class 'zope.publisher.browser.BrowserView'>,
 <class 'zope.location.location.Location'>,
 <class 'object'>)

>>> obj.factory.__bases__
(<class 'Products.CMFPlone.controlpanel.browser.site.SiteControlPanel'>,
 <class 'Products.Five.browser.metaconfigure.simple'>)

Are you sure you're looking at the same one as before? This looks like the site control panel rather than the overview.

Sorry. You're right I was looking at another view. The __mro__ was the right hint. Thank you!

>>> zcml_string
['  <browser:page\n',
 '      name="overview-controlpanel"\n',
 '      for="plone.base.interfaces.IPloneSiteRoot"\n',
 '      class=".overview.OverviewControlPanel"\n',
 '      permission="plone.app.controlpanel.Overview"\n',
 '      />\n']

>>> obj.name
'overview-controlpanel'

>>> obj.factory.__mro__[1]
<class 'Products.CMFPlone.controlpanel.browser.overview.OverviewControlPanel'>

>>> obj.factory.__mro__[0].__ac_permissions__
(('Plone Site Setup: Overview', ('', '__call__')),)

... but how do I get the for element?

obj.required[0] gives me plone.base.interfaces.siteroot.IPloneSiteRoot (note siteroot) but in configure.zcml the for element is plone.base.interfaces.IPloneSiteRoot (without siteroot)

>>> obj.required
(<InterfaceClass plone.base.interfaces.siteroot.IPloneSiteRoot>,
    <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>)

and last but not least: where do I get the class plone.app.controlpanel.Overview from (('Plone Site Setup: Overview', ('', '__call__')),)?

plone.base.interfaces.siteroot.IPloneSiteRoot and plone.base.interfaces.IPloneSiteRoot are the same object. plone.base.interface's __init__.py imports the interface from siteroot.py: plone.base/__init__.py at main · plone/plone.base · GitHub

plone.app.controlpanel.Overview is the zope 3 permission name and Plone Site Setup: Overview is the zope 2 permission name. I don't recall how to convert from one to the other.

The file ./Products/CMFPlone/controlpanel/permissions.zcml has title and id of the declared permission (see below).

Any hint where in code this file is loaded and what happens with it?

Somewhere must title and id be related to each other and maybe able to be queried ???

  <permission id="plone.app.controlpanel.Overview"
              title="Plone Site Setup: Overview">
    <role name="Manager"/>
    <role name="Site Administrator"/>
  </permission>

Both app.get_permissions() and AccessControl.Permission.getPermissions() give me tuples with the titles of the permissions but not the ids.

I guess it's https://github.com/zopefoundation/zope.security/blob/1fec9b3de6c17f95c7973ffe83d69d007fd5af0c/src/zope/security/permission.py#L56-L63 you want?