Merge lp:~jpds/launchpad/fix_517020 into lp:launchpad
- fix_517020
- Merge into devel
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Michael Nelson | ||||
Approved revision: | not available | ||||
Merged at revision: | 10283 | ||||
Proposed branch: | lp:~jpds/launchpad/fix_517020 | ||||
Merge into: | lp:launchpad | ||||
Diff against target: |
247 lines (+113/-20) 3 files modified
lib/lp/registry/interfaces/distributionmirror.py (+22/-16) lib/lp/registry/stories/webservice/xx-distribution-mirror.txt (+88/-3) lib/lp/registry/stories/webservice/xx-distribution.txt (+3/-1) |
||||
To merge this branch: | bzr merge lp:~jpds/launchpad/fix_517020 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brad Crittenden (community) | code | Approve | |
Michael Nelson (community) | code | Approve | |
Review via email: mp+18608@code.launchpad.net |
Commit message
Various fixes to exported() values in the newly exposed distribution_
Description of the change
Jonathan Davies (jpds) wrote : | # |
Michael Nelson (michael.nelson) wrote : | # |
Hi Jonathan,
It's great that you're so quick to get in there and fix his. Other than some formatting issues, the only point that I think needs addressing here is testing the writable of the fields you're changing/exporting.
> === modified file 'lib/lp/
> --- a/lib/lp/
> +++ b/lib/lp/
> @@ -287,17 +287,19 @@
>
> id = Int(title=_('The unique id'), required=True, readonly=True)
> owner = exported(
> - title=_('Owner'), required=False, readonly=True,
> - vocabulary=
> - reviewer = PublicPersonChoice(
> - title=_
> - vocabulary=
> + title=_('Owner'), description=_("The person who is set as the "
> + "current administrator of this mirror."), required=True,
> + readonly=False, vocabulary=
So the owner attribute is no-longer readonly? If that's intentional, we really
should have that tested/documented (ie. who can/can't write to it).
Also, just a few small indentation things looking at
the style guide. It might be easier to format this like:
title=
"The person who is set as the current administrator of this mirror."),
required=True, readonly=False, vocabulary=
or
title=
description=_(
"The person who is set as the current administrator of this mirror."))
> + reviewer = exported(
> + title=_
> + "mirror."), required=False, readonly=True,
> + vocabulary=
So the main change is that readonly is now true. Please ensure this is tested
also.
Similar formatting issues here. Although, I can't see anything in the
style-guide, but I thought that concatenated strings needed to be aligned (if
you have to break them).
> distribution = exported(
> Reference(
> Interface,
> # Really IDistribution, circular import fixed in
> # _schema_
> - title=_
> + title=_
Again, this needs to be tested (so it doesn't happen again).
> description=_("The distribution that is mirrored")))
> name = exported(
> title=_('Name'), required=True, readonly=False,
> @@ -325,7 +327,7 @@
> description=
> enabled = exported(Bool(
> title=_('This mirror was probed successfully.'),
> - required=False, readonly=False, default=False))
> + required=False, readonly=True, default=False))
And here too.
> speed = exported(Choice(
> title=_('Link Speed'), required=True, readonly=False,
> vocabulary=
> @@ -343,7 +345,8 @@
> title=_('Apply to...
Jonathan Davies (jpds) wrote : | # |
> === modified file 'lib/lp/
> > --- a/lib/lp/
> > +++ b/lib/lp/
> > @@ -287,17 +287,19 @@
> >
> > id = Int(title=_('The unique id'), required=True, readonly=True)
> > owner = exported(
> > - title=_('Owner'), required=False, readonly=True,
> > - vocabulary=
> > - reviewer = PublicPersonChoice(
> > - title=_
> > - vocabulary=
> > + title=_('Owner'), description=_("The person who is set as the "
> > + "current administrator of this mirror."), required=True,
> > + readonly=False, vocabulary=
>
> So the owner attribute is no-longer readonly? If that's intentional, we really
> should have that tested/documented (ie. who can/can't write to it).
This is now tested in registry/
> Also, just a few small indentation things looking at
> the style guide. It might be easier to format this like:
>
> title=_('Owner'), description=_(
> "The person who is set as the current administrator of this mirror."),
> required=True, readonly=False, vocabulary=
>
> or
>
> title=_('Owner'), required=True, readonly=False, vocabulary=
> description=_(
> "The person who is set as the current administrator of this mirror."))
I've changed all the fields to the latter.
> > + reviewer = exported(
> > + title=_
> > + "mirror."), required=False, readonly=True,
> > + vocabulary=
>
> So the main change is that readonly is now true. Please ensure this is tested
> also.
Also done.
> Similar formatting issues here. Although, I can't see anything in the
> style-guide, but I thought that concatenated strings needed to be aligned (if
> you have to break them).
>
> > distribution = exported(
> > Reference(
> > Interface,
> > # Really IDistribution, circular import fixed in
> > # _schema_
> > - title=_
> > + title=_
>
> Again, this needs to be tested (so it doesn't happen again).
This is now tested.
> > description=_("The distribution that is mirrored")))
> > name = exported(
> > title=_('Name'), required=True, readonly=False,
> > @@ -325,7 +327,7 @@
> > description=
> > enabled = exported(Bool(
> > title=_('This mirror was probed successfully.'),
> > - required=False, readonly=False, default=False))
> > + required=False, readonly=True, default=False))
>
> And here too.
Likewise.
> > speed = exported(Choice(
> > title=_('Link Speed'), required=True, readonly=False,
> > vocabul...
Michael Nelson (michael.nelson) wrote : | # |
Thanks for the changes Jonathan. I've approved the review, but do have a couple of things below that I'm interested to hear back on (they could be just oversights on my part).
> Done and full diff since r10278:
> === modified file 'lib/lp/
> mirror.txt'
> --- lib/lp/
> 2010-02-04 12:22:19 +0000
> +++ lib/lp/
> 2010-02-05 11:32:41 +0000
> @@ -57,6 +57,88 @@
> status: u'Official'
> whiteboard: None
>
> += Security checks =
> +
> +People who are not mirror listing admins or the mirrors registrar may not
> +change the owner's of mirrors:
> +
> + >>> from canonical.
> + >>> from canonical.
> + >>> from zope.component import getUtility
> + >>> from lp.registry.
> + >>> from simplejson import dumps
> + >>> login(ANONYMOUS)
> + >>> karl_db = getUtility(
> + >>> test_db = getUtility(
> + >>> karl_webservice = webservice_
> + ... permission=
> + >>> test_webservice = webservice_
> + ... permission=
> + >>> logout()
> + >>> karl = webservice.
> + >>> patch = {
> + ... u'owner_link': karl['self_link']
> + ... }
> +
> +Now trying to set the owner using Sample Person's webservice is not
> authorized.
> +
> + >>> response = test_webservice
> + ... canonical_
> + >>> print response.
> + 401 Unauthorized
> +
> +But if we use Karl, the mirror listing admin's, webservice, we can update the
s/admin's,/admin's
> owner.
> +
> + >>> response = karl_webservice
> + ... canonical_
> + >>> print response.
> + 209 Content Returned
> +
> + >>> patched_
> + >>> print patched_
> + http://
> +
> +Some attributes are read-only via the API:
> +
> + >>> distros = webservice.
> + >>> distro = distros[
> + >>> debian = webservice.
I haven't checked, but is the above line necessary? you're getting distro['self_link'] which should be equivalent to distro? (ie. distro == debian?). Actually, you only seem to use debian['self_link'] below anyway (which should be equivalent to distro['self_link'] unless I'm missing something).
> + >>> patch = {
> + ... u'date_reviewed' : u'2010-
> + ... u'distribution_
> + ... u'enabled' : False,
> + ... u'reviewer_link' : karl['self_link']
> + ... }
> + >>> response = karl_webservice
> + ... canonical_
> dum...
Jonathan Davies (jpds) wrote : | # |
The branch failed a test on distribution.txt, as I was just testing distribution-
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -124,18 +124,20 @@
>>> pprint_
content: u'CD Image'
date_created: u'2006-
+ date_reviewed: None
description: None
displayname: None
distributi
enabled: True
ftp_base_url: None
- has_ftp_
http_base_url: u'http://
name: u'canonical-
official_
owner_link: u'http://
+ reviewer_link: None
resource_
rsync_
self_link: u'http://
speed: u'100 Mbps'
status: u'Official'
+ whiteboard: None
Jonathan Davies (jpds) wrote : | # |
>> >>> is_official_mirror =
>> webservice.
>> ... 'isOfficial'
>> >>> print is_official_mirror
>> - True
>> + False
>
> I can't see anything that should have changed the expected value of this test? Why did it
> change here?
For the record:
<noodles> Also, I can't see why the expected value of is_official_mirror changed at the end of your diff?
<jpds> 13:47:01 <jpds> is_o_m> IT changes because I patch it with: u'status' : 'Unofficial'
Brad Crittenden (bac) wrote : | # |
Your additional test changes look good. Thanks.
Preview Diff
1 | === modified file 'lib/lp/registry/interfaces/distributionmirror.py' |
2 | --- lib/lp/registry/interfaces/distributionmirror.py 2010-02-01 23:17:27 +0000 |
3 | +++ lib/lp/registry/interfaces/distributionmirror.py 2010-02-05 18:56:19 +0000 |
4 | @@ -287,17 +287,19 @@ |
5 | |
6 | id = Int(title=_('The unique id'), required=True, readonly=True) |
7 | owner = exported(PublicPersonChoice( |
8 | - title=_('Owner'), required=False, readonly=True, |
9 | - vocabulary='ValidOwner')) |
10 | - reviewer = PublicPersonChoice( |
11 | - title=_('Reviewer'), required=False, readonly=False, |
12 | - vocabulary='ValidPersonOrTeam') |
13 | + title=_('Owner'), readonly=False, vocabulary='ValidOwner', |
14 | + required=True, description=_( |
15 | + "The person who is set as the current administrator of this mirror."))) |
16 | + reviewer = exported(PublicPersonChoice( |
17 | + title=_('Reviewer'), required=False, readonly=True, |
18 | + vocabulary='ValidPersonOrTeam', description=_( |
19 | + "The person who last reviewed this mirror."))) |
20 | distribution = exported( |
21 | Reference( |
22 | Interface, |
23 | # Really IDistribution, circular import fixed in |
24 | # _schema_circular_imports. |
25 | - title=_("Distribution"), required=True, |
26 | + title=_("Distribution"), required=True, readonly=True, |
27 | description=_("The distribution that is mirrored"))) |
28 | name = exported(DistributionMirrorNameField( |
29 | title=_('Name'), required=True, readonly=False, |
30 | @@ -325,7 +327,7 @@ |
31 | description=_('e.g.: rsync://archive.ubuntu.com/ubuntu/'))) |
32 | enabled = exported(Bool( |
33 | title=_('This mirror was probed successfully.'), |
34 | - required=False, readonly=False, default=False)) |
35 | + required=False, readonly=True, default=False)) |
36 | speed = exported(Choice( |
37 | title=_('Link Speed'), required=True, readonly=False, |
38 | vocabulary=MirrorSpeed)) |
39 | @@ -344,7 +346,8 @@ |
40 | required=False, readonly=False, default=True)) |
41 | status = exported(Choice( |
42 | title=_('Status'), required=True, readonly=False, |
43 | - vocabulary=MirrorStatus)) |
44 | + vocabulary=MirrorStatus, |
45 | + description=_("The current status of a mirror's registration."))) |
46 | |
47 | title = Attribute('The title of this mirror') |
48 | cdimage_series = Attribute( |
49 | @@ -355,17 +358,20 @@ |
50 | last_probe_record = Attribute( |
51 | 'The last MirrorProbeRecord for this mirror.') |
52 | all_probe_records = Attribute('All MirrorProbeRecords for this mirror.') |
53 | - has_ftp_or_rsync_base_url = exported(Bool( |
54 | - title=_('Does this mirror have a ftp or rsync base URL?'))) |
55 | + has_ftp_or_rsync_base_url = Bool( |
56 | + title=_('Does this mirror have a FTP or Rsync base URL?')) |
57 | base_url = Attribute('The HTTP or FTP base URL of this mirror') |
58 | date_created = exported(Datetime( |
59 | - title=_('Date Created'), required=True, readonly=True)) |
60 | - date_reviewed = Datetime( |
61 | - title=_('Date reviewed'), required=False, readonly=False) |
62 | - whiteboard = Whiteboard( |
63 | - title=_('Whiteboard'), required=False, |
64 | + title=_('Date Created'), required=True, readonly=True, |
65 | + description=_("The date on which this mirror was registered."))) |
66 | + date_reviewed = exported(Datetime( |
67 | + title=_('Date reviewed'), required=False, readonly=True, |
68 | + description=_( |
69 | + "The date on which this mirror was last reviewed by a mirror admin."))) |
70 | + whiteboard = exported(Whiteboard( |
71 | + title=_('Whiteboard'), required=False, readonly=False, |
72 | description=_("Notes on the current status of the mirror (only " |
73 | - "visible to admins and the mirror's registrant).")) |
74 | + "visible to admins and the mirror's registrant)."))) |
75 | |
76 | @invariant |
77 | def mirrorMustHaveHTTPOrFTPURL(mirror): |
78 | |
79 | === modified file 'lib/lp/registry/stories/webservice/xx-distribution-mirror.txt' |
80 | --- lib/lp/registry/stories/webservice/xx-distribution-mirror.txt 2010-02-01 23:17:27 +0000 |
81 | +++ lib/lp/registry/stories/webservice/xx-distribution-mirror.txt 2010-02-05 18:56:19 +0000 |
82 | @@ -13,21 +13,23 @@ |
83 | >>> pprint_entry(canonical_archive_json) |
84 | content: u'Archive' |
85 | date_created: u'2006-10-16T18:31:43.434567+00:00' |
86 | + date_reviewed: None |
87 | description: None |
88 | displayname: None |
89 | distribution_link: u'http://.../ubuntu' |
90 | enabled: True |
91 | ftp_base_url: None |
92 | - has_ftp_or_rsync_base_url: False |
93 | http_base_url: u'http://archive.ubuntu.com/ubuntu/' |
94 | name: u'canonical-archive' |
95 | official_candidate: True |
96 | owner_link: u'http://.../~mark' |
97 | resource_type_link: u'http://.../#distribution_mirror' |
98 | + reviewer_link: None |
99 | rsync_base_url: None |
100 | self_link: u'http://.../ubuntu/+mirror/canonical-archive' |
101 | speed: u'100 Mbps' |
102 | status: u'Official' |
103 | + whiteboard: None |
104 | |
105 | And CD image mirrors: |
106 | |
107 | @@ -37,21 +39,104 @@ |
108 | >>> pprint_entry(canonical_releases_json) |
109 | content: u'CD Image' |
110 | date_created: u'2006-10-16T18:31:43.434567+00:00' |
111 | + date_reviewed: None |
112 | description: None |
113 | displayname: None |
114 | distribution_link: u'http://.../ubuntu' |
115 | enabled: True |
116 | ftp_base_url: None |
117 | - has_ftp_or_rsync_base_url: False |
118 | http_base_url: u'http://releases.ubuntu.com/' |
119 | name: u'canonical-releases' |
120 | official_candidate: True |
121 | owner_link: u'http://.../~mark' |
122 | resource_type_link: u'http://.../#distribution_mirror' |
123 | + reviewer_link: None |
124 | rsync_base_url: None |
125 | self_link: u'http://.../ubuntu/+mirror/canonical-releases' |
126 | speed: u'100 Mbps' |
127 | status: u'Official' |
128 | + whiteboard: None |
129 | + |
130 | += Security checks = |
131 | + |
132 | +People who are not mirror listing admins or the mirrors registrar may not |
133 | +change the owner's of mirrors: |
134 | + |
135 | + >>> from canonical.launchpad.testing.pages import webservice_for_person |
136 | + >>> from canonical.launchpad.webapp.interfaces import OAuthPermission |
137 | + >>> from zope.component import getUtility |
138 | + >>> from lp.registry.interfaces.person import IPersonSet |
139 | + >>> from simplejson import dumps |
140 | + >>> login(ANONYMOUS) |
141 | + >>> karl_db = getUtility(IPersonSet).getByName('karl') |
142 | + >>> test_db = getUtility(IPersonSet).getByName('name12') |
143 | + >>> karl_webservice = webservice_for_person(karl_db, |
144 | + ... permission=OAuthPermission.WRITE_PUBLIC) |
145 | + >>> test_webservice = webservice_for_person(test_db, |
146 | + ... permission=OAuthPermission.WRITE_PUBLIC) |
147 | + >>> logout() |
148 | + >>> karl = webservice.get("/~karl").jsonBody() |
149 | + >>> patch = { |
150 | + ... u'owner_link': karl['self_link'] |
151 | + ... } |
152 | + |
153 | +Now trying to set the owner using Sample Person's webservice is not authorized. |
154 | + |
155 | + >>> response = test_webservice.patch( |
156 | + ... canonical_archive['self_link'], 'application/json', dumps(patch)) |
157 | + >>> print response.getheader('status') |
158 | + 401 Unauthorized |
159 | + |
160 | +But if we use Karl, the mirror listing admin's, webservice, we can update the owner. |
161 | + |
162 | + >>> response = karl_webservice.patch( |
163 | + ... canonical_archive['self_link'], 'application/json', dumps(patch)) |
164 | + >>> print response.getheader('status') |
165 | + 209 Content Returned |
166 | + |
167 | + >>> patched_canonical_archive = response.jsonBody() |
168 | + >>> print patched_canonical_archive['owner_link'] |
169 | + http://.../~karl |
170 | + |
171 | +Some attributes are read-only via the API: |
172 | + |
173 | + >>> distros = webservice.get("/distros").jsonBody() |
174 | + >>> debian_distro = distros['entries'][3] |
175 | + >>> patch = { |
176 | + ... u'date_reviewed' : u'2010-02-04T17:19:16.424198+00:00', |
177 | + ... u'distribution_link' : debian_distro['self_link'], |
178 | + ... u'enabled' : False, |
179 | + ... u'reviewer_link' : karl['self_link'] |
180 | + ... } |
181 | + >>> response = karl_webservice.patch( |
182 | + ... canonical_releases['self_link'], 'application/json', dumps(patch)) |
183 | + >>> print response |
184 | + HTTP/1.1 400 Bad Request |
185 | + Status: 400 Bad Request |
186 | + ... |
187 | + enabled: You tried to modify a read-only attribute. |
188 | + date_reviewed: You tried to modify a read-only attribute. |
189 | + reviewer_link: You tried to modify a read-only attribute. |
190 | + distribution_link: You tried to modify a read-only attribute. |
191 | + |
192 | +While others can be set with the appropriate authorization: |
193 | + |
194 | + >>> patch = { |
195 | + ... u'status' : 'Unofficial', |
196 | + ... u'whiteboard' : u'This mirror is too shiny to be true' |
197 | + ... } |
198 | + >>> response = test_webservice.patch( |
199 | + ... canonical_releases['self_link'], 'application/json', dumps(patch)) |
200 | + >>> print response.getheader('status') |
201 | + 401 Unauthorized |
202 | + |
203 | + >>> response = karl_webservice.patch( |
204 | + ... canonical_releases['self_link'], 'application/json', dumps(patch)).jsonBody() |
205 | + >>> pprint_entry(response) |
206 | + content: u'CD Image' |
207 | + ... |
208 | + status: u'Unofficial' |
209 | + whiteboard: u'This mirror is too shiny to be true' |
210 | |
211 | = Distribution Mirror Custom Operations = |
212 | |
213 | @@ -63,7 +148,7 @@ |
214 | >>> is_official_mirror = webservice.named_get(canonical_releases['self_link'], |
215 | ... 'isOfficial').jsonBody() |
216 | >>> print is_official_mirror |
217 | - True |
218 | + False |
219 | |
220 | "getOverallFreshness" returns the freshness of the mirror determined by the |
221 | mirror prober from the mirror's last probe. |
222 | |
223 | === modified file 'lib/lp/registry/stories/webservice/xx-distribution.txt' |
224 | --- lib/lp/registry/stories/webservice/xx-distribution.txt 2010-02-01 23:17:27 +0000 |
225 | +++ lib/lp/registry/stories/webservice/xx-distribution.txt 2010-02-05 18:56:19 +0000 |
226 | @@ -124,18 +124,20 @@ |
227 | >>> pprint_entry(canonical_releases) |
228 | content: u'CD Image' |
229 | date_created: u'2006-10-16T18:31:43.434567+00:00' |
230 | + date_reviewed: None |
231 | description: None |
232 | displayname: None |
233 | distribution_link: u'http://.../ubuntu' |
234 | enabled: True |
235 | ftp_base_url: None |
236 | - has_ftp_or_rsync_base_url: False |
237 | http_base_url: u'http://releases.ubuntu.com/' |
238 | name: u'canonical-releases' |
239 | official_candidate: True |
240 | owner_link: u'http://.../~mark' |
241 | resource_type_link: u'http://.../#distribution_mirror' |
242 | + reviewer_link: None |
243 | rsync_base_url: None |
244 | self_link: u'http://.../ubuntu/+mirror/canonical-releases' |
245 | speed: u'100 Mbps' |
246 | status: u'Official' |
247 | + whiteboard: None |
= Summary =
This branch fixes various problems with the newly exposed distribution_ mirror' s as described in bug #517020.
It also exposes various other things whose permissions to access are restricted by Zope's configuration.