Merge lp:~stevenk/launchpad/no-private-registrant-setbranch-redux into lp:launchpad

Proposed by Steve Kowalik
Status: Merged
Approved by: Steve Kowalik
Approved revision: no longer in the source branch.
Merged at revision: 16111
Proposed branch: lp:~stevenk/launchpad/no-private-registrant-setbranch-redux
Merge into: lp:launchpad
Diff against target: 160 lines (+42/-44)
2 files modified
lib/lp/registry/browser/productseries.py (+23/-44)
lib/lp/registry/browser/tests/productseries-setbranch-view.txt (+19/-0)
To merge this branch: bzr merge lp:~stevenk/launchpad/no-private-registrant-setbranch-redux
Reviewer Review Type Date Requested Status
Ian Booth (community) Approve
Review via email: mp+128415@code.launchpad.net

Commit message

Show a field error if we attempt to create a code import owned by a private team in ProductSeries:+setbranch.

Description of the change

While the first branch that attempted to fix this bug was fine in it's own right, it replaced one OOPS with another. This one wasn't deep in the guts of Storm, and was quite easy to ascertain meaning from. Code imports are not allowed to be owned by private teams, so we check for that and set a field error if so.

My CDO prevented me from putting up a branch that wasn't net-negative, so it contains more whitespace cleanups. I also removed a quote function that didn't seem to be called by anything.

To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :

Francis reset the squad's Lines when we started Maintenance. Your count is -954 as of today.
    ~/Work/lp-dev-utils/loc-contributions --start-rev=15931 <email address hidden>

Revision history for this message
Ian Booth (wallyworld) wrote :

Looks good

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/browser/productseries.py'
2--- lib/lp/registry/browser/productseries.py 2012-10-05 07:10:15 +0000
3+++ lib/lp/registry/browser/productseries.py 2012-10-08 05:07:24 +0000
4@@ -29,7 +29,6 @@
5 'ProductSeriesView',
6 ]
7
8-import cgi
9 from operator import attrgetter
10
11 from bzrlib.revision import NULL_REVISION
12@@ -145,11 +144,6 @@
13 )
14
15
16-def quote(text):
17- """Escape and quote text."""
18- return cgi.escape(text, quote=True)
19-
20-
21 class ProductSeriesNavigation(Navigation, BugTargetTraversalMixin,
22 StructuralSubscriptionTargetTraversalMixin):
23 """A class to navigate `IProductSeries` URLs."""
24@@ -683,10 +677,7 @@
25 """See `LaunchpadFormView`."""
26 return canonical_url(self.context)
27
28- @property
29- def cancel_url(self):
30- """See `LaunchpadFormView`."""
31- return canonical_url(self.context)
32+ cancel_url = next_url
33
34
35 class ProductSeriesDeleteView(RegistryDeleteViewMixin, LaunchpadEditFormView):
36@@ -813,9 +804,7 @@
37 class SetBranchForm(Interface):
38 """The fields presented on the form for setting a branch."""
39
40- use_template(
41- ICodeImport,
42- ['cvs_module'])
43+ use_template(ICodeImport, ['cvs_module'])
44
45 rcs_type = Choice(title=_("Type of RCS"),
46 required=False, vocabulary=RevisionControlSystems,
47@@ -826,42 +815,27 @@
48 title=_("Branch URL"), required=True,
49 description=_("The URL of the branch."),
50 allowed_schemes=["http", "https"],
51- allow_userinfo=False,
52- allow_port=True,
53- allow_query=False,
54- allow_fragment=False,
55- trailing_slash=False)
56+ allow_userinfo=False, allow_port=True, allow_query=False,
57+ allow_fragment=False, trailing_slash=False)
58
59 branch_location = copy_field(
60- IProductSeries['branch'],
61- __name__='branch_location',
62+ IProductSeries['branch'], __name__='branch_location',
63 title=_('Branch'),
64 description=_(
65 "The Bazaar branch for this series in Launchpad, "
66- "if one exists."),
67- )
68+ "if one exists."))
69
70 branch_type = Choice(
71- title=_('Import type'),
72- vocabulary=BRANCH_TYPE_VOCABULARY,
73- description=_("The type of import"),
74- required=True)
75+ title=_('Import type'), vocabulary=BRANCH_TYPE_VOCABULARY,
76+ description=_("The type of import"), required=True)
77
78 branch_name = copy_field(
79- IBranch['name'],
80- __name__='branch_name',
81- title=_('Branch name'),
82- description=_(''),
83- required=True,
84- )
85+ IBranch['name'], __name__='branch_name', title=_('Branch name'),
86+ description=_(''), required=True)
87
88 branch_owner = copy_field(
89- IBranch['owner'],
90- __name__='branch_owner',
91- title=_('Branch owner'),
92- description=_(''),
93- required=True,
94- )
95+ IBranch['owner'], __name__='branch_owner', title=_('Branch owner'),
96+ description=_(''), required=True)
97
98
99 class ProductSeriesSetBranchView(ReturnToReferrerMixin, LaunchpadFormView,
100@@ -936,9 +910,16 @@
101 rcs_type = data.get('rcs_type')
102 repo_url = data.get('repo_url')
103
104+ # Private teams are forbidden from owning code imports.
105+ branch_owner = data.get('branch_owner')
106+ if branch_owner is not None and branch_owner.private:
107+ self.setFieldError(
108+ 'branch_owner', 'Private teams are forbidden from owning '
109+ 'external imports.')
110+
111 if repo_url is None:
112- self.setFieldError('repo_url',
113- 'You must set the external repository URL.')
114+ self.setFieldError(
115+ 'repo_url', 'You must set the external repository URL.')
116 else:
117 # Ensure this URL has not been imported before.
118 code_import = getUtility(ICodeImportSet).getByURL(repo_url)
119@@ -969,12 +950,10 @@
120 """Validate that branch name and owner are set."""
121 if 'branch_name' not in data:
122 self.setFieldError(
123- 'branch_name',
124- 'The branch name must be set.')
125+ 'branch_name', 'The branch name must be set.')
126 if 'branch_owner' not in data:
127 self.setFieldError(
128- 'branch_owner',
129- 'The branch owner must be set.')
130+ 'branch_owner', 'The branch owner must be set.')
131
132 def _setRequired(self, names, value):
133 """Mark the widget field as optional."""
134
135=== modified file 'lib/lp/registry/browser/tests/productseries-setbranch-view.txt'
136--- lib/lp/registry/browser/tests/productseries-setbranch-view.txt 2012-10-05 07:29:54 +0000
137+++ lib/lp/registry/browser/tests/productseries-setbranch-view.txt 2012-10-08 05:07:24 +0000
138@@ -377,3 +377,22 @@
139 http://launchpad.dev/chevy/corvair
140 >>> for notification in view.request.response.notifications:
141 ... print notification.message
142+
143+If the owner is set to a private team, an error is raised.
144+
145+ >>> from lp.registry.enums import PersonVisibility
146+ >>> private_team = factory.makeTeam(
147+ ... visibility=PersonVisibility.PRIVATE, members=[driver])
148+ >>> form = {
149+ ... 'field.branch_type': 'import-external',
150+ ... 'field.rcs_type': 'BZR',
151+ ... 'field.branch_name': 'sport-branch',
152+ ... 'field.branch_owner': private_team.name,
153+ ... 'field.repo_url': 'http://bzr.com/sporty',
154+ ... 'field.actions.update': 'Update',
155+ ... }
156+ >>> view = create_initialized_view(
157+ ... series, name='+setbranch', principal=driver, form=form)
158+ >>> for error in view.errors:
159+ ... print error
160+ Private teams are forbidden from owning external imports.