Merge lp:~edwin-grubbs/launchpad/bug-451208-subscribing-reveals-email into lp:launchpad

Proposed by Edwin Grubbs
Status: Merged
Merged at revision: not available
Proposed branch: lp:~edwin-grubbs/launchpad/bug-451208-subscribing-reveals-email
Merge into: lp:launchpad
Diff against target: 1808 lines (+788/-258)
16 files modified
lib/canonical/launchpad/browser/vocabulary.py (+5/-1)
lib/canonical/launchpad/doc/vocabularies.txt (+8/-5)
lib/canonical/launchpad/doc/vocabulary-json.txt (+20/-0)
lib/canonical/launchpad/vocabularies/configure.zcml (+297/-86)
lib/canonical/launchpad/vocabularies/dbobjects.py (+5/-3)
lib/canonical/launchpad/webapp/configure.zcml (+1/-0)
lib/canonical/launchpad/webapp/metazcml.py (+7/-2)
lib/canonical/launchpad/zcml/binaryandsourcepackagename.zcml (+13/-2)
lib/lp/answers/configure.zcml (+9/-2)
lib/lp/answers/doc/faq-vocabulary.txt (+2/-1)
lib/lp/registry/doc/vocabularies.txt (+57/-56)
lib/lp/registry/vocabularies.zcml (+304/-95)
lib/lp/services/tests/test_vocabularies.py (+37/-0)
lib/lp/services/worlddata/vocabularies.zcml (+5/-2)
lib/lp/soyuz/configure.zcml (+16/-2)
lib/lp/soyuz/interfaces/binarypackagename.py (+2/-1)
To merge this branch: bzr merge lp:~edwin-grubbs/launchpad/bug-451208-subscribing-reveals-email
Reviewer Review Type Date Requested Status
Guilherme Salgado (community) code Approve
Canonical Launchpad Engineering code Pending
Review via email: mp+17261@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :

Summary
-------

Registered all the Launchpad vocabularies with <securedutility>
instead of <utility> so that it will not be possible to get
a db object without a security proxy.

This required an <allow> block on each utility to allow
access to the __call__ method on the vocabulary class (IVocabularyFactory).

The vocabulary objects required a <class> directive with
<allow interface=IHugeVocabulary>.

Some vocabulary factories were actually functions, such as
BugNominatableSeriesVocabulary, which would actually return either
BugNominatableProductSeriesVocabulary or BugNominatableDistroSeriesVocabulary
objects.

Implementation details
----------------------

New tests:
    lib/lp/services/tests/test_vocabularies.py
    lib/canonical/launchpad/doc/vocabulary-json.txt

Indicate in the picker widget when email address is hidden.
    lib/canonical/launchpad/browser/vocabulary.py

Some vocabularies need to get the IBinaryAndSourcePackageName.id
attribute from objects that were passed in from widgets, so they
are already security proxied.
    lib/lp/soyuz/interfaces/binarypackagename.py

Fixed tests that broke since they were accessing methods that
should not be exposed through the security proxy.
    lib/canonical/launchpad/doc/vocabularies.txt
    lib/lp/answers/doc/faq-vocabulary.txt
    lib/lp/registry/doc/vocabularies.txt

Since vocabularies must be registered with a name parameter,
the <securedutility> directive needed to be updated to pass
this along to the underlying <utility>.
    lib/canonical/launchpad/webapp/metazcml.py

Added BugNominatableDistroSeriesVocabulary and
BugNominatableProductSeriesVocabulary to __all__.
    lib/canonical/launchpad/vocabularies/dbobjects.py

ICountableIterator defines a __getitem__ method that provides
the __getslice__ functionality.
    lib/canonical/launchpad/webapp/configure.zcml

Somewhat interesting zcml changes:
    lib/canonical/launchpad/zcml/binaryandsourcepackagename.zcml
    lib/lp/soyuz/configure.zcml

The changes for SimpleVocabulary, SimpleTerm, and
BugNominatable*SeriesVocabulary are the only parts of note among the
many changes in this file.
    lib/canonical/launchpad/vocabularies/configure.zcml

TimezoneNameVocabulary is just a function that returns a
SimpleVocabulary, so it doesn't need any <class> directives.
    lib/lp/services/worlddata/vocabularies.zcml

Uninteresting bulk changes to use <securedutility>:
    lib/lp/answers/configure.zcml
    lib/lp/registry/vocabularies.zcml

Tests
-----

./bin/test -vv -t 'test_vocabularies|vocabulary-json.txt'

Demo and Q/A
------------

* Open https://launchpad.dev/people/+requestmerge
  * Click on "Choose" to bring up the picker.
  * Search for "name12".
  * The email address should be hidden.

Revision history for this message
Guilherme Salgado (salgado) wrote :
Download full text (9.1 KiB)

> === modified file 'lib/canonical/launchpad/webapp/configure.zcml'
> --- lib/canonical/launchpad/webapp/configure.zcml 2009-11-18 00:22:41 +0000
> +++ lib/canonical/launchpad/webapp/configure.zcml 2010-01-12 22:36:26 +0000
> @@ -809,6 +809,7 @@
>
> <class class="canonical.launchpad.webapp.vocabulary.CountableIterator">
> <allow interface="canonical.launchpad.webapp.vocabulary.ICountableIterator" />
> + <allow attributes="__getslice__"/>

Wouldn't it make sense to add __getslice__ to CountableIterator?

> </class>
>
> <class class="canonical.launchpad.webapp.vocabulary.BatchedCountableIterator">
>
> === modified file 'lib/lp/registry/doc/vocabularies.txt'
> --- lib/lp/registry/doc/vocabularies.txt 2009-12-24 01:41:54 +0000
> +++ lib/lp/registry/doc/vocabularies.txt 2010-01-12 22:36:26 +0000
> @@ -20,7 +20,9 @@
> The active mailing lists vocabulary matches and returns only those mailing
> lists which are active.
>
> - >>> list_vocabulary = vocabulary_registry.get(None, 'ActiveMailingList')
> + >>> from zope.security.proxy import removeSecurityProxy
> + >>> list_vocabulary = removeSecurityProxy(
> + ... vocabulary_registry.get(None, 'ActiveMailingList'))
> >>> from canonical.launchpad.webapp.testing import verifyObject
> >>> from canonical.launchpad.webapp.vocabulary import IHugeVocabulary
> >>> verifyObject(IHugeVocabulary, list_vocabulary)
> @@ -203,6 +205,7 @@
> u'The Hoary Hedgehog Release'
>
> >>> def getTerms(vocab, search_text):
> + ... vocab = removeSecurityProxy(vocab)
> ... [vocab.toTerm(item) for item in vocab.search(search_text)]
>
> >>> getTerms(distroseries_vocabulary, 'woody')
> @@ -508,7 +511,8 @@
>
> The list of selectable projects. The results are ordered by displayname.
>
> - >>> project_vocabulary = vocabulary_registry.get(None, "Project")
> + >>> project_vocabulary = removeSecurityProxy(
> + ... vocabulary_registry.get(None, "Project"))

I think we wought to have a wrapper around vocabulary_registry.get() to remove
the security proxy of the vocab before returning. Something like

    def get_naked_vocab(context, name):
        return removeSecurityProxy(vocab_registry.get(context, name))

That way we don't have to repeat the removeSecurityProxy() call in all the
places we call vocabulary_registry.get.

> >>> project_vocabulary.displayname
> 'Select a project group'
>
> @@ -542,7 +546,8 @@
>
> The list of selectable products. Results are ordered by displayname.
>
> - >>> product_vocabulary = vocabulary_registry.get(None, "Product")
> + >>> product_vocabulary = removeSecurityProxy(
> + ... vocabulary_registry.get(None, "Product"))
> >>> product_vocabulary.displayname
> 'Select a project'
>
> @@ -583,8 +588,8 @@
>
> The list of selectable products releases.
>
> - >>> productrelease_vocabulary = vocabulary_registry.get(None,
> - ... "ProductRelease")
> + >>> productrelease_vocabulary = removeSecurityProxy(
> + ... vocabulary_registry.get(None, "ProductRelease"))
> >>> productrelease_vocabular...

Read more...

review: Needs Fixing (code)
Revision history for this message
Guilherme Salgado (salgado) wrote :
Download full text (9.1 KiB)

> === modified file 'lib/canonical/launchpad/webapp/configure.zcml'
> --- lib/canonical/launchpad/webapp/configure.zcml 2009-11-18 00:22:41 +0000
> +++ lib/canonical/launchpad/webapp/configure.zcml 2010-01-12 22:36:26 +0000
> @@ -809,6 +809,7 @@
>
> <class class="canonical.launchpad.webapp.vocabulary.CountableIterator">
> <allow interface="canonical.launchpad.webapp.vocabulary.ICountableIterator" />
> + <allow attributes="__getslice__"/>

Wouldn't it make sense to add __getslice__ to CountableIterator?

> </class>
>
> <class class="canonical.launchpad.webapp.vocabulary.BatchedCountableIterator">
>
> === modified file 'lib/lp/registry/doc/vocabularies.txt'
> --- lib/lp/registry/doc/vocabularies.txt 2009-12-24 01:41:54 +0000
> +++ lib/lp/registry/doc/vocabularies.txt 2010-01-12 22:36:26 +0000
> @@ -20,7 +20,9 @@
> The active mailing lists vocabulary matches and returns only those mailing
> lists which are active.
>
> - >>> list_vocabulary = vocabulary_registry.get(None, 'ActiveMailingList')
> + >>> from zope.security.proxy import removeSecurityProxy
> + >>> list_vocabulary = removeSecurityProxy(
> + ... vocabulary_registry.get(None, 'ActiveMailingList'))
> >>> from canonical.launchpad.webapp.testing import verifyObject
> >>> from canonical.launchpad.webapp.vocabulary import IHugeVocabulary
> >>> verifyObject(IHugeVocabulary, list_vocabulary)
> @@ -203,6 +205,7 @@
> u'The Hoary Hedgehog Release'
>
> >>> def getTerms(vocab, search_text):
> + ... vocab = removeSecurityProxy(vocab)
> ... [vocab.toTerm(item) for item in vocab.search(search_text)]
>
> >>> getTerms(distroseries_vocabulary, 'woody')
> @@ -508,7 +511,8 @@
>
> The list of selectable projects. The results are ordered by displayname.
>
> - >>> project_vocabulary = vocabulary_registry.get(None, "Project")
> + >>> project_vocabulary = removeSecurityProxy(
> + ... vocabulary_registry.get(None, "Project"))

I think we wought to have a wrapper around vocabulary_registry.get() to remove
the security proxy of the vocab before returning. Something like

    def get_naked_vocab(context, name):
        return removeSecurityProxy(vocab_registry.get(context, name))

That way we don't have to repeat the removeSecurityProxy() call in all the
places we call vocabulary_registry.get.

> >>> project_vocabulary.displayname
> 'Select a project group'
>
> @@ -542,7 +546,8 @@
>
> The list of selectable products. Results are ordered by displayname.
>
> - >>> product_vocabulary = vocabulary_registry.get(None, "Product")
> + >>> product_vocabulary = removeSecurityProxy(
> + ... vocabulary_registry.get(None, "Product"))
> >>> product_vocabulary.displayname
> 'Select a project'
>
> @@ -583,8 +588,8 @@
>
> The list of selectable products releases.
>
> - >>> productrelease_vocabulary = vocabulary_registry.get(None,
> - ... "ProductRelease")
> + >>> productrelease_vocabulary = removeSecurityProxy(
> + ... vocabulary_registry.get(None, "ProductRelease"))
> >>> productrelease_vocabular...

Read more...

review: Needs Fixing (code)
Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :
Download full text (30.9 KiB)

> > === modified file 'lib/canonical/launchpad/webapp/configure.zcml'
> > --- lib/canonical/launchpad/webapp/configure.zcml 2009-11-18 00:22:41
> +0000
> > +++ lib/canonical/launchpad/webapp/configure.zcml 2010-01-12 22:36:26
> +0000
> > @@ -809,6 +809,7 @@
> >
> > <class class="canonical.launchpad.webapp.vocabulary.CountableIterator">
> > <allow
> interface="canonical.launchpad.webapp.vocabulary.ICountableIterator" />
> > + <allow attributes="__getslice__"/>
>
> Wouldn't it make sense to add __getslice__ to CountableIterator?

Gary had recommended that I add __getslice__ to the zcml instead of the interface
since this is a security concern and not a method that implementors of ICountableIterator
need to create.

> > </class>
> >
> > <class
> class="canonical.launchpad.webapp.vocabulary.BatchedCountableIterator">
> >
> > === modified file 'lib/lp/registry/doc/vocabularies.txt'
> > --- lib/lp/registry/doc/vocabularies.txt 2009-12-24 01:41:54 +0000
> > +++ lib/lp/registry/doc/vocabularies.txt 2010-01-12 22:36:26 +0000
> > @@ -20,7 +20,9 @@
> > The active mailing lists vocabulary matches and returns only those mailing
> > lists which are active.
> >
> > - >>> list_vocabulary = vocabulary_registry.get(None,
> 'ActiveMailingList')
> > + >>> from zope.security.proxy import removeSecurityProxy
> > + >>> list_vocabulary = removeSecurityProxy(
> > + ... vocabulary_registry.get(None, 'ActiveMailingList'))
> > >>> from canonical.launchpad.webapp.testing import verifyObject
> > >>> from canonical.launchpad.webapp.vocabulary import IHugeVocabulary
> > >>> verifyObject(IHugeVocabulary, list_vocabulary)
> > @@ -203,6 +205,7 @@
> > u'The Hoary Hedgehog Release'
> >
> > >>> def getTerms(vocab, search_text):
> > + ... vocab = removeSecurityProxy(vocab)
> > ... [vocab.toTerm(item) for item in vocab.search(search_text)]
> >
> > >>> getTerms(distroseries_vocabulary, 'woody')
> > @@ -508,7 +511,8 @@
> >
> > The list of selectable projects. The results are ordered by displayname.
> >
> > - >>> project_vocabulary = vocabulary_registry.get(None, "Project")
> > + >>> project_vocabulary = removeSecurityProxy(
> > + ... vocabulary_registry.get(None, "Project"))
>
> I think we wought to have a wrapper around vocabulary_registry.get() to remove
> the security proxy of the vocab before returning. Something like
>
> def get_naked_vocab(context, name):
> return removeSecurityProxy(vocab_registry.get(context, name))
>
> That way we don't have to repeat the removeSecurityProxy() call in all the
> places we call vocabulary_registry.get.

Done.

> > >>> project_vocabulary.displayname
> > 'Select a project group'
> >
> > @@ -542,7 +546,8 @@
> >
> > The list of selectable products. Results are ordered by displayname.
> >
> > - >>> product_vocabulary = vocabulary_registry.get(None, "Product")
> > + >>> product_vocabulary = removeSecurityProxy(
> > + ... vocabulary_registry.get(None, "Product"))
> > >>> product_vocabulary.displayname
> > 'Select a project'
> >
> > @@ -583,8 +588,8 @@
> >
> > The list of sel...

Revision history for this message
Guilherme Salgado (salgado) wrote :

Just add a comment explaining why we need the "vocab.__module__[:5] != 'zope.'" check in the test and it's good to go. Nice work!

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/canonical/launchpad/browser/vocabulary.py'
--- lib/canonical/launchpad/browser/vocabulary.py 2010-01-11 17:47:52 +0000
+++ lib/canonical/launchpad/browser/vocabulary.py 2010-01-18 21:51:20 +0000
@@ -23,6 +23,7 @@
23from zope.component.interfaces import ComponentLookupError23from zope.component.interfaces import ComponentLookupError
24from zope.interface import Attribute, implements, Interface24from zope.interface import Attribute, implements, Interface
25from zope.app.form.interfaces import MissingInputError25from zope.app.form.interfaces import MissingInputError
26from zope.security.interfaces import Unauthorized
2627
27from lazr.restful.interfaces import IWebServiceClientRequest28from lazr.restful.interfaces import IWebServiceClientRequest
2829
@@ -83,7 +84,10 @@
83 """Adapts IPerson to IPickerEntry."""84 """Adapts IPerson to IPickerEntry."""
84 extra = default_pickerentry_adapter(person)85 extra = default_pickerentry_adapter(person)
85 if person.preferredemail is not None:86 if person.preferredemail is not None:
86 extra.description = person.preferredemail.email87 try:
88 extra.description = person.preferredemail.email
89 except Unauthorized:
90 extra.description = '<email address hidden>'
87 return extra91 return extra
8892
89@implementer(IPickerEntry)93@implementer(IPickerEntry)
9094
=== modified file 'lib/canonical/launchpad/doc/vocabularies.txt'
--- lib/canonical/launchpad/doc/vocabularies.txt 2009-10-26 18:40:04 +0000
+++ lib/canonical/launchpad/doc/vocabularies.txt 2010-01-18 21:51:20 +0000
@@ -43,7 +43,11 @@
43vocabulary registry.43vocabulary registry.
4444
45 >>> from zope.schema.vocabulary import getVocabularyRegistry45 >>> from zope.schema.vocabulary import getVocabularyRegistry
46 >>> from zope.security.proxy import removeSecurityProxy
46 >>> vocabulary_registry = getVocabularyRegistry()47 >>> vocabulary_registry = getVocabularyRegistry()
48 >>> def get_naked_vocab(context, name):
49 ... return removeSecurityProxy(
50 ... vocabulary_registry.get(context, name))
47 >>> product_vocabulary = vocabulary_registry.get(None, "Product")51 >>> product_vocabulary = vocabulary_registry.get(None, "Product")
48 >>> product_vocabulary.displayname52 >>> product_vocabulary.displayname
49 'Select a project'53 'Select a project'
@@ -56,7 +60,7 @@
5660
57All the distributions that use Malone as their main bug tracker.61All the distributions that use Malone as their main bug tracker.
5862
59 >>> using_malone_vocabulary = vocabulary_registry.get(63 >>> using_malone_vocabulary = get_naked_vocab(
60 ... None, 'DistributionUsingMalone')64 ... None, 'DistributionUsingMalone')
61 >>> len(using_malone_vocabulary)65 >>> len(using_malone_vocabulary)
62 266 2
@@ -358,7 +362,7 @@
358concerned).362concerned).
359363
360 # Just use None as the context.364 # Just use None as the context.
361 >>> branch_vocabulary = vocabulary_registry.get(None, "Branch")365 >>> branch_vocabulary = get_naked_vocab(None, "Branch")
362 >>> def print_vocab_branches(vocab, search):366 >>> def print_vocab_branches(vocab, search):
363 ... for term in vocab.searchForTerms(search):367 ... for term in vocab.searchForTerms(search):
364 ... print term.value.unique_name368 ... print term.value.unique_name
@@ -639,8 +643,7 @@
639that matches the search string. The string is matched against the name,643that matches the search string. The string is matched against the name,
640or fallbacks to a full text search.644or fallbacks to a full text search.
641645
642 >>> vocab = vocabulary_registry.get(646 >>> vocab = get_naked_vocab(spec_a, "SpecificationDepCandidates")
643 ... spec_a, "SpecificationDepCandidates")
644 >>> list(vocab.search('spec-b')) == [spec_b]647 >>> list(vocab.search('spec-b')) == [spec_b]
645 True648 True
646 >>> list(vocab.search('third')) == [spec_c]649 >>> list(vocab.search('third')) == [spec_c]
@@ -664,7 +667,7 @@
664 >>> from canonical.launchpad.webapp.testing import verifyObject667 >>> from canonical.launchpad.webapp.testing import verifyObject
665 >>> from canonical.launchpad.webapp.vocabulary import IHugeVocabulary668 >>> from canonical.launchpad.webapp.vocabulary import IHugeVocabulary
666669
667 >>> vocabulary = vocabulary_registry.get(None, 'PPA')670 >>> vocabulary = get_naked_vocab(None, 'PPA')
668 >>> verifyObject(IHugeVocabulary, vocabulary)671 >>> verifyObject(IHugeVocabulary, vocabulary)
669 True672 True
670673
671674
=== modified file 'lib/canonical/launchpad/doc/vocabulary-json.txt'
--- lib/canonical/launchpad/doc/vocabulary-json.txt 2009-07-28 13:48:07 +0000
+++ lib/canonical/launchpad/doc/vocabulary-json.txt 2010-01-18 21:51:20 +0000
@@ -121,3 +121,23 @@
121 ],121 ],
122 "total_size": 1122 "total_size": 1
123 }123 }
124
125Hidden email addresses should also be hidden when IPerson objects are
126retrieved through vocabularies.
127
128 >>> form = dict(name='ValidPersonOrTeam', search_text='name12',
129 ... start='0', batch='1')
130 >>> view = create_vocabulary_view(form)
131 >>> print_json(view())
132 {
133 "entries": [
134 {
135 "api_uri": "/~name12",
136 "css": "sprite person",
137 "description": "<email address hidden>",
138 "title": "Sample Person",
139 "value": "name12"
140 }
141 ],
142 "total_size": 1
143 }
124144
=== modified file 'lib/canonical/launchpad/vocabularies/configure.zcml'
--- lib/canonical/launchpad/vocabularies/configure.zcml 2009-10-26 18:40:04 +0000
+++ lib/canonical/launchpad/vocabularies/configure.zcml 2010-01-18 21:51:20 +0000
@@ -4,177 +4,388 @@
44
5<configure xmlns="http://namespaces.zope.org/zope">5<configure xmlns="http://namespaces.zope.org/zope">
66
7 <utility7 <class class="zope.schema.vocabulary.SimpleVocabulary">
8 <allow interface="zope.schema.interfaces.IVocabularyTokenized"/>
9 </class>
10
11 <class class="zope.schema.vocabulary.SimpleTerm">
12 <allow interface="zope.schema.interfaces.ITitledTokenizedTerm"/>
13 </class>
14
15 <securedutility
8 name="Branch"16 name="Branch"
9 component="canonical.launchpad.vocabularies.BranchVocabulary"17 component="canonical.launchpad.vocabularies.BranchVocabulary"
10 provides="zope.schema.interfaces.IVocabularyFactory"18 provides="zope.schema.interfaces.IVocabularyFactory"
11 />19 >
1220 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
13 <utility21 </securedutility>
22
23 <class class="canonical.launchpad.vocabularies.BranchVocabulary">
24 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
25 </class>
26
27
28 <securedutility
14 name="HostedBranchRestrictedOnOwner"29 name="HostedBranchRestrictedOnOwner"
15 component="canonical.launchpad.vocabularies.HostedBranchRestrictedOnOwnerVocabulary"30 component="canonical.launchpad.vocabularies.HostedBranchRestrictedOnOwnerVocabulary"
16 provides="zope.schema.interfaces.IVocabularyFactory"31 provides="zope.schema.interfaces.IVocabularyFactory"
17 />32 >
1833 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
19 <utility34 </securedutility>
35
36 <class class="canonical.launchpad.vocabularies.HostedBranchRestrictedOnOwnerVocabulary">
37 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
38 </class>
39
40
41 <securedutility
20 name="BranchRestrictedOnProduct"42 name="BranchRestrictedOnProduct"
21 component="canonical.launchpad.vocabularies.BranchRestrictedOnProductVocabulary"43 component="canonical.launchpad.vocabularies.BranchRestrictedOnProductVocabulary"
22 provides="zope.schema.interfaces.IVocabularyFactory"44 provides="zope.schema.interfaces.IVocabularyFactory"
23 />45 >
2446 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
25 <utility47 </securedutility>
48
49 <class class="canonical.launchpad.vocabularies.BranchRestrictedOnProductVocabulary">
50 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
51 </class>
52
53
54 <securedutility
26 name="Bug"55 name="Bug"
27 component="canonical.launchpad.vocabularies.BugVocabulary"56 component="canonical.launchpad.vocabularies.BugVocabulary"
28 provides="zope.schema.interfaces.IVocabularyFactory"57 provides="zope.schema.interfaces.IVocabularyFactory"
29 />58 >
3059 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
31 <utility60 </securedutility>
61
62 <class class="canonical.launchpad.vocabularies.BugVocabulary">
63 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
64 </class>
65
66
67 <securedutility
32 name="BugNominatableSeries"68 name="BugNominatableSeries"
33 component="canonical.launchpad.vocabularies.BugNominatableSeriesVocabulary"69 component="canonical.launchpad.vocabularies.BugNominatableSeriesVocabulary"
34 provides="zope.schema.interfaces.IVocabularyFactory"70 provides="zope.schema.interfaces.IVocabularyFactory"
35 />71 >
3672 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
37 <utility73 </securedutility>
74
75 <class class="canonical.launchpad.vocabularies.BugNominatableProductSeriesVocabulary">
76 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
77 </class>
78
79 <class class="canonical.launchpad.vocabularies.BugNominatableDistroSeriesVocabulary">
80 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
81 </class>
82
83
84 <securedutility
38 name="BugTracker"85 name="BugTracker"
39 component="canonical.launchpad.vocabularies.BugTrackerVocabulary"86 component="canonical.launchpad.vocabularies.BugTrackerVocabulary"
40 provides="zope.schema.interfaces.IVocabularyFactory"87 provides="zope.schema.interfaces.IVocabularyFactory"
41 />88 >
4289 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
43 <utility90 </securedutility>
91
92 <class class="canonical.launchpad.vocabularies.BugTrackerVocabulary">
93 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
94 </class>
95
96
97 <securedutility
44 name="BugWatch"98 name="BugWatch"
45 component="canonical.launchpad.vocabularies.BugWatchVocabulary"99 component="canonical.launchpad.vocabularies.BugWatchVocabulary"
46 provides="zope.schema.interfaces.IVocabularyFactory"100 provides="zope.schema.interfaces.IVocabularyFactory"
47 />101 >
48102 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
49 <utility103 </securedutility>
104
105 <class class="canonical.launchpad.vocabularies.BugWatchVocabulary">
106 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
107 </class>
108
109
110 <securedutility
50 name="Component"111 name="Component"
51 component="canonical.launchpad.vocabularies.ComponentVocabulary"112 component="canonical.launchpad.vocabularies.ComponentVocabulary"
52 provides="zope.schema.interfaces.IVocabularyFactory"113 provides="zope.schema.interfaces.IVocabularyFactory"
53 />114 >
54115 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
55 <utility116 </securedutility>
117
118 <class class="canonical.launchpad.vocabularies.ComponentVocabulary">
119 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
120 </class>
121
122
123 <securedutility
56 name="CountryName"124 name="CountryName"
57 component="canonical.launchpad.vocabularies.CountryNameVocabulary"125 component="canonical.launchpad.vocabularies.CountryNameVocabulary"
58 provides="zope.schema.interfaces.IVocabularyFactory"126 provides="zope.schema.interfaces.IVocabularyFactory"
59 />127 >
60128 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
61 <utility129 </securedutility>
130
131 <class class="canonical.launchpad.vocabularies.CountryNameVocabulary">
132 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
133 </class>
134
135
136 <securedutility
62 name="DistributionUsingMalone"137 name="DistributionUsingMalone"
63 component="canonical.launchpad.vocabularies.DistributionUsingMaloneVocabulary"138 component="canonical.launchpad.vocabularies.DistributionUsingMaloneVocabulary"
64 provides="zope.schema.interfaces.IVocabularyFactory"139 provides="zope.schema.interfaces.IVocabularyFactory"
65 />140 >
66141 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
67 <utility142 </securedutility>
143
144 <class class="canonical.launchpad.vocabularies.DistributionUsingMaloneVocabulary">
145 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
146 </class>
147
148
149 <securedutility
68 name="FilteredDeltaLanguagePack"150 name="FilteredDeltaLanguagePack"
69 component="canonical.launchpad.vocabularies.FilteredDeltaLanguagePackVocabulary"151 component="canonical.launchpad.vocabularies.FilteredDeltaLanguagePackVocabulary"
70 provides="zope.schema.interfaces.IVocabularyFactory"152 provides="zope.schema.interfaces.IVocabularyFactory"
71 />153 >
72154 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
73 <utility155 </securedutility>
156
157 <class class="canonical.launchpad.vocabularies.FilteredDeltaLanguagePackVocabulary">
158 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
159 </class>
160
161
162 <securedutility
74 name="FilteredDistroArchSeries"163 name="FilteredDistroArchSeries"
75 component="canonical.launchpad.vocabularies.FilteredDistroArchSeriesVocabulary"164 component="canonical.launchpad.vocabularies.FilteredDistroArchSeriesVocabulary"
76 provides="zope.schema.interfaces.IVocabularyFactory"165 provides="zope.schema.interfaces.IVocabularyFactory"
77 />166 >
78167 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
79 <utility168 </securedutility>
169
170 <class class="canonical.launchpad.vocabularies.FilteredDistroArchSeriesVocabulary">
171 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
172 </class>
173
174
175 <securedutility
80 name="FilteredFullLanguagePack"176 name="FilteredFullLanguagePack"
81 component="canonical.launchpad.vocabularies.FilteredFullLanguagePackVocabulary"177 component="canonical.launchpad.vocabularies.FilteredFullLanguagePackVocabulary"
82 provides="zope.schema.interfaces.IVocabularyFactory"178 provides="zope.schema.interfaces.IVocabularyFactory"
83 />179 >
84180 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
85 <utility181 </securedutility>
182
183 <class class="canonical.launchpad.vocabularies.FilteredFullLanguagePackVocabulary">
184 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
185 </class>
186
187
188 <securedutility
86 name="FilteredLanguagePack"189 name="FilteredLanguagePack"
87 component="canonical.launchpad.vocabularies.FilteredLanguagePackVocabulary"190 component="canonical.launchpad.vocabularies.FilteredLanguagePackVocabulary"
88 provides="zope.schema.interfaces.IVocabularyFactory"191 provides="zope.schema.interfaces.IVocabularyFactory"
89 />192 >
90193 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
91 <utility194 </securedutility>
195
196 <class class="canonical.launchpad.vocabularies.FilteredLanguagePackVocabulary">
197 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
198 </class>
199
200
201 <securedutility
92 name="FutureSprint"202 name="FutureSprint"
93 component="canonical.launchpad.vocabularies.FutureSprintVocabulary"203 component="canonical.launchpad.vocabularies.FutureSprintVocabulary"
94 provides="zope.schema.interfaces.IVocabularyFactory"204 provides="zope.schema.interfaces.IVocabularyFactory"
95 />205 >
96206 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
97 <utility207 </securedutility>
208
209 <class class="canonical.launchpad.vocabularies.FutureSprintVocabulary">
210 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
211 </class>
212
213
214 <securedutility
98 name="Language"215 name="Language"
99 component="canonical.launchpad.vocabularies.LanguageVocabulary"216 component="canonical.launchpad.vocabularies.LanguageVocabulary"
100 provides="zope.schema.interfaces.IVocabularyFactory"217 provides="zope.schema.interfaces.IVocabularyFactory"
101 />218 >
102219 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
103 <utility220 </securedutility>
221
222 <class class="canonical.launchpad.vocabularies.LanguageVocabulary">
223 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
224 </class>
225
226
227 <securedutility
104 name="TranslatableLanguage"228 name="TranslatableLanguage"
105 component="canonical.launchpad.vocabularies.TranslatableLanguageVocabulary"229 component="canonical.launchpad.vocabularies.TranslatableLanguageVocabulary"
106 provides="zope.schema.interfaces.IVocabularyFactory"230 provides="zope.schema.interfaces.IVocabularyFactory"
107 />231 >
108232 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
109 <utility233 </securedutility>
234
235 <class class="canonical.launchpad.vocabularies.TranslatableLanguageVocabulary">
236 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
237 </class>
238
239
240 <securedutility
110 name="PackageRelease"241 name="PackageRelease"
111 component="canonical.launchpad.vocabularies.PackageReleaseVocabulary"242 component="canonical.launchpad.vocabularies.PackageReleaseVocabulary"
112 provides="zope.schema.interfaces.IVocabularyFactory"243 provides="zope.schema.interfaces.IVocabularyFactory"
113 />244 >
114245 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
115 <utility246 </securedutility>
247
248 <class class="canonical.launchpad.vocabularies.PackageReleaseVocabulary">
249 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
250 </class>
251
252
253 <securedutility
116 name="PPA"254 name="PPA"
117 component="canonical.launchpad.vocabularies.PPAVocabulary"255 component="canonical.launchpad.vocabularies.PPAVocabulary"
118 provides="zope.schema.interfaces.IVocabularyFactory"256 provides="zope.schema.interfaces.IVocabularyFactory"
119 />257 >
120258 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
121 <utility259 </securedutility>
260
261 <class class="canonical.launchpad.vocabularies.PPAVocabulary">
262 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
263 </class>
264
265
266 <securedutility
122 name="ProjectProductsUsingMalone"267 name="ProjectProductsUsingMalone"
123 component="canonical.launchpad.vocabularies.project_products_using_malone_vocabulary_factory"268 component="canonical.launchpad.vocabularies.project_products_using_malone_vocabulary_factory"
124 provides="zope.schema.interfaces.IVocabularyFactory"269 provides="zope.schema.interfaces.IVocabularyFactory"
125 />270 >
126271 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
127 <utility272 </securedutility>
273
274
275 <securedutility
128 name="Specification"276 name="Specification"
129 component="canonical.launchpad.vocabularies.SpecificationVocabulary"277 component="canonical.launchpad.vocabularies.SpecificationVocabulary"
130 provides="zope.schema.interfaces.IVocabularyFactory"278 provides="zope.schema.interfaces.IVocabularyFactory"
131 />279 >
132280 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
133 <utility281 </securedutility>
282
283 <class class="canonical.launchpad.vocabularies.SpecificationVocabulary">
284 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
285 </class>
286
287
288 <securedutility
134 name="SpecificationDependencies"289 name="SpecificationDependencies"
135 component="canonical.launchpad.vocabularies.SpecificationDependenciesVocabulary"290 component="canonical.launchpad.vocabularies.SpecificationDependenciesVocabulary"
136 provides="zope.schema.interfaces.IVocabularyFactory"291 provides="zope.schema.interfaces.IVocabularyFactory"
137 />292 >
138293 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
139 <utility294 </securedutility>
295
296 <class class="canonical.launchpad.vocabularies.SpecificationDependenciesVocabulary">
297 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
298 </class>
299
300
301 <securedutility
140 name="SpecificationDepCandidates"302 name="SpecificationDepCandidates"
141 component="canonical.launchpad.vocabularies.SpecificationDepCandidatesVocabulary"303 component="canonical.launchpad.vocabularies.SpecificationDepCandidatesVocabulary"
142 provides="zope.schema.interfaces.IVocabularyFactory"304 provides="zope.schema.interfaces.IVocabularyFactory"
143 />305 >
144306 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
145 <utility307 </securedutility>
308
309 <class class="canonical.launchpad.vocabularies.SpecificationDepCandidatesVocabulary">
310 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
311 </class>
312
313
314 <securedutility
146 name="Sprint"315 name="Sprint"
147 component="canonical.launchpad.vocabularies.SprintVocabulary"316 component="canonical.launchpad.vocabularies.SprintVocabulary"
148 provides="zope.schema.interfaces.IVocabularyFactory"317 provides="zope.schema.interfaces.IVocabularyFactory"
149 />318 >
150319 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
151 <utility320 </securedutility>
321
322 <class class="canonical.launchpad.vocabularies.SprintVocabulary">
323 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
324 </class>
325
326
327 <securedutility
152 name="TranslationGroup"328 name="TranslationGroup"
153 component="canonical.launchpad.vocabularies.TranslationGroupVocabulary"329 component="canonical.launchpad.vocabularies.TranslationGroupVocabulary"
154 provides="zope.schema.interfaces.IVocabularyFactory"330 provides="zope.schema.interfaces.IVocabularyFactory"
155 />331 >
156332 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
157 <utility333 </securedutility>
334
335 <class class="canonical.launchpad.vocabularies.TranslationGroupVocabulary">
336 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
337 </class>
338
339
340 <securedutility
158 name="TranslationMessage"341 name="TranslationMessage"
159 component="canonical.launchpad.vocabularies.TranslationMessageVocabulary"342 component="canonical.launchpad.vocabularies.TranslationMessageVocabulary"
160 provides="zope.schema.interfaces.IVocabularyFactory"343 provides="zope.schema.interfaces.IVocabularyFactory"
161 />344 >
162345 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
163 <utility346 </securedutility>
347
348 <class class="canonical.launchpad.vocabularies.TranslationMessageVocabulary">
349 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
350 </class>
351
352
353 <securedutility
164 name="TranslationTemplate"354 name="TranslationTemplate"
165 component="canonical.launchpad.vocabularies.TranslationTemplateVocabulary"355 component="canonical.launchpad.vocabularies.TranslationTemplateVocabulary"
166 provides="zope.schema.interfaces.IVocabularyFactory"356 provides="zope.schema.interfaces.IVocabularyFactory"
167 />357 >
168358 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
169 <utility359 </securedutility>
360
361 <class class="canonical.launchpad.vocabularies.TranslationTemplateVocabulary">
362 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
363 </class>
364
365
366 <securedutility
170 name="Processor"367 name="Processor"
171 component="canonical.launchpad.vocabularies.ProcessorVocabulary"368 component="canonical.launchpad.vocabularies.ProcessorVocabulary"
172 provides="zope.schema.interfaces.IVocabularyFactory"369 provides="zope.schema.interfaces.IVocabularyFactory"
173 />370 >
174371 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
175 <utility372 </securedutility>
373
374 <class class="canonical.launchpad.vocabularies.ProcessorVocabulary">
375 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
376 </class>
377
378
379 <securedutility
176 name="ProcessorFamily"380 name="ProcessorFamily"
177 component="canonical.launchpad.vocabularies.ProcessorFamilyVocabulary"381 component="canonical.launchpad.vocabularies.ProcessorFamilyVocabulary"
178 provides="zope.schema.interfaces.IVocabularyFactory"382 provides="zope.schema.interfaces.IVocabularyFactory"
179 />383 >
384 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
385 </securedutility>
386
387 <class class="canonical.launchpad.vocabularies.ProcessorFamilyVocabulary">
388 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
389 </class>
390
180</configure>391</configure>
181392
=== modified file 'lib/canonical/launchpad/vocabularies/dbobjects.py'
--- lib/canonical/launchpad/vocabularies/dbobjects.py 2009-10-26 18:40:04 +0000
+++ lib/canonical/launchpad/vocabularies/dbobjects.py 2010-01-18 21:51:20 +0000
@@ -10,9 +10,10 @@
10__metaclass__ = type10__metaclass__ = type
1111
12__all__ = [12__all__ = [
13 'HostedBranchRestrictedOnOwnerVocabulary',
14 'BranchRestrictedOnProductVocabulary',13 'BranchRestrictedOnProductVocabulary',
15 'BranchVocabulary',14 'BranchVocabulary',
15 'BugNominatableDistroSeriesVocabulary',
16 'BugNominatableProductSeriesVocabulary',
16 'BugNominatableSeriesVocabulary',17 'BugNominatableSeriesVocabulary',
17 'BugTrackerVocabulary',18 'BugTrackerVocabulary',
18 'BugVocabulary',19 'BugVocabulary',
@@ -25,11 +26,13 @@
25 'FilteredFullLanguagePackVocabulary',26 'FilteredFullLanguagePackVocabulary',
26 'FilteredLanguagePackVocabulary',27 'FilteredLanguagePackVocabulary',
27 'FutureSprintVocabulary',28 'FutureSprintVocabulary',
29 'HostedBranchRestrictedOnOwnerVocabulary',
28 'LanguageVocabulary',30 'LanguageVocabulary',
31 'PackageReleaseVocabulary',
29 'PPAVocabulary',32 'PPAVocabulary',
30 'PackageReleaseVocabulary',
31 'ProcessorFamilyVocabulary',33 'ProcessorFamilyVocabulary',
32 'ProcessorVocabulary',34 'ProcessorVocabulary',
35 'project_products_using_malone_vocabulary_factory',
33 'SpecificationDepCandidatesVocabulary',36 'SpecificationDepCandidatesVocabulary',
34 'SpecificationDependenciesVocabulary',37 'SpecificationDependenciesVocabulary',
35 'SpecificationVocabulary',38 'SpecificationVocabulary',
@@ -39,7 +42,6 @@
39 'TranslationMessageVocabulary',42 'TranslationMessageVocabulary',
40 'TranslationTemplateVocabulary',43 'TranslationTemplateVocabulary',
41 'WebBugTrackerVocabulary',44 'WebBugTrackerVocabulary',
42 'project_products_using_malone_vocabulary_factory',
43 ]45 ]
4446
45import cgi47import cgi
4648
=== modified file 'lib/canonical/launchpad/webapp/configure.zcml'
--- lib/canonical/launchpad/webapp/configure.zcml 2010-01-13 13:23:20 +0000
+++ lib/canonical/launchpad/webapp/configure.zcml 2010-01-18 21:51:20 +0000
@@ -815,6 +815,7 @@
815815
816 <class class="canonical.launchpad.webapp.vocabulary.CountableIterator">816 <class class="canonical.launchpad.webapp.vocabulary.CountableIterator">
817 <allow interface="canonical.launchpad.webapp.vocabulary.ICountableIterator" />817 <allow interface="canonical.launchpad.webapp.vocabulary.ICountableIterator" />
818 <allow attributes="__getslice__"/>
818 </class>819 </class>
819820
820 <class class="canonical.launchpad.webapp.vocabulary.BatchedCountableIterator">821 <class class="canonical.launchpad.webapp.vocabulary.BatchedCountableIterator">
821822
=== modified file 'lib/canonical/launchpad/webapp/metazcml.py'
--- lib/canonical/launchpad/webapp/metazcml.py 2009-10-21 13:11:48 +0000
+++ lib/canonical/launchpad/webapp/metazcml.py 2010-01-18 21:51:20 +0000
@@ -75,6 +75,8 @@
7575
76 component = GlobalObject(title=u'component', required=False)76 component = GlobalObject(title=u'component', required=False)
7777
78 name = TextLine(title=u"Name", required=False)
79
7880
79class PermissionCollectingContext:81class PermissionCollectingContext:
8082
@@ -97,7 +99,8 @@
9799
98class SecuredUtilityDirective:100class SecuredUtilityDirective:
99101
100 def __init__(self, _context, provides, class_=None, component=None):102 def __init__(self, _context, provides, class_=None, component=None,
103 name=''):
101 if class_ is not None:104 if class_ is not None:
102 assert component is None, "Both class and component specified"105 assert component is None, "Both class and component specified"
103 self.component = class_()106 self.component = class_()
@@ -107,6 +110,7 @@
107 self.component = component110 self.component = component
108 self._context = _context111 self._context = _context
109 self.provides = provides112 self.provides = provides
113 self.name = name
110 self.permission_collector = PermissionCollectingContext()114 self.permission_collector = PermissionCollectingContext()
111 self.contentdirective = ClassDirective(115 self.contentdirective = ClassDirective(
112 self.permission_collector, class_)116 self.permission_collector, class_)
@@ -127,7 +131,8 @@
127 self.permission_collector.set_permissions131 self.permission_collector.set_permissions
128 )132 )
129 component = ProxyFactory(self.component, checker=checker)133 component = ProxyFactory(self.component, checker=checker)
130 utility(self._context, self.provides, component=component)134 utility(self._context, self.provides, component=component,
135 name=self.name)
131 return ()136 return ()
132137
133138
134139
=== modified file 'lib/canonical/launchpad/zcml/binaryandsourcepackagename.zcml'
--- lib/canonical/launchpad/zcml/binaryandsourcepackagename.zcml 2009-07-13 18:15:02 +0000
+++ lib/canonical/launchpad/zcml/binaryandsourcepackagename.zcml 2010-01-18 21:51:20 +0000
@@ -15,11 +15,22 @@
15 <allow interface="canonical.launchpad.interfaces.IBinaryAndSourcePackageName" />15 <allow interface="canonical.launchpad.interfaces.IBinaryAndSourcePackageName" />
16 </class>16 </class>
1717
18 <utility18 <class class="canonical.launchpad.database.binaryandsourcepackagename.BinaryAndSourcePackageNameIterator">
19 <allow interface="canonical.launchpad.webapp.vocabulary.ICountableIterator" />
20 </class>
21
22 <securedutility
19 name="BinaryAndSourcePackageName"23 name="BinaryAndSourcePackageName"
20 component="canonical.launchpad.database.binaryandsourcepackagename.BinaryAndSourcePackageNameVocabulary"24 component="canonical.launchpad.database.binaryandsourcepackagename.BinaryAndSourcePackageNameVocabulary"
21 provides="zope.schema.interfaces.IVocabularyFactory"25 provides="zope.schema.interfaces.IVocabularyFactory"
22 />26 >
27 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
28 </securedutility>
29
30 <class class="canonical.launchpad.database.binaryandsourcepackagename.BinaryAndSourcePackageNameVocabulary">
31 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
32 </class>
33
2334
24 </facet>35 </facet>
25</configure>36</configure>
2637
=== modified file 'lib/lp/answers/configure.zcml'
--- lib/lp/answers/configure.zcml 2009-09-22 18:45:02 +0000
+++ lib/lp/answers/configure.zcml 2010-01-18 21:51:20 +0000
@@ -221,11 +221,18 @@
221 <allow interface=".interfaces.faq.IFAQSet" />221 <allow interface=".interfaces.faq.IFAQSet" />
222 </securedutility>222 </securedutility>
223223
224 <utility224 <securedutility
225 name="FAQ"225 name="FAQ"
226 component=".vocabulary.FAQVocabulary"226 component=".vocabulary.FAQVocabulary"
227 provides="zope.schema.interfaces.IVocabularyFactory"227 provides="zope.schema.interfaces.IVocabularyFactory"
228 />228 >
229 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
230 </securedutility>
231
232 <class class=".vocabulary.FAQVocabulary">
233 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
234 </class>
235
229236
230 <lp:help-folder237 <lp:help-folder
231 folder="help" type="canonical.launchpad.layers.AnswersLayer" />238 folder="help" type="canonical.launchpad.layers.AnswersLayer" />
232239
=== modified file 'lib/lp/answers/doc/faq-vocabulary.txt'
--- lib/lp/answers/doc/faq-vocabulary.txt 2009-04-17 10:32:16 +0000
+++ lib/lp/answers/doc/faq-vocabulary.txt 2010-01-18 21:51:20 +0000
@@ -73,9 +73,10 @@
73The searchForTerms() method returns a CountableIterator of terms that73The searchForTerms() method returns a CountableIterator of terms that
74are similar to the query:74are similar to the query:
7575
76 >>> from zope.security import proxy
76 >>> from canonical.launchpad.webapp.vocabulary import CountableIterator77 >>> from canonical.launchpad.webapp.vocabulary import CountableIterator
77 >>> terms = vocabulary.searchForTerms('Problem showing SVG')78 >>> terms = vocabulary.searchForTerms('Problem showing SVG')
78 >>> isinstance(terms, CountableIterator)79 >>> proxy.isinstance(terms, CountableIterator)
79 True80 True
80 >>> terms.count()81 >>> terms.count()
81 282 2
8283
=== modified file 'lib/lp/registry/doc/vocabularies.txt'
--- lib/lp/registry/doc/vocabularies.txt 2009-12-24 01:41:54 +0000
+++ lib/lp/registry/doc/vocabularies.txt 2010-01-18 21:51:20 +0000
@@ -11,8 +11,12 @@
11 >>> launchbag.clear()11 >>> launchbag.clear()
1212
13 >>> from zope.schema.vocabulary import getVocabularyRegistry13 >>> from zope.schema.vocabulary import getVocabularyRegistry
14 >>> from zope.security.proxy import removeSecurityProxy
14 >>> vocabulary_registry = getVocabularyRegistry()15 >>> vocabulary_registry = getVocabularyRegistry()
15 >>> product_vocabulary = vocabulary_registry.get(None, "Product")16 >>> def get_naked_vocab(context, name):
17 ... return removeSecurityProxy(
18 ... vocabulary_registry.get(context, name))
19 >>> product_vocabulary = get_naked_vocab(None, "Product")
1620
1721
18== ActiveMailingList ==22== ActiveMailingList ==
@@ -20,7 +24,7 @@
20The active mailing lists vocabulary matches and returns only those mailing24The active mailing lists vocabulary matches and returns only those mailing
21lists which are active.25lists which are active.
2226
23 >>> list_vocabulary = vocabulary_registry.get(None, 'ActiveMailingList')27 >>> list_vocabulary = get_naked_vocab(None, 'ActiveMailingList')
24 >>> from canonical.launchpad.webapp.testing import verifyObject28 >>> from canonical.launchpad.webapp.testing import verifyObject
25 >>> from canonical.launchpad.webapp.vocabulary import IHugeVocabulary29 >>> from canonical.launchpad.webapp.vocabulary import IHugeVocabulary
26 >>> verifyObject(IHugeVocabulary, list_vocabulary)30 >>> verifyObject(IHugeVocabulary, list_vocabulary)
@@ -181,7 +185,7 @@
181Reflects the available distribution series. Results are ordered by185Reflects the available distribution series. Results are ordered by
182`name`186`name`
183187
184 >>> distroseries_vocabulary = vocabulary_registry.get(188 >>> distroseries_vocabulary = get_naked_vocab(
185 ... None,"DistroSeries")189 ... None,"DistroSeries")
186 >>> for term in distroseries_vocabulary:190 >>> for term in distroseries_vocabulary:
187 ... print "%30s %s" % (term.token, term.title)191 ... print "%30s %s" % (term.token, term.title)
@@ -225,7 +229,7 @@
225All the teams the person is an active member of.229All the teams the person is an active member of.
226230
227 >>> foo_bar = person_set.getByEmail('foo.bar@canonical.com')231 >>> foo_bar = person_set.getByEmail('foo.bar@canonical.com')
228 >>> person_active_membership = vocabulary_registry.get(232 >>> person_active_membership = get_naked_vocab(
229 ... foo_bar, 'PersonActiveMembership')233 ... foo_bar, 'PersonActiveMembership')
230 >>> len(person_active_membership)234 >>> len(person_active_membership)
231 10235 10
@@ -320,7 +324,7 @@
320 [u'hwdb-team', u'landscape-developers', u'launchpad-users', u'name18',324 [u'hwdb-team', u'landscape-developers', u'launchpad-users', u'name18',
321 u'name20']325 u'name20']
322326
323 >>> sample_person_teams_vocabulary = vocabulary_registry.get(327 >>> sample_person_teams_vocabulary = get_naked_vocab(
324 ... sample_person, 'PersonTeamParticipations')328 ... sample_person, 'PersonTeamParticipations')
325329
326 >>> for term in sample_person_teams_vocabulary:330 >>> for term in sample_person_teams_vocabulary:
@@ -343,13 +347,13 @@
343to the current context. If no context is given, or if the context does347to the current context. If no context is given, or if the context does
344not have any milestones, a MilestoneVocabulary is empty...348not have any milestones, a MilestoneVocabulary is empty...
345349
346 >>> milestones = vocabulary_registry.get(None, 'Milestone')350 >>> milestones = get_naked_vocab(None, 'Milestone')
347 >>> len(milestones)351 >>> len(milestones)
348 0352 0
349353
350 >>> from canonical.launchpad.interfaces import IMaloneApplication354 >>> from canonical.launchpad.interfaces import IMaloneApplication
351 >>> malone = getUtility(IMaloneApplication)355 >>> malone = getUtility(IMaloneApplication)
352 >>> milestones = vocabulary_registry.get(malone, 'Milestone')356 >>> milestones = get_naked_vocab(malone, 'Milestone')
353 >>> len(milestones)357 >>> len(milestones)
354 0358 0
355359
@@ -358,7 +362,7 @@
358milestones from RelevantMilestonesMixin.getMilestoneWidgetValues()362milestones from RelevantMilestonesMixin.getMilestoneWidgetValues()
359but we need the big default vocabulary for form input validation.363but we need the big default vocabulary for form input validation.
360364
361 >>> all_milestones = vocabulary_registry.get(sample_person, 'Milestone')365 >>> all_milestones = get_naked_vocab(sample_person, 'Milestone')
362 >>> len(all_milestones)366 >>> len(all_milestones)
363 3367 3
364 >>> for term in all_milestones:368 >>> for term in all_milestones:
@@ -371,7 +375,7 @@
371vocabulary.375vocabulary.
372376
373 >>> firefox = product_set.getByName('firefox')377 >>> firefox = product_set.getByName('firefox')
374 >>> firefox_milestones = vocabulary_registry.get(firefox, 'Milestone')378 >>> firefox_milestones = get_naked_vocab(firefox, 'Milestone')
375 >>> for term in firefox_milestones:379 >>> for term in firefox_milestones:
376 ... print "%s: %s" % (term.value.target.name, term.value.name)380 ... print "%s: %s" % (term.value.target.name, term.value.name)
377 firefox: 1.0381 firefox: 1.0
@@ -382,7 +386,7 @@
382 >>> firefox_trunk = firefox.getSeries('trunk')386 >>> firefox_trunk = firefox.getSeries('trunk')
383 >>> firefox_milestone = factory.makeMilestone(387 >>> firefox_milestone = factory.makeMilestone(
384 ... product=firefox, name='firefox-milestone-no-series')388 ... product=firefox, name='firefox-milestone-no-series')
385 >>> firefox_trunk_milestones = vocabulary_registry.get(firefox_trunk,389 >>> firefox_trunk_milestones = get_naked_vocab(firefox_trunk,
386 ... 'Milestone')390 ... 'Milestone')
387 >>> for term in firefox_trunk_milestones:391 >>> for term in firefox_trunk_milestones:
388 ... print "%s: %s" % (term.value.target.name, term.value.name)392 ... print "%s: %s" % (term.value.target.name, term.value.name)
@@ -397,7 +401,7 @@
397 >>> firefox_task = bug_one.bugtasks[0]401 >>> firefox_task = bug_one.bugtasks[0]
398 >>> firefox_task.bugtargetdisplayname402 >>> firefox_task.bugtargetdisplayname
399 u'Mozilla Firefox'403 u'Mozilla Firefox'
400 >>> firefox_task_milestones = vocabulary_registry.get(404 >>> firefox_task_milestones = get_naked_vocab(
401 ... firefox_task, 'Milestone')405 ... firefox_task, 'Milestone')
402 >>> for term in firefox_task_milestones:406 >>> for term in firefox_task_milestones:
403 ... print "%s: %s" % (term.value.target.name, term.value.name)407 ... print "%s: %s" % (term.value.target.name, term.value.name)
@@ -408,7 +412,7 @@
408 >>> debian_woody_task = bug_two.bugtasks[-1]412 >>> debian_woody_task = bug_two.bugtasks[-1]
409 >>> debian_woody_task.bugtargetdisplayname413 >>> debian_woody_task.bugtargetdisplayname
410 u'mozilla-firefox (Debian Woody)'414 u'mozilla-firefox (Debian Woody)'
411 >>> debian_woody_milestones = vocabulary_registry.get(415 >>> debian_woody_milestones = get_naked_vocab(
412 ... debian_woody_task, 'Milestone')416 ... debian_woody_task, 'Milestone')
413 >>> debian_woody = debian_woody_task.distroseries417 >>> debian_woody = debian_woody_task.distroseries
414 >>> len(debian_woody_milestones)418 >>> len(debian_woody_milestones)
@@ -420,7 +424,7 @@
420 >>> milestone = debian_woody.milestones[0]424 >>> milestone = debian_woody.milestones[0]
421 >>> milestone.active = False425 >>> milestone.active = False
422 >>> flush_database_updates()426 >>> flush_database_updates()
423 >>> len(vocabulary_registry.get(debian_woody_task, 'Milestone'))427 >>> len(get_naked_vocab(debian_woody_task, 'Milestone'))
424 1428 1
425429
426If the milestone was used in a bugtask before it was marked inactive, though,430If the milestone was used in a bugtask before it was marked inactive, though,
@@ -428,7 +432,7 @@
428432
429 >>> debian_woody_task.milestone = milestone433 >>> debian_woody_task.milestone = milestone
430 >>> flush_database_updates()434 >>> flush_database_updates()
431 >>> len(vocabulary_registry.get(debian_woody_task, 'Milestone'))435 >>> len(get_naked_vocab(debian_woody_task, 'Milestone'))
432 2436 2
433437
434This is true for inactive milestones used in bugtasks for products and438This is true for inactive milestones used in bugtasks for products and
@@ -436,7 +440,7 @@
436440
437 >>> product_bugtask = factory.makeBugTask(target=firefox)441 >>> product_bugtask = factory.makeBugTask(target=firefox)
438 >>> product_bugtask.milestone = firefox_milestone442 >>> product_bugtask.milestone = firefox_milestone
439 >>> product_target_milestones = vocabulary_registry.get(443 >>> product_target_milestones = get_naked_vocab(
440 ... product_bugtask, 'Milestone')444 ... product_bugtask, 'Milestone')
441 >>> for term in product_target_milestones:445 >>> for term in product_target_milestones:
442 ... print "%s: %s" % (term.value.target.name, term.value.name)446 ... print "%s: %s" % (term.value.target.name, term.value.name)
@@ -444,7 +448,7 @@
444 firefox: firefox-milestone-no-series448 firefox: firefox-milestone-no-series
445449
446 >>> firefox_milestone.active = False450 >>> firefox_milestone.active = False
447 >>> product_target_milestones = vocabulary_registry.get(451 >>> product_target_milestones = get_naked_vocab(
448 ... product_bugtask, 'Milestone')452 ... product_bugtask, 'Milestone')
449 >>> for term in product_target_milestones:453 >>> for term in product_target_milestones:
450 ... print "%s: %s" % (term.value.target.name, term.value.name)454 ... print "%s: %s" % (term.value.target.name, term.value.name)
@@ -453,7 +457,7 @@
453457
454 >>> productseries_bugtask = factory.makeBugTask(target=firefox_trunk)458 >>> productseries_bugtask = factory.makeBugTask(target=firefox_trunk)
455 >>> productseries_bugtask.milestone = firefox_milestone459 >>> productseries_bugtask.milestone = firefox_milestone
456 >>> productseries_target_milestones = vocabulary_registry.get(460 >>> productseries_target_milestones = get_naked_vocab(
457 ... productseries_bugtask, 'Milestone')461 ... productseries_bugtask, 'Milestone')
458 >>> for term in productseries_target_milestones:462 >>> for term in productseries_target_milestones:
459 ... print "%s: %s" % (term.value.target.name, term.value.name)463 ... print "%s: %s" % (term.value.target.name, term.value.name)
@@ -464,7 +468,7 @@
464target are in the vocabulary.468target are in the vocabulary.
465469
466 >>> canvas_spec = firefox.getSpecification('canvas')470 >>> canvas_spec = firefox.getSpecification('canvas')
467 >>> spec_target_milestones = vocabulary_registry.get(471 >>> spec_target_milestones = get_naked_vocab(
468 ... canvas_spec, 'Milestone')472 ... canvas_spec, 'Milestone')
469 >>> for term in spec_target_milestones:473 >>> for term in spec_target_milestones:
470 ... print "%s: %s" % (term.value.target.name, term.value.name)474 ... print "%s: %s" % (term.value.target.name, term.value.name)
@@ -481,10 +485,10 @@
481 u'1.0'485 u'1.0'
482 >>> one_dot_o.active = False486 >>> one_dot_o.active = False
483487
484 >>> firefox_milestones = vocabulary_registry.get(firefox, 'Milestone')488 >>> firefox_milestones = get_naked_vocab(firefox, 'Milestone')
485 >>> len(firefox_milestones)489 >>> len(firefox_milestones)
486 0490 0
487 >>> firefox_task_milestones = vocabulary_registry.get(491 >>> firefox_task_milestones = get_naked_vocab(
488 ... firefox_task, 'Milestone')492 ... firefox_task, 'Milestone')
489 >>> len(firefox_task_milestones)493 >>> len(firefox_task_milestones)
490 0494 0
@@ -495,7 +499,7 @@
495All the products in a project.499All the products in a project.
496500
497 >>> mozilla_project = getUtility(IProjectSet).getByName('mozilla')501 >>> mozilla_project = getUtility(IProjectSet).getByName('mozilla')
498 >>> mozilla_products_vocabulary = vocabulary_registry.get(502 >>> mozilla_products_vocabulary = get_naked_vocab(
499 ... mozilla_project,'ProjectProducts')503 ... mozilla_project,'ProjectProducts')
500504
501 >>> for term in mozilla_products_vocabulary:505 >>> for term in mozilla_products_vocabulary:
@@ -508,7 +512,7 @@
508512
509The list of selectable projects. The results are ordered by displayname.513The list of selectable projects. The results are ordered by displayname.
510514
511 >>> project_vocabulary = vocabulary_registry.get(None, "Project")515 >>> project_vocabulary = get_naked_vocab(None, "Project")
512 >>> project_vocabulary.displayname516 >>> project_vocabulary.displayname
513 'Select a project group'517 'Select a project group'
514518
@@ -542,7 +546,7 @@
542546
543The list of selectable products. Results are ordered by displayname.547The list of selectable products. Results are ordered by displayname.
544548
545 >>> product_vocabulary = vocabulary_registry.get(None, "Product")549 >>> product_vocabulary = get_naked_vocab(None, "Product")
546 >>> product_vocabulary.displayname550 >>> product_vocabulary.displayname
547 'Select a project'551 'Select a project'
548552
@@ -583,8 +587,7 @@
583587
584The list of selectable products releases.588The list of selectable products releases.
585589
586 >>> productrelease_vocabulary = vocabulary_registry.get(None,590 >>> productrelease_vocabulary = get_naked_vocab(None, "ProductRelease")
587 ... "ProductRelease")
588 >>> productrelease_vocabulary.displayname591 >>> productrelease_vocabulary.displayname
589 'Select a Product Release'592 'Select a Product Release'
590593
@@ -603,7 +606,7 @@
603All non-merged people with at least one email address. This vocabulary is606All non-merged people with at least one email address. This vocabulary is
604meant to be used only in the people merge form.607meant to be used only in the people merge form.
605608
606 >>> vocab = vocabulary_registry.get(None, "PersonAccountToMerge")609 >>> vocab = get_naked_vocab(None, "PersonAccountToMerge")
607 >>> vocab.displayname610 >>> vocab.displayname
608 'Select a Person to Merge'611 'Select a Person to Merge'
609612
@@ -668,7 +671,6 @@
668 True671 True
669672
670 # Here we cheat because IPerson.merged is a readonly attribute.673 # Here we cheat because IPerson.merged is a readonly attribute.
671 >>> from zope.security.proxy import removeSecurityProxy
672 >>> naked_cprov = removeSecurityProxy(cprov)674 >>> naked_cprov = removeSecurityProxy(cprov)
673 >>> naked_cprov.merged = 1675 >>> naked_cprov.merged = 1
674 >>> naked_cprov.syncUpdate()676 >>> naked_cprov.syncUpdate()
@@ -693,7 +695,7 @@
693695
694The set of non-merged people.696The set of non-merged people.
695697
696 >>> vocab = vocabulary_registry.get(None, "AdminMergeablePerson")698 >>> vocab = get_naked_vocab(None, "AdminMergeablePerson")
697 >>> vocab.displayname699 >>> vocab.displayname
698 'Select a Person to Merge'700 'Select a Person to Merge'
699701
@@ -712,7 +714,7 @@
712714
713All non-merged people and teams.715All non-merged people and teams.
714716
715 >>> vocab = vocabulary_registry.get(None, "NonMergedPeopleAndTeams")717 >>> vocab = get_naked_vocab(None, "NonMergedPeopleAndTeams")
716 >>> vocab.displayname718 >>> vocab.displayname
717 'Select a Person or Team'719 'Select a Person or Team'
718720
@@ -746,7 +748,7 @@
746None). It also includes all public teams and private teams the748None). It also includes all public teams and private teams the
747user has permission to view.749user has permission to view.
748750
749 >>> vocab = vocabulary_registry.get(None, "ValidPersonOrTeam")751 >>> vocab = get_naked_vocab(None, "ValidPersonOrTeam")
750 >>> vocab.displayname752 >>> vocab.displayname
751 'Select a Person or Team'753 'Select a Person or Team'
752754
@@ -794,7 +796,7 @@
794A PRIVATE team is displayed when the logged in user is a member of the team.796A PRIVATE team is displayed when the logged in user is a member of the team.
795797
796 >>> commercial = person_set.getByEmail('commercial-member@canonical.com')798 >>> commercial = person_set.getByEmail('commercial-member@canonical.com')
797 >>> vocab = vocabulary_registry.get(commercial, "ValidPersonOrTeam")799 >>> vocab = get_naked_vocab(commercial, "ValidPersonOrTeam")
798 >>> login('commercial-member@canonical.com')800 >>> login('commercial-member@canonical.com')
799 >>> priv_team = factory.makeTeam(801 >>> priv_team = factory.makeTeam(
800 ... name='private-team',802 ... name='private-team',
@@ -861,7 +863,7 @@
861one of its email addresses.863one of its email addresses.
862864
863 >>> login('foo.bar@canonical.com')865 >>> login('foo.bar@canonical.com')
864 >>> vocab = vocabulary_registry.get(None, "ValidPersonOrTeam")866 >>> vocab = get_naked_vocab(None, "ValidPersonOrTeam")
865 >>> sorted(person.name for person in vocab.search('support'))867 >>> sorted(person.name for person in vocab.search('support'))
866 [u'ubuntu-team']868 [u'ubuntu-team']
867869
@@ -932,7 +934,7 @@
932All valid persons and teams are also valid owners.934All valid persons and teams are also valid owners.
933935
934 >>> login(ANONYMOUS)936 >>> login(ANONYMOUS)
935 >>> vocab = vocabulary_registry.get(None, "ValidOwner")937 >>> vocab = get_naked_vocab(None, "ValidOwner")
936 >>> vocab.displayname938 >>> vocab.displayname
937 'Select a Person or Team'939 'Select a Person or Team'
938940
@@ -955,7 +957,7 @@
955except that its terms are limited only to teams. No non-team Persons will be957except that its terms are limited only to teams. No non-team Persons will be
956returned.958returned.
957959
958 >>> vocab = vocabulary_registry.get(None, 'ValidTeam')960 >>> vocab = get_naked_vocab(None, 'ValidTeam')
959 >>> vocab.displayname961 >>> vocab.displayname
960 'Select a Team'962 'Select a Team'
961 >>> sorted((team.displayname, team.teamowner.displayname)963 >>> sorted((team.displayname, team.teamowner.displayname)
@@ -1062,21 +1064,21 @@
10621064
1063ValidTeamMember needs a context:1065ValidTeamMember needs a context:
10641066
1065 >>> vocab = vocabulary_registry.get(None, "ValidTeamMember")1067 >>> vocab = get_naked_vocab(None, "ValidTeamMember")
1066 Traceback (most recent call last):1068 Traceback (most recent call last):
1067 ...1069 ...
1068 AssertionError: ...1070 AssertionError: ...
10691071
1070ValidTeamMember's context must implement ITeam:1072ValidTeamMember's context must implement ITeam:
10711073
1072 >>> vocab = vocabulary_registry.get(person, "ValidTeamMember")1074 >>> vocab = get_naked_vocab(person, "ValidTeamMember")
1073 Traceback (most recent call last):1075 Traceback (most recent call last):
1074 ...1076 ...
1075 AssertionError: ...1077 AssertionError: ...
10761078
1077'name16' is a valid member for 'ubuntu-team':1079'name16' is a valid member for 'ubuntu-team':
10781080
1079 >>> vocab = vocabulary_registry.get(team, "ValidTeamMember")1081 >>> vocab = get_naked_vocab(team, "ValidTeamMember")
1080 >>> vocab.displayname1082 >>> vocab.displayname
1081 'Select a Person or Team'1083 'Select a Person or Team'
10821084
@@ -1108,25 +1110,25 @@
11081110
1109ValidTeamOwner needs a context.1111ValidTeamOwner needs a context.
11101112
1111 >>> vocab = vocabulary_registry.get(None, "ValidTeamOwner")1113 >>> vocab = get_naked_vocab(None, "ValidTeamOwner")
1112 Traceback (most recent call last):1114 Traceback (most recent call last):
1113 ...1115 ...
1114 AssertionError: ...1116 AssertionError: ...
11151117
1116ValidTeamOwner's context must provide IPerson or IPersonSet.1118ValidTeamOwner's context must provide IPerson or IPersonSet.
11171119
1118 >>> vocabulary_registry.get(team, "ValidTeamOwner")1120 >>> get_naked_vocab(team, "ValidTeamOwner")
1119 <...ValidTeamOwnerVocabulary...1121 <...ValidTeamOwnerVocabulary...
1120 >>> vocabulary_registry.get(person_set, "ValidTeamOwner")1122 >>> get_naked_vocab(person_set, "ValidTeamOwner")
1121 <...ValidTeamOwnerVocabulary...1123 <...ValidTeamOwnerVocabulary...
1122 >>> vocabulary_registry.get(firefox, "ValidTeamOwner")1124 >>> get_naked_vocab(firefox, "ValidTeamOwner")
1123 Traceback (most recent call last):1125 Traceback (most recent call last):
1124 ...1126 ...
1125 AssertionError: ...1127 AssertionError: ...
11261128
1127'ubuntu-team' is not a valid owner for itself.1129'ubuntu-team' is not a valid owner for itself.
11281130
1129 >>> vocab = vocabulary_registry.get(team, "ValidTeamOwner")1131 >>> vocab = get_naked_vocab(team, "ValidTeamOwner")
1130 >>> vocab.displayname1132 >>> vocab.displayname
1131 'Select a Person or Team'1133 'Select a Person or Team'
11321134
@@ -1147,7 +1149,7 @@
11471149
1148All 'valid' persons who are not a team.1150All 'valid' persons who are not a team.
11491151
1150 >>> vocab = vocabulary_registry.get(None, "ValidPerson")1152 >>> vocab = get_naked_vocab(None, "ValidPerson")
1151 >>> vocab.displayname1153 >>> vocab.displayname
1152 'Select a Person'1154 'Select a Person'
1153 >>> people = vocab.search(None)1155 >>> people = vocab.search(None)
@@ -1172,8 +1174,7 @@
1172 >>> carlos = getUtility(IPersonSet).getByName('carlos')1174 >>> carlos = getUtility(IPersonSet).getByName('carlos')
1173 >>> carlos_team = factory.makeTeam(1175 >>> carlos_team = factory.makeTeam(
1174 ... owner=carlos, name='carlos-team')1176 ... owner=carlos, name='carlos-team')
1175 >>> person_or_team_vocab = vocabulary_registry.get(1177 >>> person_or_team_vocab = get_naked_vocab(None, "ValidPersonOrTeam")
1176 ... None, "ValidPersonOrTeam")
1177 >>> carlos_people_or_team = person_or_team_vocab.search('carlos')1178 >>> carlos_people_or_team = person_or_team_vocab.search('carlos')
1178 >>> # The people or team search yields our one Carlos person and1179 >>> # The people or team search yields our one Carlos person and
1179 >>> # the new team.1180 >>> # the new team.
@@ -1196,7 +1197,7 @@
1196All products and distributions. Note that the value type is1197All products and distributions. Note that the value type is
1197heterogeneous.1198heterogeneous.
11981199
1199 >>> vocab = vocabulary_registry.get(None, "DistributionOrProduct")1200 >>> vocab = get_naked_vocab(None, "DistributionOrProduct")
1200 >>> for term in vocab:1201 >>> for term in vocab:
1201 ... if 'Ubuntu' in term.title:1202 ... if 'Ubuntu' in term.title:
1202 ... print term.title, '- class', term.value.__class__.__name__1203 ... print term.title, '- class', term.value.__class__.__name__
@@ -1236,12 +1237,12 @@
1236 True1237 True
1237 >>> tomcat.active = False1238 >>> tomcat.active = False
1238 >>> flush_database_updates()1239 >>> flush_database_updates()
1239 >>> vocab = vocabulary_registry.get(None, "DistributionOrProduct")1240 >>> vocab = get_naked_vocab(None, "DistributionOrProduct")
1240 >>> tomcat in vocab1241 >>> tomcat in vocab
1241 False1242 False
1242 >>> tomcat.active = True1243 >>> tomcat.active = True
1243 >>> flush_database_updates()1244 >>> flush_database_updates()
1244 >>> vocab = vocabulary_registry.get(None, "DistributionOrProduct")1245 >>> vocab = get_naked_vocab(None, "DistributionOrProduct")
1245 >>> tomcat in vocab1246 >>> tomcat in vocab
1246 True1247 True
12471248
@@ -1257,7 +1258,7 @@
1257All products, projects and distributions. Note that the value type is1258All products, projects and distributions. Note that the value type is
1258heterogeneous.1259heterogeneous.
12591260
1260 >>> vocab = vocabulary_registry.get(None, "DistributionOrProductOrProject")1261 >>> vocab = get_naked_vocab(None, "DistributionOrProductOrProject")
1261 >>> for term in vocab:1262 >>> for term in vocab:
1262 ... if 'Ubuntu' in term.title:1263 ... if 'Ubuntu' in term.title:
1263 ... print term.title, '- class', term.value.__class__.__name__1264 ... print term.title, '- class', term.value.__class__.__name__
@@ -1297,7 +1298,7 @@
1297 >>> apache in vocab1298 >>> apache in vocab
1298 False1299 False
12991300
1300 >>> vocab = vocabulary_registry.get(None, "DistributionOrProductOrProject")1301 >>> vocab = get_naked_vocab(None, "DistributionOrProductOrProject")
1301 >>> for term in vocab:1302 >>> for term in vocab:
1302 ... if 'Apache' in term.title:1303 ... if 'Apache' in term.title:
1303 ... print term.title, '- class', term.value.__class__.__name__1304 ... print term.title, '- class', term.value.__class__.__name__
@@ -1307,7 +1308,7 @@
1307 >>> product_set.getByName('tomcat').active = True1308 >>> product_set.getByName('tomcat').active = True
1308 >>> getUtility(IProjectSet).getByName('apache').active = True1309 >>> getUtility(IProjectSet).getByName('apache').active = True
1309 >>> flush_database_updates()1310 >>> flush_database_updates()
1310 >>> vocab = vocabulary_registry.get(None, "DistributionOrProductOrProject")1311 >>> vocab = get_naked_vocab(None, "DistributionOrProductOrProject")
1311 >>> for term in vocab:1312 >>> for term in vocab:
1312 ... if 'Apache' in term.title:1313 ... if 'Apache' in term.title:
1313 ... print term.title, '- class', term.value.__class__.__name__1314 ... print term.title, '- class', term.value.__class__.__name__
@@ -1325,7 +1326,7 @@
1325DistributionOrProductOrProjectVocabulary (defined using the1326DistributionOrProductOrProjectVocabulary (defined using the
1326_clauseTables).1327_clauseTables).
13271328
1328 >>> featured_project_vocabulary = vocabulary_registry.get(1329 >>> featured_project_vocabulary = get_naked_vocab(
1329 ... None, 'FeaturedProject')1330 ... None, 'FeaturedProject')
1330 >>> len(featured_project_vocabulary)1331 >>> len(featured_project_vocabulary)
1331 91332 9
@@ -1376,7 +1377,7 @@
1376 >>> check_permission('launchpad.Commercial', bac)1377 >>> check_permission('launchpad.Commercial', bac)
1377 False1378 False
13781379
1379 >>> comm_proj_vocab = vocabulary_registry.get(bac, "CommercialProjects")1380 >>> comm_proj_vocab = get_naked_vocab(bac, "CommercialProjects")
1380 >>> print comm_proj_vocab.displayname1381 >>> print comm_proj_vocab.displayname
1381 Select a commercial project1382 Select a commercial project
13821383
@@ -1404,7 +1405,7 @@
1404 >>> check_permission('launchpad.ProjectReview', product_set)1405 >>> check_permission('launchpad.ProjectReview', product_set)
1405 True1406 True
14061407
1407 >>> comm_proj_vocab = vocabulary_registry.get(registry_member, "CommercialProjects")1408 >>> comm_proj_vocab = get_naked_vocab(registry_member, "CommercialProjects")
1408 >>> print comm_proj_vocab.displayname1409 >>> print comm_proj_vocab.displayname
1409 Select a commercial project1410 Select a commercial project
14101411
14111412
=== modified file 'lib/lp/registry/vocabularies.zcml'
--- lib/lp/registry/vocabularies.zcml 2009-07-29 03:29:24 +0000
+++ lib/lp/registry/vocabularies.zcml 2010-01-18 21:51:20 +0000
@@ -3,195 +3,404 @@
3-->3-->
44
5<configure xmlns="http://namespaces.zope.org/zope">5<configure xmlns="http://namespaces.zope.org/zope">
6 <utility6 <securedutility
7 name="Distribution"7 name="Distribution"
8 component="lp.registry.vocabularies.DistributionVocabulary"8 component="lp.registry.vocabularies.DistributionVocabulary"
9 provides="zope.schema.interfaces.IVocabularyFactory"9 provides="zope.schema.interfaces.IVocabularyFactory"
10 />10 >
1111 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
12 <utility12 </securedutility>
13
14 <class class="lp.registry.vocabularies.DistributionVocabulary">
15 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
16 </class>
17
18
19 <securedutility
13 name="DistroSeries"20 name="DistroSeries"
14 component="lp.registry.vocabularies.DistroSeriesVocabulary"21 component="lp.registry.vocabularies.DistroSeriesVocabulary"
15 provides="zope.schema.interfaces.IVocabularyFactory"22 provides="zope.schema.interfaces.IVocabularyFactory"
16 />23 >
1724 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
18 <utility25 </securedutility>
26
27 <class class="lp.registry.vocabularies.DistroSeriesVocabulary">
28 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
29 </class>
30
31
32 <securedutility
19 name="FeaturedProject"33 name="FeaturedProject"
20 component="lp.registry.vocabularies.FeaturedProjectVocabulary"34 component="lp.registry.vocabularies.FeaturedProjectVocabulary"
21 provides="zope.schema.interfaces.IVocabularyFactory"35 provides="zope.schema.interfaces.IVocabularyFactory"
22 />36 >
2337 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
24 <utility38 </securedutility>
39
40 <class class="lp.registry.vocabularies.FeaturedProjectVocabulary">
41 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
42 </class>
43
44
45 <securedutility
25 name="FilteredDistroSeries"46 name="FilteredDistroSeries"
26 component="lp.registry.vocabularies.FilteredDistroSeriesVocabulary"47 component="lp.registry.vocabularies.FilteredDistroSeriesVocabulary"
27 provides="zope.schema.interfaces.IVocabularyFactory"48 provides="zope.schema.interfaces.IVocabularyFactory"
28 />49 >
2950 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
30 <utility51 </securedutility>
52
53 <class class="lp.registry.vocabularies.FilteredDistroSeriesVocabulary">
54 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
55 </class>
56
57
58 <securedutility
31 name="FilteredProductSeries"59 name="FilteredProductSeries"
32 component="lp.registry.vocabularies.FilteredProductSeriesVocabulary"60 component="lp.registry.vocabularies.FilteredProductSeriesVocabulary"
33 provides="zope.schema.interfaces.IVocabularyFactory"61 provides="zope.schema.interfaces.IVocabularyFactory"
34 />62 >
3563 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
36 <utility64 </securedutility>
65
66 <class class="lp.registry.vocabularies.FilteredProductSeriesVocabulary">
67 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
68 </class>
69
70
71 <securedutility
37 name="KarmaCategory"72 name="KarmaCategory"
38 component="lp.registry.vocabularies.KarmaCategoryVocabulary"73 component="lp.registry.vocabularies.KarmaCategoryVocabulary"
39 provides="zope.schema.interfaces.IVocabularyFactory"74 provides="zope.schema.interfaces.IVocabularyFactory"
40 />75 >
4176 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
42 <utility77 </securedutility>
78
79 <class class="lp.registry.vocabularies.KarmaCategoryVocabulary">
80 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
81 </class>
82
83
84 <securedutility
43 name="Milestone"85 name="Milestone"
44 component="lp.registry.vocabularies.MilestoneVocabulary"86 component="lp.registry.vocabularies.MilestoneVocabulary"
45 provides="zope.schema.interfaces.IVocabularyFactory"87 provides="zope.schema.interfaces.IVocabularyFactory"
46 />88 >
4789 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
48 <utility90 </securedutility>
91
92 <class class="lp.registry.vocabularies.MilestoneVocabulary">
93 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
94 </class>
95
96
97 <securedutility
49 name="NonMergedPeopleAndTeams"98 name="NonMergedPeopleAndTeams"
50 component="lp.registry.vocabularies.NonMergedPeopleAndTeamsVocabulary"99 component="lp.registry.vocabularies.NonMergedPeopleAndTeamsVocabulary"
51 provides="zope.schema.interfaces.IVocabularyFactory"100 provides="zope.schema.interfaces.IVocabularyFactory"
52 />101 >
53102 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
54 <utility103 </securedutility>
104
105 <class class="lp.registry.vocabularies.NonMergedPeopleAndTeamsVocabulary">
106 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
107 </class>
108
109
110 <securedutility
55 name="AdminMergeablePerson"111 name="AdminMergeablePerson"
56 component="lp.registry.vocabularies.AdminMergeablePersonVocabulary"112 component="lp.registry.vocabularies.AdminMergeablePersonVocabulary"
57 provides="zope.schema.interfaces.IVocabularyFactory"113 provides="zope.schema.interfaces.IVocabularyFactory"
58 />114 >
59115 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
60 <utility116 </securedutility>
117
118 <class class="lp.registry.vocabularies.AdminMergeablePersonVocabulary">
119 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
120 </class>
121
122
123 <securedutility
61 name="PersonAccountToMerge"124 name="PersonAccountToMerge"
62 component="lp.registry.vocabularies.PersonAccountToMergeVocabulary"125 component="lp.registry.vocabularies.PersonAccountToMergeVocabulary"
63 provides="zope.schema.interfaces.IVocabularyFactory"126 provides="zope.schema.interfaces.IVocabularyFactory"
64 />127 >
65128 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
66 <utility129 </securedutility>
130
131 <class class="lp.registry.vocabularies.PersonAccountToMergeVocabulary">
132 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
133 </class>
134
135
136 <securedutility
67 name="PersonActiveMembership"137 name="PersonActiveMembership"
68 component="lp.registry.vocabularies.PersonActiveMembershipVocabulary"138 component="lp.registry.vocabularies.PersonActiveMembershipVocabulary"
69 provides="zope.schema.interfaces.IVocabularyFactory"139 provides="zope.schema.interfaces.IVocabularyFactory"
70 />140 >
71141 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
72 <utility142 </securedutility>
143
144 <class class="lp.registry.vocabularies.PersonActiveMembershipVocabulary">
145 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
146 </class>
147
148
149 <securedutility
73 name="PersonTeamParticipations"150 name="PersonTeamParticipations"
74 component="lp.registry.vocabularies.person_team_participations_vocabulary_factory"151 component="lp.registry.vocabularies.person_team_participations_vocabulary_factory"
75 provides="zope.schema.interfaces.IVocabularyFactory"152 provides="zope.schema.interfaces.IVocabularyFactory"
76 />153 >
77154 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
78 <utility155 </securedutility>
156
157
158 <securedutility
79 name="Product"159 name="Product"
80 component="lp.registry.vocabularies.ProductVocabulary"160 component="lp.registry.vocabularies.ProductVocabulary"
81 provides="zope.schema.interfaces.IVocabularyFactory"161 provides="zope.schema.interfaces.IVocabularyFactory"
82 />162 >
83163 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
84 <utility164 </securedutility>
165
166 <class class="lp.registry.vocabularies.ProductVocabulary">
167 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
168 </class>
169
170
171 <securedutility
85 name="ProductRelease"172 name="ProductRelease"
86 component="lp.registry.vocabularies.ProductReleaseVocabulary"173 component="lp.registry.vocabularies.ProductReleaseVocabulary"
87 provides="zope.schema.interfaces.IVocabularyFactory"174 provides="zope.schema.interfaces.IVocabularyFactory"
88 />175 >
89176 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
90 <utility177 </securedutility>
178
179 <class class="lp.registry.vocabularies.ProductReleaseVocabulary">
180 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
181 </class>
182
183
184 <securedutility
91 name="ProductSeries"185 name="ProductSeries"
92 component="lp.registry.vocabularies.ProductSeriesVocabulary"186 component="lp.registry.vocabularies.ProductSeriesVocabulary"
93 provides="zope.schema.interfaces.IVocabularyFactory"187 provides="zope.schema.interfaces.IVocabularyFactory"
94 />188 >
95189 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
96 <utility190 </securedutility>
191
192 <class class="lp.registry.vocabularies.ProductSeriesVocabulary">
193 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
194 </class>
195
196
197 <securedutility
97 name="Project"198 name="Project"
98 component="lp.registry.vocabularies.ProjectVocabulary"199 component="lp.registry.vocabularies.ProjectVocabulary"
99 provides="zope.schema.interfaces.IVocabularyFactory"200 provides="zope.schema.interfaces.IVocabularyFactory"
100 />201 >
101202 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
102 <utility203 </securedutility>
204
205 <class class="lp.registry.vocabularies.ProjectVocabulary">
206 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
207 </class>
208
209
210 <securedutility
103 name="ProjectProducts"211 name="ProjectProducts"
104 component="lp.registry.vocabularies.project_products_vocabulary_factory"212 component="lp.registry.vocabularies.project_products_vocabulary_factory"
105 provides="zope.schema.interfaces.IVocabularyFactory"213 provides="zope.schema.interfaces.IVocabularyFactory"
106 />214 >
107215 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
108 <utility216 </securedutility>
217
218
219 <securedutility
109 name="CommercialProjects"220 name="CommercialProjects"
110 component="lp.registry.vocabularies.CommercialProjectsVocabulary"221 component="lp.registry.vocabularies.CommercialProjectsVocabulary"
111 provides="zope.schema.interfaces.IVocabularyFactory"222 provides="zope.schema.interfaces.IVocabularyFactory"
112 />223 >
113224 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
114 <utility225 </securedutility>
226
227 <class class="lp.registry.vocabularies.CommercialProjectsVocabulary">
228 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
229 </class>
230
231
232 <securedutility
115 name="UserTeamsParticipation"233 name="UserTeamsParticipation"
116 component="lp.registry.vocabularies.UserTeamsParticipationVocabulary"234 component="lp.registry.vocabularies.UserTeamsParticipationVocabulary"
117 provides="zope.schema.interfaces.IVocabularyFactory"235 provides="zope.schema.interfaces.IVocabularyFactory"
118 />236 >
119237 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
120 <utility238 </securedutility>
239
240 <class class="lp.registry.vocabularies.UserTeamsParticipationVocabulary">
241 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
242 </class>
243
244
245 <securedutility
121 name="UserTeamsParticipationPlusSelf"246 name="UserTeamsParticipationPlusSelf"
122 component="lp.registry.vocabularies.UserTeamsParticipationPlusSelfVocabulary"247 component="lp.registry.vocabularies.UserTeamsParticipationPlusSelfVocabulary"
123 provides="zope.schema.interfaces.IVocabularyFactory"248 provides="zope.schema.interfaces.IVocabularyFactory"
124 />249 >
125250 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
126 <utility251 </securedutility>
252
253 <class class="lp.registry.vocabularies.UserTeamsParticipationPlusSelfVocabulary">
254 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
255 </class>
256
257
258 <securedutility
127 name="ActiveMailingList"259 name="ActiveMailingList"
128 component="lp.registry.vocabularies.ActiveMailingListVocabulary"260 component="lp.registry.vocabularies.ActiveMailingListVocabulary"
129 provides="zope.schema.interfaces.IVocabularyFactory"261 provides="zope.schema.interfaces.IVocabularyFactory"
130 />262 >
131263 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
132 <utility264 </securedutility>
265
266 <class class="lp.registry.vocabularies.ActiveMailingListVocabulary">
267 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
268 </class>
269
270
271 <securedutility
133 name="ValidPersonOrTeam"272 name="ValidPersonOrTeam"
134 component="lp.registry.vocabularies.ValidPersonOrTeamVocabulary"273 component="lp.registry.vocabularies.ValidPersonOrTeamVocabulary"
135 provides="zope.schema.interfaces.IVocabularyFactory"274 provides="zope.schema.interfaces.IVocabularyFactory"
136 />275 >
137276 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
138 <utility277 </securedutility>
278
279 <class class="lp.registry.vocabularies.ValidPersonOrTeamVocabulary">
280 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
281 </class>
282
283
284 <securedutility
139 name="ValidAssignee"285 name="ValidAssignee"
140 component="lp.registry.vocabularies.ValidPersonOrTeamVocabulary"286 component="lp.registry.vocabularies.ValidPersonOrTeamVocabulary"
141 provides="zope.schema.interfaces.IVocabularyFactory"287 provides="zope.schema.interfaces.IVocabularyFactory"
142 />288 >
143289 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
144 <utility290 </securedutility>
291
292
293 <securedutility
145 name="ValidMaintainer"294 name="ValidMaintainer"
146 component="lp.registry.vocabularies.ValidPersonOrTeamVocabulary"295 component="lp.registry.vocabularies.ValidPersonOrTeamVocabulary"
147 provides="zope.schema.interfaces.IVocabularyFactory"296 provides="zope.schema.interfaces.IVocabularyFactory"
148 />297 >
149298 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
150 <utility299 </securedutility>
300
301
302 <securedutility
151 name="ValidOwner"303 name="ValidOwner"
152 component="lp.registry.vocabularies.ValidPersonOrTeamVocabulary"304 component="lp.registry.vocabularies.ValidPersonOrTeamVocabulary"
153 provides="zope.schema.interfaces.IVocabularyFactory"305 provides="zope.schema.interfaces.IVocabularyFactory"
154 />306 >
155307 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
156 <utility308 </securedutility>
309
310
311 <securedutility
157 name="ValidTeam"312 name="ValidTeam"
158 component="lp.registry.vocabularies.ValidTeamVocabulary"313 component="lp.registry.vocabularies.ValidTeamVocabulary"
159 provides="zope.schema.interfaces.IVocabularyFactory"314 provides="zope.schema.interfaces.IVocabularyFactory"
160 />315 >
161316 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
162 <utility317 </securedutility>
318
319 <class class="lp.registry.vocabularies.ValidTeamVocabulary">
320 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
321 </class>
322
323
324 <securedutility
163 name="ValidPerson"325 name="ValidPerson"
164 component="lp.registry.vocabularies.ValidPersonVocabulary"326 component="lp.registry.vocabularies.ValidPersonVocabulary"
165 provides="zope.schema.interfaces.IVocabularyFactory"327 provides="zope.schema.interfaces.IVocabularyFactory"
166 />328 >
167329 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
168 <utility330 </securedutility>
331
332 <class class="lp.registry.vocabularies.ValidPersonVocabulary">
333 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
334 </class>
335
336
337 <securedutility
169 name="ValidTeamMember"338 name="ValidTeamMember"
170 component="lp.registry.vocabularies.ValidTeamMemberVocabulary"339 component="lp.registry.vocabularies.ValidTeamMemberVocabulary"
171 provides="zope.schema.interfaces.IVocabularyFactory"340 provides="zope.schema.interfaces.IVocabularyFactory"
172 />341 >
173342 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
174 <utility343 </securedutility>
344
345 <class class="lp.registry.vocabularies.ValidTeamMemberVocabulary">
346 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
347 </class>
348
349
350 <securedutility
175 name="ValidTeamOwner"351 name="ValidTeamOwner"
176 component="lp.registry.vocabularies.ValidTeamOwnerVocabulary"352 component="lp.registry.vocabularies.ValidTeamOwnerVocabulary"
177 provides="zope.schema.interfaces.IVocabularyFactory"353 provides="zope.schema.interfaces.IVocabularyFactory"
178 />354 >
179355 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
180 <utility356 </securedutility>
357
358 <class class="lp.registry.vocabularies.ValidTeamOwnerVocabulary">
359 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
360 </class>
361
362
363 <securedutility
181 name="DistributionOrProduct"364 name="DistributionOrProduct"
182 component="lp.registry.vocabularies.DistributionOrProductVocabulary"365 component="lp.registry.vocabularies.DistributionOrProductVocabulary"
183 provides="zope.schema.interfaces.IVocabularyFactory"366 provides="zope.schema.interfaces.IVocabularyFactory"
184 />367 >
185368 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
186 <utility369 </securedutility>
370
371 <class class="lp.registry.vocabularies.DistributionOrProductVocabulary">
372 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
373 </class>
374
375
376 <securedutility
187 name="DistributionOrProductOrProject"377 name="DistributionOrProductOrProject"
188 component="lp.registry.vocabularies.DistributionOrProductOrProjectVocabulary"378 component="lp.registry.vocabularies.DistributionOrProductOrProjectVocabulary"
189 provides="zope.schema.interfaces.IVocabularyFactory"379 provides="zope.schema.interfaces.IVocabularyFactory"
190 />380 >
191381 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
192 <utility382 </securedutility>
383
384 <class class="lp.registry.vocabularies.DistributionOrProductOrProjectVocabulary">
385 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
386 </class>
387
388
389 <securedutility
193 name="SourcePackageName"390 name="SourcePackageName"
194 component="lp.registry.vocabularies.SourcePackageNameVocabulary"391 component="lp.registry.vocabularies.SourcePackageNameVocabulary"
195 provides="zope.schema.interfaces.IVocabularyFactory"392 provides="zope.schema.interfaces.IVocabularyFactory"
196 />393 >
394 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
395 </securedutility>
396
397 <class class="lp.registry.vocabularies.SourcePackageNameVocabulary">
398 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
399 </class>
400
401
402 <class class="lp.registry.vocabularies.SourcePackageNameIterator">
403 <allow interface="canonical.launchpad.webapp.vocabulary.ICountableIterator"/>
404 </class>
405
197</configure>406</configure>
198407
=== added file 'lib/lp/services/tests/test_vocabularies.py'
--- lib/lp/services/tests/test_vocabularies.py 1970-01-01 00:00:00 +0000
+++ lib/lp/services/tests/test_vocabularies.py 2010-01-18 21:51:20 +0000
@@ -0,0 +1,37 @@
1# Copyright 2010 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Test registered vocabularies."""
5
6__metaclass__ = type
7__all__ = []
8
9import unittest
10
11from zope.component import getUtilitiesFor
12from zope.proxy import isProxy
13from zope.schema.interfaces import IVocabularyFactory
14from zope.security._proxy import _Proxy
15
16from canonical.testing.layers import FunctionalLayer
17from lp.testing import TestCase
18
19
20class TestVocabularies(TestCase):
21 layer = FunctionalLayer
22
23 def test_security_proxy(self):
24 """Our vocabularies should be registered with <securedutility>."""
25 vocabularies = getUtilitiesFor(IVocabularyFactory)
26 for name, vocab in vocabularies:
27 # If the vocabulary is not in a security proxy, check
28 # whether it is a vocabulary defined by zope, which are
29 # not registered with <securedutility> and can be ignored.
30 if not isProxy(vocab) and vocab.__module__[:5] != 'zope.':
31 raise AssertionError(
32 '%s.%s vocabulary is not wrapped in a security proxy.' % (
33 vocab.__module__, name))
34
35
36def test_suite():
37 return unittest.TestLoader().loadTestsFromName(__name__)
038
=== modified file 'lib/lp/services/worlddata/vocabularies.zcml'
--- lib/lp/services/worlddata/vocabularies.zcml 2009-07-13 18:15:02 +0000
+++ lib/lp/services/worlddata/vocabularies.zcml 2010-01-18 21:51:20 +0000
@@ -3,9 +3,12 @@
3-->3-->
44
5<configure xmlns="http://namespaces.zope.org/zope">5<configure xmlns="http://namespaces.zope.org/zope">
6 <utility6 <securedutility
7 name="TimezoneName"7 name="TimezoneName"
8 component="lp.services.worlddata.vocabularies.TimezoneNameVocabulary"8 component="lp.services.worlddata.vocabularies.TimezoneNameVocabulary"
9 provides="zope.schema.interfaces.IVocabularyFactory"9 provides="zope.schema.interfaces.IVocabularyFactory"
10 />10 >
11 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
12 </securedutility>
13
11</configure>14</configure>
1215
=== modified file 'lib/lp/soyuz/configure.zcml'
--- lib/lp/soyuz/configure.zcml 2010-01-14 03:39:27 +0000
+++ lib/lp/soyuz/configure.zcml 2010-01-18 21:51:20 +0000
@@ -260,10 +260,24 @@
260 <allow260 <allow
261 interface="lp.soyuz.interfaces.binarypackagename.IBinaryPackageName"/>261 interface="lp.soyuz.interfaces.binarypackagename.IBinaryPackageName"/>
262 </class>262 </class>
263 <utility263 <securedutility
264 name="BinaryPackageName"264 name="BinaryPackageName"
265 component="lp.soyuz.model.binarypackagename.BinaryPackageNameVocabulary"265 component="lp.soyuz.model.binarypackagename.BinaryPackageNameVocabulary"
266 provides="zope.schema.interfaces.IVocabularyFactory"/>266 provides="zope.schema.interfaces.IVocabularyFactory">
267 <allow interface="zope.schema.interfaces.IVocabularyFactory"/>
268 </securedutility>
269
270 <class class="lp.soyuz.model.binarypackagename.BinaryPackageNameVocabulary">
271 <allow interface="canonical.launchpad.webapp.vocabulary.IHugeVocabulary"/>
272 </class>
273
274 <!-- BinaryPackagenameIterator -->
275
276 <class
277 class="lp.soyuz.model.binarypackagename.BinaryPackageNameIterator">
278 <allow
279 interface="canonical.launchpad.webapp.vocabulary.ICountableIterator"/>
280 </class>
267281
268 <!-- BinaryPackageNameSet -->282 <!-- BinaryPackageNameSet -->
269283
270284
=== modified file 'lib/lp/soyuz/interfaces/binarypackagename.py'
--- lib/lp/soyuz/interfaces/binarypackagename.py 2009-06-25 04:06:00 +0000
+++ lib/lp/soyuz/interfaces/binarypackagename.py 2010-01-18 21:51:20 +0000
@@ -84,6 +84,7 @@
84 to report a bug in.84 to report a bug in.
85 """85 """
8686
87 id = Int(title=_('ID'), required=True, readonly=True)
88
87 name = TextLine(title=_('Binary or Source package name'),89 name = TextLine(title=_('Binary or Source package name'),
88 required=True, constraint=name_validator)90 required=True, constraint=name_validator)
89