Zope URL namespaces also looked up as views, unexpectedly mask other names

Bug #589010 reported by Robert Collins
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Launchpad itself
Fix Released
Low
Gary Poster

Bug Description

Zope provides a mechanism to explicitly identify path elements in a URI as belonging to a certain "namespace." The spelling is ++NAMESPACE++PATH_ELEMENT. As an example, "/foo/" can cause a database object to be looked up with the identifier "foo", while "/++etc++foo/" might cause a completely separate lookup for the name "foo," as registered in the "etc" namespace.

Unfortunately, the registration of namespaces is leaky: they also will be looked up as views, if no view of the same name exists. This is because namespaces are registered for adapting (context, request) and providing zope.traversing.interfaces.ITraversable, and views are looked up for adapting (context, request) and providing anything at all.

This means, for example, that the following, original symptoms of this bug and bug 589011 happens:

"""
Visit https://launchpad.net/

in the search box type 'oops' and search. should take you to https://edge.launchpad.net/+search?field.text=oops

where the first hit under 'exact matches' is
Oops (Proprietary)
This project is about associating log information with an event. Later, when an event becomes interesting (an
...

This project doesn't seem to really exist, LOSA's can't access it even.
"""

The project did exist, and the search results were correct to include it. The problem was that traversal was blocked by this leaky registration.

This is true of any registered URI namespace. This is probably reasonably indicative of the specific problems we have:

$ make harness
>>> from zope import component
>>> from zope.traversing.interfaces import ITraversable
>>> from zope.interface import Interface
>>> gsm = component.getGlobalSiteManager()
>>> from zope.publisher.interfaces.browser import IBrowserRequest
>>> gsm.adapters.lookupAll((Interface, IBrowserRequest), ITraversable)
((u'resource', <class 'zope.traversing.namespace.resource'>), (u'oops', <class 'canonical.launchpad.webapp.errorlog.OopsNamespace'>), (u'form', <class 'canonical.launchpad.webapp.namespace.FormNamespaceView'>), (u'view', <class 'zope.traversing.namespace.view'>))

The proper fix would be to make view registration in the Zope framework actually based on a view being registered for a specific view interface, rather than anything at all. Backwards compatibility concerns make this very unlikely to happen.

Another approach would be to change our navigation to reject views that provide ITraversable. There are at least two reasons why this is a bad idea. First, ITraversable is a generic interface, and views sometimes legitimately provide it. Second, our navigation code is spread out over many modules, so changing this logic would be fragile.

A third approach would be to automatically or manually register null adapters to hide the namespace registrations from view lookup. Here's an example of manual registration that just fixes the "oops" namespace, as a proof of concept:

=== modified file 'lib/canonical/launchpad/webapp/errorlog.py'
--- lib/canonical/launchpad/webapp/errorlog.py 2010-05-15 17:43:59 +0000
+++ lib/canonical/launchpad/webapp/errorlog.py 2010-06-04 15:31:28 +0000
@@ -24,7 +24,7 @@
 from zope.error.interfaces import IErrorReportingUtility
 from zope.event import notify
 from zope.exceptions.exceptionformatter import format_exception
-from zope.interface import implements
+from zope.interface import implements, implementer, Interface
 from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
 from zope.traversing.namespace import view

@@ -695,3 +695,7 @@
         # Store the oops request in the request annotations.
         self.request.annotations[LAZR_OOPS_USER_REQUESTED_KEY] = True
         return self.context
+
+@implementer(Interface)
+def adapter_mask(*args):
+ return None

=== modified file 'lib/canonical/launchpad/webapp/errorlog.zcml'
--- lib/canonical/launchpad/webapp/errorlog.zcml 2009-07-23 05:02:47 +0000
+++ lib/canonical/launchpad/webapp/errorlog.zcml 2010-06-04 18:19:22 +0000
@@ -35,5 +35,16 @@
         provides="zope.traversing.interfaces.ITraversable" for="*"
         factory="canonical.launchpad.webapp.errorlog.OopsNamespace"
         />
+ <!-- Because Zope view lookup is for factories that provide *any*
+ interface (an underlying problem in the framework that cannot be
+ fixed now without serious backwards compatibility problems), the
+ above will appear as a view and mask database objects in
+ traversal for the "oops" name unless we register a mask, as below.
+ See bug -->
+ <adapter
+ name="oops"
+ for="* zope.publisher.interfaces.IRequest"
+ factory=".errorlog.adapter_mask"
+ />

 </configure>

I'm going to pursue an automatic version of this approach. We could catch an event signaling the start of publishing, which will be after zcml has been processed. We could then automatically register adapter masks for all registered ITraversables that do not have views registered for them.

Related branches

Revision history for this message
Gary Poster (gary) wrote :

It appears to me that the reported bug is that the project is broken, not that the search is broken. Therefore, I assigned it to registry. If I misunderstood, and this indicates a broken aspect of searching generally, please throw it over to launchpad-foundations.

affects: launchpad → launchpad-registry
Revision history for this message
Curtis Hovey (sinzui) wrote : Re: Cannot access project with blacklisted name

This issue is a data issue. I converted it to a question so that the data can be fixed. Elliot Murphy created the 'oops' project last year, then the name was taken by the app (blacklisted), but no one fixed the project name though :( I discovered the issue a few months ago when fixing licenses. I should have asked the admins to rename the project then.

Changed in launchpad-registry:
status: New → Invalid
summary: - searching for 'oops' on home page gives strange Proprietary project as
- first result
+ Cannot access project with blacklisted name
Revision history for this message
Robert Collins (lifeless) wrote : Re: [Bug 589010] Re: searching for 'oops' on home page gives strange Proprietary project as first result

Gary, This bug is specifically about the search, not the access - I
filed a separate bug for accessing the project.

We shouldn't show blacklisted projects in search results.

Changed in launchpad-registry:
status: Invalid → New
affects: launchpad-registry → launchpad-foundations
summary: - Cannot access project with blacklisted name
+ blacklisted project shows up in search results
Revision history for this message
Gary Poster (gary) wrote : Re: blacklisted project shows up in search results

Got it, thanks.

Changed in launchpad-foundations:
status: New → Triaged
importance: Undecided → Low
Revision history for this message
Curtis Hovey (sinzui) wrote :

No this is still not the problem. *No one* can access that project, not even an admin. This issue is not about search or about showing projects who name is the same as a blacklisted item. This is about incompetant engineers who create a blacklist names without first vetting the production data. There are two kinds of black list names, those that follow a pattern that are reserved for special users, and those used by the app so cannot be used by any one. This is a case of the second instance. Launchpad uses the oops name, so no one may use it.

Revision history for this message
Robert Collins (lifeless) wrote : Re: [Bug 589010] Re: blacklisted project shows up in search results

I filed a *separate bug* about the behaviour on the actual url itself;
our search code should handle the silliness in the database more
gracefully than it does: we may blacklist things in the future that
already exist, and making admins and engineers understand this quirky
part of the system is inefficient. We have code handling the
blacklist, it should be kicking in for search generation too - exactly
like privacy kicks in in search generation.

summary: - blacklisted project shows up in search results
+ non blacklisted webapp hooks subtly break search
description: updated
Gary Poster (gary)
summary: - non blacklisted webapp hooks subtly break search
+ Zope URL namespaces also looked up as views, unexpectedly mask other
+ names
Gary Poster (gary)
description: updated
Gary Poster (gary)
Changed in launchpad-foundations:
assignee: nobody → Gary Poster (gary)
Revision history for this message
Ursula Junque (ursinha) wrote : Bug fixed by a commit
Changed in launchpad-foundations:
milestone: none → 10.06
status: Triaged → Fix Committed
tags: added: qa-needstesting
Curtis Hovey (sinzui)
tags: added: qa-ok
removed: qa-needstesting
Curtis Hovey (sinzui)
Changed in launchpad-foundations:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.