← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~stevenk/launchpad/forbid-proprietary-multi-pillar into lp:launchpad

 

Steve Kowalik has proposed merging lp:~stevenk/launchpad/forbid-proprietary-multi-pillar into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~stevenk/launchpad/forbid-proprietary-multi-pillar/+merge/100557

Due to my recent refactoring, IBug.transistionToInformationType() became a lot more strict, refusing to deal with multi-pillar bugs at all and tossing an exception, whereas it used to only complain if the privacy flag was flipped (back when it was IBug.setPrivacyAndSecurityRelated()).

I have changed to only complain if the bug's information_type is PROPRIETARY, and removed the feature flag. Said feature flag was used in a fair number of places, so this diff is a little large.

I have changed the exception to explicitly mention proprietary bugs rather than private.


-- 
https://code.launchpad.net/~stevenk/launchpad/forbid-proprietary-multi-pillar/+merge/100557
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~stevenk/launchpad/forbid-proprietary-multi-pillar into lp:launchpad.
=== modified file 'lib/lp/bugs/browser/bug.py'
--- lib/lp/bugs/browser/bug.py	2012-03-26 06:02:37 +0000
+++ lib/lp/bugs/browser/bug.py	2012-04-03 06:22:26 +0000
@@ -95,7 +95,7 @@
 from lp.bugs.model.structuralsubscription import (
     get_structural_subscriptions_for_bug,
     )
-from lp.services import features
+from lp.registry.enums import InformationType
 from lp.services.fields import DuplicateBug
 from lp.services.librarian.browser import ProxiedLibraryFileAlias
 from lp.services.mail.mailwrapper import MailWrapper
@@ -847,11 +847,10 @@
 
     def setUpFields(self):
         """See `LaunchpadFormView`."""
-        LaunchpadFormView.setUpFields(self)
-        allow_multi_pillar_private = bool(features.getFeatureFlag(
-                'disclosure.allow_multipillar_private_bugs.enabled'))
-        if (not allow_multi_pillar_private
-                and len(self.context.bug.affected_pillars) > 1):
+        super(BugSecrecyEditView, self).setUpFields()
+        bug = self.context.bug
+        if (bug.information_type == InformationType.PROPRIETARY
+            and len(bug.affected_pillars) > 1):
             self.form_fields = self.form_fields.omit('private')
 
     @property
@@ -861,6 +860,8 @@
             return canonical_url(self.context)
         return None
 
+    cancel_url = next_url
+
     @property
     def initial_values(self):
         """See `LaunchpadFormView.`"""
@@ -954,7 +955,7 @@
         self.context = context
         self.request = request
         self.status = 303
-    
+
     def __call__(self):
         self.target = canonical_url(
             getUtility(ILaunchBag).user, view_name='+assignedbugs')

=== modified file 'lib/lp/bugs/browser/bugtask.py'
--- lib/lp/bugs/browser/bugtask.py	2012-03-28 16:05:47 +0000
+++ lib/lp/bugs/browser/bugtask.py	2012-04-03 06:22:26 +0000
@@ -220,6 +220,7 @@
 from lp.bugs.model.bugtasksearch import orderby_expression
 from lp.code.interfaces.branchcollection import IAllBranches
 from lp.layers import FeedsLayer
+from lp.registry.enums import InformationType
 from lp.registry.interfaces.distribution import (
     IDistribution,
     IDistributionSet,
@@ -2709,7 +2710,8 @@
                     batch_navigator.field_visibility)
                 cache.objects['field_visibility_defaults'] = (
                     batch_navigator.field_visibility_defaults)
-                cache.objects['cbl_cookie_name'] = batch_navigator.getCookieName()
+                cache.objects['cbl_cookie_name'] = (
+                    batch_navigator.getCookieName())
 
                 def _getBatchInfo(batch):
                     if batch is None:
@@ -2724,7 +2726,8 @@
                 cache.objects['total'] = batch_navigator.batch.total()
                 cache.objects['order_by'] = ','.join(
                     get_sortorder_from_request(self.request))
-                cache.objects['forwards'] = batch_navigator.batch.range_forwards
+                cache.objects['forwards'] = (
+                    batch_navigator.batch.range_forwards)
                 last_batch = batch_navigator.batch.lastBatch()
                 cache.objects['last_start'] = last_batch.startNumber() - 1
                 cache.objects.update(_getBatchInfo(batch_navigator.batch))
@@ -3855,12 +3858,6 @@
         else:
             return None
 
-    @property
-    def _allow_multipillar_private_bugs(self):
-        """ Some teams still need to have multi pillar private bugs."""
-        return bool(getFeatureFlag(
-            'disclosure.allow_multipillar_private_bugs.enabled'))
-
     def canAddProjectTask(self):
         """Can a new bug task on a project be added to this bug?
 
@@ -3875,7 +3872,7 @@
 
         """
         bug = self.context
-        if self._allow_multipillar_private_bugs:
+        if bug.information_type != InformationType.PROPRIETARY:
             return True
         return len(bug.bugtasks) == 0
 
@@ -3896,7 +3893,7 @@
         is used to hide the link when body.private is True.
         """
         bug = self.context
-        if self._allow_multipillar_private_bugs:
+        if bug.information_type != InformationType.PROPRIETARY:
             return True
         for pillar in bug.affected_pillars:
             if IProduct.providedBy(pillar):

=== modified file 'lib/lp/bugs/browser/tests/special/bugs-fixed-elsewhere.txt'
--- lib/lp/bugs/browser/tests/special/bugs-fixed-elsewhere.txt	2011-12-24 17:49:30 +0000
+++ lib/lp/bugs/browser/tests/special/bugs-fixed-elsewhere.txt	2012-04-03 06:22:26 +0000
@@ -84,41 +84,35 @@
 ------------
 
 Only bugs that the user has permission to view are included in the count.
-We are moving away from allowing private bugs to affect multiple projects.
-This is required still for some teams until they update their tools and
-processes. So we need to use a feature flag to perform this part of the test.
 
-    >>> from lp.services.features.testing import FeatureFixture
-    >>> flags = {'disclosure.allow_multipillar_private_bugs.enabled': 'on'}
-    >>> with FeatureFixture(flags):
-    ...     another_bug = filebug(bugtarget, 'Example Bug')
-    ...     another_bug.setPrivate(True, getUtility(ILaunchBag).user)
+    >>> another_bug = filebug(bugtarget, 'Example Bug')
+    >>> another_bug.setPrivate(True, getUtility(ILaunchBag).user)
     True
 
-    ...     another_elsewhere = getUtility(IBugTaskSet).createTask(
-    ...         another_bug, getUtility(ILaunchBag).user, evolution)
-    ...     another_elsewhere.transitionToStatus(
-    ...         BugTaskStatus.FIXRELEASED, getUtility(ILaunchBag).user)
+    >>> another_elsewhere = getUtility(IBugTaskSet).createTask(
+    >>>     another_bug, getUtility(ILaunchBag).user, evolution)
+    >>> another_elsewhere.transitionToStatus(
+    >>>     BugTaskStatus.FIXRELEASED, getUtility(ILaunchBag).user)
 
-    ...     get_view().bugs_fixed_elsewhere_count
+    >>> get_view().bugs_fixed_elsewhere_count
     2L
 
 This means that No Privileges Person will see that there is only one bug
 fixed elsewhere.
 
-    ...     login('no-priv@xxxxxxxxxxxxx')
-    ...     get_view().bugs_fixed_elsewhere_count
+    >>> login('no-priv@xxxxxxxxxxxxx')
+    >>> get_view().bugs_fixed_elsewhere_count
     1L
 
 If the private bug is made public again, he will of course see that
 there are two bugs fixed.
 
-    ...     login('foo.bar@xxxxxxxxxxxxx')
-    ...     another_bug.setPrivate(False, getUtility(ILaunchBag).user)
+    >>> login('foo.bar@xxxxxxxxxxxxx')
+    >>> another_bug.setPrivate(False, getUtility(ILaunchBag).user)
     True
 
-    ...     login('no-priv@xxxxxxxxxxxxx')
-    ...     get_view().bugs_fixed_elsewhere_count
+    >>> login('no-priv@xxxxxxxxxxxxx')
+    >>> get_view().bugs_fixed_elsewhere_count
     2L
 
 

=== modified file 'lib/lp/bugs/browser/tests/test_bug_views.py'
--- lib/lp/bugs/browser/tests/test_bug_views.py	2012-02-24 04:24:48 +0000
+++ lib/lp/bugs/browser/tests/test_bug_views.py	2012-04-03 06:22:26 +0000
@@ -19,6 +19,7 @@
 from zope.component import getUtility
 from zope.security.proxy import removeSecurityProxy
 
+from lp.registry.enums import InformationType
 from lp.registry.interfaces.person import PersonVisibility
 from lp.services.features.testing import FeatureFixture
 from lp.services.webapp.interfaces import IOpenLaunchBag
@@ -400,22 +401,18 @@
         with person_logged_in(owner):
             self.assertTrue(bug.security_related)
 
-    def test_hide_private_option_for_multipillar_bugs(self):
+    def test_hide_private_option_for_multipillar_proprietary_bugs(self):
         # A multi-pillar bug cannot be made private, so hide the form field.
-        bug = self.factory.makeBug()
+        bug = self.factory.makeBug(
+            information_type=InformationType.PROPRIETARY)
         product = self.factory.makeProduct()
         self.factory.makeBugTask(bug=bug, target=product)
         view = create_initialized_view(bug.default_bugtask, '+secrecy')
         self.assertIsNone(find_tag_by_id(view.render(), 'field.private'))
-
-        # Some teams though need multi-pillar private bugs.
-        feature_flag = {
-            'disclosure.allow_multipillar_private_bugs.enabled': 'on'
-            }
-        with FeatureFixture(feature_flag):
-            view = create_initialized_view(bug.default_bugtask, '+secrecy')
-            self.assertIsNotNone(
-                find_tag_by_id(view.render(), 'field.private'))
+        bug.transitionToInformationType(InformationType.USERDATA, bug.owner)
+        view = create_initialized_view(bug.default_bugtask, '+secrecy')
+        self.assertIsNotNone(
+            find_tag_by_id(view.render(), 'field.private'))
 
 
 class TestBugTextViewPrivateTeams(TestCaseWithFactory):

=== modified file 'lib/lp/bugs/browser/tests/test_bugtask.py'
--- lib/lp/bugs/browser/tests/test_bugtask.py	2012-03-29 14:32:25 +0000
+++ lib/lp/bugs/browser/tests/test_bugtask.py	2012-04-03 06:22:26 +0000
@@ -57,6 +57,7 @@
     FeedsLayer,
     setFirstLayer,
     )
+from lp.registry.enums import InformationType
 from lp.registry.interfaces.person import PersonVisibility
 from lp.services.config import config
 from lp.services.database.constants import UTC_NOW
@@ -1058,19 +1059,12 @@
 
 
 class TestBugTasksAndNominationsViewAlsoAffects(TestCaseWithFactory):
-    """ Tests the boolean methods on the view used to indicate whether the
-        Also Affects... links should be allowed or not. Currently these
-        restrictions are only used for private bugs. ie where body.private
-        is true.
-
-        A feature flag is used to turn off the new restrictions. Each test
-        is performed with and without the feature flag.
-    """
+    """Tests the boolean methods on the view used to indicate whether the
+       Also Affects... links should be allowed or not. These restrictions
+       are only used for proprietary bugs. """
 
     layer = DatabaseFunctionalLayer
 
-    feature_flag = {'disclosure.allow_multipillar_private_bugs.enabled': 'on'}
-
     def _createView(self, bug):
         request = LaunchpadTestRequest()
         bugtasks_and_nominations_view = getMultiAdapter(
@@ -1080,25 +1074,28 @@
     def test_project_bug_cannot_affect_something_else(self):
         # A bug affecting a project cannot also affect another project or
         # package.
-        bug = self.factory.makeBug()
+        bug = self.factory.makeBug(
+            information_type=InformationType.PROPRIETARY)
         view = self._createView(bug)
         self.assertFalse(view.canAddProjectTask())
         self.assertFalse(view.canAddPackageTask())
-        with FeatureFixture(self.feature_flag):
-            self.assertTrue(view.canAddProjectTask())
-            self.assertTrue(view.canAddPackageTask())
+        bug.transitionToInformationType(InformationType.USERDATA, bug.owner)
+        self.assertTrue(view.canAddProjectTask())
+        self.assertTrue(view.canAddPackageTask())
 
     def test_distro_bug_cannot_affect_project(self):
         # A bug affecting a distro cannot also affect another project but it
         # could affect another package.
         distro = self.factory.makeDistribution()
-        bug = self.factory.makeBug(distribution=distro)
+        bug = self.factory.makeBug(
+            distribution=distro,
+            information_type=InformationType.PROPRIETARY)
         view = self._createView(bug)
         self.assertFalse(view.canAddProjectTask())
         self.assertTrue(view.canAddPackageTask())
-        with FeatureFixture(self.feature_flag):
-            self.assertTrue(view.canAddProjectTask())
-            self.assertTrue(view.canAddPackageTask())
+        bug.transitionToInformationType(InformationType.USERDATA, bug.owner)
+        self.assertTrue(view.canAddProjectTask())
+        self.assertTrue(view.canAddPackageTask())
 
     def test_sourcepkg_bug_cannot_affect_project(self):
         # A bug affecting a source pkg cannot also affect another project but
@@ -1109,13 +1106,14 @@
         self.factory.makeSourcePackage(
             sourcepackagename=sp_name, distroseries=distroseries)
         bug = self.factory.makeBug(
-            distribution=distro, sourcepackagename=sp_name)
+            distribution=distro, sourcepackagename=sp_name,
+            information_type=InformationType.PROPRIETARY)
         view = self._createView(bug)
         self.assertFalse(view.canAddProjectTask())
         self.assertTrue(view.canAddPackageTask())
-        with FeatureFixture(self.feature_flag):
-            self.assertTrue(view.canAddProjectTask())
-            self.assertTrue(view.canAddPackageTask())
+        bug.transitionToInformationType(InformationType.USERDATA, bug.owner)
+        self.assertTrue(view.canAddProjectTask())
+        self.assertTrue(view.canAddPackageTask())
 
 
 class TestBugTaskEditViewStatusField(TestCaseWithFactory):
@@ -1451,7 +1449,6 @@
         self.assertIsNone(cache.objects.get('mustache_model'))
 
 
-
 class TestDistributionBugs(TestCaseWithFactory):
     """Test the bugs overview page for distributions."""
 

=== modified file 'lib/lp/bugs/doc/bug-tags.txt'
--- lib/lp/bugs/doc/bug-tags.txt	2011-12-30 06:14:56 +0000
+++ lib/lp/bugs/doc/bug-tags.txt	2012-04-03 06:22:26 +0000
@@ -364,13 +364,6 @@
     [(u'dataloss', 1L), (u'layout-test', 1L), (u'pebcak', 1L)]
 
 Only bugs that the supplied user has access to will be counted:
-We need a feature flag so that multi-pillar bugs can be made private.
-
-    >>> from lp.services.features.testing import FeatureFixture
-    >>> feature_flag = {
-    ...     'disclosure.allow_multipillar_private_bugs.enabled': 'on'}
-    >>> flags = FeatureFixture(feature_flag)
-    >>> flags.setUp()
 
     >>> bug_nine = getUtility(IBugSet).get(9)
     >>> bug_nine.setPrivate(True, getUtility(ILaunchBag).user)

=== modified file 'lib/lp/bugs/doc/bug.txt'
--- lib/lp/bugs/doc/bug.txt	2012-03-23 06:10:28 +0000
+++ lib/lp/bugs/doc/bug.txt	2012-04-03 06:22:26 +0000
@@ -729,14 +729,15 @@
     Mozilla Firefox
 
 It's not always possible to add another bug task to a bug.
-Private bugs are only allowed to affect a single project or distribution.
+Proprietary bugs are only allowed to affect a single project or distribution.
 
     >>> params = CreateBugParams(
     ...     title="a test private bug",
     ...     comment="a description of the bug",
     ...     owner=current_user())
     >>> private_bug = firefox.createBug(params)
-    >>> private_bug.setPrivate(True, current_user())
+    >>> private_bug.transitionToInformationType(
+    ...     InformationType.PROPRIETARY, current_user())
     True
 
     >>> params = CreateBugParams(
@@ -760,14 +761,14 @@
     >>> private_bug.addTask(owner=foobar, target=tomcat)
     Traceback (most recent call last):
     ...
-    IllegalTarget: This private bug already affects Mozilla Firefox.
-    Private bugs cannot affect multiple projects.
+    IllegalTarget: This proprietary bug already affects Mozilla Firefox.
+    Proprietary bugs cannot affect multiple projects.
 
     >>> private_bug.addTask(owner=foobar, target=ubuntu)
     Traceback (most recent call last):
     ...
-    IllegalTarget: This private bug already affects Mozilla Firefox.
-    Private bugs cannot affect multiple projects.
+    IllegalTarget: This proprietary bug already affects Mozilla Firefox.
+    Proprietary bugs cannot affect multiple projects.
 
 We can add a new product series task so long as it's for the same product as
 is already targeted.
@@ -780,8 +781,8 @@
     >>> private_bug.addTask(owner=foobar, target=target)
     Traceback (most recent call last):
     ...
-    IllegalTarget: This private bug already affects Mozilla Firefox.
-    Private bugs cannot affect multiple projects.
+    IllegalTarget: This proprietary bug already affects Mozilla Firefox.
+    Proprietary bugs cannot affect multiple projects.
 
 Now we create a bug on a distribution.
 
@@ -809,29 +810,20 @@
     >>> private_bug.addTask(owner=foobar, target=warty)
     Traceback (most recent call last):
     ...
-    IllegalTarget: This private bug already affects Tubuntu.
-    Private bugs cannot affect multiple projects.
+    IllegalTarget: This proprietary bug already affects Tubuntu.
+    Proprietary bugs cannot affect multiple projects.
 
     >>> private_bug.addTask(owner=foobar, target=warty_fox_package)
     Traceback (most recent call last):
     ...
-    IllegalTarget: This private bug already affects Tubuntu.
-    Private bugs cannot affect multiple projects.
+    IllegalTarget: This proprietary bug already affects Tubuntu.
+    Proprietary bugs cannot affect multiple projects.
 
 
 Changing bug visibility.
 
     >>> bug_before_modification = Snapshot(firefox_bug, providing=IBug)
 
-We need a feature flag for this test since multi-pillar bugs shouldn't be
-private by default.
-
-    >>> from lp.services.features.testing import FeatureFixture
-    >>> feature_flag = {
-    ...     'disclosure.allow_multipillar_private_bugs.enabled': 'on'}
-    >>> flags = FeatureFixture(feature_flag)
-    >>> flags.setUp()
-
     >>> firefox_bug.private
     False
     >>> firefox_bug.setPrivate(True, current_user())
@@ -847,12 +839,8 @@
     >>> firefox_bug.date_last_updated > current_date_last_updated
     True
 
-Clean up the feature flag.
-    >>> flags.cleanUp()
-
 Changing bug security.
 
-    >>> ign = firefox_bug.setPrivate(False, getUtility(ILaunchBag).user)
     >>> bug_before_modification = Snapshot(firefox_bug, providing=IBug)
 
     >>> firefox_bug.security_related

=== modified file 'lib/lp/bugs/doc/bugsubscription.txt'
--- lib/lp/bugs/doc/bugsubscription.txt	2012-03-23 06:10:28 +0000
+++ lib/lp/bugs/doc/bugsubscription.txt	2012-04-03 06:22:26 +0000
@@ -384,11 +384,10 @@
 direct subscribers (eg bugtask pillar maintainers) will remain subscribed.
 
 We currently use a feature flag to control who is subscribed when a bug is
-made private and to allow multi-pillar bugs to be private.
+made private.
 
     >>> from lp.services.features.testing import FeatureFixture
     >>> feature_flag = {
-    ...     'disclosure.allow_multipillar_private_bugs.enabled': 'on',
     ...     'disclosure.enhanced_private_bug_subscriptions.enabled': 'on'}
     >>> flags = FeatureFixture(feature_flag)
     >>> flags.setUp()

=== modified file 'lib/lp/bugs/doc/bugtask-expiration.txt'
--- lib/lp/bugs/doc/bugtask-expiration.txt	2012-03-27 13:41:17 +0000
+++ lib/lp/bugs/doc/bugtask-expiration.txt	2012-04-03 06:22:26 +0000
@@ -397,13 +397,6 @@
 
 If one of the bugs is set to private, anonymous users can no longer see
 it as being marked for expiration.
-We need a feature flag so that multi-pillar bugs can be made private.
-
-    >>> from lp.services.features.testing import FeatureFixture
-    >>> feature_flag = {
-    ...     'disclosure.allow_multipillar_private_bugs.enabled': 'on'}
-    >>> flags = FeatureFixture(feature_flag)
-    >>> flags.setUp()
 
     >>> private_bug = ubuntu_bugtask.bug
     >>> private_bug.title

=== modified file 'lib/lp/bugs/doc/bugtask-find-similar.txt'
--- lib/lp/bugs/doc/bugtask-find-similar.txt	2011-12-26 06:01:53 +0000
+++ lib/lp/bugs/doc/bugtask-find-similar.txt	2012-04-03 06:22:26 +0000
@@ -84,14 +84,6 @@
 the Firefox bug to private, and repeat the search as a user who isn't
 allowed to view it, only the Thunderbird bug will be returned this time.
 
-We need a feature flag so that multi-pillar bugs can be made private.
-
-    >>> from lp.services.features.testing import FeatureFixture
-    >>> feature_flag = {
-    ...     'disclosure.allow_multipillar_private_bugs.enabled': 'on'}
-    >>> flags = FeatureFixture(feature_flag)
-    >>> flags.setUp()
-
     >>> from lp.bugs.interfaces.bug import IBugSet
     >>> login('test@xxxxxxxxxxxxx')
     >>> firefox_svg_bug = getUtility(IBugSet).get(1)

=== modified file 'lib/lp/bugs/doc/initial-bug-contacts.txt'
--- lib/lp/bugs/doc/initial-bug-contacts.txt	2011-12-24 17:49:30 +0000
+++ lib/lp/bugs/doc/initial-bug-contacts.txt	2012-04-03 06:22:26 +0000
@@ -290,11 +290,10 @@
 
 
 We currently use a feature flag to control who is subscribed when a bug is
-made private and to allow multi-pillar bugs to be private.
+made private.
 
     >>> from lp.services.features.testing import FeatureFixture
     >>> feature_flag = {
-    ...     'disclosure.allow_multipillar_private_bugs.enabled': 'on',
     ...     'disclosure.enhanced_private_bug_subscriptions.enabled': 'on'}
     >>> flags = FeatureFixture(feature_flag)
     >>> flags.setUp()

=== modified file 'lib/lp/bugs/doc/security-teams.txt'
--- lib/lp/bugs/doc/security-teams.txt	2012-03-23 06:10:28 +0000
+++ lib/lp/bugs/doc/security-teams.txt	2012-04-03 06:22:26 +0000
@@ -203,16 +203,6 @@
     >>> subscriber_names(bug)
     [u'name12', u'name16']
 
-We are moving away from allowing private bugs to affect multiple projects.
-This is required still for some teams until they update their tools and
-processes. So we need to use a feature flag to perform the next tests.
-
-    >>> from lp.services.features.testing import FeatureFixture
-    >>> feature_flag = {
-    ...     'disclosure.allow_multipillar_private_bugs.enabled': 'on'}
-    >>> privacy_flags = FeatureFixture(feature_flag)
-    >>> privacy_flags.setUp()
-
     >>> bug_in_evolution = bugtaskset.createTask(bug, foobar, evolution)
     >>> subscriber_names(bug)
     [u'name12', u'name16']

=== modified file 'lib/lp/bugs/mail/tests/test_commands.py'
--- lib/lp/bugs/mail/tests/test_commands.py	2012-03-26 06:02:37 +0000
+++ lib/lp/bugs/mail/tests/test_commands.py	2012-04-03 06:22:26 +0000
@@ -286,15 +286,16 @@
         # Test that attempts to invalidly add a new bug task results in the
         # expected error message.
         product = self.factory.makeProduct()
-        bug = self.factory.makeBug(private=True, product=product)
+        bug = self.factory.makeBug(
+            product=product, information_type=InformationType.PROPRIETARY)
         self.factory.makeProduct(name='fnord')
         login_celebrity('admin')
         login_person(bug.owner)
         command = AffectsEmailCommand('affects', ['fnord'])
         error = self.assertRaises(
             EmailProcessingError, command.execute, bug, None)
-        reason = ("This private bug already affects %s. "
-                    "Private bugs cannot affect multiple projects." %
+        reason = ("This proprietary bug already affects %s. "
+                    "Proprietary bugs cannot affect multiple projects." %
                     product.displayname)
         self.assertEqual(
             normalize_whitespace(

=== modified file 'lib/lp/bugs/model/bug.py'
--- lib/lp/bugs/model/bug.py	2012-03-29 06:02:46 +0000
+++ lib/lp/bugs/model/bug.py	2012-04-03 06:22:26 +0000
@@ -1733,13 +1733,11 @@
         f_flag = bool(getFeatureFlag(f_flag_str))
         if f_flag:
             self.reconcileSubscribers(information_type, who)
+        if (information_type == InformationType.PROPRIETARY and
+            len(self.affected_pillars) > 1):
+            raise BugCannotBePrivate(
+                "Multi-pillar bugs cannot be proprietary.")
         if information_type in PRIVATE_INFORMATION_TYPES:
-            allow_multi_pillar_private = bool(getFeatureFlag(
-                'disclosure.allow_multipillar_private_bugs.enabled'))
-            if (not allow_multi_pillar_private
-                    and len(self.affected_pillars) > 1):
-                raise BugCannotBePrivate(
-                    "Multi-pillar bugs cannot be private.")
             self.who_made_private = who
             self.date_made_private = UTC_NOW
         else:

=== modified file 'lib/lp/bugs/model/bugtask.py'
--- lib/lp/bugs/model/bugtask.py	2012-03-29 00:48:21 +0000
+++ lib/lp/bugs/model/bugtask.py	2012-04-03 06:22:26 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2012 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 # pylint: disable-msg=E0611,W0212
@@ -84,7 +84,10 @@
     UserCannotEditBugTaskMilestone,
     UserCannotEditBugTaskStatus,
     )
-from lp.registry.enums import PUBLIC_INFORMATION_TYPES
+from lp.registry.enums import (
+    InformationType,
+    PUBLIC_INFORMATION_TYPES,
+    )
 from lp.registry.interfaces.distribution import (
     IDistribution,
     IDistributionSet,
@@ -365,8 +368,7 @@
             except NotFoundError, e:
                 raise IllegalTarget(e[0])
 
-    if bug.private and not bool(features.getFeatureFlag(
-            'disclosure.allow_multipillar_private_bugs.enabled')):
+    if bug.information_type == InformationType.PROPRIETARY:
         # Perhaps we are replacing the one and only existing bugtask, in
         # which case that's ok.
         if retarget_existing and len(bug.bugtasks) <= 1:
@@ -375,8 +377,8 @@
         if (len(bug.affected_pillars) > 0
                 and target.pillar not in bug.affected_pillars):
             raise IllegalTarget(
-                "This private bug already affects %s. "
-                "Private bugs cannot affect multiple projects."
+                "This proprietary bug already affects %s. "
+                "Proprietary bugs cannot affect multiple projects."
                     % bug.default_bugtask.target.bugtargetdisplayname)
 
 

=== modified file 'lib/lp/bugs/model/tests/test_bug.py'
--- lib/lp/bugs/model/tests/test_bug.py	2012-03-26 06:02:37 +0000
+++ lib/lp/bugs/model/tests/test_bug.py	2012-04-03 06:22:26 +0000
@@ -896,24 +896,17 @@
 
     layer = DatabaseFunctionalLayer
 
-    def test_multipillar_private_bugs_disallowed(self):
-        # A multi-pillar bug cannot be made private.
+    def test_multipillar_proprietary_bugs_disallowed(self):
+        # A multi-pillar bug cannot be made proprietary.
         bug = self.factory.makeBug()
         product = self.factory.makeProduct()
         self.factory.makeBugTask(bug=bug, target=product)
         login_person(bug.owner)
         self.assertRaises(
             BugCannotBePrivate, bug.transitionToInformationType,
-            InformationType.USERDATA, bug.owner)
-
-        # Some teams though need multi-pillar private bugs.
-        feature_flag = {
-            'disclosure.allow_multipillar_private_bugs.enabled': 'on'
-            }
-        with FeatureFixture(feature_flag):
-            bug.transitionToInformationType(
-                InformationType.USERDATA, bug.owner)
-            self.assertTrue(bug.private)
+            InformationType.PROPRIETARY, bug.owner)
+        bug.transitionToInformationType(InformationType.USERDATA, bug.owner)
+        self.assertTrue(bug.private)
 
     def test_bug_information_type(self):
         # Bugs have the correct corresponding information type.

=== modified file 'lib/lp/bugs/model/tests/test_bugtask.py'
--- lib/lp/bugs/model/tests/test_bugtask.py	2012-03-29 03:39:27 +0000
+++ lib/lp/bugs/model/tests/test_bugtask.py	2012-04-03 06:22:26 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2012 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 __metaclass__ = type
@@ -50,6 +50,7 @@
     HWBus,
     IHWDeviceSet,
     )
+from lp.registry.enums import InformationType
 from lp.registry.interfaces.distribution import IDistributionSet
 from lp.registry.interfaces.person import (
     IPerson,
@@ -59,7 +60,6 @@
 from lp.registry.interfaces.product import IProductSet
 from lp.registry.interfaces.projectgroup import IProjectGroupSet
 from lp.services.database.sqlbase import flush_database_updates
-from lp.services.features.testing import FeatureFixture
 from lp.services.searchbuilder import (
     all,
     any,
@@ -2217,8 +2217,6 @@
         a private bugs to check for multi-tenant constraints.
     """
 
-    feature_flag = {'disclosure.allow_multipillar_private_bugs.enabled': 'on'}
-
     def test_private_multi_tenanted_forbidden(self):
         # A new task project cannot be added if there is already one from
         # another pillar.
@@ -2228,16 +2226,17 @@
             self.factory.makeBugTask(bug=bug)
         p = self.factory.makeProduct()
         with person_logged_in(bug.owner):
-            bug.setPrivate(True, bug.owner)
+            bug.transitionToInformationType(
+                InformationType.PROPRIETARY, bug.owner)
             self.assertRaisesWithContent(
                 IllegalTarget,
-                "This private bug already affects %s. "
-                "Private bugs cannot affect multiple projects."
+                "This proprietary bug already affects %s. "
+                "Proprietary bugs cannot affect multiple projects."
                     % d.displayname,
                 self.validate_method, bug, p)
-            # It works with the feature flag
-            with FeatureFixture(self.feature_flag):
-                self.validate_method(bug, p)
+            bug.transitionToInformationType(
+                InformationType.USERDATA, bug.owner)
+            self.validate_method(bug, p)
 
     def test_private_incorrect_pillar_task_forbidden(self):
         # A product or distro cannot be added if there is already a bugtask.
@@ -2248,22 +2247,23 @@
         if not self.multi_tenant_test_one_task_only:
             self.factory.makeBugTask(bug=bug)
         with person_logged_in(bug.owner):
-            bug.setPrivate(True, bug.owner)
+            bug.transitionToInformationType(
+                InformationType.PROPRIETARY, bug.owner)
             self.assertRaisesWithContent(
                 IllegalTarget,
-                "This private bug already affects %s. "
-                "Private bugs cannot affect multiple projects."
+                "This proprietary bug already affects %s. "
+                "Proprietary bugs cannot affect multiple projects."
                     % p1.displayname,
                 self.validate_method, bug, p2)
             self.assertRaisesWithContent(
                 IllegalTarget,
-                "This private bug already affects %s. "
-                "Private bugs cannot affect multiple projects."
+                "This proprietary bug already affects %s. "
+                "Proprietary bugs cannot affect multiple projects."
                     % p1.displayname,
                 self.validate_method, bug, d)
-            # It works with the feature flag
-            with FeatureFixture(self.feature_flag):
-                self.validate_method(bug, p2)
+            bug.transitionToInformationType(
+                InformationType.USERDATA, bug.owner)
+            self.validate_method(bug, p2)
 
     def test_private_incorrect_product_series_task_forbidden(self):
         # A product series cannot be added if there is already a bugtask for
@@ -2275,16 +2275,17 @@
         if not self.multi_tenant_test_one_task_only:
             self.factory.makeBugTask(bug=bug)
         with person_logged_in(bug.owner):
-            bug.setPrivate(True, bug.owner)
+            bug.transitionToInformationType(
+                InformationType.PROPRIETARY, bug.owner)
             self.assertRaisesWithContent(
                 IllegalTarget,
-                "This private bug already affects %s. "
-                "Private bugs cannot affect multiple projects."
+                "This proprietary bug already affects %s. "
+                "Proprietary bugs cannot affect multiple projects."
                     % p1.displayname,
                 self.validate_method, bug, series)
-            # It works with the feature flag
-            with FeatureFixture(self.feature_flag):
-                self.validate_method(bug, series)
+            bug.transitionToInformationType(
+                InformationType.USERDATA, bug.owner)
+            self.validate_method(bug, series)
 
     def test_private_incorrect_distro_series_task_forbidden(self):
         # A distro series cannot be added if there is already a bugtask for
@@ -2296,16 +2297,17 @@
         if not self.multi_tenant_test_one_task_only:
             self.factory.makeBugTask(bug=bug)
         with person_logged_in(bug.owner):
-            bug.setPrivate(True, bug.owner)
+            bug.transitionToInformationType(
+                InformationType.PROPRIETARY, bug.owner)
             self.assertRaisesWithContent(
                 IllegalTarget,
-                "This private bug already affects %s. "
-                "Private bugs cannot affect multiple projects."
+                "This proprietary bug already affects %s. "
+                "Proprietary bugs cannot affect multiple projects."
                     % d1.displayname,
                 self.validate_method, bug, series)
-            # It works with the feature flag
-            with FeatureFixture(self.feature_flag):
-                self.validate_method(bug, series)
+            bug.transitionToInformationType(
+                InformationType.USERDATA, bug.owner)
+            self.validate_method(bug, series)
 
 
 class TestValidateTarget(TestCaseWithFactory, ValidateTargetMixin):

=== modified file 'lib/lp/bugs/stories/bug-also-affects/xx-also-affects-upstream-private-bug.txt'
--- lib/lp/bugs/stories/bug-also-affects/xx-also-affects-upstream-private-bug.txt	2011-10-28 17:09:49 +0000
+++ lib/lp/bugs/stories/bug-also-affects/xx-also-affects-upstream-private-bug.txt	2012-04-03 06:22:26 +0000
@@ -6,17 +6,6 @@
 upstream bug supervisor won't be notified. They will also be given a link to
 the Subscribe someone else page.
 
-We are moving away from allowing private bugs to affect multiple projects.
-This is required still for some teams until they update their tools and
-processes. So we need to use a feature flag to perform the next tests.
-
-    >>> from lp.services.features.testing import FeatureFixture
-    >>> feature_flag = {
-    ...     'disclosure.allow_multipillar_private_bugs.enabled': 'on',
-    ...     }
-    >>> privacy_flags = FeatureFixture(feature_flag)
-    >>> privacy_flags.setUp()
-
     >>> admin_browser.open('http://bugs.launchpad.dev/firefox/+bugsupervisor')
     >>> admin_browser.getControl('Bug Supervisor').value = 'name16'
     >>> admin_browser.getControl('Change').click()

=== modified file 'lib/lp/bugs/stories/bug-also-affects/xx-bug-also-affects.txt'
--- lib/lp/bugs/stories/bug-also-affects/xx-bug-also-affects.txt	2011-12-24 17:49:30 +0000
+++ lib/lp/bugs/stories/bug-also-affects/xx-bug-also-affects.txt	2012-04-03 06:22:26 +0000
@@ -226,8 +226,8 @@
 
     >>> print get_feedback_messages(browser.contents)
     [u'There is 1 error.',
-     u'This private bug already affects Mozilla Firefox.
-       Private bugs cannot affect multiple projects.']
+     u'This proprietary bug already affects Mozilla Firefox.
+       Proprietary bugs cannot affect multiple projects.']
 
 
 Forwarding bugs upstream

=== modified file 'lib/lp/bugs/stories/bug-privacy/xx-bug-privacy.txt'
--- lib/lp/bugs/stories/bug-privacy/xx-bug-privacy.txt	2011-12-24 17:49:30 +0000
+++ lib/lp/bugs/stories/bug-privacy/xx-bug-privacy.txt	2012-04-03 06:22:26 +0000
@@ -22,12 +22,11 @@
     Ubuntu Team
 
 We currently use a feature flag to control who is subscribed when a bug is
-made private and also to allow multi-pillar private bugs.
+made private.
 
     >>> from lp.services.features.testing import FeatureFixture
     >>> feature_flag = {
-    ...     'disclosure.enhanced_private_bug_subscriptions.enabled': 'on',
-    ...     'disclosure.allow_multipillar_private_bugs.enabled': 'on'}
+    ...     'disclosure.enhanced_private_bug_subscriptions.enabled': 'on'}
     >>> flags = FeatureFixture(feature_flag)
     >>> flags.setUp()
 

=== modified file 'lib/lp/bugs/stories/bugs/xx-bug-activity.txt'
--- lib/lp/bugs/stories/bugs/xx-bug-activity.txt	2012-03-23 06:10:28 +0000
+++ lib/lp/bugs/stories/bugs/xx-bug-activity.txt	2012-04-03 06:22:26 +0000
@@ -98,13 +98,6 @@
     --------
 
 Alterations to a bug's privacy will show up as 'visibility' changes.
-We need a feature flag so that multi-pillar bugs can be made private.
-
-    >>> from lp.services.features.testing import FeatureFixture
-    >>> feature_flag = {
-    ...     'disclosure.allow_multipillar_private_bugs.enabled': 'on'}
-    >>> flags = FeatureFixture(feature_flag)
-    >>> flags.setUp()
 
     >>> admin_browser.open(
     ...     'http://bugs.launchpad.dev/redfish/+bug/15/+secrecy')

=== modified file 'lib/lp/bugs/stories/bugtracker/xx-bugtracker-remote-bug.txt'
--- lib/lp/bugs/stories/bugtracker/xx-bugtracker-remote-bug.txt	2011-11-28 00:35:15 +0000
+++ lib/lp/bugs/stories/bugtracker/xx-bugtracker-remote-bug.txt	2012-04-03 06:22:26 +0000
@@ -52,14 +52,6 @@
 If a bug is marked private, and multiple Launchpad bugs are watching a
 particular remote bug, we do not expose the title of the remote bug.
 
-We need a feature flag so that multi-pillar bugs can be made private.
-
-    >>> from lp.services.features.testing import FeatureFixture
-    >>> feature_flag = {
-    ...     'disclosure.allow_multipillar_private_bugs.enabled': 'on'}
-    >>> flags = FeatureFixture(feature_flag)
-    >>> flags.setUp()
-
 Mark bug 1 as private:
 
   >>> browser.addHeader('Authorization', 'Basic test@xxxxxxxxxxxxx:test')

=== modified file 'lib/lp/bugs/templates/bugtasks-and-nominations-portal.pt'
--- lib/lp/bugs/templates/bugtasks-and-nominations-portal.pt	2012-02-01 15:31:32 +0000
+++ lib/lp/bugs/templates/bugtasks-and-nominations-portal.pt	2012-04-03 06:22:26 +0000
@@ -93,7 +93,7 @@
         replace="structure link/render" />
     <div class="private-only formHelp"
         tal:condition="python:not view.canAddPackageTask() or not view.canAddProjectTask()">
-        Private bugs cannot affect multiple projects.
+        Proprietary bugs cannot affect multiple projects.
     </div>
   </tal:also-affects-links>
 

=== modified file 'lib/lp/bugs/tests/test_bug_mirror_access_triggers.py'
--- lib/lp/bugs/tests/test_bug_mirror_access_triggers.py	2012-03-26 00:12:50 +0000
+++ lib/lp/bugs/tests/test_bug_mirror_access_triggers.py	2012-04-03 06:22:26 +0000
@@ -18,7 +18,6 @@
     IAccessPolicyArtifactSource,
     IAccessPolicySource,
     )
-from lp.services.features.testing import FeatureFixture
 from lp.testing import TestCaseWithFactory
 from lp.testing.layers import DatabaseFunctionalLayer
 
@@ -27,11 +26,6 @@
 
     layer = DatabaseFunctionalLayer
 
-    def setUp(self):
-        super(TestBugMirrorAccessTriggers, self).setUp()
-        self.useFixture(FeatureFixture(
-            {'disclosure.allow_multipillar_private_bugs.enabled': 'true'}))
-
     def assertMirrored(self, bug):
         """Check that a bug has been correctly mirrored to the new schema.
 

=== modified file 'lib/lp/bugs/tests/test_bugtask_search.py'
--- lib/lp/bugs/tests/test_bugtask_search.py	2012-03-22 19:36:38 +0000
+++ lib/lp/bugs/tests/test_bugtask_search.py	2012-04-03 06:22:26 +0000
@@ -1,4 +1,4 @@
-# Copyright 2010-2011 Canonical Ltd.  This software is licensed under the
+# Copyright 2010-2012 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 __metaclass__ = type
@@ -36,7 +36,6 @@
 from lp.registry.interfaces.product import IProduct
 from lp.registry.interfaces.sourcepackage import ISourcePackage
 from lp.registry.model.person import Person
-from lp.services.features.testing import FeatureFixture
 from lp.services.searchbuilder import (
     all,
     any,
@@ -62,12 +61,6 @@
     def setUp(self):
         super(SearchTestBase, self).setUp()
         self.bugtask_set = getUtility(IBugTaskSet)
-        # We need a feature flag so that multipillar bugs can be made private.
-        feature_flag = {
-                'disclosure.allow_multipillar_private_bugs.enabled': 'on'}
-        flags = FeatureFixture(feature_flag)
-        flags.setUp()
-        self.addCleanup(flags.cleanUp)
 
     def assertSearchFinds(self, params, expected_bugtasks):
         # Run a search for the given search parameters and check if
@@ -1587,9 +1580,8 @@
             dateexpected=ten_days_from_now)
         current_milestone_bug = self.factory.makeBug(
             milestone=current_milestone)
-        old_milestone_bug = self.factory.makeBug(milestone=old_milestone)
-        future_milestone_bug = self.factory.makeBug(
-            milestone=future_milestone)
+        self.factory.makeBug(milestone=old_milestone)
+        self.factory.makeBug(milestone=future_milestone)
         # Search for bugs whose milestone.dateexpected is between yesterday
         # and tomorrow.  This will return only the one task targeted to
         # current_milestone.

=== modified file 'lib/lp/bugs/tests/test_bugtaskflat_triggers.py'
--- lib/lp/bugs/tests/test_bugtaskflat_triggers.py	2012-03-29 07:56:30 +0000
+++ lib/lp/bugs/tests/test_bugtaskflat_triggers.py	2012-04-03 06:22:26 +0000
@@ -20,7 +20,6 @@
     IAccessPolicySource,
     )
 from lp.services.database.lpstorm import IStore
-from lp.services.features.testing import FeatureFixture
 from lp.testing import (
     login_person,
     person_logged_in,
@@ -59,11 +58,6 @@
 
 class BugTaskFlatTestMixin(TestCaseWithFactory):
 
-    def setUp(self):
-        super(BugTaskFlatTestMixin, self).setUp()
-        self.useFixture(FeatureFixture(
-            {'disclosure.allow_multipillar_private_bugs.enabled': 'true'}))
-
     def checkFlattened(self, bugtask, check_only=True):
         if hasattr(bugtask, 'id'):
             bugtask = bugtask.id

=== modified file 'lib/lp/services/features/flags.py'
--- lib/lp/services/features/flags.py	2012-03-26 21:23:40 +0000
+++ lib/lp/services/features/flags.py	2012-04-03 06:22:26 +0000
@@ -217,12 +217,6 @@
      '',
      '',
      ''),
-    ('disclosure.allow_multipillar_private_bugs.enabled',
-     'boolean',
-     'Allows private bugs to have more than one bug task.',
-     '',
-     '',
-     ''),
     ('disclosure.users_hide_own_bug_comments.enabled',
      'boolean',
      'Allows users in project roles and comment owners to hide bug comments.',