Merge lp:~michael.nelson/launchpad/ppa-privatisation-test-refactor6 into lp:launchpad

Proposed by Michael Nelson
Status: Merged
Approved by: Gary Poster
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~michael.nelson/launchpad/ppa-privatisation-test-refactor6
Merge into: lp:launchpad
Prerequisite: lp:~michael.nelson/launchpad/ppa-privatisation-test-refactor5
Diff against target: 750 lines (+158/-167)
6 files modified
lib/lp/soyuz/stories/soyuz/xx-private-builds.txt (+47/-77)
lib/lp/soyuz/stories/soyuz/xx-queue-pages-delayed-copies.txt (+9/-9)
lib/lp/soyuz/stories/webservice/xx-archive.txt (+28/-28)
lib/lp/soyuz/stories/webservice/xx-archivedependency.txt (+18/-24)
lib/lp/soyuz/stories/webservice/xx-binary-package-publishing.txt (+21/-10)
lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt (+35/-19)
To merge this branch: bzr merge lp:~michael.nelson/launchpad/ppa-privatisation-test-refactor6
Reviewer Review Type Date Requested Status
Gary Poster (community) Approve
Review via email: mp+20227@code.launchpad.net

Commit message

Ensures that the privacy of a PPA cannot be altered once it has published packages (and updates a gazillion tests that depended on being able to do just that)

To post a comment you must log in.
Revision history for this message
Michael Nelson (michael.nelson) wrote :

This is the sixth (and final!) branch in a series to refactor soyuz tests after fixing bug 506203.

The MP for the branch that actually fixed the bug is at:

https://code.edge.launchpad.net/~michael.nelson/launchpad/506203-ppa-privatisation-check/+merge/19415

The original fix ensures that the privacy of a PPA cannot be altered once it has packages published. Unfortunately most of our test infrastructure does exactly that (switches the privacy to do a few tests and then switches it back).

The complete test breakages are as follows:
http://pastebin.ubuntu.com/378292/

This branch fixes:
bin/test -vv -t xx-private-builds.txt -t xx-queue-pages-delayed-copies.txt -t webservice/xx-archive.txt -t xx-archivedependency.txt -t xx-binary-package-publishing.txt -t xx-source-package-publishing.txt

Thanks.

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

Hi Michael. These look like nice fixes.

I asked some questions on IRC to which you replied to my satisfaction. I'll include the log beneath for reference.

I did ask you to consider whether the duplicated code for private setup in xx-source-package-publishing.txt and xx-binary-package-publishing.txt (">>> from lp.registry.interfaces.distribution import IDistributionSet...") should be factored into a testing helper. You thought this was a reasonable idea, which is great by me. :-)

Thank you!

Gary

Edited IRC log:

gary_poster: noodles775: why did you remove test_login.py?
noodles775: gary_poster: I didn't... a local diff between this pipe and the prev shows everything but the test_login.py.
noodles775: I was just trying to figure out what was going on with the MP.
gary_poster: noodles775: ok, I'll just clarify in the review that merging that removal is not ok, and leave you to handle the mechanism
noodles775: gary_poster: I'll merge RF into the initial pipe (there are 7 in total) and push it through and see if it's still there when the diff regenerates on the MP.
gary_poster: noodles775: ack, ok
salgado: gary_poster, noodles775, in my openid branch I added a test_new_login.py file and later removed test_login.py. then on a subsequent branch I renamed test_new_login.py to test_login.py. that, together with pipes, might have confused bzr?
noodles775: salgado: thanks for the info - I thought it may have been related to your branch I reviewed yesterday. If that's the case, pumping a fresh RF through my pipes should resolve the issue. (I hope)
gary_poster: noodles775: in xx-private-builds.txt, why is it OK to remove diff line 375ff? ("Now visit the same page as an admin we can see that there are four more...")
gary_poster: thanks salgado
gary_poster: noodles775: also, in the previous section of the same file, why did the result change (5 of 17 results, and different values)? If explaining it takes too long, I'll accept "because of changes that have previously passed review"
gary_poster: but I'd like reassurance that you are confident of the change, at least
gary_poster: hm, I could understand an increase of 1, since we added the private p3a archive, but I don't understand 14 -> 17
noodles775: gary_poster: so, regarding your first question, 375ff, the test for authorised viewers seeing the builds in the history was moved to just below with the Frog builder.
noodles775: It looks like a lot less test-code because the Frog builder only has the one build in its history (it's not polluted with sample data :)).
gary_poster: noodles775: ah ok cool thanks
noodles775: gary_poster: and your second question is related, because previously cprov's ppa was switched to private (which is no longer allowed), and had a bunch of publishings.
noodles775: So the 14 -> 17 is because there are 3 packages in cprov's public archive (when it was private ,they did not show up).
Topic changed to "on call: adeuring,gary_poster || reviewing: ?,noodles775, sinzui || queue [] || This channel is logged: http://irclogs.ubuntu.com/ || https://code.edge.launchpad.net/launchpad/+activereviews" by sinzui.
noodles775: s/packages/builds of course.
gary_poster: noodles775: we ...

Read more...

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/soyuz/stories/soyuz/xx-private-builds.txt'
--- lib/lp/soyuz/stories/soyuz/xx-private-builds.txt 2009-12-24 01:41:54 +0000
+++ lib/lp/soyuz/stories/soyuz/xx-private-builds.txt 2010-02-26 15:44:20 +0000
@@ -20,6 +20,7 @@
20 >>> from zope.component import getUtility20 >>> from zope.component import getUtility
21 >>> from canonical.launchpad.interfaces import (21 >>> from canonical.launchpad.interfaces import (
22 ... IBuilderSet, IPersonSet)22 ... IBuilderSet, IPersonSet)
23 >>> from lp.registry.interfaces.distribution import IDistributionSet
23 >>> from lp.soyuz.tests.test_publishing import (24 >>> from lp.soyuz.tests.test_publishing import (
24 ... SoyuzTestPublisher)25 ... SoyuzTestPublisher)
25 >>> from lp.soyuz.interfaces.publishing import (26 >>> from lp.soyuz.interfaces.publishing import (
@@ -29,14 +30,16 @@
2930
30 >>> login("foo.bar@canonical.com")31 >>> login("foo.bar@canonical.com")
31 >>> cprov = getUtility(IPersonSet).getByName("cprov")32 >>> cprov = getUtility(IPersonSet).getByName("cprov")
32 >>> cprov.archive.buildd_secret = "secret"33 >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
33 >>> cprov.archive.private = True34 >>> cprov_private_ppa = factory.makeArchive(
35 ... private=True, owner=cprov, name="p3a",
36 ... distribution=ubuntu)
34 >>> test_publisher = SoyuzTestPublisher()37 >>> test_publisher = SoyuzTestPublisher()
35 >>> test_publisher.prepareBreezyAutotest()38 >>> test_publisher.prepareBreezyAutotest()
36 >>> private_source_pub = test_publisher.getPubSource(39 >>> private_source_pub = test_publisher.getPubSource(
37 ... status=PackagePublishingStatus.PUBLISHED,40 ... status=PackagePublishingStatus.PUBLISHED,
38 ... sourcename='privacy-test',41 ... sourcename='privacy-test',
39 ... archive=cprov.archive)42 ... archive=cprov_private_ppa)
40 >>> [private_build] = private_source_pub.createMissingBuilds()43 >>> [private_build] = private_source_pub.createMissingBuilds()
41 >>> frog = getUtility(IBuilderSet)['frog']44 >>> frog = getUtility(IBuilderSet)['frog']
42 >>> frog.builderok = True45 >>> frog.builderok = True
@@ -105,7 +108,7 @@
105users:108users:
106109
107 >>> anon_browser.open(110 >>> anon_browser.open(
108 ... "http://launchpad.dev/~cprov/+archive/ppa/+build/%s" %111 ... "http://launchpad.dev/~cprov/+archive/p3a/+build/%s" %
109 ... private_build.id)112 ... private_build.id)
110 Traceback (most recent call last):113 Traceback (most recent call last):
111 ...114 ...
@@ -114,10 +117,10 @@
114But it is fine for authorised users:117But it is fine for authorised users:
115118
116 >>> cprov_browser.open(119 >>> cprov_browser.open(
117 ... "http://launchpad.dev/~cprov/+archive/ppa/+build/%s" %120 ... "http://launchpad.dev/~cprov/+archive/p3a/+build/%s" %
118 ... private_build.id)121 ... private_build.id)
119 >>> print cprov_browser.url122 >>> print cprov_browser.url
120 http://launchpad.dev/~cprov/+archive/ppa/+build/...123 http://launchpad.dev/~cprov/+archive/p3a/+build/...
121124
122125
123== Builder history page ==126== Builder history page ==
@@ -130,7 +133,7 @@
130user is viewing it.133user is viewing it.
131134
132The builder "bob" has lots of builds in the sample data, including some135The builder "bob" has lots of builds in the sample data, including some
133for cprov's private archive. We can visit bob's history page and see136for cprov's public archive. We can visit bob's history page and see
134what it shows a non-privileged user:137what it shows a non-privileged user:
135138
136 >>> anon_browser.open("http://launchpad.dev/+builds/bob/+history")139 >>> anon_browser.open("http://launchpad.dev/+builds/bob/+history")
@@ -141,63 +144,20 @@
141 ...144 ...
142 hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE145 hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
143 ...146 ...
144 i386 build of cdrkit 1.0 in ubuntu warty RELEASE147 hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
145 ...148 ...
146 i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE149 i386 build of pmount 0.1-1 in ubuntu warty RELEASE
147 ...150 ...
148 i386 build of foobar 1.0 in ubuntu warty RELEASE151 i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE
149 ...152 ...
150 i386 build of netapplet 0.99.6-1 in ubuntu warty RELEASE153 i386 build of cdrkit 1.0 in ubuntu warty RELEASE
151 ...154 ...
152 5 of 14 results155 5 of 17 results
153 ...156 ...
154157
155Now visit the same page as an admin we can see that there are four more158
156results in the total set of results with an extra "mozilla-firefox"159The builder "Frog" has only the one build created above. So viewing the
157build at the top of the first batch.160history as an unauthorised user shows an empty history.
158
159 >>> admin_browser.open("http://launchpad.dev/+builds/bob/+history")
160 >>> [builds_list] = find_tags_by_class(
161 ... admin_browser.contents, 'builds_list')
162 >>> print extract_text(builds_list)
163 Package:
164 ...
165 hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
166 ...
167 hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
168 ...
169 i386 build of pmount 0.1-1 in ubuntu warty RELEASE
170 ...
171 i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE
172 ...
173 i386 build of cdrkit 1.0 in ubuntu warty RELEASE
174 ...
175 5 of 17 results
176 ...
177
178If cprov browses the list he will also see his own builds in the list.
179
180 >>> cprov_browser.open("http://launchpad.dev/+builds/bob/+history")
181 >>> [builds_list] = find_tags_by_class(
182 ... cprov_browser.contents, 'builds_list')
183 >>> print extract_text(builds_list)
184 Package:
185 ...
186 hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
187 ...
188 hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
189 ...
190 i386 build of pmount 0.1-1 in ubuntu warty RELEASE
191 ...
192 i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE
193 ...
194 i386 build of cdrkit 1.0 in ubuntu warty RELEASE
195 ...
196 5 of 17 results
197 ...
198
199"Frog" is currently building a private build but again the unauthorised user
200cannot see any of the private details.
201161
202 >>> anon_browser.open("http://launchpad.dev/+builds/frog/+history")162 >>> anon_browser.open("http://launchpad.dev/+builds/frog/+history")
203 >>> [builds_list] = find_tags_by_class(163 >>> [builds_list] = find_tags_by_class(
@@ -207,7 +167,17 @@
207 ...167 ...
208 No build records.168 No build records.
209169
210An authorised user will see the build however:170Both admin and the owner of the build, cprov, can see the build in
171"Frog"'s build history.
172
173 >>> admin_browser.open("http://launchpad.dev/+builds/frog/+history")
174 >>> [builds_list] = find_tags_by_class(
175 ... admin_browser.contents, 'builds_list')
176 >>> print extract_text(builds_list)
177 Package:
178 ...
179 i386 build of privacy-test 666 in ubuntutest breezy-autotest RELEASE
180 ...
211181
212 >>> cprov_browser.open("http://launchpad.dev/+builds/frog/+history")182 >>> cprov_browser.open("http://launchpad.dev/+builds/frog/+history")
213 >>> [builds_list] = find_tags_by_class(183 >>> [builds_list] = find_tags_by_class(
@@ -233,7 +203,7 @@
233 ...203 ...
234 Name Processor Status204 Name Processor Status
235 bob 386 Building i386 build of mozilla-firefox ...205 bob 386 Building i386 build of mozilla-firefox ...
236 frog 386 Building i386 build of privacy-test ... [cprov/ppa]206 frog 386 Building i386 build of privacy-test ... [cprov/p3a]
237 ...207 ...
238208
239Launchpad Buildd admins cannot see private builds.209Launchpad Buildd admins cannot see private builds.
@@ -255,7 +225,7 @@
255 ...225 ...
256 Name Processor Status226 Name Processor Status
257 bob 386 Building i386 build of mozilla-firefox ...227 bob 386 Building i386 build of mozilla-firefox ...
258 frog 386 Building i386 build of privacy-test ... [cprov/ppa]228 frog 386 Building i386 build of privacy-test ... [cprov/p3a]
259 Updated on ...229 Updated on ...
260230
261Anonymous users cannot see the private build:231Anonymous users cannot see the private build:
@@ -282,7 +252,7 @@
282 >>> from zope.security.interfaces import Unauthorized252 >>> from zope.security.interfaces import Unauthorized
283 >>> try:253 >>> try:
284 ... anon_browser.open(254 ... anon_browser.open(
285 ... "http://launchpad.dev/~cprov/+archive/ppa/+build/%s" %255 ... "http://launchpad.dev/~cprov/+archive/p3a/+build/%s" %
286 ... private_build.id)256 ... private_build.id)
287 ... except Unauthorized:257 ... except Unauthorized:
288 ... print "Got expected exception"258 ... print "Got expected exception"
@@ -293,7 +263,7 @@
293 >>> browser = setupBrowser(auth="Basic no-priv@canonical.com:test")263 >>> browser = setupBrowser(auth="Basic no-priv@canonical.com:test")
294 >>> try:264 >>> try:
295 ... browser.open(265 ... browser.open(
296 ... "http://launchpad.dev/~cprov/+archive/ppa/+build/%s" %266 ... "http://launchpad.dev/~cprov/+archive/p3a/+build/%s" %
297 ... private_build.id)267 ... private_build.id)
298 ... except Unauthorized:268 ... except Unauthorized:
299 ... print "Got expected exception"269 ... print "Got expected exception"
@@ -331,7 +301,7 @@
331 ...301 ...
332 Name Processor Status302 Name Processor Status
333 bob 386 Building i386 build of mozilla-firefox ...303 bob 386 Building i386 build of mozilla-firefox ...
334 frog 386 Building i386 build of privacy-test 666 ... [cprov/ppa]304 frog 386 Building i386 build of privacy-test 666 ... [cprov/p3a]
335 ...305 ...
336306
337Any other logged-in user will also see the build:307Any other logged-in user will also see the build:
@@ -342,22 +312,22 @@
342 ...312 ...
343 Name Processor Status313 Name Processor Status
344 bob 386 Building i386 build of mozilla-firefox ...314 bob 386 Building i386 build of mozilla-firefox ...
345 frog 386 Building i386 build of privacy-test 666 ... [cprov/ppa]315 frog 386 Building i386 build of privacy-test 666 ... [cprov/p3a]
346 ...316 ...
347317
348Accessing the build page will now also work:318Accessing the build page will now also work:
349319
350 >>> anon_browser.open(320 >>> anon_browser.open(
351 ... "http://launchpad.dev/~cprov/+archive/ppa/+build/%s" %321 ... "http://launchpad.dev/~cprov/+archive/p3a/+build/%s" %
352 ... private_build.id)322 ... private_build.id)
353 >>> print anon_browser.title323 >>> print anon_browser.title
354 PPA for Celso Providelo : Celso Providelo324 PPA named p3a for Celso Providelo : Celso Providelo
355325
356 >>> browser.open(326 >>> browser.open(
357 ... "http://launchpad.dev/~cprov/+archive/ppa/+build/%s" %327 ... "http://launchpad.dev/~cprov/+archive/p3a/+build/%s" %
358 ... private_build.id)328 ... private_build.id)
359 >>> print browser.title329 >>> print browser.title
360 PPA for Celso Providelo : Celso Providelo330 PPA named p3a for Celso Providelo : Celso Providelo
361331
362When accessing the distroseries source package release page, the builds332When accessing the distroseries source package release page, the builds
363portlet will display a link to the newly unembargoed build:333portlet will display a link to the newly unembargoed build:
@@ -371,7 +341,7 @@
371 breezy-autotest i386 Successfully built341 breezy-autotest i386 Successfully built
372342
373 >>> print browser.getLink('i386').url343 >>> print browser.getLink('i386').url
374 http://launchpad.dev/~cprov/+archive/ppa/+build/...344 http://launchpad.dev/~cprov/+archive/p3a/+build/...
375345
376Similarly, when accessing the distribution source package release page,346Similarly, when accessing the distribution source package release page,
377the main content will display a link to the newly unembargoed build:347the main content will display a link to the newly unembargoed build:
@@ -384,4 +354,4 @@
384 Breezy Badger Autotest: i386354 Breezy Badger Autotest: i386
385355
386 >>> print browser.getLink('i386').url356 >>> print browser.getLink('i386').url
387 http://launchpad.dev/~cprov/+archive/ppa/+build/...357 http://launchpad.dev/~cprov/+archive/p3a/+build/...
388358
=== modified file 'lib/lp/soyuz/stories/soyuz/xx-queue-pages-delayed-copies.txt'
--- lib/lp/soyuz/stories/soyuz/xx-queue-pages-delayed-copies.txt 2009-11-16 21:42:53 +0000
+++ lib/lp/soyuz/stories/soyuz/xx-queue-pages-delayed-copies.txt 2010-02-26 15:44:20 +0000
@@ -15,12 +15,12 @@
15 >>> login('foo.bar@canonical.com')15 >>> login('foo.bar@canonical.com')
16 >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')16 >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
17 >>> cprov = getUtility(IPersonSet).getByName('cprov')17 >>> cprov = getUtility(IPersonSet).getByName('cprov')
18 >>> cprov.archive.buildd_secret = 'x'18 >>> cprov_private_ppa = factory.makeArchive(
19 >>> cprov.archive.private = True19 ... private=True, owner=cprov, distribution=ubuntu,
20 >>> cprov.archive.require_virtualized = False20 ... virtualized=False, name="p3a")
21 >>> stp = SoyuzTestPublisher()21 >>> stp = SoyuzTestPublisher()
22 >>> stp.prepareBreezyAutotest()22 >>> stp.prepareBreezyAutotest()
23 >>> [bin_hppa, bin_i386] = stp.getPubBinaries(archive=cprov.archive)23 >>> [bin_hppa, bin_i386] = stp.getPubBinaries(archive=cprov_private_ppa)
24 >>> build = bin_hppa.binarypackagerelease.build24 >>> build = bin_hppa.binarypackagerelease.build
25 >>> breezy_autotest = ubuntu.getSeries('breezy-autotest')25 >>> breezy_autotest = ubuntu.getSeries('breezy-autotest')
26 >>> stp.addFakeChroots(breezy_autotest)26 >>> stp.addFakeChroots(breezy_autotest)
@@ -63,12 +63,12 @@
63 >>> print extract_text(63 >>> print extract_text(
64 ... first_tag_by_class(anon_browser.contents,64 ... first_tag_by_class(anon_browser.contents,
65 ... 'queue-%s' % delayed_copy.id))65 ... 'queue-%s' % delayed_copy.id))
66 Copied from PPA for Celso Providelo66 Copied from PPA named p3a for Celso Providelo
6767
68The delayed-copy source archive is not linked, since the requester has68The delayed-copy source archive is not linked, since the requester has
69no permission to view it.69no permission to view it.
7070
71 >>> anon_browser.getLink('PPA for Celso Providelo')71 >>> anon_browser.getLink('PPA named p3a for Celso Providelo')
72 Traceback (most recent call last):72 Traceback (most recent call last):
73 ...73 ...
74 LinkNotFoundError74 LinkNotFoundError
@@ -95,10 +95,10 @@
95 >>> print extract_text(95 >>> print extract_text(
96 ... first_tag_by_class(cprov_browser.contents,96 ... first_tag_by_class(cprov_browser.contents,
97 ... 'queue-%s' % delayed_copy.id))97 ... 'queue-%s' % delayed_copy.id))
98 Copied from PPA for Celso Providelo98 Copied from PPA named p3a for Celso Providelo
9999
100 >>> print cprov_browser.getLink('PPA for Celso Providelo').url100 >>> print cprov_browser.getLink('PPA named p3a for Celso Providelo').url
101 http://launchpad.dev/~cprov/+archive/ppa101 http://launchpad.dev/~cprov/+archive/p3a
102102
103When the delayed-copy is processed (moved to DONE queue) its contents103When the delayed-copy is processed (moved to DONE queue) its contents
104become available to everyone.104become available to everyone.
105105
=== modified file 'lib/lp/soyuz/stories/webservice/xx-archive.txt'
--- lib/lp/soyuz/stories/webservice/xx-archive.txt 2010-02-02 12:04:19 +0000
+++ lib/lp/soyuz/stories/webservice/xx-archive.txt 2010-02-26 15:44:20 +0000
@@ -736,15 +736,14 @@
736736
737== Private archives ==737== Private archives ==
738738
739Make Celso's PPA private and create a private source publication.739Create a private PPA for Celso with a private source publication.
740740
741 >>> login('foo.bar@canonical.com')741 >>> login('foo.bar@canonical.com')
742742 >>> cprov_private_ppa_db = factory.makeArchive(
743 >>> cprov.archive.buildd_secret = 'boing'743 ... private=True, owner=cprov, distribution=ubuntu_db, name="p3a",
744 >>> cprov.archive.private = True744 ... description="packages to help my friends.")
745
746 >>> private_publication = test_publisher.createSource(745 >>> private_publication = test_publisher.createSource(
747 ... cprov.archive, 'foocomm', '1.0-1')746 ... cprov_private_ppa_db, 'foocomm', '1.0-1')
748 >>> private_publication.secure_record.status = (747 >>> private_publication.secure_record.status = (
749 ... PackagePublishingStatus.PUBLISHED)748 ... PackagePublishingStatus.PUBLISHED)
750749
@@ -760,28 +759,28 @@
760attributes are only exposed when the requestor has View permission in759attributes are only exposed when the requestor has View permission in
761the IArchive context, in this case only Celso has it.760the IArchive context, in this case only Celso has it.
762761
763 >>> pprint_entry(user_webservice.get("/~cprov/+archive/ppa").jsonBody())762 >>> pprint_entry(user_webservice.get("/~cprov/+archive/p3a").jsonBody())
764 dependencies_collection_link: u'http://.../~cprov/+archive/ppa/dependencies'763 dependencies_collection_link: u'http://.../~cprov/+archive/p3a/dependencies'
765 description: u'tag:launchpad.net:2008:redacted'764 description: u'tag:launchpad.net:2008:redacted'
766 displayname: u'PPA for Celso Providelo'765 displayname: u'PPA named p3a for Celso Providelo'
767 distribution_link: u'http://.../ubuntu'766 distribution_link: u'http://.../ubuntu'
768 name: u'ppa'767 name: u'p3a'
769 owner_link: u'http://.../~cprov'768 owner_link: u'http://.../~cprov'
770 private: True769 private: True
771 resource_type_link: u'http://.../#archive'770 resource_type_link: u'http://.../#archive'
772 self_link: u'http://.../~cprov/+archive/ppa'771 self_link: u'http://.../~cprov/+archive/p3a'
773 signing_key_fingerprint: u'tag:launchpad.net:2008:redacted'772 signing_key_fingerprint: u'tag:launchpad.net:2008:redacted'
774773
775 >>> pprint_entry(cprov_webservice.get("/~cprov/+archive/ppa").jsonBody())774 >>> pprint_entry(cprov_webservice.get("/~cprov/+archive/p3a").jsonBody())
776 dependencies_collection_link: u'http://.../~cprov/+archive/ppa/dependencies'775 dependencies_collection_link: u'http://.../~cprov/+archive/p3a/dependencies'
777 description: u'packages to help my friends.'776 description: u'packages to help my friends.'
778 displayname: u'PPA for Celso Providelo'777 displayname: u'PPA named p3a for Celso Providelo'
779 distribution_link: u'http://.../ubuntu'778 distribution_link: u'http://.../ubuntu'
780 name: u'ppa'779 name: u'p3a'
781 owner_link: u'http://.../~cprov'780 owner_link: u'http://.../~cprov'
782 private: True781 private: True
783 resource_type_link: u'http://.../#archive'782 resource_type_link: u'http://.../#archive'
784 self_link: u'http://.../~cprov/+archive/ppa'783 self_link: u'http://.../~cprov/+archive/p3a'
785 signing_key_fingerprint: u'ABCDEF0123456789ABCDDCBA0000111112345678'784 signing_key_fingerprint: u'ABCDEF0123456789ABCDDCBA0000111112345678'
786785
787== Creating subscriptions to a (private) archive ==786== Creating subscriptions to a (private) archive ==
@@ -813,9 +812,10 @@
813First we'll subscribe mark to cprov's archive:812First we'll subscribe mark to cprov's archive:
814813
815 >>> mark = webservice.get("/~mark").jsonBody()814 >>> mark = webservice.get("/~mark").jsonBody()
816 >>> cprov_archive = cprov_webservice.get("/~cprov/+archive/ppa").jsonBody()815 >>> cprov_private_ppa = cprov_webservice.get(
816 ... "/~cprov/+archive/p3a").jsonBody()
817 >>> response = cprov_webservice.named_post(817 >>> response = cprov_webservice.named_post(
818 ... cprov_archive['self_link'], 'newSubscription',818 ... cprov_private_ppa['self_link'], 'newSubscription',
819 ... subscriber=mark['self_link'])819 ... subscriber=mark['self_link'])
820820
821 >>> print response821 >>> print response
@@ -823,20 +823,20 @@
823 ...823 ...
824824
825 >>> print response.getHeader('Location')825 >>> print response.getHeader('Location')
826 http://.../~cprov/+archive/ppa/+subscriptions/mark826 http://.../~cprov/+archive/p3a/+subscriptions/mark
827827
828We publish a subset of the IArchiveSubscriber attributes.828We publish a subset of the IArchiveSubscriber attributes.
829829
830 >>> new_subscription = cprov_webservice.get(830 >>> new_subscription = cprov_webservice.get(
831 ... response.getHeader('Location')).jsonBody()831 ... response.getHeader('Location')).jsonBody()
832 >>> pprint_entry(new_subscription)832 >>> pprint_entry(new_subscription)
833 archive_link: u'http://api.launchpad.dev/beta/~cprov/+archive/ppa'833 archive_link: u'http://api.launchpad.dev/beta/~cprov/+archive/p3a'
834 date_created: ...834 date_created: ...
835 date_expires: None835 date_expires: None
836 description: None836 description: None
837 registrant_link: u'http://api.launchpad.dev/beta/~cprov'837 registrant_link: u'http://api.launchpad.dev/beta/~cprov'
838 resource_type_link: u'http://api.launchpad.dev/beta/#archive_subscriber'838 resource_type_link: u'http://api.launchpad.dev/beta/#archive_subscriber'
839 self_link: u'http://api.launchpad.dev/beta/~cprov/+archive/ppa/+subscriptions/mark'839 self_link: u'http://api.../~cprov/+archive/p3a/+subscriptions/mark'
840 status: u'Active'840 status: u'Active'
841 subscriber_link: u'http://api.launchpad.dev/beta/~mark'841 subscriber_link: u'http://api.launchpad.dev/beta/~mark'
842842
@@ -854,7 +854,7 @@
854854
855 >>> response = user_webservice.named_post(855 >>> response = user_webservice.named_post(
856 ... cprov_archive['self_link'], 'newSubscription',856 ... cprov_archive['self_link'], 'newSubscription',
857 ... subscriber=cprov_archive['owner_link'])857 ... subscriber=cprov_private_ppa['owner_link'])
858 >>> print response858 >>> print response
859 HTTP/1.1 401 Unauthorized859 HTTP/1.1 401 Unauthorized
860 ...860 ...
@@ -863,13 +863,13 @@
863is already a current subscription:863is already a current subscription:
864864
865 >>> response = cprov_webservice.named_post(865 >>> response = cprov_webservice.named_post(
866 ... cprov_archive['self_link'], 'newSubscription',866 ... cprov_private_ppa['self_link'], 'newSubscription',
867 ... subscriber=mark['self_link'])867 ... subscriber=mark['self_link'])
868 >>> print response868 >>> print response
869 HTTP/1.1 400 Bad Request869 HTTP/1.1 400 Bad Request
870 ...870 ...
871 AlreadySubscribed: Mark Shuttleworth already has a current subscription871 AlreadySubscribed: Mark Shuttleworth already has a current subscription
872 for 'PPA for Celso Providelo'.872 for 'PPA named p3a for Celso Providelo'.
873873
874874
875== Modifying privacy ==875== Modifying privacy ==
@@ -904,7 +904,7 @@
904 >>> print cprov_webservice.named_post(904 >>> print cprov_webservice.named_post(
905 ... ubuntu['main_archive_link'], 'syncSource', {},905 ... ubuntu['main_archive_link'], 'syncSource', {},
906 ... source_name='foocomm', version='1.0-1', to_pocket='release',906 ... source_name='foocomm', version='1.0-1', to_pocket='release',
907 ... from_archive=cprov_archive['self_link'],907 ... from_archive=cprov_private_ppa['self_link'],
908 ... to_series="hoary")908 ... to_series="hoary")
909 HTTP/1.1 200 Ok909 HTTP/1.1 200 Ok
910 ...910 ...
@@ -914,7 +914,7 @@
914914
915 >>> login('foo.bar@canonical.com')915 >>> login('foo.bar@canonical.com')
916 >>> subsequent_version = test_publisher.createSource(916 >>> subsequent_version = test_publisher.createSource(
917 ... cprov.archive, 'foocomm', '1.0-2')917 ... cprov_private_ppa_db, 'foocomm', '1.0-2')
918 >>> subsequent_version.secure_record.status = (918 >>> subsequent_version.secure_record.status = (
919 ... PackagePublishingStatus.PUBLISHED)919 ... PackagePublishingStatus.PUBLISHED)
920 >>> logout()920 >>> logout()
@@ -922,7 +922,7 @@
922 >>> print cprov_webservice.named_post(922 >>> print cprov_webservice.named_post(
923 ... ubuntu['main_archive_link'], 'syncSources', {},923 ... ubuntu['main_archive_link'], 'syncSources', {},
924 ... source_names=['foocomm'], to_pocket='release',924 ... source_names=['foocomm'], to_pocket='release',
925 ... from_archive=cprov_archive['self_link'],925 ... from_archive=cprov_private_ppa['self_link'],
926 ... to_series="hoary")926 ... to_series="hoary")
927 HTTP/1.1 200 Ok927 HTTP/1.1 200 Ok
928 ...928 ...
@@ -933,7 +933,7 @@
933 >>> print cprov_webservice.named_post(933 >>> print cprov_webservice.named_post(
934 ... ubuntu['main_archive_link'], 'syncSource', {},934 ... ubuntu['main_archive_link'], 'syncSource', {},
935 ... source_name='foocomm', version='1.0-2', to_pocket='release',935 ... source_name='foocomm', version='1.0-2', to_pocket='release',
936 ... from_archive=cprov_archive['self_link'],936 ... from_archive=cprov_private_ppa['self_link'],
937 ... to_series="hoary")937 ... to_series="hoary")
938 HTTP/1.1 400 Bad Request938 HTTP/1.1 400 Bad Request
939 ...939 ...
940940
=== modified file 'lib/lp/soyuz/stories/webservice/xx-archivedependency.txt'
--- lib/lp/soyuz/stories/webservice/xx-archivedependency.txt 2009-08-28 06:39:38 +0000
+++ lib/lp/soyuz/stories/webservice/xx-archivedependency.txt 2010-02-26 15:44:20 +0000
@@ -1,14 +1,15 @@
1= Archive dependencies =1= Archive dependencies =
22
3`ArchiveDependency` records represent build-dependencies between3`ArchiveDependency` records represent build-dependencies between
4archives, and are exposed through the API. 4archives, and are exposed through the API.
55
6Most of the tests live in6Most of the tests live in
7lib/lp/soyuz/stories/webservice/xx-archive.txt.7lib/lp/soyuz/stories/webservice/xx-archive.txt.
88
9Firstly we need to set some things up: we need a PPA with a dependency.9Firstly we need to set some things up: we need a PPA with a dependency.
10We'll use Celso's PPA, and give it a custom dependency on the primary10We'll use Celso's PPA, and give it a custom dependency on the primary
11archive.11archive, and then create a private PPA for Celso with a similar custom
12dependency.
1213
13 >>> import simplejson14 >>> import simplejson
14 >>> from zope.component import getUtility15 >>> from zope.component import getUtility
@@ -22,14 +23,18 @@
22 ... cprov_ppa_db.distribution.main_archive,23 ... cprov_ppa_db.distribution.main_archive,
23 ... PackagePublishingPocket.RELEASE,24 ... PackagePublishingPocket.RELEASE,
24 ... component=getUtility(IComponentSet)['universe'])25 ... component=getUtility(IComponentSet)['universe'])
26 >>> cprov_private_ppa_db = factory.makeArchive(
27 ... private=True, owner=cprov_db, name="p3a",
28 ... distribution=cprov_ppa_db.distribution,
29 ... description="packages to help my friends.")
30 >>> dep = cprov_private_ppa_db.addArchiveDependency(
31 ... cprov_ppa_db.distribution.main_archive,
32 ... PackagePublishingPocket.RELEASE,
33 ... component=getUtility(IComponentSet)['universe'])
25 >>> logout()34 >>> logout()
2635
27Any user can retrieve a public PPA's dependencies.36Any user can retrieve a public PPA's dependencies.
2837
29 >>> login('foo.bar@canonical.com')
30 >>> cprov_ppa_db.private = False
31 >>> logout()
32
33 >>> print user_webservice.get(38 >>> print user_webservice.get(
34 ... '/~cprov/+archive/ppa/dependencies')39 ... '/~cprov/+archive/ppa/dependencies')
35 HTTP/1.1 200 Ok40 HTTP/1.1 200 Ok
@@ -40,18 +45,11 @@
40 HTTP/1.1 200 Ok45 HTTP/1.1 200 Ok
41 ...46 ...
4247
43The dependencies of a private archive are private. Let's make48The dependencies of a private archive are private. Unprivileged users
44Celso's PPA private.49can't get a list of the dependencies.
45
46 >>> login('foo.bar@canonical.com')
47 >>> cprov_ppa_db.private = True
48 >>> cprov_ppa_db.buildd_secret = 'foobar'
49 >>> logout()
50
51Now our unprivileged user can't get a list of the dependencies.
5250
53 >>> print user_webservice.get(51 >>> print user_webservice.get(
54 ... '/~cprov/+archive/ppa/dependencies')52 ... '/~cprov/+archive/p3a/dependencies')
55 HTTP/1.1 401 Unauthorized53 HTTP/1.1 401 Unauthorized
56 ...54 ...
57 Unauthorized: (<Archive at ...>, 'dependencies', 'launchpad.View')55 Unauthorized: (<Archive at ...>, 'dependencies', 'launchpad.View')
@@ -60,31 +58,27 @@
60Nor can said user craft a URL to a dependency.58Nor can said user craft a URL to a dependency.
6159
62 >>> print user_webservice.get(60 >>> print user_webservice.get(
63 ... '/~cprov/+archive/ppa/+dependency/1')61 ... '/~cprov/+archive/p3a/+dependency/1')
64 HTTP/1.1 401 Unauthorized62 HTTP/1.1 401 Unauthorized
65 ...63 ...
66 Unauthorized: (<Archive at ...>, 'getArchiveDependency', 'launchpad.View')64 Unauthorized: (<Archive at ...>, 'getArchiveDependency', 'launchpad.View')
67 <BLANKLINE>65 <BLANKLINE>
6866
69Celso can still see them if we grant private permissions, of course.67Celso can see them if we grant private permissions, of course.
7068
71 >>> from canonical.launchpad.testing.pages import webservice_for_person69 >>> from canonical.launchpad.testing.pages import webservice_for_person
72 >>> from canonical.launchpad.webapp.interfaces import OAuthPermission70 >>> from canonical.launchpad.webapp.interfaces import OAuthPermission
73 >>> cprov_webservice = webservice_for_person(71 >>> cprov_webservice = webservice_for_person(
74 ... cprov_db, permission=OAuthPermission.WRITE_PRIVATE)72 ... cprov_db, permission=OAuthPermission.WRITE_PRIVATE)
75 >>> print cprov_webservice.get(73 >>> print cprov_webservice.get(
76 ... '/~cprov/+archive/ppa/dependencies')74 ... '/~cprov/+archive/p3a/dependencies')
77 HTTP/1.1 200 Ok75 HTTP/1.1 200 Ok
78 ...76 ...
79 >>> print cprov_webservice.get(77 >>> print cprov_webservice.get(
80 ... '/~cprov/+archive/ppa/+dependency/1')78 ... '/~cprov/+archive/p3a/+dependency/1')
81 HTTP/1.1 200 Ok79 HTTP/1.1 200 Ok
82 ...80 ...
8381
84 >>> login('foo.bar@canonical.com')
85 >>> cprov_ppa_db.private = False
86 >>> logout()
87
88But even he can't write to a dependency.82But even he can't write to a dependency.
8983
90 >>> mark_ppa = cprov_webservice.get(84 >>> mark_ppa = cprov_webservice.get(
9185
=== modified file 'lib/lp/soyuz/stories/webservice/xx-binary-package-publishing.txt'
--- lib/lp/soyuz/stories/webservice/xx-binary-package-publishing.txt 2009-08-20 04:46:48 +0000
+++ lib/lp/soyuz/stories/webservice/xx-binary-package-publishing.txt 2010-02-26 15:44:20 +0000
@@ -90,26 +90,36 @@
90Security90Security
91========91========
9292
93When Celso's PPA becomes private ...93Create a private PPA for Celso with some binaries.
9494
95 >>> login("foo.bar@canonical.com")95 >>> login("foo.bar@canonical.com")
9696
97 >>> from zope.component import getUtility97 >>> from zope.component import getUtility
98 >>> from lp.registry.interfaces.person import IPersonSet98 >>> from lp.registry.interfaces.person import IPersonSet
9999 >>> from lp.registry.interfaces.distribution import IDistributionSet
100 >>> cprov = getUtility(IPersonSet).getByName('cprov')100 >>> from lp.soyuz.tests.test_publishing import (
101 >>> cprov.archive.buildd_secret = 'boing'101 ... SoyuzTestPublisher)
102 >>> cprov.archive.private = True102 >>> from lp.soyuz.interfaces.publishing import (
103103 ... PackagePublishingStatus)
104 >>> transaction.commit()104 >>> cprov_db = getUtility(IPersonSet).getByName('cprov')
105105 >>> ubuntu_db = getUtility(IDistributionSet).getByName('ubuntu')
106 >>> cprov_private_ppa_db = factory.makeArchive(
107 ... private=True, owner=cprov_db, name="p3a",
108 ... distribution=ubuntu_db)
109 >>> test_publisher = SoyuzTestPublisher()
110 >>> test_publisher.prepareBreezyAutotest()
111 >>> private_source_pub = test_publisher.getPubBinaries(
112 ... status=PackagePublishingStatus.PUBLISHED,
113 ... binaryname='privacy-test-bin',
114 ... archive=cprov_private_ppa_db)
106 >>> logout()115 >>> logout()
107116
108Only Celso (or anyone who participates on the PPA owner team) has117Only Celso (or anyone who participates on the PPA owner team) has
109access to the PPA publications.118access to the PPA publications.
110119
120 >>> cprov_private_ppa = webservice.get("/~cprov/+archive/p3a").jsonBody()
111 >>> cprov_bins_response = webservice.named_get(121 >>> cprov_bins_response = webservice.named_get(
112 ... cprov_archive['self_link'], 'getPublishedBinaries')122 ... cprov_private_ppa['self_link'], 'getPublishedBinaries')
113 >>> print cprov_bins_response123 >>> print cprov_bins_response
114 HTTP/1.1 200 Ok124 HTTP/1.1 200 Ok
115 ...125 ...
@@ -117,7 +127,7 @@
117Any other user attempt would result in a 401 error.127Any other user attempt would result in a 401 error.
118128
119 >>> response = user_webservice.named_get(129 >>> response = user_webservice.named_get(
120 ... cprov_archive['self_link'], 'getPublishedBinaries')130 ... cprov_private_ppa['self_link'], 'getPublishedBinaries')
121 >>> print response131 >>> print response
122 HTTP/1.1 401 Unauthorized132 HTTP/1.1 401 Unauthorized
123 ...133 ...
@@ -125,6 +135,7 @@
125If the user attempts to access the publication URL directly they will135If the user attempts to access the publication URL directly they will
126also fail in their quest.136also fail in their quest.
127137
138 >>> pubs = cprov_bins_response.jsonBody()
128 >>> private_publication_url = pubs['entries'][0]['self_link']139 >>> private_publication_url = pubs['entries'][0]['self_link']
129 >>> response = user_webservice.get(private_publication_url)140 >>> response = user_webservice.get(private_publication_url)
130 >>> print response141 >>> print response
131142
=== modified file 'lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt'
--- lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt 2010-01-13 05:18:26 +0000
+++ lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt 2010-02-26 15:44:20 +0000
@@ -21,12 +21,12 @@
21 >>> for pub in ppa.getPublishedSources():21 >>> for pub in ppa.getPublishedSources():
22 ... pub = removeSecurityProxy(pub)22 ... pub = removeSecurityProxy(pub)
23 ... pub.sourcepackagerelease.dscsigningkey = fake_signer23 ... pub.sourcepackagerelease.dscsigningkey = fake_signer
24 >>> transaction.commit()
25 >>> logout()24 >>> logout()
2625
27 >>> cprov_archive = webservice.get("/~cprov/+archive/ppa").jsonBody()26 >>> cprov_archive = webservice.get("/~cprov/+archive/ppa").jsonBody()
28 >>> pubs = webservice.named_get(27 >>> cprov_srcs_response = pubs = webservice.named_get(
29 ... cprov_archive['self_link'], 'getPublishedSources').jsonBody()28 ... cprov_archive['self_link'], 'getPublishedSources')
29 >>> pubs = cprov_srcs_response.jsonBody()
3030
31 >>> def print_publications(pubs):31 >>> def print_publications(pubs):
32 ... for display_name in sorted(32 ... for display_name in sorted(
@@ -150,7 +150,6 @@
150 >>> for pub in ppa.getPublishedSources():150 >>> for pub in ppa.getPublishedSources():
151 ... pub = removeSecurityProxy(pub)151 ... pub = removeSecurityProxy(pub)
152 ... pub.sourcepackagerelease.dscsigningkey = None152 ... pub.sourcepackagerelease.dscsigningkey = None
153 >>> transaction.commit()
154 >>> logout()153 >>> logout()
155154
156Query the source again:155Query the source again:
@@ -181,9 +180,9 @@
181Anonymous users can't remove packages.180Anonymous users can't remove packages.
182181
183 >>> response = webservice.named_post(182 >>> response = webservice.named_post(
184 ... package, 'requestDeletion', 183 ... package, 'requestDeletion',
185 ... removal_comment="No longer needed")184 ... removal_comment="No longer needed")
186 >>> print response 185 >>> print response
187 HTTP/1.1 401 Unauthorized186 HTTP/1.1 401 Unauthorized
188 ...187 ...
189188
@@ -194,12 +193,12 @@
194 >>> logout()193 >>> logout()
195 >>> from canonical.launchpad.testing.pages import webservice_for_person194 >>> from canonical.launchpad.testing.pages import webservice_for_person
196 >>> from canonical.launchpad.webapp.interfaces import OAuthPermission195 >>> from canonical.launchpad.webapp.interfaces import OAuthPermission
197 >>> cprov_webservice = webservice_for_person(cprov, 196 >>> cprov_webservice = webservice_for_person(cprov,
198 ... permission=OAuthPermission.WRITE_PUBLIC)197 ... permission=OAuthPermission.WRITE_PUBLIC)
199 >>> response = cprov_webservice.named_post(198 >>> response = cprov_webservice.named_post(
200 ... package, 'requestDeletion', 199 ... package, 'requestDeletion',
201 ... removal_comment="No longer needed")200 ... removal_comment="No longer needed")
202 >>> print response 201 >>> print response
203 HTTP/1.1 200 Ok202 HTTP/1.1 200 Ok
204 ...203 ...
205204
@@ -215,30 +214,46 @@
215Privacy214Privacy
216=======215=======
217216
218When Celso's PPA becomes private ...217Create a private PPA for Celso with some binaries.
219218
220 >>> login("foo.bar@canonical.com")219 >>> login("foo.bar@canonical.com")
221220
222 >>> cprov_ppa.buildd_secret = 'boing'221 >>> from zope.component import getUtility
223 >>> cprov_ppa.private = True222 >>> from lp.registry.interfaces.person import IPersonSet
224223 >>> from lp.registry.interfaces.distribution import IDistributionSet
225 >>> transaction.commit()224 >>> from lp.soyuz.tests.test_publishing import (
226225 ... SoyuzTestPublisher)
226 >>> from lp.soyuz.interfaces.publishing import (
227 ... PackagePublishingStatus)
228 >>> cprov_db = getUtility(IPersonSet).getByName('cprov')
229 >>> ubuntu_db = getUtility(IDistributionSet).getByName('ubuntu')
230 >>> cprov_private_ppa_db = factory.makeArchive(
231 ... private=True, owner=cprov_db, name="p3a",
232 ... distribution=ubuntu_db)
233 >>> test_publisher = SoyuzTestPublisher()
234 >>> test_publisher.prepareBreezyAutotest()
235 >>> private_source_pub = test_publisher.getPubBinaries(
236 ... status=PackagePublishingStatus.PUBLISHED,
237 ... binaryname='privacy-test-bin',
238 ... archive=cprov_private_ppa_db)
227 >>> logout()239 >>> logout()
228240
241
229Only Celso (or anyone who participates on the PPA owner team) has242Only Celso (or anyone who participates on the PPA owner team) has
230access to the PPA publications.243access to the PPA publications.
231244
232 >>> cprov_srcs_response = webservice.named_get(245 >>> cprov_private_ppa = webservice.get(
233 ... cprov_archive['self_link'], 'getPublishedSources')246 ... "/~cprov/+archive/p3a").jsonBody()
234 >>> print cprov_srcs_response247 >>> cprov_srcs_response_private = webservice.named_get(
248 ... cprov_private_ppa['self_link'], 'getPublishedSources')
249 >>> print cprov_srcs_response_private
235 HTTP/1.1 200 Ok250 HTTP/1.1 200 Ok
236 ...251 ...
237252
238Any other user attempt would result in a 401 error.253Any other user attempt would result in a 401 error.
239254
240 >>> response = user_webservice.named_get(255 >>> response = user_webservice.named_get(
241 ... cprov_archive['self_link'], 'getPublishedSources')256 ... cprov_private_ppa['self_link'], 'getPublishedSources')
242 >>> print response257 >>> print response
243 HTTP/1.1 401 Unauthorized258 HTTP/1.1 401 Unauthorized
244 ...259 ...
@@ -246,6 +261,7 @@
246If the user attempts to access the publication URL directly they will261If the user attempts to access the publication URL directly they will
247also fail in their quest.262also fail in their quest.
248263
264 >>> pubs = cprov_srcs_response_private.jsonBody()
249 >>> private_publication_url = pubs['entries'][0]['self_link']265 >>> private_publication_url = pubs['entries'][0]['self_link']
250 >>> response = user_webservice.get(private_publication_url)266 >>> response = user_webservice.get(private_publication_url)
251 >>> print response267 >>> print response