Merge lp:~sinzui/launchpad/location-bug-262193 into lp:launchpad
- location-bug-262193
- Merge into devel
Proposed by
Curtis Hovey
Status: | Merged |
---|---|
Approved by: | Eleanor Berger |
Approved revision: | not available |
Merged at revision: | not available |
Proposed branch: | lp:~sinzui/launchpad/location-bug-262193 |
Merge into: | lp:launchpad |
Diff against target: |
459 lines (+57/-212) 10 files modified
lib/canonical/launchpad/emailtemplates/person-location-modified.txt (+0/-19) lib/canonical/launchpad/permissions.zcml (+0/-4) lib/canonical/launchpad/security.py (+0/-32) lib/lp/registry/browser/configure.zcml (+1/-1) lib/lp/registry/browser/person.py (+2/-14) lib/lp/registry/configure.zcml (+1/-1) lib/lp/registry/doc/personlocation.txt (+15/-53) lib/lp/registry/model/person.py (+0/-14) lib/lp/registry/stories/location/personlocation-edit.txt (+27/-59) lib/lp/registry/stories/location/personlocation.txt (+11/-15) |
To merge this branch: | bzr merge lp:~sinzui/launchpad/location-bug-262193 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Eleanor Berger (community) | code | Approve | |
Review via email: mp+14878@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote : | # |
Revision history for this message
Eleanor Berger (intellectronica) wrote : | # |
simplicity rocks!
review:
Approve
(code)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === removed file 'lib/canonical/launchpad/emailtemplates/person-location-modified.txt' | |||
2 | --- lib/canonical/launchpad/emailtemplates/person-location-modified.txt 2008-06-18 13:06:54 +0000 | |||
3 | +++ lib/canonical/launchpad/emailtemplates/person-location-modified.txt 1970-01-01 00:00:00 +0000 | |||
4 | @@ -1,19 +0,0 @@ | |||
5 | 1 | |||
6 | 2 | %(actor_browsername)s has updated your location and time zone information in | ||
7 | 3 | Launchpad. This lets us present dates and times in your local time, and | ||
8 | 4 | helps to coordinate team events that will span multiple time zones. | ||
9 | 5 | |||
10 | 6 | Your information can be updated by any other user until you provide | ||
11 | 7 | definitive data yourself, at which point the information is locked | ||
12 | 8 | so that only you can edit it. | ||
13 | 9 | |||
14 | 10 | Your details (now with map!): https://launchpad.net/~%(person)s | ||
15 | 11 | %(actor_browsername)s's details: https://launchpad.net/~%(actor)s | ||
16 | 12 | |||
17 | 13 | You can edit the location and time zone information for yourself at: | ||
18 | 14 | |||
19 | 15 | https://launchpad.net/~%(person)s/+editlocation | ||
20 | 16 | |||
21 | 17 | Regards, | ||
22 | 18 | |||
23 | 19 | The Launchpad team | ||
24 | 20 | 0 | ||
25 | === modified file 'lib/canonical/launchpad/permissions.zcml' | |||
26 | --- lib/canonical/launchpad/permissions.zcml 2009-08-13 15:12:16 +0000 | |||
27 | +++ lib/canonical/launchpad/permissions.zcml 2009-11-15 01:25:23 +0000 | |||
28 | @@ -16,10 +16,6 @@ | |||
29 | 16 | <permission | 16 | <permission |
30 | 17 | id="launchpad.Edit" title="Editing something" access_level="write" /> | 17 | id="launchpad.Edit" title="Editing something" access_level="write" /> |
31 | 18 | 18 | ||
32 | 19 | <permission | ||
33 | 20 | id="launchpad.EditLocation" title="Editing an object's location" | ||
34 | 21 | access_level="write" /> | ||
35 | 22 | |||
36 | 23 | <!-- Request large downloads, or other heavyweight jobs that are not | 19 | <!-- Request large downloads, or other heavyweight jobs that are not |
37 | 24 | semantically like "editing" and are not restricted to administrators. | 20 | semantically like "editing" and are not restricted to administrators. |
38 | 25 | --> | 21 | --> |
39 | 26 | 22 | ||
40 | === modified file 'lib/canonical/launchpad/security.py' | |||
41 | --- lib/canonical/launchpad/security.py 2009-11-13 05:13:07 +0000 | |||
42 | +++ lib/canonical/launchpad/security.py 2009-11-15 01:25:23 +0000 | |||
43 | @@ -624,38 +624,6 @@ | |||
44 | 624 | return person == user or user.inTeam(admins) | 624 | return person == user or user.inTeam(admins) |
45 | 625 | 625 | ||
46 | 626 | 626 | ||
47 | 627 | class EditPersonLocation(AuthorizationBase): | ||
48 | 628 | permission = 'launchpad.EditLocation' | ||
49 | 629 | usedfor = IPerson | ||
50 | 630 | |||
51 | 631 | def checkAuthenticated(self, user): | ||
52 | 632 | """Anybody can edit a person's location until that person sets it. | ||
53 | 633 | |||
54 | 634 | Once a person sets his own location that information can only be | ||
55 | 635 | changed by the person himself or admins. | ||
56 | 636 | """ | ||
57 | 637 | location = self.obj.location | ||
58 | 638 | if location is None: | ||
59 | 639 | # No PersonLocation entry exists for this person, so anybody can | ||
60 | 640 | # change this person's location. | ||
61 | 641 | return True | ||
62 | 642 | |||
63 | 643 | # There is a PersonLocation entry for this person, so we'll check its | ||
64 | 644 | # details to find out whether or not the user can edit them. | ||
65 | 645 | if (location.visible | ||
66 | 646 | and (location.latitude is None | ||
67 | 647 | or location.last_modified_by != self.obj)): | ||
68 | 648 | # No location has been specified yet or it has been specified | ||
69 | 649 | # by a non-authoritative source (not the person himself), so | ||
70 | 650 | # anybody can change it. | ||
71 | 651 | return True | ||
72 | 652 | else: | ||
73 | 653 | admins = getUtility(ILaunchpadCelebrities).admin | ||
74 | 654 | # The person himself and LP admins can always change that person's | ||
75 | 655 | # location. | ||
76 | 656 | return user == self.obj or user.inTeam(admins) | ||
77 | 657 | |||
78 | 658 | |||
79 | 659 | class ViewPersonLocation(AuthorizationBase): | 627 | class ViewPersonLocation(AuthorizationBase): |
80 | 660 | permission = 'launchpad.View' | 628 | permission = 'launchpad.View' |
81 | 661 | usedfor = IPersonLocation | 629 | usedfor = IPersonLocation |
82 | 662 | 630 | ||
83 | === modified file 'lib/lp/registry/browser/configure.zcml' | |||
84 | --- lib/lp/registry/browser/configure.zcml 2009-11-11 10:30:23 +0000 | |||
85 | +++ lib/lp/registry/browser/configure.zcml 2009-11-15 01:25:23 +0000 | |||
86 | @@ -830,7 +830,7 @@ | |||
87 | 830 | name="+editlocation" | 830 | name="+editlocation" |
88 | 831 | for="lp.registry.interfaces.person.IPerson" | 831 | for="lp.registry.interfaces.person.IPerson" |
89 | 832 | class="lp.registry.browser.person.PersonEditLocationView" | 832 | class="lp.registry.browser.person.PersonEditLocationView" |
91 | 833 | permission="launchpad.EditLocation" | 833 | permission="launchpad.Edit" |
92 | 834 | template="../templates/person-editlocation.pt"/> | 834 | template="../templates/person-editlocation.pt"/> |
93 | 835 | <browser:page | 835 | <browser:page |
94 | 836 | name="+contactuser" | 836 | name="+contactuser" |
95 | 837 | 837 | ||
96 | === modified file 'lib/lp/registry/browser/person.py' | |||
97 | --- lib/lp/registry/browser/person.py 2009-11-09 04:24:09 +0000 | |||
98 | +++ lib/lp/registry/browser/person.py 2009-11-15 01:25:23 +0000 | |||
99 | @@ -954,7 +954,7 @@ | |||
100 | 954 | text = 'Update Jabber IDs' | 954 | text = 'Update Jabber IDs' |
101 | 955 | return Link(target, text, icon='edit') | 955 | return Link(target, text, icon='edit') |
102 | 956 | 956 | ||
104 | 957 | @enabled_with_permission('launchpad.EditLocation') | 957 | @enabled_with_permission('launchpad.Edit') |
105 | 958 | def editlocation(self): | 958 | def editlocation(self): |
106 | 959 | target = '+editlocation' | 959 | target = '+editlocation' |
107 | 960 | text = 'Set location and time zone' | 960 | text = 'Set location and time zone' |
108 | @@ -5333,6 +5333,7 @@ | |||
109 | 5333 | """Edit a person's location.""" | 5333 | """Edit a person's location.""" |
110 | 5334 | 5334 | ||
111 | 5335 | schema = PersonLocationForm | 5335 | schema = PersonLocationForm |
112 | 5336 | field_names = ['location', 'hide'] | ||
113 | 5336 | custom_widget('location', LocationWidget) | 5337 | custom_widget('location', LocationWidget) |
114 | 5337 | 5338 | ||
115 | 5338 | @property | 5339 | @property |
116 | @@ -5343,19 +5344,6 @@ | |||
117 | 5343 | label = page_title | 5344 | label = page_title |
118 | 5344 | 5345 | ||
119 | 5345 | @property | 5346 | @property |
120 | 5346 | def field_names(self): | ||
121 | 5347 | """See `LaunchpadFormView`. | ||
122 | 5348 | |||
123 | 5349 | If the user has launchpad.Edit on this context, then allow him to set | ||
124 | 5350 | whether or not the location should be visible. The field for setting | ||
125 | 5351 | the person's location is always shown. | ||
126 | 5352 | """ | ||
127 | 5353 | if check_permission('launchpad.Edit', self.context): | ||
128 | 5354 | return ['location', 'hide'] | ||
129 | 5355 | else: | ||
130 | 5356 | return ['location'] | ||
131 | 5357 | |||
132 | 5358 | @property | ||
133 | 5359 | def initial_values(self): | 5347 | def initial_values(self): |
134 | 5360 | """See `LaunchpadFormView`. | 5348 | """See `LaunchpadFormView`. |
135 | 5361 | 5349 | ||
136 | 5362 | 5350 | ||
137 | === modified file 'lib/lp/registry/configure.zcml' | |||
138 | --- lib/lp/registry/configure.zcml 2009-11-12 12:01:22 +0000 | |||
139 | +++ lib/lp/registry/configure.zcml 2009-11-15 01:25:23 +0000 | |||
140 | @@ -805,7 +805,7 @@ | |||
141 | 805 | permission="launchpad.View" | 805 | permission="launchpad.View" |
142 | 806 | interface="lp.registry.interfaces.person.IPersonViewRestricted"/> | 806 | interface="lp.registry.interfaces.person.IPersonViewRestricted"/> |
143 | 807 | <require | 807 | <require |
145 | 808 | permission="launchpad.EditLocation" | 808 | permission="launchpad.Edit" |
146 | 809 | interface="lp.registry.interfaces.location.ISetLocation"/> | 809 | interface="lp.registry.interfaces.location.ISetLocation"/> |
147 | 810 | <require | 810 | <require |
148 | 811 | permission="launchpad.Edit" | 811 | permission="launchpad.Edit" |
149 | 812 | 812 | ||
150 | === modified file 'lib/lp/registry/doc/personlocation.txt' | |||
151 | --- lib/lp/registry/doc/personlocation.txt 2009-04-17 10:32:16 +0000 | |||
152 | +++ lib/lp/registry/doc/personlocation.txt 2009-11-15 01:25:23 +0000 | |||
153 | @@ -38,53 +38,22 @@ | |||
154 | 38 | requires that the user providing the information is passed as a | 38 | requires that the user providing the information is passed as a |
155 | 39 | parameter. | 39 | parameter. |
156 | 40 | 40 | ||
159 | 41 | We'll use jdub as a prolific source of location information for | 41 | A user cannot set another user's location. |
158 | 42 | community members. | ||
160 | 43 | 42 | ||
161 | 44 | >>> jdub = personset.getByName('jdub') | 43 | >>> jdub = personset.getByName('jdub') |
162 | 45 | >>> login_person(jdub) | 44 | >>> login_person(jdub) |
163 | 46 | |||
164 | 47 | First, jdub will provide information about cprov, who doesn't have any | ||
165 | 48 | location data in the sampledata. | ||
166 | 49 | |||
167 | 50 | >>> cprov = personset.getByName('cprov') | 45 | >>> cprov = personset.getByName('cprov') |
168 | 51 | >>> print cprov.latitude | ||
169 | 52 | None | ||
170 | 53 | >>> print cprov.time_zone | ||
171 | 54 | None | ||
172 | 55 | >>> cprov.setLocation(-43.0, -62.1, 'America/Sao_Paulo', jdub) | 46 | >>> cprov.setLocation(-43.0, -62.1, 'America/Sao_Paulo', jdub) |
189 | 56 | >>> print cprov.time_zone | 47 | Traceback (most recent call last): |
190 | 57 | America/Sao_Paulo | 48 | ... |
191 | 58 | 49 | Unauthorized:... | |
192 | 59 | When a person's location is changed by somebody else, we notify the | 50 | |
193 | 60 | person through email. | 51 | A user can set his own location. |
178 | 61 | |||
179 | 62 | >>> from canonical.launchpad.database import PersonNotification | ||
180 | 63 | >>> notification = PersonNotification.selectOneBy(person=cprov) | ||
181 | 64 | >>> print notification.subject | ||
182 | 65 | Jeff Waugh updated your location and time zone | ||
183 | 66 | |||
184 | 67 | # Delete the notification so that it doesn't interfere in other tests. | ||
185 | 68 | >>> notification.destroySelf() | ||
186 | 69 | |||
187 | 70 | And once cprov provides data for himself, jdub won't be able to edit it | ||
188 | 71 | any more. | ||
194 | 72 | 52 | ||
195 | 73 | >>> login_person(cprov) | 53 | >>> login_person(cprov) |
196 | 74 | >>> cprov.setLocation(-43.2, -61.93, 'America/Sao_Paulo', cprov) | 54 | >>> cprov.setLocation(-43.2, -61.93, 'America/Sao_Paulo', cprov) |
197 | 75 | 55 | ||
210 | 76 | >>> login_person(jdub) | 56 | cprov can change his location information. We need to deal |
199 | 77 | >>> cprov.setLocation(-43.0, -62.1, 'America/Sao_Paulo', jdub) | ||
200 | 78 | Traceback (most recent call last): | ||
201 | 79 | ... | ||
202 | 80 | Unauthorized:... | ||
203 | 81 | |||
204 | 82 | When a user changes his own location, no notification is sent, though. | ||
205 | 83 | |||
206 | 84 | >>> PersonNotification.selectBy(person=cprov).count() | ||
207 | 85 | 0 | ||
208 | 86 | |||
209 | 87 | But cprov can obviously still edit his own information. We need to deal | ||
211 | 88 | with some floating point precision issues here, hence the rounding. | 57 | with some floating point precision issues here, hence the rounding. |
212 | 89 | 58 | ||
213 | 90 | >>> login_person(cprov) | 59 | >>> login_person(cprov) |
214 | @@ -92,7 +61,7 @@ | |||
215 | 92 | >>> abs(cprov.latitude + 43.52) < 0.001 | 61 | >>> abs(cprov.latitude + 43.52) < 0.001 |
216 | 93 | True | 62 | True |
217 | 94 | 63 | ||
219 | 95 | And admins can, too. | 64 | Admins can set a user's location. |
220 | 96 | 65 | ||
221 | 97 | >>> admin = personset.getByName('name16') | 66 | >>> admin = personset.getByName('name16') |
222 | 98 | >>> login_person(admin) | 67 | >>> login_person(admin) |
223 | @@ -100,20 +69,6 @@ | |||
224 | 100 | >>> abs(cprov.longitude + 62.1) < 0.001 | 69 | >>> abs(cprov.longitude + 62.1) < 0.001 |
225 | 101 | True | 70 | True |
226 | 102 | 71 | ||
227 | 103 | If a user had provided only his time zone but not his location, other | ||
228 | 104 | people would still be able to set his location. That's the case of | ||
229 | 105 | most our existing users, who set their time zone but hadn't set their | ||
230 | 106 | locations (since there was no UI for that). | ||
231 | 107 | |||
232 | 108 | >>> salgado = personset.getByName('salgado') | ||
233 | 109 | >>> login_person(salgado) | ||
234 | 110 | >>> salgado.setLocation(None, None, 'America/Sao_Paulo', salgado) | ||
235 | 111 | |||
236 | 112 | >>> login_person(jdub) | ||
237 | 113 | >>> salgado.setLocation(-43.0, -62.1, 'America/Sao_Paulo', jdub) | ||
238 | 114 | >>> print salgado.latitude | ||
239 | 115 | -43.0 | ||
240 | 116 | |||
241 | 117 | We cannot store a location for a team, though. | 72 | We cannot store a location for a team, though. |
242 | 118 | 73 | ||
243 | 119 | >>> guadamen = personset.getByName('guadamen') | 74 | >>> guadamen = personset.getByName('guadamen') |
244 | @@ -214,11 +169,18 @@ | |||
245 | 214 | we provide a way for them to hide their location from other users. By | 169 | we provide a way for them to hide their location from other users. By |
246 | 215 | default a person's location is visible. | 170 | default a person's location is visible. |
247 | 216 | 171 | ||
248 | 172 | >>> salgado = personset.getByName('salgado') | ||
249 | 173 | >>> login_person(salgado) | ||
250 | 174 | >>> salgado.setLocation(-43.0, -62.1, 'America/Sao_Paulo', salgado) | ||
251 | 217 | >>> salgado.location.visible | 175 | >>> salgado.location.visible |
252 | 218 | True | 176 | True |
253 | 219 | >>> salgado.location.latitude | 177 | >>> salgado.location.latitude |
254 | 220 | -43... | 178 | -43... |
255 | 221 | 179 | ||
256 | 180 | >>> login_person(jdub) | ||
257 | 181 | >>> salgado.location.latitude | ||
258 | 182 | -43... | ||
259 | 183 | |||
260 | 222 | But it can be changed through the setLocationVisibility() method. If the | 184 | But it can be changed through the setLocationVisibility() method. If the |
261 | 223 | visibility is set to False, only the person himself will be able to see | 185 | visibility is set to False, only the person himself will be able to see |
262 | 224 | the location data except for time zone. | 186 | the location data except for time zone. |
263 | 225 | 187 | ||
264 | === modified file 'lib/lp/registry/model/person.py' | |||
265 | --- lib/lp/registry/model/person.py 2009-11-12 20:55:43 +0000 | |||
266 | +++ lib/lp/registry/model/person.py 2009-11-15 01:25:23 +0000 | |||
267 | @@ -551,20 +551,6 @@ | |||
268 | 551 | person=self, time_zone=time_zone, latitude=latitude, | 551 | person=self, time_zone=time_zone, latitude=latitude, |
269 | 552 | longitude=longitude, last_modified_by=user) | 552 | longitude=longitude, last_modified_by=user) |
270 | 553 | 553 | ||
271 | 554 | # Make a note that we need to tell this person that their | ||
272 | 555 | # information was updated by the user. We can only do this if we | ||
273 | 556 | # have a validated email address for this person. | ||
274 | 557 | if user != self and self.preferredemail is not None: | ||
275 | 558 | mail_text = get_email_template('person-location-modified.txt') | ||
276 | 559 | mail_text = mail_text % { | ||
277 | 560 | 'actor': user.name, | ||
278 | 561 | 'actor_browsername': user.displayname, | ||
279 | 562 | 'person': self.name} | ||
280 | 563 | subject = '%s updated your location and time zone' % ( | ||
281 | 564 | user.displayname) | ||
282 | 565 | getUtility(IPersonNotificationSet).addNotification( | ||
283 | 566 | self, subject, mail_text) | ||
284 | 567 | |||
285 | 568 | # specification-related joins | 554 | # specification-related joins |
286 | 569 | @property | 555 | @property |
287 | 570 | def assigned_specs(self): | 556 | def assigned_specs(self): |
288 | 571 | 557 | ||
289 | === modified file 'lib/lp/registry/stories/location/personlocation-edit.txt' | |||
290 | --- lib/lp/registry/stories/location/personlocation-edit.txt 2009-03-24 12:43:49 +0000 | |||
291 | +++ lib/lp/registry/stories/location/personlocation-edit.txt 2009-11-15 01:25:23 +0000 | |||
292 | @@ -1,9 +1,7 @@ | |||
293 | 1 | == Edit person location information == | 1 | == Edit person location information == |
294 | 2 | 2 | ||
299 | 3 | The location information is editable by anybody (like a wiki), until the | 3 | A person's location is only editable by people who have launchpad.Edit on |
300 | 4 | person provides location data for themselves. At that point it is only | 4 | the person, which is that person and admins. |
297 | 5 | editable by people who have launchpad.Edit on the person, which is that | ||
298 | 6 | person and admins. | ||
301 | 7 | 5 | ||
302 | 8 | >>> login('test@canonical.com') | 6 | >>> login('test@canonical.com') |
303 | 9 | >>> zzz = factory.makePerson( | 7 | >>> zzz = factory.makePerson( |
304 | @@ -11,37 +9,15 @@ | |||
305 | 11 | ... latitude=None, longitude=None, password='test') | 9 | ... latitude=None, longitude=None, password='test') |
306 | 12 | >>> logout() | 10 | >>> logout() |
307 | 13 | 11 | ||
310 | 14 | Anybody logged in can see the Location widget for a person who has no | 12 | A user cannot set another user's location. |
309 | 15 | location set. | ||
311 | 16 | 13 | ||
312 | 17 | >>> nopriv_browser = setupBrowser(auth="Basic no-priv@canonical.com:test") | 14 | >>> nopriv_browser = setupBrowser(auth="Basic no-priv@canonical.com:test") |
313 | 18 | >>> nopriv_browser.open('http://launchpad.dev/~zzz/+editlocation') | 15 | >>> nopriv_browser.open('http://launchpad.dev/~zzz/+editlocation') |
340 | 19 | >>> find_tag_by_id(nopriv_browser.contents, "field.location.latitude") | 16 | Traceback (most recent call last): |
341 | 20 | <input...name="field.location.latitude" type="hidden"... | 17 | ... |
342 | 21 | 18 | Unauthorized:... | |
343 | 22 | Not only can we see the widgets, but anybody logged in can actually provide | 19 | |
344 | 23 | new location information. Here we need to provide the location and time | 20 | A user can set his own location: |
319 | 24 | zone, but when accessed through a real browser the page will use Javascript | ||
320 | 25 | to infer the time zone based on the location given. | ||
321 | 26 | |||
322 | 27 | >>> nopriv_browser.getControl(name='field.location.latitude').value = ( | ||
323 | 28 | ... '13.0') | ||
324 | 29 | >>> nopriv_browser.getControl(name='field.location.longitude').value = ( | ||
325 | 30 | ... '17.0') | ||
326 | 31 | >>> nopriv_browser.getControl(name='field.location.time_zone').value = [ | ||
327 | 32 | ... 'Europe/Madrid'] | ||
328 | 33 | >>> nopriv_browser.getControl('Update').click() | ||
329 | 34 | >>> login('test@canonical.com') | ||
330 | 35 | >>> zzz.latitude | ||
331 | 36 | 13.0 | ||
332 | 37 | >>> zzz.longitude | ||
333 | 38 | 17.0 | ||
334 | 39 | >>> zzz.time_zone | ||
335 | 40 | u'Europe/Madrid' | ||
336 | 41 | >>> logout() | ||
337 | 42 | |||
338 | 43 | If the person provides his own location information, then the data is | ||
339 | 44 | locked, and random people can no longer edit it. | ||
345 | 45 | 21 | ||
346 | 46 | >>> self_browser = setupBrowser(auth="Basic zzz@foo.com:test") | 22 | >>> self_browser = setupBrowser(auth="Basic zzz@foo.com:test") |
347 | 47 | >>> self_browser.open('http://launchpad.dev/~zzz/+editlocation') | 23 | >>> self_browser.open('http://launchpad.dev/~zzz/+editlocation') |
348 | @@ -53,12 +29,16 @@ | |||
349 | 53 | ... 'Europe/Madrid'] | 29 | ... 'Europe/Madrid'] |
350 | 54 | >>> self_browser.getControl('Update').click() | 30 | >>> self_browser.getControl('Update').click() |
351 | 55 | 31 | ||
356 | 56 | >>> nopriv_browser.open('http://launchpad.dev/~zzz/+editlocation') | 32 | >>> login('zzz@foo.com') |
357 | 57 | Traceback (most recent call last): | 33 | >>> zzz.latitude |
358 | 58 | ... | 34 | 39.4... |
359 | 59 | Unauthorized:... | 35 | >>> zzz.longitude |
360 | 36 | -0.4... | ||
361 | 37 | >>> zzz.time_zone | ||
362 | 38 | u'Europe/Madrid' | ||
363 | 39 | >>> logout() | ||
364 | 60 | 40 | ||
366 | 61 | Of course, the person himself can continue to edit it: | 41 | The user can change his location: |
367 | 62 | 42 | ||
368 | 63 | >>> self_browser.open('http://launchpad.dev/~zzz/+editlocation') | 43 | >>> self_browser.open('http://launchpad.dev/~zzz/+editlocation') |
369 | 64 | >>> self_browser.getControl(name='field.location.latitude').value | 44 | >>> self_browser.getControl(name='field.location.latitude').value |
370 | @@ -71,33 +51,21 @@ | |||
371 | 71 | '39.48' | 51 | '39.48' |
372 | 72 | 52 | ||
373 | 73 | The +editlocation page also allows a person to change his location | 53 | The +editlocation page also allows a person to change his location |
377 | 74 | visibility, that is, whether or not others can see it. Unlike the actual | 54 | visibility, that is, whether or not others can see it. |
378 | 75 | location (which can be changed by anybody until the person himself sets | 55 | |
379 | 76 | it), the visibility can only be changed by the person himself. | 56 | >>> nopriv_browser.open('http://launchpad.dev/~no-priv/+editlocation') |
380 | 57 | >>> nopriv_browser.getControl( | ||
381 | 58 | ... 'Hide my location details from others.').selected = True | ||
382 | 59 | >>> nopriv_browser.getControl('Update').click() | ||
383 | 60 | >>> nopriv_browser.url | ||
384 | 61 | 'http://launchpad.dev/~no-priv' | ||
385 | 62 | |||
386 | 63 | Once hidden, other users can't see it. | ||
387 | 77 | 64 | ||
388 | 78 | >>> name12_browser = setupBrowser(auth="Basic test@canonical.com:test") | 65 | >>> name12_browser = setupBrowser(auth="Basic test@canonical.com:test") |
389 | 79 | >>> name12_browser.open('http://launchpad.dev/~no-priv/+editlocation') | ||
390 | 80 | >>> name12_browser.getControl('Hide my location details from others.') | ||
391 | 81 | Traceback (most recent call last): | ||
392 | 82 | ... | ||
393 | 83 | LookupError:... | ||
394 | 84 | |||
395 | 85 | >>> nopriv_browser.open('http://launchpad.dev/~no-priv/+editlocation') | ||
396 | 86 | >>> nopriv_browser.getControl( | ||
397 | 87 | ... 'Hide my location details from others.').selected = True | ||
398 | 88 | >>> nopriv_browser.getControl('Update').click() | ||
399 | 89 | >>> nopriv_browser.url | ||
400 | 90 | 'http://launchpad.dev/~no-priv' | ||
401 | 91 | |||
402 | 92 | Once hidden, other users can't see nor change it. | ||
403 | 93 | |||
404 | 94 | >>> name12_browser.open('http://launchpad.dev/~no-priv') | 66 | >>> name12_browser.open('http://launchpad.dev/~no-priv') |
405 | 95 | >>> print str(find_tag_by_id(name12_browser.contents, 'person_map_div')) | 67 | >>> print str(find_tag_by_id(name12_browser.contents, 'person_map_div')) |
406 | 96 | None | 68 | None |
407 | 97 | >>> name12_browser.open('http://launchpad.dev/~no-priv/+editlocation') | ||
408 | 98 | Traceback (most recent call last): | ||
409 | 99 | ... | ||
410 | 100 | Unauthorized:... | ||
411 | 101 | 69 | ||
412 | 102 | The person himself can still see and change it, though. | 70 | The person himself can still see and change it, though. |
413 | 103 | 71 | ||
414 | 104 | 72 | ||
415 | === modified file 'lib/lp/registry/stories/location/personlocation.txt' | |||
416 | --- lib/lp/registry/stories/location/personlocation.txt 2009-09-16 17:56:17 +0000 | |||
417 | +++ lib/lp/registry/stories/location/personlocation.txt 2009-11-15 01:25:23 +0000 | |||
418 | @@ -8,30 +8,26 @@ | |||
419 | 8 | >>> zzz = factory.makePerson(name='zzz', time_zone='Africa/Maseru', | 8 | >>> zzz = factory.makePerson(name='zzz', time_zone='Africa/Maseru', |
420 | 9 | ... latitude=None, longitude=None) | 9 | ... latitude=None, longitude=None) |
421 | 10 | >>> logout() | 10 | >>> logout() |
432 | 11 | >>> nopriv_browser = setupBrowser(auth='Basic no-priv@canonical.com:test') | 11 | |
433 | 12 | >>> nopriv_browser.open('http://launchpad.dev/~zzz') | 12 | Any person can see another person's time zone. |
434 | 13 | 13 | ||
435 | 14 | They should see a link to the +editlocation page (around the map image) | 14 | >>> anon_browser.open('http://launchpad.dev/~zzz') |
436 | 15 | and the person's time zone. | 15 | >>> print extract_text( |
437 | 16 | 16 | ... find_tag_by_id(anon_browser.contents, 'portlet-map')) | |
428 | 17 | >>> editlink = nopriv_browser.getLink(url='+editlocation', index=1) | ||
429 | 18 | >>> editlink.text | ||
430 | 19 | '[IMG]' | ||
431 | 20 | >>> print extract_text(find_tag_by_id(nopriv_browser.contents, 'portlet-map')) | ||
438 | 21 | Location | 17 | Location |
439 | 22 | Time zone: Africa/Maseru | 18 | Time zone: Africa/Maseru |
440 | 23 | 19 | ||
443 | 24 | If a person has a location, they should have a little map portlet in their | 20 | If a person has a location, there is a little map portlet in their |
444 | 25 | home page. We can't test all the google javascript, but we can make sure | 21 | profile page. We can't test all the google javascript, but we can make sure |
445 | 26 | there's a map, and the scripts are loaded. | 22 | there's a map, and the scripts are loaded. |
446 | 27 | 23 | ||
447 | 28 | >>> login('test@canonical.com') | 24 | >>> login('test@canonical.com') |
448 | 29 | >>> yyy = factory.makePerson(name='yyy', time_zone='Europe/London', | 25 | >>> yyy = factory.makePerson(name='yyy', time_zone='Europe/London', |
449 | 30 | ... latitude=52.2, longitude=0.3) | 26 | ... latitude=52.2, longitude=0.3) |
450 | 31 | >>> logout() | 27 | >>> logout() |
454 | 32 | >>> nopriv_browser = setupBrowser(auth='Basic no-priv@canonical.com:test') | 28 | |
455 | 33 | >>> nopriv_browser.open('http://launchpad.dev/~yyy') | 29 | >>> anon_browser.open('http://launchpad.dev/~yyy') |
456 | 34 | >>> markup = str(nopriv_browser.contents) | 30 | >>> markup = str(anon_browser.contents) |
457 | 35 | >>> print extract_text(find_tag_by_id(markup, 'portlet-map'), skip_tags=[]) | 31 | >>> print extract_text(find_tag_by_id(markup, 'portlet-map'), skip_tags=[]) |
458 | 36 | Location | 32 | Location |
459 | 37 | Time zone: Europe/London... | 33 | Time zone: Europe/London... |
This is my branch to only permit users to edit their own location.
lp:~sinzui/launchpad/location-bug-262193 /bugs.launchpad .net/bugs/ 262193 implementation: my conscience
Diff size: 460
Launchpad bug: https:/
Test command: ./bin/test -vvt "personlocation"
Pre-
Target release: 3.1.11
= Only permit users to edit their own location. =
After much debate about allowing users to set someone else's location, it
is clear from the usage statistics that the feature is rarely used.
Removing the feature will not have a significant impact on Launchpad.
== Rules ==
* Restrict the permissions to edit a location to the owner or admin: .Edit Editlocation permission.
launchpad
* Remove the launchpad.
\o/ one less exception permission in security.py
* Remove any UI that suggests that a user can edit someone else's
location. Most, maybe all the UI elements suggesting that a person
can set another person's location was removed in 3.0.
* Remove the notification email set when some edits another person's
location.
== QA ==
* On staging, verify that the page does not prompt you to set someone's
location.
* Verify that you cannot access the user's +editlocation page.
== Lint ==
Linting changed files: /launchpad/ permissions. zcml /launchpad/ security. py registry/ configure. zcml registry/ browser/ configure. zcml registry/ browser/ person. py registry/ doc/personlocat ion.txt registry/ model/person. py registry/ stories/ location/ personlocation- edit.txt registry/ stories/ location/ personlocation. txt
lib/canonical
lib/canonical
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
== Test ==
* lib/lp/ registry/ doc/personlocat ion.txt registry/ stories/ location/ personlocation- edit.txt registry/ stories/ location/ personlocation. txt
* Revised the test to show that a user's location is only editable
by himself or an admin.
* Removed all tests that showed that a user could set someone else's
location if the location was unset.
* lib/lp/
* Removed the tests that demonstrated a user could set another user's
location if the location was unset.
* lib/lp/
* Removed the test that implied a user could set another user's
location.
* Revised to the test to show that any user can see another user's
location if it is public (the previous test implied the user had
to be logged in).
== Implementation ==
* lib/canonical/ launchpad/ emailtemplates/ person- location- modified. txt
* Deleted because it is not possible to set another user's location.
* lib/canonical/ launchpad/ permissions. zcml launchpad/ security. py EditLocation.
* lib/canonical/
* Removed launchpad.
* lib/lp/ registry/ configure. zcml registry/ browser/ configure. zcml EditLocation with launchpad.Edit.
* lib/lp/
* Replaced launchpad.
* lib/lp/ registry/ browser/ person. py EditLocation with launchpad.Edit.
* Replaced launchpad.
* Since there is only one permission to access +editlocation, the
field_names never change.
* lib/lp/ registry/ model/person. py
* Removed the notification about a user setting an...