> > === 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 @@ > > > > > > interface="canonical.launchpad.webapp.vocabulary.ICountableIterator" /> > > + > > 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="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 selectable products releases. > > > > - >>> productrelease_vocabulary = vocabulary_registry.get(None, > > - ... > "ProductRelease") > > + >>> productrelease_vocabulary = removeSecurityProxy( > > + ... vocabulary_registry.get(None, "ProductRelease")) > > >>> productrelease_vocabulary.displayname > > 'Select a Product Release' > > > > @@ -603,7 +608,8 @@ > > All non-merged people with at least one email address. This vocabulary is > > meant to be used only in the people merge form. > > > > - >>> vocab = vocabulary_registry.get(None, "PersonAccountToMerge") > > + >>> vocab = removeSecurityProxy( > > + ... vocabulary_registry.get(None, "PersonAccountToMerge")) > > >>> vocab.displayname > > 'Select a Person to Merge' > > > > @@ -693,7 +699,8 @@ > > > > The set of non-merged people. > > > > - >>> vocab = vocabulary_registry.get(None, "AdminMergeablePerson") > > + >>> vocab = removeSecurityProxy( > > + ... vocabulary_registry.get(None, "AdminMergeablePerson")) > > >>> vocab.displayname > > 'Select a Person to Merge' > > > > @@ -712,7 +719,8 @@ > > > > All non-merged people and teams. > > > > - >>> vocab = vocabulary_registry.get(None, "NonMergedPeopleAndTeams") > > + >>> vocab = removeSecurityProxy( > > + ... vocabulary_registry.get(None, "NonMergedPeopleAndTeams")) > > >>> vocab.displayname > > 'Select a Person or Team' > > > > @@ -746,7 +754,8 @@ > > None). It also includes all public teams and private teams the > > user has permission to view. > > > > - >>> vocab = vocabulary_registry.get(None, "ValidPersonOrTeam") > > + >>> vocab = removeSecurityProxy( > > + ... vocabulary_registry.get(None, "ValidPersonOrTeam")) > > >>> vocab.displayname > > 'Select a Person or Team' > > > > @@ -794,7 +803,8 @@ > > A PRIVATE team is displayed when the logged in user is a member of the > team. > > > > >>> commercial = person_set.getByEmail('commercial- >