← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~wgrant/launchpad/multipolicy-1 into lp:launchpad

 

William Grant has proposed merging lp:~wgrant/launchpad/multipolicy-1 into lp:launchpad with lp:~wgrant/launchpad/multipolicy-0 as a prerequisite.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~wgrant/launchpad/multipolicy-1/+merge/93171

Assumptions we made during the design of the new access policy model proved to be false, so it requires a major rework to support multiple pillars per private bug. Due to fastdowntime's restrictions, person merge and branch deletion code, and the fact that the tables are unused and empty, this is most easily done by deleting the old one and creating the new one in a lovely 5 step process.

This branch removes the code for the old model.
-- 
https://code.launchpad.net/~wgrant/launchpad/multipolicy-1/+merge/93171
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wgrant/launchpad/multipolicy-1 into lp:launchpad.
=== modified file 'lib/lp/bugs/configure.zcml'
--- lib/lp/bugs/configure.zcml	2012-01-04 17:21:01 +0000
+++ lib/lp/bugs/configure.zcml	2012-02-15 10:13:33 +0000
@@ -851,7 +851,6 @@
                     setPrivate
                     setSecurityRelated
                     setPrivacyAndSecurityRelated
-                    setAccessPolicy
                     setStatus
                     subscribe
                     unlinkBranch

=== modified file 'lib/lp/bugs/interfaces/bug.py'
--- lib/lp/bugs/interfaces/bug.py	2012-02-07 06:42:27 +0000
+++ lib/lp/bugs/interfaces/bug.py	2012-02-15 10:13:33 +0000
@@ -247,7 +247,6 @@
     security_related = exported(
         Bool(title=_("This bug is a security vulnerability."),
              required=False, default=False, readonly=True))
-    access_policy = Attribute("Access policy")
     displayname = TextLine(title=_("Text of the form 'Bug #X"),
         readonly=True)
     activity = exported(
@@ -888,9 +887,6 @@
         Return (private_changed, security_related_changed) tuple.
         """
 
-    def setAccessPolicy(policy_type):
-        """Set the `IAccessPolicy` that controls access to this bug."""
-
     def getBugTask(target):
         """Return the bugtask with the specified target.
 

=== modified file 'lib/lp/bugs/model/bug.py'
--- lib/lp/bugs/model/bug.py	2012-02-08 10:43:29 +0000
+++ lib/lp/bugs/model/bug.py	2012-02-15 10:13:33 +0000
@@ -162,10 +162,6 @@
     )
 from lp.code.interfaces.branchcollection import IAllBranches
 from lp.hardwaredb.interfaces.hwdb import IHWSubmissionBugSet
-from lp.registry.interfaces.accesspolicy import (
-    IAccessPolicySource,
-    UnsuitableAccessPolicyError,
-    )
 from lp.registry.interfaces.distribution import IDistribution
 from lp.registry.interfaces.distroseries import IDistroSeries
 from lp.registry.interfaces.person import (
@@ -360,8 +356,6 @@
         dbName='who_made_private', foreignKey='Person',
         storm_validator=validate_public_person, default=None)
     security_related = BoolCol(notNull=True, default=False)
-    access_policy_id = Int(name="access_policy")
-    access_policy = Reference(access_policy_id, 'AccessPolicy.id')
 
     # useful Joins
     activity = SQLMultipleJoin('BugActivity', joinColumn='bug', orderBy='id')
@@ -1801,19 +1795,6 @@
         return self.setPrivacyAndSecurityRelated(
             self.private, security_related, who)[1]
 
-    def setAccessPolicy(self, type):
-        """See `IBug`."""
-        if type is None:
-            policy = None
-        else:
-            policy = getUtility(IAccessPolicySource).getByPillarAndType(
-                self.default_bugtask.pillar, type)
-            if policy is None:
-                raise UnsuitableAccessPolicyError(
-                    "%s doesn't have a %s access policy."
-                    % (self.default_bugtask.pillar.name, type.title))
-        self.access_policy = policy
-
     def getRequiredSubscribers(self, for_private, for_security_related, who):
         """Return the mandatory subscribers for a bug with given attributes.
 

=== modified file 'lib/lp/bugs/model/bugtask.py'
--- lib/lp/bugs/model/bugtask.py	2012-02-09 22:40:44 +0000
+++ lib/lp/bugs/model/bugtask.py	2012-02-15 10:13:33 +0000
@@ -83,7 +83,6 @@
     UserCannotEditBugTaskMilestone,
     UserCannotEditBugTaskStatus,
     )
-from lp.registry.interfaces.accesspolicy import IAccessPolicySource
 from lp.registry.interfaces.distribution import (
     IDistribution,
     IDistributionSet,
@@ -345,8 +344,7 @@
 def validate_target(bug, target, retarget_existing=True):
     """Validate a bugtask target against a bug's existing tasks.
 
-    Checks that no conflicting tasks already exist, and that the new
-    target's pillar supports the bug's access policy.
+    Checks that no conflicting tasks already exist.
     """
     if bug.getBugTask(target):
         raise IllegalTarget(
@@ -379,14 +377,6 @@
                 "Private bugs cannot affect multiple projects."
                     % bug.default_bugtask.target.bugtargetdisplayname)
 
-    if (bug.access_policy is not None and
-        bug.access_policy.pillar != target.pillar and
-        not getUtility(IAccessPolicySource).getByPillarAndType(
-            target.pillar, bug.access_policy.type)):
-        raise IllegalTarget(
-            "%s doesn't have a %s access policy."
-            % (target.pillar.displayname, bug.access_policy.type.title))
-
 
 def validate_new_target(bug, target):
     """Validate a bugtask target to be added.
@@ -1179,12 +1169,6 @@
             setattr(self, name, value)
         self.updateTargetNameCache()
 
-        # If there's a policy set and we're changing to a another
-        # pillar, recalculate the access policy.
-        if (self.bug.access_policy is not None and
-            self.bug.access_policy.pillar != target.pillar):
-            self.bug.setAccessPolicy(self.bug.access_policy.type)
-
         # START TEMPORARY BIT FOR BUGTASK AUTOCONFIRM FEATURE FLAG.
         # We also should see if we ought to auto-transition to the
         # CONFIRMED status.

=== modified file 'lib/lp/bugs/model/tests/test_bugtask.py'
--- lib/lp/bugs/model/tests/test_bugtask.py	2012-02-08 14:28:06 +0000
+++ lib/lp/bugs/model/tests/test_bugtask.py	2012-02-15 10:13:33 +0000
@@ -2118,22 +2118,6 @@
             (t.target for t in bug.bugtasks),
             [sp, sp.distribution_sourcepackage, other_distro])
 
-    def test_access_policy_changed(self):
-        # If an access policy is set, changing the pillar also switches
-        # to the matching policy on the new pillar.
-        orig_product = self.factory.makeProduct()
-        orig_policy = self.factory.makeAccessPolicy(pillar=orig_product)
-        new_product = self.factory.makeProduct()
-        new_policy = self.factory.makeAccessPolicy(
-            pillar=new_product, type=orig_policy.type)
-
-        bug = self.factory.makeBug(product=orig_product)
-        with person_logged_in(bug.owner):
-            bug.setAccessPolicy(orig_policy.type)
-            self.assertEqual(orig_policy, bug.access_policy)
-            bug.default_bugtask.transitionToTarget(new_product)
-            self.assertEqual(new_policy, bug.access_policy)
-
 
 class TestBugTargetKeys(TestCaseWithFactory):
     """Tests for bug_target_to_key and bug_target_from_key."""
@@ -2460,39 +2444,6 @@
             % (dsp.sourcepackagename.name, dsp.distribution.displayname),
             validate_target, task.bug, dsp)
 
-    def test_present_access_policy_works(self):
-        # If an access policy is set, changing the pillar is permitted
-        # if the target has an access policy of the same type.
-        orig_product = self.factory.makeProduct()
-        orig_policy = self.factory.makeAccessPolicy(pillar=orig_product)
-        new_product = self.factory.makeProduct()
-        self.factory.makeAccessPolicy(
-            pillar=new_product, type=orig_policy.type)
-
-        bug = self.factory.makeBug(product=orig_product)
-        with person_logged_in(bug.owner):
-            bug.setAccessPolicy(orig_policy.type)
-        self.assertEqual(orig_policy, bug.access_policy)
-        # No exception is raised.
-        validate_target(bug, new_product)
-
-    def test_missing_access_policy_rejected(self):
-        # If the new pillar doesn't have a corresponding access policy,
-        # the transition is forbidden.
-        orig_product = self.factory.makeProduct()
-        orig_policy = self.factory.makeAccessPolicy(pillar=orig_product)
-        new_product = self.factory.makeProduct()
-
-        bug = self.factory.makeBug(product=orig_product)
-        with person_logged_in(bug.owner):
-            bug.setAccessPolicy(orig_policy.type)
-        self.assertEqual(orig_policy, bug.access_policy)
-        self.assertRaisesWithContent(
-            IllegalTarget,
-            "%s doesn't have a %s access policy."
-            % (new_product.displayname, bug.access_policy.type.title),
-            validate_target, bug, new_product)
-
 
 class TestValidateNewTarget(TestCaseWithFactory, ValidateTargetMixin):
 

=== modified file 'lib/lp/bugs/tests/test_bug.py'
--- lib/lp/bugs/tests/test_bug.py	2012-01-01 02:58:52 +0000
+++ lib/lp/bugs/tests/test_bug.py	2012-02-15 10:13:33 +0000
@@ -22,10 +22,6 @@
     UserCannotEditBugTaskImportance,
     UserCannotEditBugTaskMilestone,
     )
-from lp.registry.interfaces.accesspolicy import (
-    AccessPolicyType,
-    UnsuitableAccessPolicyError,
-    )
 from lp.testing import (
     person_logged_in,
     StormStatementRecorder,
@@ -301,38 +297,3 @@
         params.setBugTarget(product=target)
         bug = getUtility(IBugSet).createBug(params)
         self.assertEqual([cve], [cve_link.cve for cve_link in bug.cve_links])
-
-
-class TestBugAccessPolicy(TestCaseWithFactory):
-    layer = DatabaseFunctionalLayer
-
-    def test_setAccessPolicy(self):
-        product = self.factory.makeProduct()
-        policy = self.factory.makeAccessPolicy(
-            pillar=product, type=AccessPolicyType.PRIVATE)
-        bug = self.factory.makeBug(product=product)
-        self.assertIs(None, bug.access_policy)
-        with person_logged_in(bug.owner):
-            bug.setAccessPolicy(AccessPolicyType.PRIVATE)
-        self.assertEqual(policy, bug.access_policy)
-
-    def test_setAccessPolicy_none(self):
-        product = self.factory.makeProduct()
-        policy = self.factory.makeAccessPolicy(pillar=product)
-        bug = self.factory.makeBug(product=product)
-        self.assertIs(None, bug.access_policy)
-        with person_logged_in(bug.owner):
-            bug.setAccessPolicy(policy.type)
-            bug.setAccessPolicy(None)
-        self.assertIs(None, bug.access_policy)
-
-    def test_setAccessPolicy_without_use(self):
-        # Attempting to set the access policy to a type that is not used
-        # by the pillar fails.
-        bug = self.factory.makeBug()
-        self.assertIs(None, bug.access_policy)
-        with person_logged_in(bug.owner):
-            self.assertRaises(
-                UnsuitableAccessPolicyError, bug.setAccessPolicy,
-                AccessPolicyType.PRIVATE)
-        self.assertIs(None, bug.access_policy)

=== modified file 'lib/lp/code/model/branch.py'
--- lib/lp/code/model/branch.py	2012-02-09 21:46:47 +0000
+++ lib/lp/code/model/branch.py	2012-02-15 10:13:33 +0000
@@ -127,7 +127,6 @@
     )
 from lp.code.model.seriessourcepackagebranch import SeriesSourcePackageBranch
 from lp.codehosting.safe_open import safe_open
-from lp.registry.interfaces.accesspolicy import IAccessPolicyArtifactSource
 from lp.registry.interfaces.person import (
     validate_person,
     validate_public_person,
@@ -181,8 +180,6 @@
     # transitively private branch. The value of this attribute is maintained
     # by a database trigger.
     transitively_private = BoolCol(dbName='transitively_private')
-    access_policy_id = Int(name="access_policy")
-    access_policy = Reference(access_policy_id, "AccessPolicy.id")
 
     @property
     def private(self):
@@ -1122,7 +1119,6 @@
 
         self._deleteBranchSubscriptions()
         self._deleteJobs()
-        getUtility(IAccessPolicyArtifactSource).delete(self)
 
         # Now destroy the branch.
         branch_id = self.id

=== modified file 'lib/lp/code/model/tests/test_branch.py'
--- lib/lp/code/model/tests/test_branch.py	2011-12-30 06:14:56 +0000
+++ lib/lp/code/model/tests/test_branch.py	2012-02-15 10:13:33 +0000
@@ -103,7 +103,6 @@
 from lp.code.model.revision import Revision
 from lp.code.tests.helpers import add_revision_to_branch
 from lp.codehosting.safe_open import BadUrl
-from lp.registry.interfaces.accesspolicy import IAccessPolicyArtifactSource
 from lp.registry.interfaces.person import PersonVisibility
 from lp.registry.interfaces.pocket import PackagePublishingPocket
 from lp.registry.model.sourcepackage import SourcePackage
@@ -1138,12 +1137,6 @@
             branch.canBeDeleted(), True,
             "A branch that has a import is deletable.")
 
-    def test_accessPolicyArtifactDoesntDisableDeletion(self):
-        """A branch referenced by an AccessPolicyArtifact can be deleted."""
-        artifact = self.factory.makeAccessPolicyArtifact(self.branch)
-        self.factory.makeAccessPolicyGrant(object=artifact)
-        self.assertEqual(True, self.branch.canBeDeleted())
-
     def test_bugBranchLinkDisablesDeletion(self):
         """A branch linked to a bug cannot be deleted."""
         params = CreateBugParams(
@@ -1278,17 +1271,6 @@
             BuildQueue, BuildQueue.job == other_job.job)
         self.assertNotEqual([], list(other_buildqueue))
 
-    def test_AccessPolicyArtifact_deleted(self):
-        # Any AccessPolicyArtifact referencing the branch is removed.
-        branch = self.factory.makeAnyBranch()
-        artifact = self.factory.makeAccessPolicyArtifact(branch)
-        self.factory.makeAccessPolicyGrant(object=artifact)
-        self.assertIsNot(
-            None, getUtility(IAccessPolicyArtifactSource).get(branch))
-        branch.destroySelf()
-        self.assertIs(
-            None, getUtility(IAccessPolicyArtifactSource).get(branch))
-
     def test_createsJobToReclaimSpace(self):
         # When a branch is deleted from the database, a job to remove the
         # branch from disk as well.

=== modified file 'lib/lp/registry/configure.zcml'
--- lib/lp/registry/configure.zcml	2012-02-15 02:24:38 +0000
+++ lib/lp/registry/configure.zcml	2012-02-15 10:13:33 +0000
@@ -1906,41 +1906,4 @@
         for="lp.registry.interfaces.person.IPerson"
         provides="lp.registry.interfaces.role.IPersonRoles"
         factory="lp.registry.model.personroles.PersonRoles" />
-
-    <class
-        class="lp.registry.model.accesspolicy.AccessPolicy">
-        <allow
-            interface="lp.registry.interfaces.accesspolicy.IAccessPolicy"/>
-    </class>
-    <securedutility
-        component="lp.registry.model.accesspolicy.AccessPolicy"
-        provides="lp.registry.interfaces.accesspolicy.IAccessPolicySource">
-        <allow
-            interface="lp.registry.interfaces.accesspolicy.IAccessPolicySource"/>
-    </securedutility>
-    <class
-        class="lp.registry.model.accesspolicy.AccessPolicyArtifact">
-        <allow
-            interface="lp.registry.interfaces.accesspolicy.IAccessPolicyArtifact"/>
-        <require
-            permission="zope.Public"
-            set_attributes="policy"/>
-    </class>
-    <securedutility
-        component="lp.registry.model.accesspolicy.AccessPolicyArtifact"
-        provides="lp.registry.interfaces.accesspolicy.IAccessPolicyArtifactSource">
-        <allow
-            interface="lp.registry.interfaces.accesspolicy.IAccessPolicyArtifactSource"/>
-    </securedutility>
-    <class
-        class="lp.registry.model.accesspolicy.AccessPolicyGrant">
-        <allow
-            interface="lp.registry.interfaces.accesspolicy.IAccessPolicyGrant"/>
-    </class>
-    <securedutility
-        component="lp.registry.model.accesspolicy.AccessPolicyGrant"
-        provides="lp.registry.interfaces.accesspolicy.IAccessPolicyGrantSource">
-        <allow
-            interface="lp.registry.interfaces.accesspolicy.IAccessPolicyGrantSource"/>
-    </securedutility>
 </configure>

=== removed file 'lib/lp/registry/interfaces/accesspolicy.py'
--- lib/lp/registry/interfaces/accesspolicy.py	2011-11-22 04:35:08 +0000
+++ lib/lp/registry/interfaces/accesspolicy.py	1970-01-01 00:00:00 +0000
@@ -1,127 +0,0 @@
-# Copyright 2011 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Interfaces for pillar and artifact access policies."""
-
-__metaclass__ = type
-
-__all__ = [
-    'AccessPolicyType',
-    'IAccessPolicy',
-    'IAccessPolicyArtifact',
-    'IAccessPolicyArtifactSource',
-    'IAccessPolicyGrant',
-    'IAccessPolicySource',
-    'UnsuitableAccessPolicyError',
-    ]
-
-import httplib
-
-from lazr.enum import (
-    DBEnumeratedType,
-    DBItem,
-    )
-from lazr.restful.declarations import error_status
-from zope.interface import (
-    Attribute,
-    Interface,
-    )
-
-
-@error_status(httplib.BAD_REQUEST)
-class UnsuitableAccessPolicyError(Exception):
-    pass
-
-
-class AccessPolicyType(DBEnumeratedType):
-    """Access policy type."""
-
-    PRIVATE = DBItem(1, """
-        Private
-
-        This policy covers general private information.
-        """)
-
-    SECURITY = DBItem(2, """
-        Security
-
-        This policy covers information relating to confidential security
-        vulnerabilities.
-        """)
-
-
-class IAccessPolicy(Interface):
-    id = Attribute("ID")
-    pillar = Attribute("Pillar")
-    type = Attribute("Type")
-
-
-class IAccessPolicyArtifact(Interface):
-    id = Attribute("ID")
-    concrete_artifact = Attribute("Concrete artifact")
-    policy = Attribute("Access policy")
-
-
-class IAccessPolicyGrant(Interface):
-    id = Attribute("ID")
-    grantee = Attribute("Grantee")
-    grantor = Attribute("Grantor")
-    date_created = Attribute("Date created")
-    policy = Attribute("Access policy")
-    abstract_artifact = Attribute("Abstract artifact")
-
-    concrete_artifact = Attribute("Concrete artifact")
-
-
-class IAccessPolicySource(Interface):
-
-    def create(pillar, display_name):
-        """Create an `IAccessPolicy` for the pillar with the given name."""
-
-    def getByID(id):
-        """Return the `IAccessPolicy` with the given ID."""
-
-    def getByPillarAndType(pillar, type):
-        """Return the pillar's `IAccessPolicy` with the given type."""
-
-    def findByPillar(pillar):
-        """Return a ResultSet of all `IAccessPolicy`s for the pillar."""
-
-
-class IAccessPolicyArtifactSource(Interface):
-
-    def ensure(concrete_artifact):
-        """Return the `IAccessPolicyArtifact` for a concrete artifact.
-
-        Creates the abstract artifact if it doesn't already exist.
-        """
-
-    def get(concrete_artifact):
-        """Return the `IAccessPolicyArtifact` for an artifact, if it exists.
-
-        Use ensure() if you want to create one if it doesn't yet exist.
-        """
-
-    def delete(concrete_artifact):
-        """Delete the `IAccessPolicyArtifact` for a concrete artifact.
-
-        Also removes any AccessPolicyGrants for the artifact.
-        """
-
-
-class IAccessPolicyGrantSource(Interface):
-
-    def grant(grantee, grantor, object):
-        """Create an `IAccessPolicyGrant`.
-
-        :param grantee: the `IPerson` to hold the access.
-        :param grantor: the `IPerson` that grants the access.
-        :param object: the `IAccessPolicy` or `IAccessPolicyArtifact` to
-            grant access to.
-        """
-
-    def getByID(id):
-        """Return the `IAccessPolicyGrant` with the given ID."""
-
-    def findByPolicy(policy):
-        """Return all `IAccessPolicyGrant` objects for the policy."""

=== removed file 'lib/lp/registry/model/accesspolicy.py'
--- lib/lp/registry/model/accesspolicy.py	2011-12-30 06:14:56 +0000
+++ lib/lp/registry/model/accesspolicy.py	1970-01-01 00:00:00 +0000
@@ -1,198 +0,0 @@
-# Copyright 2011 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Model classes for pillar and artifact access policies."""
-
-__metaclass__ = type
-__all__ = [
-    'AccessPolicy',
-    'AccessPolicyArtifact',
-    'AccessPolicyGrant',
-    ]
-
-from storm.properties import (
-    DateTime,
-    Int,
-    )
-from storm.references import Reference
-from zope.interface import implements
-
-from lp.registry.interfaces.accesspolicy import (
-    AccessPolicyType,
-    IAccessPolicy,
-    IAccessPolicyArtifact,
-    IAccessPolicyGrant,
-    )
-from lp.services.database.enumcol import DBEnum
-from lp.services.database.lpstorm import IStore
-from lp.services.database.stormbase import StormBase
-
-
-class AccessPolicy(StormBase):
-    implements(IAccessPolicy)
-
-    __storm_table__ = 'AccessPolicy'
-
-    id = Int(primary=True)
-    product_id = Int(name='product')
-    product = Reference(product_id, 'Product.id')
-    distribution_id = Int(name='distribution')
-    distribution = Reference(distribution_id, 'Distribution.id')
-    type = DBEnum(allow_none=True, enum=AccessPolicyType)
-
-    @property
-    def pillar(self):
-        return self.product or self.distribution
-
-    @classmethod
-    def create(cls, pillar, type):
-        from lp.registry.interfaces.distribution import IDistribution
-        from lp.registry.interfaces.product import IProduct
-        obj = cls()
-        if IProduct.providedBy(pillar):
-            obj.product = pillar
-        elif IDistribution.providedBy(pillar):
-            obj.distribution = pillar
-        else:
-            raise ValueError("%r is not a supported pillar" % pillar)
-        obj.type = type
-        IStore(cls).add(obj)
-        return obj
-
-    @classmethod
-    def _constraintForPillar(cls, pillar):
-        from lp.registry.interfaces.distribution import IDistribution
-        from lp.registry.interfaces.product import IProduct
-        if IProduct.providedBy(pillar):
-            col = cls.product
-        elif IDistribution.providedBy(pillar):
-            col = cls.distribution
-        else:
-            raise ValueError("%r is not a supported pillar" % pillar)
-        return col == pillar
-
-    @classmethod
-    def getByID(cls, id):
-        """See `IAccessPolicySource`."""
-        return IStore(cls).get(cls, id)
-
-    @classmethod
-    def findByPillar(cls, pillar):
-        """See `IAccessPolicySource`."""
-        return IStore(cls).find(cls, cls._constraintForPillar(pillar))
-
-    @classmethod
-    def getByPillarAndType(cls, pillar, type):
-        """See `IAccessPolicySource`."""
-        return cls.findByPillar(pillar).find(type=type).one()
-
-
-class AccessPolicyArtifact(StormBase):
-    implements(IAccessPolicyArtifact)
-
-    __storm_table__ = 'AccessPolicyArtifact'
-
-    id = Int(primary=True)
-    bug_id = Int(name='bug')
-    bug = Reference(bug_id, 'Bug.id')
-    branch_id = Int(name='branch')
-    branch = Reference(branch_id, 'Branch.id')
-    policy_id = Int(name='policy')
-    policy = Reference(policy_id, 'AccessPolicy.id')
-
-    @property
-    def concrete_artifact(self):
-        artifact = self.bug or self.branch
-        assert artifact is not None
-        return artifact
-
-    @staticmethod
-    def _getConcreteAttribute(concrete_artifact):
-        from lp.bugs.interfaces.bug import IBug
-        from lp.code.interfaces.branch import IBranch
-        if IBug.providedBy(concrete_artifact):
-            return 'bug'
-        elif IBranch.providedBy(concrete_artifact):
-            return 'branch'
-        else:
-            raise ValueError(
-                "%r is not a valid artifact" % concrete_artifact)
-
-    @classmethod
-    def get(cls, concrete_artifact):
-        """See `IAccessPolicyArtifactSource`."""
-        constraints = {
-            cls._getConcreteAttribute(concrete_artifact): concrete_artifact}
-        return IStore(cls).find(cls, **constraints).one()
-
-    @classmethod
-    def ensure(cls, concrete_artifact):
-        """See `IAccessPolicyArtifactSource`."""
-        existing = cls.get(concrete_artifact)
-        if existing is not None:
-            return existing
-        # No existing object. Create a new one.
-        obj = cls()
-        setattr(
-            obj, cls._getConcreteAttribute(concrete_artifact),
-            concrete_artifact)
-        IStore(cls).add(obj)
-        return obj
-
-    @classmethod
-    def delete(cls, concrete_artifact):
-        """See `IAccessPolicyArtifactSource`."""
-        abstract = cls.get(concrete_artifact)
-        if abstract is None:
-            return
-        IStore(abstract).find(
-            AccessPolicyGrant, abstract_artifact=abstract).remove()
-        IStore(abstract).find(AccessPolicyArtifact, id=abstract.id).remove()
-
-
-class AccessPolicyGrant(StormBase):
-    implements(IAccessPolicyGrant)
-
-    __storm_table__ = 'AccessPolicyGrant'
-
-    id = Int(primary=True)
-    grantee_id = Int(name='grantee')
-    grantee = Reference(grantee_id, 'Person.id')
-    policy_id = Int(name='policy')
-    policy = Reference(policy_id, 'AccessPolicy.id')
-    abstract_artifact_id = Int(name='artifact')
-    abstract_artifact = Reference(
-        abstract_artifact_id, 'AccessPolicyArtifact.id')
-    grantor_id = Int(name='grantor')
-    grantor = Reference(grantor_id, 'Person.id')
-    date_created = DateTime()
-
-    @property
-    def concrete_artifact(self):
-        if self.abstract_artifact is not None:
-            return self.abstract_artifact.concrete_artifact
-
-    @classmethod
-    def grant(cls, grantee, grantor, object):
-        """See `IAccessPolicyGrantSource`."""
-        grant = cls()
-        grant.grantee = grantee
-        grant.grantor = grantor
-        if IAccessPolicy.providedBy(object):
-            grant.policy = object
-        elif IAccessPolicyArtifact.providedBy(object):
-            grant.abstract_artifact = object
-        else:
-            raise ValueError("Unsupported object: %r" % object)
-        IStore(cls).add(grant)
-        return grant
-
-    @classmethod
-    def getByID(cls, id):
-        """See `IAccessPolicyGrantSource`."""
-        return IStore(cls).get(cls, id)
-
-    @classmethod
-    def findByPolicy(cls, policy):
-        """See `IAccessPolicyGrantSource`."""
-        return IStore(cls).find(cls, policy=policy)

=== modified file 'lib/lp/registry/model/person.py'
--- lib/lp/registry/model/person.py	2012-02-15 00:57:40 +0000
+++ lib/lp/registry/model/person.py	2012-02-15 10:13:33 +0000
@@ -3616,31 +3616,6 @@
         skip.append(
             (decorator_table.lower(), person_pointer_column.lower()))
 
-    def _mergeAccessPolicyGrant(self, cur, from_id, to_id):
-        # Update only the AccessPolicyGrants that will not conflict.
-        cur.execute('''
-            UPDATE AccessPolicyGrant
-            SET grantee=%(to_id)d
-            WHERE grantee = %(from_id)d AND (
-                policy NOT IN
-                    (
-                    SELECT policy
-                    FROM AccessPolicyGrant
-                    WHERE grantee = %(to_id)d
-                    )
-                OR artifact NOT IN
-                    (
-                    SELECT artifact
-                    FROM AccessPolicyGrant
-                    WHERE grantee = %(to_id)d
-                    )
-                )
-            ''' % vars())
-        # and delete those left over.
-        cur.execute('''
-            DELETE FROM AccessPolicyGrant WHERE grantee = %(from_id)d
-            ''' % vars())
-
     def _mergeBranches(self, from_person, to_person):
         # This shouldn't use removeSecurityProxy.
         branches = getUtility(IBranchCollection).ownedBy(from_person)
@@ -4194,9 +4169,6 @@
             % vars())
         skip.append(('gpgkey', 'owner'))
 
-        self._mergeAccessPolicyGrant(cur, from_id, to_id)
-        skip.append(('accesspolicygrant', 'grantee'))
-
         # Update the Branches that will not conflict, and fudge the names of
         # ones that *do* conflict.
         self._mergeBranches(from_person, to_person)

=== removed file 'lib/lp/registry/tests/test_accesspolicy.py'
--- lib/lp/registry/tests/test_accesspolicy.py	2012-01-01 02:58:52 +0000
+++ lib/lp/registry/tests/test_accesspolicy.py	1970-01-01 00:00:00 +0000
@@ -1,287 +0,0 @@
-# Copyright 2011 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-__metaclass__ = type
-
-from storm.exceptions import LostObjectError
-from storm.store import Store
-from testtools.matchers import MatchesStructure
-from zope.component import getUtility
-
-from lp.registry.interfaces.accesspolicy import (
-    AccessPolicyType,
-    IAccessPolicy,
-    IAccessPolicyArtifact,
-    IAccessPolicyArtifactSource,
-    IAccessPolicyGrant,
-    IAccessPolicyGrantSource,
-    IAccessPolicySource,
-    )
-from lp.services.database.lpstorm import IStore
-from lp.testing import TestCaseWithFactory
-from lp.testing.layers import DatabaseFunctionalLayer
-from lp.testing.matchers import Provides
-
-
-class TestAccessPolicy(TestCaseWithFactory):
-    layer = DatabaseFunctionalLayer
-
-    def test_provides_interface(self):
-        self.assertThat(
-            self.factory.makeAccessPolicy(), Provides(IAccessPolicy))
-
-    def test_pillar(self):
-        product = self.factory.makeProduct()
-        policy = self.factory.makeAccessPolicy(pillar=product)
-        self.assertEqual(product, policy.pillar)
-
-
-class TestAccessPolicySource(TestCaseWithFactory):
-    layer = DatabaseFunctionalLayer
-
-    def test_create_for_product(self):
-        product = self.factory.makeProduct()
-        type = AccessPolicyType.SECURITY
-        policy = getUtility(IAccessPolicySource).create(product, type)
-        self.assertThat(
-            policy,
-            MatchesStructure.byEquality(pillar=product, type=type))
-
-    def test_getByID(self):
-        # getByID finds the right policy.
-        policy = self.factory.makeAccessPolicy()
-        # Flush so we get an ID.
-        Store.of(policy).flush()
-        self.assertEqual(
-            policy, getUtility(IAccessPolicySource).getByID(policy.id))
-
-    def test_getByID_nonexistent(self):
-        # getByID returns None if the policy doesn't exist.
-        self.assertIs(
-            None,
-            getUtility(IAccessPolicySource).getByID(
-                self.factory.getUniqueInteger()))
-
-    def test_getByPillarAndType(self):
-        # getByPillarAndType finds the right policy.
-        product = self.factory.makeProduct()
-
-        private_policy = self.factory.makeAccessPolicy(
-            pillar=product, type=AccessPolicyType.PRIVATE)
-        security_policy = self.factory.makeAccessPolicy(
-            pillar=product, type=AccessPolicyType.SECURITY)
-        self.assertEqual(
-            private_policy,
-            getUtility(IAccessPolicySource).getByPillarAndType(
-                product, AccessPolicyType.PRIVATE))
-        self.assertEqual(
-            security_policy,
-            getUtility(IAccessPolicySource).getByPillarAndType(
-                product, AccessPolicyType.SECURITY))
-
-    def test_getByPillarAndType_nonexistent(self):
-        # getByPillarAndType returns None if the policy doesn't exist.
-        # Create policy identifiers, and an unrelated policy.
-        self.factory.makeAccessPolicy(type=AccessPolicyType.PRIVATE)
-        product = self.factory.makeProduct()
-        self.assertIs(
-            None,
-            getUtility(IAccessPolicySource).getByPillarAndType(
-                product, AccessPolicyType.PRIVATE))
-
-    def test_findByPillar(self):
-        # findByPillar finds only the relevant policies.
-        product = self.factory.makeProduct()
-        policies = [
-            self.factory.makeAccessPolicy(pillar=product, type=type)
-            for type in AccessPolicyType.items]
-        self.factory.makeAccessPolicy()
-        self.assertContentEqual(
-            policies,
-            getUtility(IAccessPolicySource).findByPillar(product))
-
-
-class TestAccessPolicyArtifact(TestCaseWithFactory):
-    layer = DatabaseFunctionalLayer
-
-    def test_provides_interface(self):
-        self.assertThat(
-            self.factory.makeAccessPolicyArtifact(),
-            Provides(IAccessPolicyArtifact))
-
-    def test_policy(self):
-        policy = self.factory.makeAccessPolicy()
-        self.assertEqual(
-            policy,
-            self.factory.makeAccessPolicyArtifact(policy=policy).policy)
-
-
-class TestAccessPolicyArtifactSourceOnce(TestCaseWithFactory):
-    layer = DatabaseFunctionalLayer
-
-    def test_ensure_other_fails(self):
-        # ensure() rejects unsupported objects.
-        self.assertRaises(
-            ValueError,
-            getUtility(IAccessPolicyArtifactSource).ensure,
-            self.factory.makeProduct())
-
-
-class BaseAccessPolicyArtifactTests:
-    layer = DatabaseFunctionalLayer
-
-    def getConcreteArtifact(self):
-        raise NotImplementedError()
-
-    def test_ensure(self):
-        # ensure() creates an abstract artifact which maps to the
-        # concrete one.
-        concrete = self.getConcreteArtifact()
-        abstract = getUtility(IAccessPolicyArtifactSource).ensure(concrete)
-        Store.of(abstract).flush()
-        self.assertEqual(concrete, abstract.concrete_artifact)
-
-    def test_get(self):
-        # get() finds an abstract artifact which maps to the concrete
-        # one.
-        concrete = self.getConcreteArtifact()
-        abstract = getUtility(IAccessPolicyArtifactSource).ensure(concrete)
-        self.assertEqual(
-            abstract, getUtility(IAccessPolicyArtifactSource).get(concrete))
-
-    def test_ensure_twice(self):
-        # ensure() will reuse an existing matching abstract artifact if
-        # it exists.
-        concrete = self.getConcreteArtifact()
-        abstract = getUtility(IAccessPolicyArtifactSource).ensure(concrete)
-        Store.of(abstract).flush()
-        self.assertEqual(
-            abstract.id,
-            getUtility(IAccessPolicyArtifactSource).ensure(concrete).id)
-
-    def test_delete(self):
-        # delete() removes the abstract artifact and any associated
-        # grants.
-        concrete = self.getConcreteArtifact()
-        abstract = getUtility(IAccessPolicyArtifactSource).ensure(concrete)
-        grant = self.factory.makeAccessPolicyGrant(object=abstract)
-
-        # Make some other grants to ensure they're unaffected.
-        other_grants = [
-            self.factory.makeAccessPolicyGrant(
-                object=self.factory.makeAccessPolicyArtifact()),
-            self.factory.makeAccessPolicyGrant(
-                object=self.factory.makeAccessPolicy()),
-            ]
-
-        getUtility(IAccessPolicyArtifactSource).delete(concrete)
-        IStore(grant).invalidate()
-        self.assertRaises(LostObjectError, getattr, grant, 'policy')
-        self.assertRaises(
-            LostObjectError, getattr, abstract, 'concrete_artifact')
-
-        for other_grant in other_grants:
-            self.assertEqual(
-                other_grant,
-                getUtility(IAccessPolicyGrantSource).getByID(other_grant.id))
-
-    def test_delete_noop(self):
-        # delete() works even if there's no abstract artifact.
-        concrete = self.getConcreteArtifact()
-        getUtility(IAccessPolicyArtifactSource).delete(concrete)
-
-
-class TestAccessPolicyArtifactBranch(BaseAccessPolicyArtifactTests,
-                                     TestCaseWithFactory):
-
-    def getConcreteArtifact(self):
-        return self.factory.makeBranch()
-
-
-class TestAccessPolicyArtifactBug(BaseAccessPolicyArtifactTests,
-                                  TestCaseWithFactory):
-
-    def getConcreteArtifact(self):
-        return self.factory.makeBug()
-
-
-class TestAccessPolicyGrant(TestCaseWithFactory):
-    layer = DatabaseFunctionalLayer
-
-    def test_provides_interface(self):
-        self.assertThat(
-            self.factory.makeAccessPolicyGrant(),
-            Provides(IAccessPolicyGrant))
-
-    def test_concrete_artifact(self):
-        bug = self.factory.makeBug()
-        abstract = self.factory.makeAccessPolicyArtifact(bug)
-        grant = self.factory.makeAccessPolicyGrant(
-            object=abstract)
-        self.assertEqual(bug, grant.concrete_artifact)
-
-    def test_no_concrete_artifact(self):
-        grant = self.factory.makeAccessPolicyGrant(
-            object=self.factory.makeAccessPolicy())
-        self.assertIs(None, grant.concrete_artifact)
-
-
-class TestAccessPolicyGrantSource(TestCaseWithFactory):
-    layer = DatabaseFunctionalLayer
-
-    def test_grant_for_policy(self):
-        policy = self.factory.makeAccessPolicy()
-        grantee = self.factory.makePerson()
-        grantor = self.factory.makePerson()
-        grant = getUtility(IAccessPolicyGrantSource).grant(
-            grantee, grantor, policy)
-        self.assertThat(
-            grant,
-            MatchesStructure.byEquality(
-                grantee=grantee,
-                grantor=grantor,
-                policy=policy,
-                abstract_artifact=None,
-                concrete_artifact=None,))
-
-    def test_grant_with_artifact(self):
-        artifact = self.factory.makeAccessPolicyArtifact()
-        grantee = self.factory.makePerson()
-        grantor = self.factory.makePerson()
-        grant = getUtility(IAccessPolicyGrantSource).grant(
-            grantee, grantor, artifact)
-        self.assertThat(
-            grant,
-            MatchesStructure.byEquality(
-                grantee=grantee,
-                grantor=grantor,
-                policy=None,
-                abstract_artifact=artifact,
-                concrete_artifact=artifact.concrete_artifact))
-
-    def test_getByID(self):
-        # getByID finds the right grant.
-        grant = self.factory.makeAccessPolicyGrant()
-        # Flush so we get an ID.
-        Store.of(grant).flush()
-        self.assertEqual(
-            grant,
-            getUtility(IAccessPolicyGrantSource).getByID(grant.id))
-
-    def test_getByID_nonexistent(self):
-        # getByID returns None if the grant doesn't exist.
-        self.assertIs(
-            None,
-            getUtility(IAccessPolicyGrantSource).getByID(
-                self.factory.getUniqueInteger()))
-
-    def test_findByPolicy(self):
-        # findByPolicy finds only the relevant grants.
-        policy = self.factory.makeAccessPolicy()
-        grants = [
-            self.factory.makeAccessPolicyGrant(object=policy)
-            for i in range(3)]
-        self.factory.makeAccessPolicyGrant()
-        self.assertContentEqual(
-            grants,
-            getUtility(IAccessPolicyGrantSource).findByPolicy(policy))

=== modified file 'lib/lp/registry/tests/test_personset.py'
--- lib/lp/registry/tests/test_personset.py	2012-02-09 20:23:49 +0000
+++ lib/lp/registry/tests/test_personset.py	2012-02-15 10:13:33 +0000
@@ -36,7 +36,6 @@
     TeamEmailAddressError,
     )
 from lp.registry.interfaces.personnotification import IPersonNotificationSet
-from lp.registry.model.accesspolicy import AccessPolicyGrant
 from lp.registry.model.person import (
     Person,
     PersonSet,
@@ -529,41 +528,6 @@
         dsp = self.factory.makeDistributionSourcePackage()
         self.assertConflictingSubscriptionDeletes(dsp)
 
-    def test_merge_accesspolicygrants(self):
-        # AccessPolicyGrants are transferred from the duplicate.
-        person = self.factory.makePerson()
-        grant = self.factory.makeAccessPolicyGrant()
-        self._do_premerge(grant.grantee, person)
-        with person_logged_in(person):
-            self._do_merge(grant.grantee, person)
-        self.assertEqual(person, grant.grantee)
-
-    def test_merge_accesspolicygrants_conflicts(self):
-        # Conflicting AccessPolicyGrants are deleted.
-        policy = self.factory.makeAccessPolicy()
-
-        person = self.factory.makePerson()
-        person_grantor = self.factory.makePerson()
-        person_grant = self.factory.makeAccessPolicyGrant(
-            grantee=person, grantor=person_grantor, object=policy)
-
-        duplicate = self.factory.makePerson()
-        duplicate_grantor = self.factory.makePerson()
-        duplicate_grant = self.factory.makeAccessPolicyGrant(
-            grantee=duplicate, grantor=duplicate_grantor, object=policy)
-
-        self._do_premerge(duplicate, person)
-        with person_logged_in(person):
-            self._do_merge(duplicate, person)
-        transaction.commit()
-
-        self.assertEqual(person, person_grant.grantee)
-        self.assertEqual(person_grantor, person_grant.grantor)
-        self.assertIs(
-            None,
-            IStore(AccessPolicyGrant).get(
-                AccessPolicyGrant, duplicate_grant.id))
-
     def test_mergeAsync(self):
         # mergeAsync() creates a new `PersonMergeJob`.
         from_person = self.factory.makePerson()

=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py	2012-02-14 02:22:59 +0000
+++ lib/lp/testing/factory.py	2012-02-15 10:13:33 +0000
@@ -140,12 +140,6 @@
     DistroSeriesDifferenceStatus,
     DistroSeriesDifferenceType,
     )
-from lp.registry.interfaces.accesspolicy import (
-    AccessPolicyType,
-    IAccessPolicyArtifactSource,
-    IAccessPolicyGrantSource,
-    IAccessPolicySource,
-    )
 from lp.registry.interfaces.distribution import (
     IDistribution,
     IDistributionSet,
@@ -4345,33 +4339,6 @@
             target_distroseries, target_pocket,
             package_version=package_version, requester=requester)
 
-    def makeAccessPolicy(self, pillar=None, type=AccessPolicyType.PRIVATE):
-        if pillar is None:
-            pillar = self.makeProduct()
-        policy = getUtility(IAccessPolicySource).create(pillar, type)
-        IStore(policy).flush()
-        return policy
-
-    def makeAccessPolicyArtifact(self, concrete=None, policy=None):
-        if concrete is None:
-            concrete = self.makeBranch()
-        artifact = getUtility(IAccessPolicyArtifactSource).ensure(concrete)
-        artifact.policy = policy
-        IStore(artifact).flush()
-        return artifact
-
-    def makeAccessPolicyGrant(self, grantee=None, object=None, grantor=None):
-        if grantee is None:
-            grantee = self.makePerson()
-        if grantor is None:
-            grantor = self.makePerson()
-        if object is None:
-            object = self.makeAccessPolicy()
-        grant = getUtility(IAccessPolicyGrantSource).grant(
-            grantee, grantor, object)
-        IStore(grant).flush()
-        return grant
-
     def makeFakeFileUpload(self, filename=None, content=None):
         """Return a zope.publisher.browser.FileUpload like object.