[Zope-CMF] Access problem.

Ignacio Dosil Lago idosil@ccietic.usc.es
Thu, 26 Sep 2002 12:57:52 +0200


On Wednesday 25 September 2002 13:39, you wrote:
> On Wed, 2002-09-25 at 06:41, Ignacio Dosil Lago wrote:
> > -- I am developing a CMF "link" product which defines its own travers=
e
> > method:
> >
> >   def __bobo_traverse__(self, request, name=3DNone):
> >     "Traverse method hook"
> >
> >     if hasattr(self, name):
> >       # return own attributes/subobjects
> >       return getattr(self, name)
> >     else:
> >       t=3D self.getTarget()
> >       if hasattr(t, name):
> >         # return target's attributes/subobjects
> >         return getattr(t, name)
> >       else:
> >         return t
> >
> > -- It works fine under the ZMI but when I try to access an object of =
this
> > product into a CMF portal using the CMF interface, Zope requests me l=
ogin
> > name and password (even if I am admin!!), which it doesn't accept, so=
 the
> > only way to continue is to cancel instead of triying to log in.
>
> I don't know why it would work in the ZMI;  this smells like a problem
> in the way you wrap (or don't) the target object returned by
> 'getTarget'.  Try the following to test that:
>
>     from Acquisition import aq_base, aq_parent
>     def __bobo_traverse__(self, request, name=3DNone):
>       "Traverse method hook"
>
>       if hasattr(self, name):
>         # return own attributes/subobjects
>         return getattr(self, name)
>       else:
>         t =3D self.getTarget()
>         t =3D aq_base( t ).__of__( aq_parent( self ) )
>         if hasattr(t, name):
>           # return target's attributes/subobjects
>           return getattr(t, name)
>         else:
>           return t
>
> This version addresses the issue that the security machinery expects to
> crawl up the containment part of the acquisition chain to verify that
> the user and the accessed object are in proper relation to one another;
> it does this by ripping off any existing acquisition wrapper (the
> 'aq_base' call) and re-wrapping the object in the context of the link's
> parent ( the '__of__' call).
>
> Hope this helps,
>
> Tres.



-- Well, I know this is a rather long answer but I hope you have time to =
read=20
it. :)
I've tried the solution you proposed yesterday and it doesn't seem to wor=
k.=20
The same error appears.=20
I decided to study the case in which a user creates a new link under the =
CMF=20
interface and gather some further information.=20
First of all, I'll try to explain what happens in "__bobo_traverse__" whe=
n a=20
user creates a new link. No target is assigned when a new link is created=
=20
(the link must be edited), so the method "getTarget" will always return=20
"None" and so Zope will throw a "not found" exception after calling=20
"__bobo_traverse__". That exception is never thrown when a new link is=20
created because the 'portal_url' is an =BFacquired? link attribute (what =
we=20
catch with the 1st  condition "if hasattr(self, name):" .=20
I mean, when a new link is created, the "getTarget" method is never calle=
d in=20
"__bobo_traberse__", so I suppose that it isn't the problem.




-- I've added this code at the beginning of "__bobo_traverse__":
  if name=3D=3D'portal_url':
    out=3D open('log.txt','a')
    out.write('Traversing '+str(self)+'. Target: '+str(self.getTarget())+=
'\n')
    out.close()

so when I create a new link this is the output:

Traversing <CMFUSCLinkImp instance at 8cbfb80>. Target: None
Traversing <CMFUSCLinkImp instance at 8cbfb80>. Target: None
Traversing <CMFUSCLinkImp instance at 8cbfb80>. Target: None
Traversing <CMFUSCLinkImp instance at 8cbfb80>. Target: None



-- Once the user clicks the "add" button at the CMF interface to add a ne=
w=20
link, the metadata edit form should appear. Instead Zope asks for login n=
ame=20
and password. Login is impossible so the only way out is to click "cancel=
".=20
This is the error Zope always throws after cancelling login:

Site Error

An error was encountered while publishing this resource.

Unauthorized
Sorry, a site error occurred.

Traceback (innermost last):
  File /home/Zope/Zope-2.5.1-linux2-x86/lib/python/ZPublisher/Publish.py,=
 line=20
150, in publish_module
  File=20
/home/Zope/Zope-2.5.1-linux2-x86/lib/python/Products/Localizer/__init__.p=
y,=20
line 65, in new_publish
  File /home/Zope/Zope-2.5.1-linux2-x86/lib/python/ZPublisher/Publish.py,=
 line=20
114, in publish
  File /home/Zope/Zope-2.5.1-linux2-x86/lib/python/Zope/__init__.py, line=
 159,=20
in zpublisher_exception_hook
    (Object: Link)
  File /home/Zope/Zope-2.5.1-linux2-x86/lib/python/ZPublisher/Publish.py,=
 line=20
98, in publish
  File /home/Zope/Zope-2.5.1-linux2-x86/lib/python/ZPublisher/mapply.py, =
line=20
88, in mapply
    (Object: metadata_edit_form)
  File /home/Zope/Zope-2.5.1-linux2-x86/lib/python/ZPublisher/Publish.py,=
 line=20
39, in call_object
    (Object: metadata_edit_form)
  File=20
/home/Zope/Zope-2.5.1-linux2-x86/lib/python/Shared/DC/Scripts/Bindings.py=
,=20
line 252, in __call__
    (Object: metadata_edit_form)
  File=20
/home/Zope/Zope-2.5.1-linux2-x86/lib/python/Shared/DC/Scripts/Bindings.py=
,=20
line 283, in _bindAndExec
    (Object: metadata_edit_form)
  File=20
/home/Zope/Zope-2.5.1-linux2-x86/lib/python/Products/PageTemplates/Expres=
sions.py,=20
line 186, in _eval
  File=20
/home/Zope/Zope-2.5.1-linux2-x86/lib/python/Products/PageTemplates/Expres=
sions.py,=20
line 143, in _eval
    (Info: here)
  File=20
/home/Zope/Zope-2.5.1-linux2-x86/lib/python/Products/PageTemplates/Expres=
sions.py,=20
line 339, in restrictedTraverse
    (Object: Link)
    (Info: {'path': ['portal_url'], 'TraversalRequestNameStack': []})
Unauthorized: You are not allowed to access portal_url in this context



-- I've added code to gather some information about what happens into=20
"restrictedTraverse" in the Expressions.py module, where the exception is=
=20
thrown, and this is the output (don't know if useful to you, but not for =
me):

  def restrictedTraverse(self, path, securityManager, get=3Dgetattr,=20
                                 has=3Dhasattr, N=3DNone, M=3D[],
                                 TupleType=3Dtype(())):

Initial param values passed:
 self=3D<CMFUSCLinkImp instance at 8f30628>
 path=3D[]
 securityManager=3D<AccessControl.SecurityManager.SecurityManager instanc=
e at=20
0x8eb6684>
 get=3D<built-in function getattr>
 has=3D<built-in function hasattr>
 N=3DNone
 M=3D[]
 TupleType=3D<type 'tuple'>

-- The condition which throws the exception:
  ...
  validate =3D securityManager.validate
  ...
  if not validate(object, container, name, o):

Params passed:
 object=3D<CMFUSCLinkImp instance at 8f30628>
 container=3DNone
 name=3Dportal_url
 o=3D<URLTool instance at 8ccf308>


Hope this clarifies :-(  a little bit what the problem is about.
Any suggestions/questions?
Kind regards.