Merge lp:~abentley/launchpad/recipe-interfaces into lp:launchpad

Proposed by Aaron Bentley on 2010-09-02
Status: Merged
Approved by: Paul Hummer on 2010-09-02
Approved revision: no longer in the source branch.
Merged at revision: 11517
Proposed branch: lp:~abentley/launchpad/recipe-interfaces
Merge into: lp:launchpad
Diff against target: 232 lines (+82/-69)
3 files modified
lib/lp/code/configure.zcml (+8/-13)
lib/lp/code/interfaces/sourcepackagerecipe.py (+70/-54)
lib/lp/code/model/tests/test_sourcepackagerecipe.py (+4/-2)
To merge this branch: bzr merge lp:~abentley/launchpad/recipe-interfaces
Reviewer Review Type Date Requested Status
Paul Hummer (community) 2010-09-02 Approve on 2010-09-02
Review via email: mp+34453@code.launchpad.net

Commit Message

Update security on SourcePackageRecipe to use multiple-interface style.

Description of the Change

= Summary =
Update the security configuration to use multiple interfaces.

== Proposed fix ==
Update the security configuration to use multiple interfaces.

== Pre-implementation notes ==
Discussed with rockstar

== Implementation details == For reasons I don't understand, the builder_recipe
and date_last_modified attributes weren't accessible (Forbidden, not
Unauthorized), despite being on the ISourcePackageRecipeEditableAttributes
interface. I had to provide them manually.

== Tests ==
bin/test -v test_sourcepackagerecipe

== Demo and Q/A ==
None

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/code/configure.zcml
  lib/lp/code/model/tests/test_sourcepackagerecipe.py
  lib/lp/code/interfaces/sourcepackagerecipe.py

./lib/lp/code/model/tests/test_sourcepackagerecipe.py
     280: E231 missing whitespace after ','
     304: E231 missing whitespace after ','
     312: E231 missing whitespace after ','
     319: E231 missing whitespace after ','
     327: E231 missing whitespace after ','
     365: E231 missing whitespace after ','
     425: E231 missing whitespace after ','
     506: E301 expected 1 blank line, found 0
     727: Line exceeds 78 characters.
./lib/lp/code/interfaces/sourcepackagerecipe.py
      77: E231 missing whitespace after ','
     121: E202 whitespace before ')'
     121: E231 missing whitespace after ','
     150: E302 expected 2 blank lines, found 1

To post a comment you must log in.
Paul Hummer (rockstar) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/code/configure.zcml'
2--- lib/lp/code/configure.zcml 2010-08-27 02:11:36 +0000
3+++ lib/lp/code/configure.zcml 2010-09-02 17:47:47 +0000
4@@ -960,28 +960,23 @@
5 <!-- SourcePackageRecipeData -->
6 <class
7 class="lp.code.model.sourcepackagerecipedata.SourcePackageRecipeData">
8- <allow
9+ <require permission="launchpad.View"
10 interface="lp.code.interfaces.sourcepackagerecipe.ISourcePackageRecipeData"/>
11 </class>
12 <!-- SourcePackageRecipe -->
13 <class
14 class="lp.code.model.sourcepackagerecipe.SourcePackageRecipe">
15 <require permission="launchpad.View"
16- interface="lp.code.interfaces.sourcepackagerecipe.ISourcePackageRecipe"
17+ interface="lp.code.interfaces.sourcepackagerecipe.ISourcePackageRecipeView
18+ lp.code.interfaces.sourcepackagerecipe.ISourcePackageRecipeEditableAttributes
19+ lp.code.interfaces.sourcepackagerecipe.ISourcePackageRecipeData"
20 />
21 <require
22 permission="launchpad.Edit"
23- set_attributes="
24- build_daily
25- builder_recipe
26- daily_build_archive
27- date_last_modified
28- description
29- distroseries
30- name
31- owner
32- sourcepackagename
33- is_stale"/>
34+ interface="lp.code.interfaces.sourcepackagerecipe.ISourcePackageRecipeEdit"
35+ set_schema="lp.code.interfaces.sourcepackagerecipe.ISourcePackageRecipeEditableAttributes"
36+ set_attributes="builder_recipe date_last_modified"
37+ />
38 </class>
39 <class
40 class="bzrlib.plugins.builder.recipe.BaseRecipeBranch">
41
42=== modified file 'lib/lp/code/interfaces/sourcepackagerecipe.py'
43--- lib/lp/code/interfaces/sourcepackagerecipe.py 2010-08-20 20:31:18 +0000
44+++ lib/lp/code/interfaces/sourcepackagerecipe.py 2010-09-02 17:47:47 +0000
45@@ -80,21 +80,12 @@
46 """An iterator of the branches referenced by this recipe."""
47
48
49-class ISourcePackageRecipe(IHasOwner, ISourcePackageRecipeData):
50- """An ISourcePackageRecipe describes how to build a source package.
51-
52- More precisely, it describes how to combine a number of branches into a
53- debianized source tree.
54- """
55- export_as_webservice_entry()
56+class ISourcePackageRecipeView(Interface):
57+ """IBranch attributes that require launchpad.View permission."""
58
59 id = Int()
60
61- daily_build_archive = exported(Reference(
62- IArchive, title=_("The archive to use for daily builds.")))
63-
64 date_created = Datetime(required=True, readonly=True)
65- date_last_modified = Datetime(required=True, readonly=True)
66
67 registrant = exported(
68 PublicPersonChoice(
69@@ -102,42 +93,8 @@
70 required=True, readonly=True,
71 vocabulary='ValidPersonOrTeam'))
72
73- owner = exported(
74- PersonChoice(
75- title=_('Owner'),
76- required=True, readonly=False,
77- vocabulary='UserTeamsParticipationPlusSelf',
78- description=_("The person or team who can edit this recipe.")))
79-
80- distroseries = CollectionField(
81- Reference(IDistroSeries), title=_("The distroseries this recipe will"
82- " build a source package for"),
83- readonly=False)
84- build_daily = exported(Bool(
85- title=_("Build daily")))
86 is_stale = Bool(title=_('Recipe is stale.'))
87
88- name = exported(TextLine(
89- title=_("Name"), required=True,
90- constraint=name_validator,
91- description=_("The name of this recipe.")))
92-
93- description = Text(
94- title=_('Description'), required=True,
95- description=_('A short description of the recipe.'))
96-
97- builder_recipe = Attribute(
98- _("The bzr-builder data structure for the recipe."))
99-
100- base_branch = Reference(
101- IBranch, title=_("The base branch used by this recipe."),
102- required=True, readonly=True)
103-
104- @operation_parameters(recipe_text=Text())
105- @export_write_operation()
106- def setRecipeText(recipe_text):
107- """Set the text of the recipe."""
108-
109 recipe_text = exported(Text())
110
111 def isOverQuota(requester, distroseries):
112@@ -147,6 +104,16 @@
113 :param distroseries: The distroseries to build for.
114 """
115
116+ def getBuilds(pending=False):
117+ """Return a ResultSet of all the builds in the given state.
118+
119+ :param pending: If True, select all builds that are pending. If
120+ False, select all builds that are not pending.
121+ """
122+
123+ def getLastBuild():
124+ """Return the the most recent build of this recipe."""
125+
126 @call_with(requester=REQUEST_USER)
127 @operation_parameters(
128 archive=Reference(schema=IArchive),
129@@ -164,15 +131,14 @@
130 able to upload to the archive.
131 """
132
133- def getBuilds(pending=False):
134- """Return a ResultSet of all the builds in the given state.
135-
136- :param pending: If True, select all builds that are pending. If
137- False, select all builds that are not pending.
138- """
139-
140- def getLastBuild():
141- """Return the the most recent build of this recipe."""
142+
143+class ISourcePackageRecipeEdit(Interface):
144+ """ISourcePackageRecipe methods that require launchpad.Edit permission."""
145+
146+ @operation_parameters(recipe_text=Text())
147+ @export_write_operation()
148+ def setRecipeText(recipe_text):
149+ """Set the text of the recipe."""
150
151 def destroySelf():
152 """Remove this SourcePackageRecipe from the database.
153@@ -181,6 +147,56 @@
154 references to this object.
155 """
156
157+class ISourcePackageRecipeEditableAttributes(IHasOwner):
158+ """ISourcePackageRecipe attributes that can be edited.
159+
160+ These attributes need launchpad.View to see, and launchpad.Edit to change.
161+ """
162+ daily_build_archive = exported(Reference(
163+ IArchive, title=_("The archive to use for daily builds.")))
164+
165+ builder_recipe = Attribute(
166+ _("The bzr-builder data structure for the recipe."))
167+
168+ owner = exported(
169+ PersonChoice(
170+ title=_('Owner'),
171+ required=True, readonly=False,
172+ vocabulary='UserTeamsParticipationPlusSelf',
173+ description=_("The person or team who can edit this recipe.")))
174+
175+ distroseries = CollectionField(
176+ Reference(IDistroSeries), title=_("The distroseries this recipe will"
177+ " build a source package for"),
178+ readonly=False)
179+ build_daily = exported(Bool(
180+ title=_("Build daily")))
181+
182+ name = exported(TextLine(
183+ title=_("Name"), required=True,
184+ constraint=name_validator,
185+ description=_("The name of this recipe.")))
186+
187+ description = Text(
188+ title=_('Description'), required=True,
189+ description=_('A short description of the recipe.'))
190+
191+ date_last_modified = Datetime(required=True, readonly=True)
192+
193+
194+class ISourcePackageRecipe(ISourcePackageRecipeData,
195+ ISourcePackageRecipeEdit, ISourcePackageRecipeEditableAttributes,
196+ ISourcePackageRecipeView):
197+ """An ISourcePackageRecipe describes how to build a source package.
198+
199+ More precisely, it describes how to combine a number of branches into a
200+ debianized source tree.
201+ """
202+ export_as_webservice_entry()
203+ base_branch = Reference(
204+ IBranch, title=_("The base branch used by this recipe."),
205+ required=True, readonly=True)
206+
207
208 class ISourcePackageRecipeSource(Interface):
209 """A utility of this interface can be used to create and access recipes.
210
211=== modified file 'lib/lp/code/model/tests/test_sourcepackagerecipe.py'
212--- lib/lp/code/model/tests/test_sourcepackagerecipe.py 2010-09-01 03:25:36 +0000
213+++ lib/lp/code/model/tests/test_sourcepackagerecipe.py 2010-09-02 17:47:47 +0000
214@@ -177,7 +177,8 @@
215 recipe = self.makeSourcePackageRecipeFromBuilderRecipe(
216 self.factory.makeRecipe())
217 transaction.commit()
218- self.assertProvides(recipe, ISourcePackageRecipe)
219+ with person_logged_in(recipe.owner):
220+ self.assertProvides(recipe, ISourcePackageRecipe)
221
222 def test_base_branch(self):
223 # When a recipe is created, we can access its base branch.
224@@ -484,7 +485,8 @@
225 self.factory.makeSourcePackageRecipeBuildJob(
226 recipe_build=past_build)
227 removeSecurityProxy(past_build).datebuilt = datetime.now(UTC)
228- recipe.destroySelf()
229+ with person_logged_in(recipe.owner):
230+ recipe.destroySelf()
231 # Show no database constraints were violated
232 Store.of(recipe).flush()
233