Merge lp:~jamalta/launchpad/515761-anonymrelease into lp:launchpad/db-devel
- 515761-anonymrelease
- Merge into db-devel
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Brad Crittenden | ||||
Approved revision: | not available | ||||
Merged at revision: | not available | ||||
Proposed branch: | lp:~jamalta/launchpad/515761-anonymrelease | ||||
Merge into: | lp:launchpad/db-devel | ||||
Diff against target: |
270 lines (+84/-30) (has conflicts) 7 files modified
lib/canonical/launchpad/security.py (+36/-17) lib/lp/bugs/interfaces/bugtask.py (+2/-4) lib/lp/bugs/stories/webservice/xx-bug.txt (+12/-7) lib/lp/registry/browser/configure.zcml (+1/-1) lib/lp/registry/browser/productseries.py (+1/-1) lib/lp/registry/stories/webservice/xx-project-registry.txt (+14/-0) lib/lp/testing/factory.py (+18/-0) Text conflict in lib/canonical/launchpad/security.py Text conflict in lib/lp/testing/factory.py |
||||
To merge this branch: | bzr merge lp:~jamalta/launchpad/515761-anonymrelease | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Paul Hummer (community) | code | Approve | |
Review via email: mp+18641@code.launchpad.net |
Commit message
Created View classes for IMessage, IProductRelease, and IBugSubscription to allow anonymous API access to these interfaces. Fixed misspelling of 'permission' attribute for ViewProductSeries. Fixed security problem in test xx-product-
Description of the change
Jamal Fanaian (jamalta) wrote : | # |
Jamal Fanaian (jamalta) wrote : | # |
= Summary =
Anonymous API Access to some collections returns nothing.
== Proposed fix ==
Create View classes in security.py for the interfaces that need anonymous access.
== Pre-implementation notes ==
Decision to make these collections available to everyone needs to be considered during review.
== Implementation details ==
Created ViewBugMessage, ViewProductRelease, and ViewBugSubscription in security.py with checkUnauthorized and checkAuthorized both returning True. Also had to modify permissions for ubuntupkg which bac caught.
== Tests ==
% bin/test -vvct webservice/
% bin/test -vvct xx-project-registry
% bin/test -vvct xx-product-
== Demo and Q/A ==
>>> from launchpadlib.
>>> launchpad = Launchpad.
>>> list(launchpad.
[<project_series at https:/
>>> list(launchpad.
[<message at https:/
>>> list(launchpad.
[<bug_subscription at https:/
== Launchpad lint ==
Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.
Linting changed files:
lib/canonical
lib/canonical
lib/lp/
lib/lp/
Paul Hummer (rockstar) wrote : | # |
<rockstar> jamalta, hm, maybe you should have a single class that inherits from AuthorizationBase that deals with checkAuthenticated and checkUnauthenti
<jamalta> rockstar: i was thinking of doing that but no other class does that
<rockstar> jamalta, well, that may be for hysterical reasons. I don't see why new code should be like that.
<jamalta> and then there's the message on launchpad-dev from henning talking about refactoring security.py altogether
<jamalta> rockstar: i could do that if you would prefer though
<rockstar> jamalta, I say do it. Talk on a mailing list gets trumped by actual code.
<jamalta> rockstar: haha, sounds good :)
<jamalta> ViewByAnyUser a good name?
<rockstar> jamalta, AnonymousAuthor
<jamalta> rockstar: even better
Jamal Fanaian (jamalta) wrote : | # |
=== modified file 'lib/canonical/
--- lib/canonical/
+++ lib/canonical/
@@ -172,6 +172,19 @@
return True
+class AnonymousAuthor
+ """Allow any authenticated and unauthenticated user access."""
+ permission = 'launchpad.View'
+
+ def checkUnauthenti
+ """Any unauthorized user can see this object."""
+ return True
+
+ def checkAuthentica
+ """Any authorized user can see this object."""
+ return True
+
+
class AdminByAdminsTe
permission = 'launchpad.Admin'
usedfor = Interface
@@ -815,24 +828,9 @@
-class ViewProductSeri
+class ViewProductSeri
usedfor = IProductSeries
- permission = 'launchpad.View'
-
- def checkUnauthenti
- """See `IAuthorization
-
- :return: True or False.
- """
- return True
-
- def checkAuthentica
- """See `IAuthorization
-
- :return: True or False.
- """
- return True
class EditProductSeri
@@ -980,44 +978,14 @@
self, bugattachment.bug)
-class ViewBugSubscrip
+class ViewBugSubscrip
usedfor = IBugSubscription
- permission = 'launchpad.View'
-
- def checkUnauthenti
- """See `IAuthorization
-
- :return: True or False.
- """
- return True
-
- def checkAuthentica
- """See `IAuthorization
-
- :return: True or False.
- """
- return True
-
-
-class ViewBugMessage(
+
+
+class ViewBugMessage(
usedfor = IMessage
- permission = 'launchpad.View'
-
- def checkUnauthenti
- """See `IAuthorization
-
- :return: True or False.
- """
- return True
-
- def checkAuthentica
- """See `IAuthorization
-
- :return: True or False.
- """
- return True
class ViewAnnouncemen
@@ -1323,24 +1291,9 @@
self, user)
-class ViewProductRele
+class ViewProductRele
usedfor = IProductRelease
- permission = 'launchpad.View'
-
- def checkUnauthenti
- """See `IAuthorization
-
- :return: True or False.
- """
- return True
-
- def checkAuthentica
- """See `IAuthorization
-
- :return: True or False.
- """
- return True
class AdminTranslatio
Jamal Fanaian (jamalta) wrote : | # |
Paul,
That was the diff for the last changes you requested. Based on salgado's recommendation I posted a message to launchpad-dev to confirm any security concerns with these changes.
Thanks again for reviewing this.
Paul Hummer (rockstar) wrote : | # |
Thanks for making the changes I asked for.
Preview Diff
1 | === modified file 'lib/canonical/launchpad/security.py' | |||
2 | --- lib/canonical/launchpad/security.py 2010-02-04 00:01:23 +0000 | |||
3 | +++ lib/canonical/launchpad/security.py 2010-02-08 14:16:33 +0000 | |||
4 | @@ -29,6 +29,7 @@ | |||
5 | 29 | from lp.bugs.interfaces.bugattachment import IBugAttachment | 29 | from lp.bugs.interfaces.bugattachment import IBugAttachment |
6 | 30 | from lp.bugs.interfaces.bugbranch import IBugBranch | 30 | from lp.bugs.interfaces.bugbranch import IBugBranch |
7 | 31 | from lp.bugs.interfaces.bugnomination import IBugNomination | 31 | from lp.bugs.interfaces.bugnomination import IBugNomination |
8 | 32 | from lp.bugs.interfaces.bugsubscription import IBugSubscription | ||
9 | 32 | from lp.bugs.interfaces.bugtracker import IBugTracker | 33 | from lp.bugs.interfaces.bugtracker import IBugTracker |
10 | 33 | from lp.soyuz.interfaces.build import IBuild | 34 | from lp.soyuz.interfaces.build import IBuild |
11 | 34 | from lp.buildmaster.interfaces.builder import IBuilder, IBuilderSet | 35 | from lp.buildmaster.interfaces.builder import IBuilder, IBuilderSet |
12 | @@ -63,6 +64,7 @@ | |||
13 | 63 | from lp.registry.interfaces.mailinglist import IMailingListSet | 64 | from lp.registry.interfaces.mailinglist import IMailingListSet |
14 | 64 | from lp.registry.interfaces.milestone import ( | 65 | from lp.registry.interfaces.milestone import ( |
15 | 65 | IMilestone, IProjectMilestone) | 66 | IMilestone, IProjectMilestone) |
16 | 67 | from canonical.launchpad.interfaces.message import IMessage | ||
17 | 66 | from canonical.launchpad.interfaces.oauth import ( | 68 | from canonical.launchpad.interfaces.oauth import ( |
18 | 67 | IOAuthAccessToken, IOAuthRequestToken) | 69 | IOAuthAccessToken, IOAuthRequestToken) |
19 | 68 | from lp.soyuz.interfaces.packageset import IPackageset, IPackagesetSet | 70 | from lp.soyuz.interfaces.packageset import IPackageset, IPackagesetSet |
20 | @@ -170,6 +172,19 @@ | |||
21 | 170 | return True | 172 | return True |
22 | 171 | 173 | ||
23 | 172 | 174 | ||
24 | 175 | class AnonymousAuthorization(AuthorizationBase): | ||
25 | 176 | """Allow any authenticated and unauthenticated user access.""" | ||
26 | 177 | permission = 'launchpad.View' | ||
27 | 178 | |||
28 | 179 | def checkUnauthenticated(self): | ||
29 | 180 | """Any unauthorized user can see this object.""" | ||
30 | 181 | return True | ||
31 | 182 | |||
32 | 183 | def checkAuthenticated(self, user): | ||
33 | 184 | """Any authorized user can see this object.""" | ||
34 | 185 | return True | ||
35 | 186 | |||
36 | 187 | |||
37 | 173 | class AdminByAdminsTeam(AuthorizationBase): | 188 | class AdminByAdminsTeam(AuthorizationBase): |
38 | 174 | permission = 'launchpad.Admin' | 189 | permission = 'launchpad.Admin' |
39 | 175 | usedfor = Interface | 190 | usedfor = Interface |
40 | @@ -813,24 +828,9 @@ | |||
41 | 813 | user.in_admin) | 828 | user.in_admin) |
42 | 814 | 829 | ||
43 | 815 | 830 | ||
45 | 816 | class ViewProductSeries(AuthorizationBase): | 831 | class ViewProductSeries(AnonymousAuthorization): |
46 | 817 | 832 | ||
47 | 818 | usedfor = IProductSeries | 833 | usedfor = IProductSeries |
48 | 819 | permision = 'launchpad.View' | ||
49 | 820 | |||
50 | 821 | def checkUnauthenticated(self): | ||
51 | 822 | """See `IAuthorization.checkUnauthenticated`. | ||
52 | 823 | |||
53 | 824 | :return: True or False. | ||
54 | 825 | """ | ||
55 | 826 | return True | ||
56 | 827 | |||
57 | 828 | def checkAuthenticated(self, user): | ||
58 | 829 | """See `IAuthorization.checkAuthenticated`. | ||
59 | 830 | |||
60 | 831 | :return: True or False. | ||
61 | 832 | """ | ||
62 | 833 | return True | ||
63 | 834 | 834 | ||
64 | 835 | 835 | ||
65 | 836 | class EditProductSeries(EditByOwnersOrAdmins): | 836 | class EditProductSeries(EditByOwnersOrAdmins): |
66 | @@ -978,6 +978,16 @@ | |||
67 | 978 | self, bugattachment.bug) | 978 | self, bugattachment.bug) |
68 | 979 | 979 | ||
69 | 980 | 980 | ||
70 | 981 | class ViewBugSubscription(AnonymousAuthorization): | ||
71 | 982 | |||
72 | 983 | usedfor = IBugSubscription | ||
73 | 984 | |||
74 | 985 | |||
75 | 986 | class ViewBugMessage(AnonymousAuthorization): | ||
76 | 987 | |||
77 | 988 | usedfor = IMessage | ||
78 | 989 | |||
79 | 990 | |||
80 | 981 | class ViewAnnouncement(AuthorizationBase): | 991 | class ViewAnnouncement(AuthorizationBase): |
81 | 982 | permission = 'launchpad.View' | 992 | permission = 'launchpad.View' |
82 | 983 | usedfor = IAnnouncement | 993 | usedfor = IAnnouncement |
83 | @@ -1281,7 +1291,16 @@ | |||
84 | 1281 | self, user) | 1291 | self, user) |
85 | 1282 | 1292 | ||
86 | 1283 | 1293 | ||
88 | 1284 | class AdminTranslationImportQueueEntry(AuthorizationBase): | 1294 | <<<<<<< TREE |
89 | 1295 | class AdminTranslationImportQueueEntry(AuthorizationBase): | ||
90 | 1296 | ======= | ||
91 | 1297 | class ViewProductRelease(AnonymousAuthorization): | ||
92 | 1298 | |||
93 | 1299 | usedfor = IProductRelease | ||
94 | 1300 | |||
95 | 1301 | |||
96 | 1302 | class AdminTranslationImportQueueEntry(AuthorizationBase): | ||
97 | 1303 | >>>>>>> MERGE-SOURCE | ||
98 | 1285 | permission = 'launchpad.Admin' | 1304 | permission = 'launchpad.Admin' |
99 | 1286 | usedfor = ITranslationImportQueueEntry | 1305 | usedfor = ITranslationImportQueueEntry |
100 | 1287 | 1306 | ||
101 | 1288 | 1307 | ||
102 | === modified file 'lib/lp/bugs/browser/configure.zcml' | |||
103 | === modified file 'lib/lp/bugs/interfaces/bugtask.py' | |||
104 | --- lib/lp/bugs/interfaces/bugtask.py 2010-02-06 12:23:17 +0000 | |||
105 | +++ lib/lp/bugs/interfaces/bugtask.py 2010-02-08 14:16:33 +0000 | |||
106 | @@ -474,11 +474,9 @@ | |||
107 | 474 | description=_("The age of this task, expressed as the " | 474 | description=_("The age of this task, expressed as the " |
108 | 475 | "length of time between the creation date " | 475 | "length of time between the creation date " |
109 | 476 | "and now.")) | 476 | "and now.")) |
112 | 477 | task_age = exported( | 477 | task_age = Int(title=_("Age of the bug task"), |
111 | 478 | Int(title=_("Age of the bug task"), | ||
113 | 479 | description=_("The age of this task in seconds, a delta between " | 478 | description=_("The age of this task in seconds, a delta between " |
116 | 480 | "now and the date the bug task was created."), | 479 | "now and the date the bug task was created.")) |
115 | 481 | readonly=True)) | ||
117 | 482 | owner = exported( | 480 | owner = exported( |
118 | 483 | Reference(title=_("The owner"), schema=IPerson, readonly=True)) | 481 | Reference(title=_("The owner"), schema=IPerson, readonly=True)) |
119 | 484 | target = exported(Reference( | 482 | target = exported(Reference( |
120 | 485 | 483 | ||
121 | === modified file 'lib/lp/bugs/stories/webservice/xx-bug.txt' | |||
122 | --- lib/lp/bugs/stories/webservice/xx-bug.txt 2010-02-03 18:57:40 +0000 | |||
123 | +++ lib/lp/bugs/stories/webservice/xx-bug.txt 2010-02-08 14:16:33 +0000 | |||
124 | @@ -255,6 +255,12 @@ | |||
125 | 255 | >>> webservice.get("/messages").status | 255 | >>> webservice.get("/messages").status |
126 | 256 | 404 | 256 | 404 |
127 | 257 | 257 | ||
128 | 258 | Bug messages can be accessed anonymously. | ||
129 | 259 | |||
130 | 260 | >>> messages = anon_webservice.get("/bugs/5/messages").jsonBody()['entries'] | ||
131 | 261 | >>> print messages[0]['self_link'] | ||
132 | 262 | http://.../firefox/+bug/5/comments/0 | ||
133 | 263 | |||
134 | 258 | We can add a new message to a bug by calling the newMessage method. | 264 | We can add a new message to a bug by calling the newMessage method. |
135 | 259 | 265 | ||
136 | 260 | >>> print webservice.named_post( | 266 | >>> print webservice.named_post( |
137 | @@ -332,15 +338,8 @@ | |||
138 | 332 | self_link: u'http://api.../debian/+source/mozilla-firefox/+bug/1' | 338 | self_link: u'http://api.../debian/+source/mozilla-firefox/+bug/1' |
139 | 333 | status: u'Confirmed' | 339 | status: u'Confirmed' |
140 | 334 | target_link: u'http://api.../debian/+source/mozilla-firefox' | 340 | target_link: u'http://api.../debian/+source/mozilla-firefox' |
141 | 335 | task_age: ... | ||
142 | 336 | title: u'Bug #1 in mozilla-firefox (Debian): "Firefox does not support SVG"' | 341 | title: u'Bug #1 in mozilla-firefox (Debian): "Firefox does not support SVG"' |
143 | 337 | 342 | ||
144 | 338 | Because task age is a dynamic calculation between now and the date_created | ||
145 | 339 | we will just verify that an integer is returned. | ||
146 | 340 | |||
147 | 341 | >>> print type(bug_one_bugtasks[0]['task_age']) | ||
148 | 342 | <type 'int'> | ||
149 | 343 | |||
150 | 344 | The collection of bug tasks is not exposed as a resource: | 343 | The collection of bug tasks is not exposed as a resource: |
151 | 345 | 344 | ||
152 | 346 | >>> webservice.get("/bug_tasks").status | 345 | >>> webservice.get("/bug_tasks").status |
153 | @@ -869,6 +868,12 @@ | |||
154 | 869 | self_link: u'http://.../bugs/1/+subscription/stevea' | 868 | self_link: u'http://.../bugs/1/+subscription/stevea' |
155 | 870 | subscribed_by_link: u'http://.../~janitor' | 869 | subscribed_by_link: u'http://.../~janitor' |
156 | 871 | 870 | ||
157 | 871 | Subscriptions can also be accessed anonymously. | ||
158 | 872 | |||
159 | 873 | >>> subscriptions = anon_webservice.get(bug_one_subscriptions_url).jsonBody() | ||
160 | 874 | >>> print subscriptions['entries'][0]['self_link'] | ||
161 | 875 | http://.../bugs/1/+subscription/stevea | ||
162 | 876 | |||
163 | 872 | We can also create new subscriptions. | 877 | We can also create new subscriptions. |
164 | 873 | 878 | ||
165 | 874 | >>> new_subscription = webservice.named_post( | 879 | >>> new_subscription = webservice.named_post( |
166 | 875 | 880 | ||
167 | === modified file 'lib/lp/code/model/branchmergeproposaljob.py' | |||
168 | === modified file 'lib/lp/registry/browser/configure.zcml' | |||
169 | --- lib/lp/registry/browser/configure.zcml 2010-01-30 18:15:36 +0000 | |||
170 | +++ lib/lp/registry/browser/configure.zcml 2010-02-08 14:16:33 +0000 | |||
171 | @@ -1606,7 +1606,7 @@ | |||
172 | 1606 | template="../templates/productseries-ubuntupkg.pt" | 1606 | template="../templates/productseries-ubuntupkg.pt" |
173 | 1607 | for="lp.registry.interfaces.productseries.IProductSeries" | 1607 | for="lp.registry.interfaces.productseries.IProductSeries" |
174 | 1608 | class="lp.registry.browser.productseries.ProductSeriesUbuntuPackagingView" | 1608 | class="lp.registry.browser.productseries.ProductSeriesUbuntuPackagingView" |
176 | 1609 | permission="launchpad.View"/> | 1609 | permission="launchpad.AnyPerson"/> |
177 | 1610 | <browser:pages | 1610 | <browser:pages |
178 | 1611 | for="lp.registry.interfaces.productseries.IProductSeries" | 1611 | for="lp.registry.interfaces.productseries.IProductSeries" |
179 | 1612 | class="lp.registry.browser.productseries.ProductSeriesView" | 1612 | class="lp.registry.browser.productseries.ProductSeriesView" |
180 | 1613 | 1613 | ||
181 | === modified file 'lib/lp/registry/browser/productseries.py' | |||
182 | --- lib/lp/registry/browser/productseries.py 2010-01-22 16:44:39 +0000 | |||
183 | +++ lib/lp/registry/browser/productseries.py 2010-02-08 14:16:33 +0000 | |||
184 | @@ -205,7 +205,7 @@ | |||
185 | 205 | summary = "Register a new Bazaar branch for this series' project" | 205 | summary = "Register a new Bazaar branch for this series' project" |
186 | 206 | return Link('+addbranch', text, summary, icon='add') | 206 | return Link('+addbranch', text, summary, icon='add') |
187 | 207 | 207 | ||
189 | 208 | @enabled_with_permission('launchpad.View') | 208 | @enabled_with_permission('launchpad.AnyPerson') |
190 | 209 | def ubuntupkg(self): | 209 | def ubuntupkg(self): |
191 | 210 | """Return a link to link this series to an ubuntu sourcepackage.""" | 210 | """Return a link to link this series to an ubuntu sourcepackage.""" |
192 | 211 | text = 'Link to Ubuntu package' | 211 | text = 'Link to Ubuntu package' |
193 | 212 | 212 | ||
194 | === modified file 'lib/lp/registry/stories/webservice/xx-project-registry.txt' | |||
195 | --- lib/lp/registry/stories/webservice/xx-project-registry.txt 2010-01-27 19:12:10 +0000 | |||
196 | +++ lib/lp/registry/stories/webservice/xx-project-registry.txt 2010-02-08 14:16:33 +0000 | |||
197 | @@ -282,6 +282,13 @@ | |||
198 | 282 | >>> print series_1_0['self_link'] | 282 | >>> print series_1_0['self_link'] |
199 | 283 | http://.../firefox/1.0 | 283 | http://.../firefox/1.0 |
200 | 284 | 284 | ||
201 | 285 | Series can also be accessed anonymously. | ||
202 | 286 | |||
203 | 287 | >>> response = anon_webservice.get(firefox['series_collection_link']) | ||
204 | 288 | >>> series = response.jsonBody() | ||
205 | 289 | >>> print series['total_size'] | ||
206 | 290 | 2 | ||
207 | 291 | |||
208 | 285 | A list of releases can be accessed through the releases_collection_link. | 292 | A list of releases can be accessed through the releases_collection_link. |
209 | 286 | 293 | ||
210 | 287 | >>> response = webservice.get(firefox['releases_collection_link']) | 294 | >>> response = webservice.get(firefox['releases_collection_link']) |
211 | @@ -302,6 +309,13 @@ | |||
212 | 302 | >>> print release_0_9_1['self_link'] | 309 | >>> print release_0_9_1['self_link'] |
213 | 303 | http://.../firefox/trunk/0.9.1 | 310 | http://.../firefox/trunk/0.9.1 |
214 | 304 | 311 | ||
215 | 312 | Releases can also be accessed anonymously. | ||
216 | 313 | |||
217 | 314 | >>> response = anon_webservice.get(firefox['releases_collection_link']) | ||
218 | 315 | >>> releases = response.jsonBody() | ||
219 | 316 | >>> print releases['total_size'] | ||
220 | 317 | 4 | ||
221 | 318 | |||
222 | 305 | The development focus series can be accessed through the | 319 | The development focus series can be accessed through the |
223 | 306 | development_focus_link. | 320 | development_focus_link. |
224 | 307 | 321 | ||
225 | 308 | 322 | ||
226 | === modified file 'lib/lp/services/job/runner.py' | |||
227 | === modified file 'lib/lp/testing/factory.py' | |||
228 | --- lib/lp/testing/factory.py 2010-02-06 12:23:17 +0000 | |||
229 | +++ lib/lp/testing/factory.py 2010-02-08 14:16:33 +0000 | |||
230 | @@ -36,8 +36,22 @@ | |||
231 | 36 | from canonical.autodecorate import AutoDecorate | 36 | from canonical.autodecorate import AutoDecorate |
232 | 37 | from canonical.config import config | 37 | from canonical.config import config |
233 | 38 | from canonical.database.constants import UTC_NOW | 38 | from canonical.database.constants import UTC_NOW |
234 | 39 | <<<<<<< TREE | ||
235 | 40 | ======= | ||
236 | 41 | from lp.code.interfaces.sourcepackagerecipe import ISourcePackageRecipeSource | ||
237 | 42 | from lp.code.interfaces.sourcepackagerecipebuild import ( | ||
238 | 43 | ISourcePackageRecipeBuildSource, | ||
239 | 44 | ) | ||
240 | 45 | from lp.codehosting.codeimport.worker import CodeImportSourceDetails | ||
241 | 46 | >>>>>>> MERGE-SOURCE | ||
242 | 39 | from canonical.database.sqlbase import flush_database_updates | 47 | from canonical.database.sqlbase import flush_database_updates |
243 | 48 | <<<<<<< TREE | ||
244 | 40 | 49 | ||
245 | 50 | ======= | ||
246 | 51 | from lp.soyuz.adapters.packagelocation import PackageLocation | ||
247 | 52 | from lp.soyuz.interfaces.publishing import PackagePublishingStatus | ||
248 | 53 | from lp.soyuz.interfaces.section import ISectionSet | ||
249 | 54 | >>>>>>> MERGE-SOURCE | ||
250 | 41 | from canonical.launchpad.database.account import Account | 55 | from canonical.launchpad.database.account import Account |
251 | 42 | from canonical.launchpad.database.emailaddress import EmailAddress | 56 | from canonical.launchpad.database.emailaddress import EmailAddress |
252 | 43 | from canonical.launchpad.database.message import Message, MessageChunk | 57 | from canonical.launchpad.database.message import Message, MessageChunk |
253 | @@ -83,6 +97,7 @@ | |||
254 | 83 | from lp.code.interfaces.codeimportmachine import ICodeImportMachineSet | 97 | from lp.code.interfaces.codeimportmachine import ICodeImportMachineSet |
255 | 84 | from lp.code.interfaces.codeimportresult import ICodeImportResultSet | 98 | from lp.code.interfaces.codeimportresult import ICodeImportResultSet |
256 | 85 | from lp.code.interfaces.revision import IRevisionSet | 99 | from lp.code.interfaces.revision import IRevisionSet |
257 | 100 | <<<<<<< TREE | ||
258 | 86 | from lp.code.interfaces.sourcepackagerecipe import ISourcePackageRecipeSource | 101 | from lp.code.interfaces.sourcepackagerecipe import ISourcePackageRecipeSource |
259 | 87 | from lp.code.interfaces.sourcepackagerecipebuild import ( | 102 | from lp.code.interfaces.sourcepackagerecipebuild import ( |
260 | 88 | ISourcePackageRecipeBuildSource, | 103 | ISourcePackageRecipeBuildSource, |
261 | @@ -91,6 +106,9 @@ | |||
262 | 91 | from lp.codehosting.codeimport.worker import CodeImportSourceDetails | 106 | from lp.codehosting.codeimport.worker import CodeImportSourceDetails |
263 | 92 | 107 | ||
264 | 93 | from lp.registry.interfaces.distribution import IDistributionSet | 108 | from lp.registry.interfaces.distribution import IDistributionSet |
265 | 109 | ======= | ||
266 | 110 | from lp.code.model.diff import Diff, PreviewDiff | ||
267 | 111 | >>>>>>> MERGE-SOURCE | ||
268 | 94 | from lp.registry.model.distributionsourcepackage import ( | 112 | from lp.registry.model.distributionsourcepackage import ( |
269 | 95 | DistributionSourcePackage) | 113 | DistributionSourcePackage) |
270 | 96 | from lp.registry.interfaces.distroseries import IDistroSeries | 114 | from lp.registry.interfaces.distroseries import IDistroSeries |
= Summary =
Anonymous API Access to some collections returns nothing.
== Proposed fix ==
Create View classes in security.py for the interfaces that need anonymous access.
== Pre-implementation notes ==
Decision to make these collections available to everyone needs to be considered during review.
== Implementation details ==
Created ViewBugMessage, ViewProductRelease, and ViewBugSubscription in security.py with checkUnauthorized and checkAuthorized both returning True.
== Tests ==
% bin/test -vvct webservice/ xx-bug. txt
% bin/test -vvct xx-project-registry
== Demo and Q/A ==
>>> from launchpadlib. launchpad import Launchpad login(' test', '', '', 'https:/ /api.launchpad. dev/beta/ ') projects[ 'alsa-utils' ].series) /api.launchpad. dev/beta/ alsa-utils/ trunk>] bugs[1] .messages) /api.launchpad. dev/beta/ firefox/ +bug/1/ comments/ 0>, <message at https:/ /api.launchpad. dev/beta/ firefox/ +bug/1/ comments/ 1>] bugs[1] .subscriptions) /api.launchpad. dev/beta/ bugs/1/ +subscription/ stevea>, <bug_subscription at https:/ /api.launchpad. dev/beta/ bugs/1/ +subscription/ name12>]
>>> launchpad = Launchpad.
>>> list(launchpad.
[<project_series at https:/
>>> list(launchpad.
[<message at https:/
>>> list(launchpad.
[<bug_subscription at https:/
== Launchpad lint ==
Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.
Linting changed files: /launchpad/ security. py /launchpad/ apidoc/ wadl-testrunner .xml bugs/stories/ webservice/ xx-bug. txt registry/ stories/ webservice/ xx-project- registry. txt
lib/canonical
lib/canonical
lib/lp/
lib/lp/