Merge lp:~salgado/launchpad/apidoc into lp:launchpad

Proposed by Guilherme Salgado
Status: Merged
Approved by: Guilherme Salgado
Approved revision: no longer in the source branch.
Merged at revision: 11220
Proposed branch: lp:~salgado/launchpad/apidoc
Merge into: lp:launchpad
Diff against target: 593 lines (+217/-52)
20 files modified
configs/development/apidoc-configure-normal.zcml (+84/-39)
configs/development/launchpad-lazr.conf (+3/-0)
lib/canonical/config/schema-lazr.conf (+2/-0)
lib/canonical/launchpad/browser/launchpad.py (+2/-2)
lib/canonical/launchpad/doc/webapp-publication.txt (+5/-0)
lib/canonical/launchpad/layers.py (+4/-0)
lib/canonical/launchpad/permissions.zcml (+5/-0)
lib/canonical/launchpad/security.py (+14/-0)
lib/canonical/launchpad/systemhomes.py (+11/-2)
lib/canonical/launchpad/webapp/authentication.py (+21/-1)
lib/canonical/launchpad/webapp/authorization.py (+6/-2)
lib/canonical/launchpad/webapp/configure.zcml (+1/-1)
lib/canonical/launchpad/webapp/interfaces.py (+4/-0)
lib/canonical/launchpad/webapp/publisher.py (+0/-3)
lib/canonical/launchpad/webapp/servers.py (+15/-1)
lib/lp/app/stories/apidoc.txt (+25/-0)
setup.py (+5/-0)
site.zcml (+1/-0)
versions.cfg (+7/-1)
zopeapp.zcml (+2/-0)
To merge this branch: bzr merge lp:~salgado/launchpad/apidoc
Reviewer Review Type Date Requested Status
Gary Poster (community) Approve
Review via email: mp+30520@code.launchpad.net

Commit message

Add a new vhost (apidoc.launchpad.dev), enabled only when devmode is on, for Launchpad's apidoc using zope.app.apidoc.

Description of the change

Make zope.app.apidoc available on the new apidoc.lp.dev vhost.

To post a comment you must log in.
Revision history for this message
Gary Poster (gary) wrote :
Download full text (4.4 KiB)

Hi Salgado. Very cool. Thank you. Comments below.

Requested:

- Let's put the changes from lib/canonical/launchpad/webapp/configure.zcml into apidoc-configure-normal.zcml.

Questions and comments:

- Why is this necessary, do you know? I realize it is an existing code that you moved around, but neither the comment nor the "provides" made much sense to me, though Google did show me some hints that it might be standard practice for enabling the apidoc for some reason. Did you try removing it?
+ <!-- Turn on devmode for the following includes principal=work -->
+ <meta:provides feature="devmode" />

- I'm concerned that the tests are going to be run with even more registrations that will not be part of production. I wish there were a light, easy way to start up another LP instance for the apidoc smoke test that then would not pollute the rest of the tests with the apidoc registrations in the zcml file. However, I don't know of one, and unless you do, I won't insist that we address this concern. It's certainly just slightly enlarging an existing problem, rather than making a new one.

- Did you audit zope.login to make sure it's registrations don't do something we need to be worried about from a security perspective? If not, one of us should. I'd feel somewhat happier if ``<include package="zope.login" />`` were part of the apidoc zcml, but then we're exacerbating the previous problem (that is, production registrations are more and more different from test registrations).

Suggested:

- I suggest renaming LaunchpadPrincipalAnnotations to TemporaryPrincipalAnnotations: the behavior (and the fact that the implementation is effectively a stub) is something worth highlighting. Calling it "Launchpad" doesn't buy us anything.

- FWIW, LaunchpadPrincipalAnnotations could subclass UserDict.UserDict and be shortened to the __init__ plus a call to the shared constructor and the interface declarations. Do it if you want.

- For this comment:
+ <!-- XXX: Copied from zope.browserresource as apidoc breaks if we make
+ IAPIDocRoot implement ISite so that the original registration works
+ for us. -->
I suggest that this is not an XXX. To that point, this is not "Copied" but "Modified" (the "for" is different, and that's the key).

- For this comment:
+ <!-- XXX Probably make this in overrides for ISimpleReadContainer. Safer:
+ register for all apidoc containers, one way or another -->
You mentioned that these comments came from me. I think we can just remove the comment entirely. As I said on IRC, for the first half, I think I expected that this was going to have to go in overrides. Since it works without being in overrides, this is a "never mind...". For the second half ("Safer:..."), I think we're probably fine. It would be nice if we could easily register this only for the bots we care about, but, eh. It's all right, I think.

- I have said that I was fine with the change to authorization.py, but actually I had another idea. I'm not 100% convinced the new idea is better, but it is simpler, at least. The idea is to revert all current changes from that file, and then add ``from zope.proxy import removeAllProx...

Read more...

Revision history for this message
Gary Poster (gary) :
review: Needs Information
Revision history for this message
Guilherme Salgado (salgado) wrote :
Download full text (6.0 KiB)

On Wed, 2010-07-21 at 17:08 +0000, Gary Poster wrote:
> Hi Salgado. Very cool. Thank you. Comments below.
>
> Requested:
>
> - Let's put the changes from
> lib/canonical/launchpad/webapp/configure.zcml into
> apidoc-configure-normal.zcml.

Good catch. Done.

>
> Questions and comments:
>
> - Why is this necessary, do you know? I realize it is an existing
> code that you moved around, but neither the comment nor the "provides"
> made much sense to me, though Google did show me some hints that it
> might be standard practice for enabling the apidoc for some reason.
> Did you try removing it?
> + <!-- Turn on devmode for the following includes principal=work
> -->
> + <meta:provides feature="devmode" />

For some reason it became necessary when I moved the zcml to
apidoc-configure-normal.zcml. I've moved the principal= part.

>
> - I'm concerned that the tests are going to be run with even more
> registrations that will not be part of production. I wish there were
> a light, easy way to start up another LP instance for the apidoc smoke
> test that then would not pollute the rest of the tests with the apidoc
> registrations in the zcml file. However, I don't know of one, and
> unless you do, I won't insist that we address this concern. It's
> certainly just slightly enlarging an existing problem, rather than
> making a new one.

I hadn't thought about that, but I'll see if I can find a way to not
make this situation any worse.

>
> - Did you audit zope.login to make sure it's registrations don't do
> something we need to be worried about from a security perspective? If
> not, one of us should. I'd feel somewhat happier if ``<include
> package="zope.login" />`` were part of the apidoc zcml, but then we're
> exacerbating the previous problem (that is, production registrations
> are more and more different from test registrations).

zope.login is now needed because the ILoginPassword adapter has been
moved there from zope.publisher, but you have a good point that it
should be audited.

I've just checked and it just registers the ILoginPassword adapters for
both IHTTPCredentials and IFTPCredentials as zope.publisher did until
version 3.10.

I'm now wondering if I should do the same for all the eggs that I've
updated as part of this -- they could also register new things that
we're not expecting.

>
> Suggested:
>
> - I suggest renaming LaunchpadPrincipalAnnotations to
> TemporaryPrincipalAnnotations: the behavior (and the fact that the
> implementation is effectively a stub) is something worth highlighting.
> Calling it "Launchpad" doesn't buy us anything.

I like your suggestion; renamed.

>
> - FWIW, LaunchpadPrincipalAnnotations could subclass UserDict.UserDict
> and be shortened to the __init__ plus a call to the shared constructor
> and the interface declarations. Do it if you want.

I'm all for it!

Also, I thought I could make apidoc.lp.dev work for anonymous users by
just registering an adapter like the above for
IUnauthenticatedPrincipal, but then I got
http://paste.ubuntu.com/467401/

I'm thinking that it may be better to actually require a logged-in user
to use apidoc.lp.dev and ask them to login in case they're no...

Read more...

Revision history for this message
Guilherme Salgado (salgado) wrote :

Another alternative to deal with the fact that apidoc.lp.dev doesn't seem to work for anonymous users would be to somehow pretend all requests on apidoc.lp.dev are authenticated. I did that by making APIDocBrowserPublication.getPrincipal() return a fixed principal, but now I always get that same LocationError traceback: http://paste.ubuntu.com/467401/

Revision history for this message
Gary Poster (gary) wrote :
Download full text (5.9 KiB)

Hey Salgado. Thank you. Below, I've deleted sections for which I thought no further discussion was necessary.

On Jul 22, 2010, at 5:15 AM, Guilherme Salgado wrote:

> On Wed, 2010-07-21 at 17:08 +0000, Gary Poster wrote:
>> Hi Salgado. Very cool. Thank you. Comments below.
>>
>> Requested:
>>
>> - Let's put the changes from
>> lib/canonical/launchpad/webapp/configure.zcml into
>> apidoc-configure-normal.zcml.
>
> Good catch. Done.

I don't understand why you didn't also move this:
+ <utility
+ component="canonical.launchpad.systemhomes.apidocroot"
+ provides="canonical.launchpad.webapp.interfaces.IAPIDocRoot" />
Was it an oversight, or is there a reason to keep it where it is?

...

>> - I'm concerned that the tests are going to be run with even more
>> registrations that will not be part of production. I wish there were
>> a light, easy way to start up another LP instance for the apidoc smoke
>> test that then would not pollute the rest of the tests with the apidoc
>> registrations in the zcml file. However, I don't know of one, and
>> unless you do, I won't insist that we address this concern. It's
>> certainly just slightly enlarging an existing problem, rather than
>> making a new one.
>
> I hadn't thought about that, but I'll see if I can find a way to not
> make this situation any worse.

Ack, thanks.

>> - Did you audit zope.login to make sure it's registrations don't do
>> something we need to be worried about from a security perspective? If
>> not, one of us should. I'd feel somewhat happier if ``<include
>> package="zope.login" />`` were part of the apidoc zcml, but then we're
>> exacerbating the previous problem (that is, production registrations
>> are more and more different from test registrations).
>
> zope.login is now needed because the ILoginPassword adapter has been
> moved there from zope.publisher, but you have a good point that it
> should be audited.
>
> I've just checked and it just registers the ILoginPassword adapters for
> both IHTTPCredentials and IFTPCredentials as zope.publisher did until
> version 3.10.

Cool.

> I'm now wondering if I should do the same for all the eggs that I've
> updated as part of this -- they could also register new things that
> we're not expecting.

The reason why I singled in on this one is that it is registered in zopeapp.zcml, so it will affect production. The rest will only affect tests and development, so I'm less concerned in this regard.

zope.publisher's update I guess is worth a look, actually. But that's the only other one I see.

> - FWIW, LaunchpadPrincipalAnnotations could subclass UserDict.UserDict
>> and be shortened to the __init__ plus a call to the shared constructor
>> and the interface declarations. Do it if you want.
>
> I'm all for it!
>
> Also, I thought I could make apidoc.lp.dev work for anonymous users by
> just registering an adapter like the above for
> IUnauthenticatedPrincipal, but then I got
> http://paste.ubuntu.com/467401/

Meh, digging into it just a bit, I see that preference group thing is doing somewhat unusual security dances. I wouldn't be all that surprised if that LocationError were actually hiding a Forbidd...

Read more...

Revision history for this message
Gary Poster (gary) :
review: Approve
Revision history for this message
Guilherme Salgado (salgado) wrote :
Download full text (5.5 KiB)

On Fri, 2010-07-23 at 12:42 +0000, Gary Poster wrote:
> Hey Salgado. Thank you. Below, I've deleted sections for which I thought no further discussion was necessary.
>
> On Jul 22, 2010, at 5:15 AM, Guilherme Salgado wrote:
>
> > On Wed, 2010-07-21 at 17:08 +0000, Gary Poster wrote:
> >> Hi Salgado. Very cool. Thank you. Comments below.
> >>
> >> Requested:
> >>
> >> - Let's put the changes from
> >> lib/canonical/launchpad/webapp/configure.zcml into
> >> apidoc-configure-normal.zcml.
> >
> > Good catch. Done.
>
> I don't understand why you didn't also move this:
> + <utility
> + component="canonical.launchpad.systemhomes.apidocroot"
> + provides="canonical.launchpad.webapp.interfaces.IAPIDocRoot" />
> Was it an oversight, or is there a reason to keep it where it is?

Yep, oversight. Moved.

>
> > I'm now wondering if I should do the same for all the eggs that I've
> > updated as part of this -- they could also register new things that
> > we're not expecting.
>
> The reason why I singled in on this one is that it is registered in
> zopeapp.zcml, so it will affect production. The rest will only affect
> tests and development, so I'm less concerned in this regard.
>
> zope.publisher's update I guess is worth a look, actually. But that's
> the only other one I see.
>

http://paste.ubuntu.com/467986/ is the diff between the previous
configure.zcml and the current version, so nothing to worry about, I
think?

> > - FWIW, LaunchpadPrincipalAnnotations could subclass UserDict.UserDict
> >> and be shortened to the __init__ plus a call to the shared constructor
> >> and the interface declarations. Do it if you want.
> >
> > I'm all for it!
> >
> > Also, I thought I could make apidoc.lp.dev work for anonymous users by
> > just registering an adapter like the above for
> > IUnauthenticatedPrincipal, but then I got
> > http://paste.ubuntu.com/467401/
>
> Meh, digging into it just a bit, I see that preference group thing is
> doing somewhat unusual security dances. I wouldn't be all that
> surprised if that LocationError were actually hiding a
> ForbiddenAttribute on a value that should be there, but maybe I'm
> wrong.
>
> > I'm thinking that it may be better to actually require a logged-in user
> > to use apidoc.lp.dev and ask them to login in case they're not, just
> > like we do on other launchpad.AnyPerson pages. What do you think?
>
> Since this is only for devel instances, in the abstract there's no
> reason not to expose this for anonymous users that I see. That will
> also make it easier to make a static version of the apidoc, which I
> think is part of the plan.

Agreed. All I wanted was to make sure we require people to login as
early as possible so that they don't see these obscure errors that one
has no idea can be worked around just by logging in.

>
> If you want me to look into the traceback further just ask.

I'd really appreciate as I wouldn't know where to start. Just some
pointers so I can get started would be great.

>
> ...
>
> >> - I have said that I was fine with the change to authorization.py, but
> >> actually I had another idea. I'm not 100% convinced the new idea is
> >> better, ...

Read more...

Revision history for this message
Gary Poster (gary) wrote :
Download full text (3.6 KiB)

On Jul 23, 2010, at 9:12 AM, Guilherme Salgado wrote:

> On Fri, 2010-07-23 at 12:42 +0000, Gary Poster wrote:
>> Hey Salgado. Thank you. Below, I've deleted sections for which I thought no further discussion was necessary.

Doing that again.

>>
>> On Jul 22, 2010, at 5:15 AM, Guilherme Salgado wrote:
>>
>>> On Wed, 2010-07-21 at 17:08 +0000, Gary Poster wrote:
>
...

>>
>>> I'm now wondering if I should do the same for all the eggs that I've
>>> updated as part of this -- they could also register new things that
>>> we're not expecting.
>>
>> The reason why I singled in on this one is that it is registered in
>> zopeapp.zcml, so it will affect production. The rest will only affect
>> tests and development, so I'm less concerned in this regard.
>>
>> zope.publisher's update I guess is worth a look, actually. But that's
>> the only other one I see.
>>
>
> http://paste.ubuntu.com/467986/ is the diff between the previous
> configure.zcml and the current version, so nothing to worry about, I
> think?

Agreed, thanks.

>
>
>>> - FWIW, LaunchpadPrincipalAnnotations could subclass UserDict.UserDict
>>>> and be shortened to the __init__ plus a call to the shared constructor
>>>> and the interface declarations. Do it if you want.
>>>
>>> I'm all for it!
>>>
>>> Also, I thought I could make apidoc.lp.dev work for anonymous users by
>>> just registering an adapter like the above for
>>> IUnauthenticatedPrincipal, but then I got
>>> http://paste.ubuntu.com/467401/
>>
>> Meh, digging into it just a bit, I see that preference group thing is
>> doing somewhat unusual security dances. I wouldn't be all that
>> surprised if that LocationError were actually hiding a
>> ForbiddenAttribute on a value that should be there, but maybe I'm
>> wrong.
>>
>>> I'm thinking that it may be better to actually require a logged-in user
>>> to use apidoc.lp.dev and ask them to login in case they're not, just
>>> like we do on other launchpad.AnyPerson pages. What do you think?
>>
>> Since this is only for devel instances, in the abstract there's no
>> reason not to expose this for anonymous users that I see. That will
>> also make it easier to make a static version of the apidoc, which I
>> think is part of the plan.
>
> Agreed. All I wanted was to make sure we require people to login as
> early as possible so that they don't see these obscure errors that one
> has no idea can be worked around just by logging in.
>
>>
>> If you want me to look into the traceback further just ask.
>
> I'd really appreciate as I wouldn't know where to start. Just some
> pointers so I can get started would be great.

I was skeptical of the way you were using object and UserDict together--that doesn't make UserDict a new-style class, so it doesn't play the "super" game. This fixes the traceback for unauthenticated users, and is generally more correct:

=== modified file 'lib/canonical/launchpad/webapp/authentication.py'
--- lib/canonical/launchpad/webapp/authentication.py 2010-07-22 09:12:46 +0000
+++ lib/canonical/launchpad/webapp/authentication.py 2010-07-23 14:54:07 +0000
@@ -326,12 +326,12 @@

 # zope.app.apidoc expects our principals to be adaptable into IAnno...

Read more...

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

One more thing, but it's really important.

I think LP devs might get a lot more excited about this if you just add this little bit.

=== modified file 'configs/development/apidoc-configure-normal.zcml'
--- configs/development/apidoc-configure-normal.zcml 2010-07-22 09:12:46 +0000
+++ configs/development/apidoc-configure-normal.zcml 2010-07-23 18:25:06 +0000
@@ -3,6 +3,7 @@
     xmlns:browser="http://namespaces.zope.org/browser"
     xmlns:meta="http://namespaces.zope.org/meta"
     xmlns:i18n="http://namespaces.zope.org/i18n"
+ xmlns:apidoc="http://namespaces.zope.org/apidoc"
     i18n_domain="canonical">

     <!-- These packages/declarations are required by apidoc. If they are
@@ -48,7 +49,7 @@
     <!-- apidoc.lp.dev breaks if we make IAPIDocRoot subclass ISite, so we
       need to register this view here. -->
     <view
- for="canonical.launchpad.webapp.interfaces.IAPIDocRoot"
+ for="canonical.launchpad.webapp.interfaces.IAPIDocRoot"
         type="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
         name=""
         factory="zope.browserresource.resources.Resources"
@@ -74,5 +75,15 @@
     <include package="zope.app.tree" />
     <include package="zope.app.apidoc" />

+ <apidoc:rootModule module="canonical" />
+ <apidoc:rootModule module="lp" />
+ <apidoc:rootModule module="lazr" />
+ <apidoc:rootModule module="zc" />
+ <apidoc:rootModule module="wadllib" />
+ <apidoc:rootModule module="martian" />
+ <apidoc:rootModule module="manuel" />
+ <apidoc:rootModule module="chameleon" />
+ <apidoc:rootModule module="bzrlib" />
+ <apidoc:rootModule module="storm" />
+
 </configure>
-

With this, all of that code is browsable and searchable, and the work you've done shows what we expect in the apidoc. It's pretty cool, I think.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== renamed file 'configs/development/apidoc-configure-normal.zcml.OFF' => 'configs/development/apidoc-configure-normal.zcml'
2--- configs/development/apidoc-configure-normal.zcml.OFF 2008-09-02 16:03:35 +0000
3+++ configs/development/apidoc-configure-normal.zcml 2010-07-23 19:21:07 +0000
4@@ -1,48 +1,93 @@
5 <configure
6 xmlns="http://namespaces.zope.org/zope"
7- xmlns:meta="http://namespaces.zope.org/meta">
8- <!-- These packages are required by apidoc. If they are deemed
9- generally useful, move them to zopeapp.zcml
10- -->
11- <!--
12- How frustrating. This is needed for just one page registration
13- in introspector.zcml.
14- -->
15- <include package="zope.app" file="menus.zcml" />
16- <include package="zope.app.tree.browser" />
17- <include package="zope.app.tree" />
18- <include package="zope.app.renderer" file="meta.zcml" />
19+ xmlns:browser="http://namespaces.zope.org/browser"
20+ xmlns:meta="http://namespaces.zope.org/meta"
21+ xmlns:i18n="http://namespaces.zope.org/i18n"
22+ xmlns:apidoc="http://namespaces.zope.org/apidoc"
23+ i18n_domain="canonical">
24+
25+ <!-- These packages/declarations are required by apidoc. If they are
26+ deemed generally useful, move them to zopeapp.zcml -->
27+
28+ <browser:menu
29+ id="zmi_views"
30+ title="Views"
31+ description="Menu for displaying alternate representations of an object"
32+ />
33+ <browser:menu
34+ id="zmi_actions"
35+ title="Actions"
36+ description="Menu for displaying actions to be performed"
37+ />
38+
39+ <!-- Use the default IAbsoluteURL adapter for requests on the apidoc
40+ vhost. -->
41+ <adapter
42+ for="zope.interface.Interface
43+ canonical.launchpad.webapp.servers.APIDocBrowserRequest"
44+ provides="zope.traversing.browser.interfaces.IAbsoluteURL"
45+ factory="zope.traversing.browser.AbsoluteURL"
46+ />
47+
48+ <view
49+ for="zope.container.interfaces.IReadContainer"
50+ type="zope.publisher.interfaces.http.IHTTPRequest"
51+ provides="zope.publisher.interfaces.IPublishTraverse"
52+ factory="zope.container.traversal.ContainerTraverser"
53+ permission="zope.Public"
54+ allowed_interface="zope.publisher.interfaces.IPublishTraverse"
55+ />
56+
57+ <utility
58+ component="canonical.launchpad.systemhomes.apidocroot"
59+ provides="canonical.launchpad.webapp.interfaces.IAPIDocRoot" />
60+
61+ <adapter factory="canonical.launchpad.webapp.authentication.TemporaryPrincipalAnnotations" />
62+ <adapter
63+ factory="canonical.launchpad.webapp.authentication.TemporaryUnauthenticatedPrincipalAnnotations" />
64+
65+ <class class="canonical.launchpad.webapp.servers.LaunchpadBrowserRequest">
66+ <implements interface="zope.app.apidoc.browser.skin.APIDOC" />
67+ </class>
68+
69+ <!-- apidoc.lp.dev breaks if we make IAPIDocRoot subclass ISite, so we
70+ need to register this view here. -->
71+ <view
72+ for="canonical.launchpad.webapp.interfaces.IAPIDocRoot"
73+ type="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
74+ name=""
75+ factory="zope.browserresource.resources.Resources"
76+ permission="zope.Public"
77+ allowed_interface="zope.publisher.interfaces.browser.IBrowserPublisher"
78+ />
79+
80+ <browser:defaultView
81+ for="canonical.launchpad.webapp.interfaces.IAPIDocRoot"
82+ name="++apidoc++"
83+ />
84+
85+ <!-- Turn on devmode for the following includes to work -->
86+ <meta:provides feature="devmode" />
87+
88+ <include package="zope.location" />
89+ <include package="zope.app.applicationcontrol" />
90 <include package="zope.app.renderer" />
91-
92- <!-- XXX: StuartBishop 2005-03-13 bug=39834:
93- We also need the Z3 preference junk, whatever that is.
94- Unfortunately, this depends on annotatable principals so will not
95- currently work with Launchpad. We can still get some apidoc functionality,
96- such as the ZCML browser, but the bulk of it is not functional.
97- -->
98 <include package="zope.app.preference" file="meta.zcml" />
99- <!--
100+ <include package="zope.app.apidoc.codemodule" file="meta.zcml" />
101+ <include package="zope.app.apidoc.bookmodule" file="meta.zcml" />
102 <include package="zope.app.preference" />
103- -->
104-
105-
106- <!-- Turn on devmode for the following includes principal=work -->
107- <meta:provides feature="devmode" />
108-
109- <include package="zope.app.apidoc" file="meta.zcml" />
110+ <include package="zope.app.tree" />
111 <include package="zope.app.apidoc" />
112
113- <meta:redefinePermission
114- from="zope.app.apidoc.UseAPIDoc" to="zope.Public"
115- />
116-
117- <!-- Override a strange permission in apidoc -->
118- <class class="zope.app.apidoc.apidoc.APIDocumentation">
119- <require
120- interface="zope.app.container.interfaces.IReadContainer"
121- permission="zope.Public"
122- />
123- </class>
124+ <apidoc:rootModule module="canonical" />
125+ <apidoc:rootModule module="lp" />
126+ <apidoc:rootModule module="lazr" />
127+ <apidoc:rootModule module="zc" />
128+ <apidoc:rootModule module="wadllib" />
129+ <apidoc:rootModule module="martian" />
130+ <apidoc:rootModule module="manuel" />
131+ <apidoc:rootModule module="chameleon" />
132+ <apidoc:rootModule module="bzrlib" />
133+ <apidoc:rootModule module="storm" />
134
135 </configure>
136-
137
138=== modified file 'configs/development/launchpad-lazr.conf'
139--- configs/development/launchpad-lazr.conf 2010-07-15 15:57:40 +0000
140+++ configs/development/launchpad-lazr.conf 2010-07-23 19:21:07 +0000
141@@ -300,6 +300,9 @@
142 [vhost.openid]
143 hostname: openid.launchpad.dev
144
145+[vhost.apidoc]
146+hostname: apidoc.launchpad.dev
147+
148 [vhost.testopenid]
149 hostname: testopenid.dev
150
151
152=== added symlink 'configs/testrunner/apidoc-configure-normal.zcml'
153=== target is u'../development/apidoc-configure-normal.zcml'
154=== modified file 'lib/canonical/config/schema-lazr.conf'
155--- lib/canonical/config/schema-lazr.conf 2010-07-16 20:55:50 +0000
156+++ lib/canonical/config/schema-lazr.conf 2010-07-23 19:21:07 +0000
157@@ -1977,6 +1977,8 @@
158
159 [vhost.testopenid]
160
161+[vhost.apidoc]
162+
163 [vhost.ubuntu_openid]
164
165 [vhost.shipitubuntu]
166
167=== modified file 'lib/canonical/launchpad/browser/launchpad.py'
168--- lib/canonical/launchpad/browser/launchpad.py 2010-07-14 13:54:20 +0000
169+++ lib/canonical/launchpad/browser/launchpad.py 2010-07-23 19:21:07 +0000
170@@ -62,8 +62,8 @@
171 stepto)
172 from canonical.launchpad.webapp.breadcrumb import Breadcrumb
173 from canonical.launchpad.webapp.interfaces import (
174- GoneError, IBreadcrumb, ILaunchBag, ILaunchpadRoot, INavigationMenu,
175- NotFoundError, POSTToNonCanonicalURL)
176+ GoneError, IBreadcrumb, ILaunchBag, ILaunchpadRoot,
177+ INavigationMenu, NotFoundError, POSTToNonCanonicalURL)
178 from canonical.launchpad.webapp.publisher import RedirectionView
179 from canonical.launchpad.webapp.authorization import check_permission
180 from canonical.launchpad.webapp.tales import PageTemplateContextsAPI
181
182=== modified file 'lib/canonical/launchpad/doc/webapp-publication.txt'
183--- lib/canonical/launchpad/doc/webapp-publication.txt 2010-07-21 00:34:38 +0000
184+++ lib/canonical/launchpad/doc/webapp-publication.txt 2010-07-23 19:21:07 +0000
185@@ -41,6 +41,10 @@
186 rooturl: http://api.launchpad.dev/
187 althosts:
188 ----
189+ apidoc @ apidoc.launchpad.dev
190+ rooturl: http://apidoc.launchpad.dev/
191+ althosts:
192+ ----
193 blueprints @ blueprints.launchpad.dev
194 rooturl: http://blueprints.launchpad.dev/
195 althosts:
196@@ -106,6 +110,7 @@
197 ... print hostname
198 answers.launchpad.dev
199 api.launchpad.dev
200+ apidoc.launchpad.dev
201 blueprints.launchpad.dev
202 bugs.launchpad.dev
203 code.launchpad.dev
204
205=== modified file 'lib/canonical/launchpad/layers.py'
206--- lib/canonical/launchpad/layers.py 2010-07-21 22:09:39 +0000
207+++ lib/canonical/launchpad/layers.py 2010-07-23 19:21:07 +0000
208@@ -36,6 +36,10 @@
209 """
210
211
212+class APIDocLayer(IBrowserRequest, IDefaultBrowserLayer):
213+ """The `APIDocLayer` layer."""
214+
215+
216 class TestOpenIDLayer(LaunchpadLayer):
217 """The `TestOpenIDLayer` layer."""
218
219
220=== modified file 'lib/canonical/launchpad/permissions.zcml'
221--- lib/canonical/launchpad/permissions.zcml 2009-11-15 01:05:49 +0000
222+++ lib/canonical/launchpad/permissions.zcml 2010-07-23 19:21:07 +0000
223@@ -85,5 +85,10 @@
224 title="Review Launchpad projects"
225 access_level="write" />
226
227+ <!-- This permission only exists to please apidoc.launchpad.dev and
228+ shouldn't be used anywhere else. -->
229+ <permission
230+ id="zope.ManageApplication" title="Needed by zope.app.apidoc"
231+ access_level="read" />
232
233 </configure>
234
235=== modified file 'lib/canonical/launchpad/security.py'
236--- lib/canonical/launchpad/security.py 2010-07-20 12:33:43 +0000
237+++ lib/canonical/launchpad/security.py 2010-07-23 19:21:07 +0000
238@@ -1080,13 +1080,27 @@
239
240
241 class UseApiDoc(AuthorizationBase):
242+ """This is just to please apidoc.launchpad.dev."""
243 permission = 'zope.app.apidoc.UseAPIDoc'
244 usedfor = Interface
245
246+ def checkUnauthenticated(self):
247+ return True
248+
249 def checkAuthenticated(self, user):
250 return True
251
252
253+class ManageApplicationForEverybody(UseApiDoc):
254+ """This is just to please apidoc.launchpad.dev.
255+
256+ We do this because zope.app.apidoc uses that permission, but nothing else
257+ should be using it.
258+ """
259+ permission = 'zope.ManageApplication'
260+ usedfor = Interface
261+
262+
263 class OnlyBazaarExpertsAndAdmins(AuthorizationBase):
264 """Base class that allows only the Launchpad admins and Bazaar
265 experts."""
266
267=== modified file 'lib/canonical/launchpad/systemhomes.py'
268--- lib/canonical/launchpad/systemhomes.py 2010-04-19 06:35:23 +0000
269+++ lib/canonical/launchpad/systemhomes.py 2010-07-23 19:21:07 +0000
270@@ -6,7 +6,7 @@
271 __all__ = [
272 'AuthServerApplication',
273 'BazaarApplication',
274- 'CodeImportScheduler',
275+ 'CodeImportSchedulerApplication',
276 'FeedsApplication',
277 'MailingListApplication',
278 'MaloneApplication',
279@@ -39,7 +39,8 @@
280 from lp.hardwaredb.interfaces.hwdb import (
281 IHWDeviceSet, IHWDriverSet, IHWSubmissionDeviceSet, IHWSubmissionSet,
282 IHWVendorIDSet, ParameterError)
283-from canonical.launchpad.webapp.interfaces import ICanonicalUrlData
284+from canonical.launchpad.webapp.interfaces import (
285+ IAPIDocRoot, ICanonicalUrlData)
286 from lp.bugs.interfaces.bug import (
287 CreateBugParams, IBugSet, InvalidBugTargetType)
288 from lp.code.interfaces.codehosting import ICodehostingApplication
289@@ -388,3 +389,11 @@
290
291 class TestOpenIDApplication:
292 implements(ITestOpenIDApplication)
293+
294+
295+class APIDocRoot:
296+ implements(IAPIDocRoot)
297+ __parent__ = None
298+ __name__ = None
299+
300+apidocroot = APIDocRoot()
301
302=== modified file 'lib/canonical/launchpad/webapp/authentication.py'
303--- lib/canonical/launchpad/webapp/authentication.py 2010-02-16 14:25:51 +0000
304+++ lib/canonical/launchpad/webapp/authentication.py 2010-07-23 19:21:07 +0000
305@@ -16,12 +16,16 @@
306 import binascii
307 import hashlib
308 import random
309+from UserDict import UserDict
310
311 from contrib.oauth import OAuthRequest
312
313+from zope.annotation.interfaces import IAnnotations
314+from zope.authentication.interfaces import IUnauthenticatedPrincipal
315 from zope.interface import implements
316-from zope.component import getUtility
317+from zope.component import adapts, getUtility
318 from zope.event import notify
319+from zope.preference.interfaces import IPreferenceGroup
320
321 from zope.security.proxy import removeSecurityProxy
322
323@@ -320,6 +324,22 @@
324 return encryptor.validate(pw1, pw2)
325
326
327+# zope.app.apidoc expects our principals to be adaptable into IAnnotations, so
328+# we use these dummy adapters here just to make that code not OOPS.
329+class TemporaryPrincipalAnnotations(UserDict):
330+ implements(IAnnotations)
331+ adapts(ILaunchpadPrincipal, IPreferenceGroup)
332+
333+ def __init__(self, principal, pref_group):
334+ UserDict.__init__(self)
335+
336+
337+class TemporaryUnauthenticatedPrincipalAnnotations(
338+ TemporaryPrincipalAnnotations):
339+ implements(IAnnotations)
340+ adapts(IUnauthenticatedPrincipal, IPreferenceGroup)
341+
342+
343 def get_oauth_authorization(request):
344 """Retrieve OAuth authorization information from a request.
345
346
347=== modified file 'lib/canonical/launchpad/webapp/authorization.py'
348--- lib/canonical/launchpad/webapp/authorization.py 2010-01-14 13:25:34 +0000
349+++ lib/canonical/launchpad/webapp/authorization.py 2010-07-23 19:21:07 +0000
350@@ -10,6 +10,7 @@
351 from zope.component import getUtility, queryAdapter
352 from zope.browser.interfaces import IView
353
354+from zope.proxy import removeAllProxies
355 from zope.publisher.interfaces import IApplicationRequest
356 from zope.security.interfaces import ISecurityPolicy
357 from zope.security.checker import CheckerPublic
358@@ -138,8 +139,11 @@
359 # We will not be able to lookup an adapter for this, so we can
360 # return False already.
361 return False
362- # Remove security proxies from object to authorize.
363- objecttoauthorize = removeSecurityProxy(objecttoauthorize)
364+ # Remove all proxies from object to authorize. The security proxy is
365+ # removed for obvious reasons but we also need to remove the location
366+ # proxy (which is used on apidoc.lp.dev) because otherwise we can't
367+ # create a weak reference to our object in our security policy cache.
368+ objecttoauthorize = removeAllProxies(objecttoauthorize)
369
370 participations = [participation
371 for participation in self.participations
372
373=== modified file 'lib/canonical/launchpad/webapp/configure.zcml'
374--- lib/canonical/launchpad/webapp/configure.zcml 2010-07-15 15:57:40 +0000
375+++ lib/canonical/launchpad/webapp/configure.zcml 2010-07-23 19:21:07 +0000
376@@ -672,7 +672,7 @@
377 permission="zope.Public"
378 class="canonical.launchpad.webapp.launchbag.LaunchBagView"
379 />
380-
381+
382 <!-- Resource unnamed view, allowing Z3 preferred spelling
383 /@@/launchpad-icon-small to access the images directory -->
384 <browser:page
385
386=== modified file 'lib/canonical/launchpad/webapp/interfaces.py'
387--- lib/canonical/launchpad/webapp/interfaces.py 2010-07-15 15:59:24 +0000
388+++ lib/canonical/launchpad/webapp/interfaces.py 2010-07-23 19:21:07 +0000
389@@ -65,6 +65,10 @@
390 """
391
392
393+class IAPIDocRoot(IContainmentRoot):
394+ """Marker interface for the root object of the apidoc vhost."""
395+
396+
397 class ILaunchpadContainer(Interface):
398 """Marker interface for objects used as the context of something."""
399
400
401=== modified file 'lib/canonical/launchpad/webapp/publisher.py'
402--- lib/canonical/launchpad/webapp/publisher.py 2010-03-15 17:17:05 +0000
403+++ lib/canonical/launchpad/webapp/publisher.py 2010-07-23 19:21:07 +0000
404@@ -544,9 +544,6 @@
405
406 class RootObject:
407 implements(ILaunchpadApplication, ILaunchpadRoot)
408- # These next two needed by the Z3 API browser
409- __parent__ = None
410- __name__ = 'Launchpad'
411
412
413 rootObject = ProxyFactory(RootObject(), NamesChecker(["__class__"]))
414
415=== modified file 'lib/canonical/launchpad/webapp/servers.py'
416--- lib/canonical/launchpad/webapp/servers.py 2010-07-23 18:54:44 +0000
417+++ lib/canonical/launchpad/webapp/servers.py 2010-07-23 19:21:07 +0000
418@@ -61,7 +61,7 @@
419 from canonical.launchpad.webapp.notifications import (
420 NotificationRequest, NotificationResponse, NotificationList)
421 from canonical.launchpad.webapp.interfaces import (
422- IBasicLaunchpadRequest, IBrowserFormNG,
423+ IAPIDocRoot, IBasicLaunchpadRequest, IBrowserFormNG,
424 ILaunchpadBrowserApplicationRequest, ILaunchpadProtocolError,
425 INotificationRequest, INotificationResponse, IPlacelessAuthUtility,
426 IPlacelessLoginSource, OAuthPermission, UnexpectedFormData)
427@@ -1077,6 +1077,16 @@
428 implements(canonical.launchpad.layers.FeedsLayer)
429
430
431+# ---- apidoc
432+
433+class APIDocBrowserRequest(LaunchpadBrowserRequest):
434+ implements(canonical.launchpad.layers.APIDocLayer)
435+
436+
437+class APIDocBrowserPublication(LaunchpadBrowserPublication):
438+ root_object_interface = IAPIDocRoot
439+
440+
441 # ---- testopenid
442
443 class TestOpenIDBrowserRequest(LaunchpadBrowserRequest):
444@@ -1442,6 +1452,10 @@
445 factories.append(VHRP('testopenid', TestOpenIDBrowserRequest,
446 TestOpenIDBrowserPublication))
447
448+ if config.devmode:
449+ factories.append(
450+ VHRP('apidoc', APIDocBrowserRequest, APIDocBrowserPublication))
451+
452 # We may also have a private XML-RPC server.
453 private_port = None
454 for server in config.servers:
455
456=== added file 'lib/lp/app/stories/apidoc.txt'
457--- lib/lp/app/stories/apidoc.txt 1970-01-01 00:00:00 +0000
458+++ lib/lp/app/stories/apidoc.txt 2010-07-23 19:21:07 +0000
459@@ -0,0 +1,25 @@
460+Launchpad's API docs
461+====================
462+
463+It is generated by the zope.app.apidoc package, and can be seen on
464+apidoc.launchpad.dev. (Note that this is just a smoke test)
465+
466+ >>> browser.open('http://apidoc.launchpad.dev')
467+ >>> print extract_text(browser.contents)
468+ Zope 3 API Documentation
469+
470+It uses frames, so here we open the URL of the main frame manually.
471+
472+ >>> browser.open('http://apidoc.launchpad.dev/++apidoc++/contents.html')
473+ >>> print extract_text(browser.contents)
474+ Zope 3 apidoc...
475+ Welcome to the Zope 3 API documentation tool...
476+ Code Browser...
477+ Interfaces...
478+
479+And here we open the page of one of our interfaces, just to make sure they
480+render fine.
481+
482+ >>> browser.open('http://apidoc.launchpad.dev/++apidoc++/Interface/'
483+ ... 'lp.code.interfaces.branchcollection.IAllBranches/'
484+ ... 'index.html')
485
486=== modified file 'setup.py'
487--- setup.py 2010-07-21 18:51:37 +0000
488+++ setup.py 2010-07-23 19:21:07 +0000
489@@ -71,6 +71,7 @@
490 'z3c.pt',
491 'z3c.ptcompat',
492 'zc.zservertracelog',
493+ 'zope.app.apidoc',
494 'zope.app.appsetup',
495 'zope.app.component',
496 'zope.app.dav', # ./package-includes/dav-configure.zcml
497@@ -78,7 +79,9 @@
498 'zope.app.exception',
499 'zope.app.file',
500 'zope.app.form',
501+ 'zope.app.onlinehelp',
502 'zope.app.pagetemplate',
503+ 'zope.app.preference',
504 'zope.app.publication',
505 'zope.app.publisher',
506 'zope.app.security',
507@@ -86,6 +89,7 @@
508 'zope.app.server',
509 'zope.app.session',
510 'zope.app.testing',
511+ 'zope.app.tree',
512 'zope.app.zcmlfiles',
513 'zope.app.wsgi',
514 'zope.app.zapi',
515@@ -102,6 +106,7 @@
516 'zope.hookable', # indirect, via zope.app.component
517 'zope.lifecycleevent',
518 'zope.location',
519+ 'zope.login',
520 'zope.pagetemplate',
521 'zope.publisher',
522 'zope.proxy',
523
524=== modified file 'site.zcml'
525--- site.zcml 2009-07-13 18:15:02 +0000
526+++ site.zcml 2010-07-23 19:21:07 +0000
527@@ -38,4 +38,5 @@
528 <include file="summarizerequests.zcml" />
529
530 <include package="zc.zservertracelog" />
531+
532 </configure>
533
534=== modified file 'versions.cfg'
535--- versions.cfg 2010-07-21 18:51:37 +0000
536+++ versions.cfg 2010-07-23 19:21:07 +0000
537@@ -124,6 +124,7 @@
538 ZODB3 = 3.9.2
539 zodbcode = 3.4.0
540 zope.annotation = 3.5.0
541+zope.app.apidoc = 3.7.3
542 zope.app.applicationcontrol = 3.5.1
543 zope.app.appsetup = 3.12.0
544 zope.app.authentication = 3.6.1
545@@ -146,7 +147,10 @@
546 zope.app.interface = 3.5.0
547 zope.app.locales = 3.5.1
548 zope.app.localpermission = 3.7.0
549+zope.app.onlinehelp = 3.5.2
550 zope.app.pagetemplate = 3.7.1
551+zope.app.preference = 3.8.1
552+zope.preference = 3.8.0
553 zope.app.principalannotation = 3.6.1
554 zope.app.publication = 3.9.0
555 zope.app.publisher = 3.10.0
556@@ -159,6 +163,7 @@
557 # not in ZTK
558 zope.app.session = 3.6.0
559 zope.app.testing = 3.7.5
560+zope.app.tree = 3.6.0
561 zope.app.wsgi = 3.6.0
562 # not in ZTK
563 zope.app.zapi = 3.4.1
564@@ -198,6 +203,7 @@
565 zope.interface = 3.5.2
566 zope.lifecycleevent = 3.5.2
567 zope.location = 3.7.0
568+zope.login = 1.0.0
569 zope.minmax = 1.1.1
570 zope.modulealias = 3.4.0
571 zope.pagetemplate = 3.5.0
572@@ -207,7 +213,7 @@
573 zope.processlifetime = 1.0
574 zope.proxy = 3.5.0
575 zope.ptresource = 3.9.0
576-zope.publisher = 3.10.0
577+zope.publisher = 3.12.0
578 zope.schema = 3.5.4
579 zope.security = 3.7.1
580 zope.securitypolicy = 3.6.1
581
582=== modified file 'zopeapp.zcml'
583--- zopeapp.zcml 2009-07-13 18:15:02 +0000
584+++ zopeapp.zcml 2010-07-23 19:21:07 +0000
585@@ -25,6 +25,8 @@
586 <include package="zope.app.interface" />
587 <include package="zope.app.security" />
588
589+ <include package="zope.login" />
590+
591 <!--
592 <include package="zope.app.observable" />
593 <include package="zope.app.annotation" />