← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~cjwatson/launchpad/close-account-more-2 into lp:launchpad

 

Colin Watson has proposed merging lp:~cjwatson/launchpad/close-account-more-2 into lp:launchpad.

Commit message:
Handle archive subscriptions and hardware submissions in close-account.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/close-account-more-2/+merge/363259

We have a potential erasure request in progress that requires this.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/close-account-more-2 into lp:launchpad.
=== modified file 'database/schema/security.cfg'
--- database/schema/security.cfg	2018-12-03 13:42:36 +0000
+++ database/schema/security.cfg	2019-02-15 16:33:55 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 #
 # Possible permissions: SELECT, INSERT, UPDATE, EXECUTE
@@ -333,6 +333,8 @@
 [launchpad]
 groups=launchpad_main
 type=user
+public.archivesubscriber                = SELECT, INSERT, UPDATE, DELETE
+public.hwsubmission                     = SELECT, INSERT, UPDATE, DELETE
 public.karma                            = SELECT, INSERT, UPDATE, DELETE
 public.sharingjob                       = SELECT, INSERT, UPDATE, DELETE
 public.signedcodeofconduct              = SELECT, INSERT, UPDATE, DELETE

=== modified file 'lib/lp/registry/scripts/closeaccount.py'
--- lib/lp/registry/scripts/closeaccount.py	2019-01-15 17:04:31 +0000
+++ lib/lp/registry/scripts/closeaccount.py	2019-02-15 16:33:55 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Remove personal details of a user from the database, leaving a stub."""
@@ -234,6 +234,7 @@
         ('GpgKey', 'owner'),
 
         # Subscriptions and notifications
+        ('ArchiveSubscriber', 'subscriber'),
         ('BranchSubscription', 'person'),
         ('BugMute', 'person'),
         ('BugNotificationRecipient', 'person'),
@@ -282,6 +283,9 @@
 
         # "Affects me too" information
         ('BugAffectsPerson', 'person'),
+
+        # Hardware submissions
+        ('HWSubmission', 'owner'),
         ]
     for table, person_id_column in removals:
         table_notification(table)
@@ -306,6 +310,15 @@
     # the placeholder person row.
     skip.add(('sprintattendance', 'attendee'))
 
+    # XXX cjwatson 2019-02-15: We can't just delete archive auth tokens at
+    # the moment, because generate_ppa_htaccess currently relies on seeing
+    # active rows there so that it knows which ones to remove from .htpasswd
+    # files on disk in response to the removal of the corresponding
+    # ArchiveSubscriber rows.  Once PPA authorisation is handled dynamically
+    # (e.g. via a WSGI authenticator), we can simplify this and just delete
+    # the ArchiveAuthToken rows instead.
+    skip.add(('archiveauthtoken', 'person'))
+
     # Closing the account will only work if all references have been handled
     # by this point.  If not, it's safer to bail out.  It's OK if this
     # doesn't work in all conceivable situations, since some of them may

=== modified file 'lib/lp/registry/scripts/tests/test_closeaccount.py'
--- lib/lp/registry/scripts/tests/test_closeaccount.py	2019-01-15 17:04:31 +0000
+++ lib/lp/registry/scripts/tests/test_closeaccount.py	2019-02-15 16:33:55 +0000
@@ -1,4 +1,4 @@
-# Copyright 2018 Canonical Ltd.  This software is licensed under the
+# Copyright 2018-2019 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Test the close-account script."""
@@ -18,6 +18,7 @@
 
 from lp.answers.enums import QuestionStatus
 from lp.app.interfaces.launchpad import ILaunchpadCelebrities
+from lp.hardwaredb.interfaces.hwdb import IHWSubmissionSet
 from lp.registry.interfaces.person import IPersonSet
 from lp.registry.scripts.closeaccount import CloseAccountScript
 from lp.scripts.garbo import PopulateLatestPersonSourcePackageReleaseCache
@@ -33,6 +34,7 @@
     )
 from lp.services.scripts.base import LaunchpadScriptFailure
 from lp.soyuz.enums import PackagePublishingStatus
+from lp.soyuz.interfaces.archivesubscriber import IArchiveSubscriberSet
 from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
 from lp.testing import TestCaseWithFactory
 from lp.testing.dbuser import dbuser
@@ -320,3 +322,41 @@
             self.runScript(script)
         self.assertRemoved(account_id, person_id)
         self.assertTrue(translations_person.translations_relicensing_agreement)
+
+    def test_handles_archive_subscriptions_and_tokens(self):
+        person = self.factory.makePerson()
+        ppa = self.factory.makeArchive(private=True)
+        ppa.newSubscription(person, ppa.owner)
+        ppa.newAuthToken(person)
+        archive_subscriber_set = getUtility(IArchiveSubscriberSet)
+        self.assertNotEqual(
+            [],
+            list(archive_subscriber_set.getBySubscriber(person, archive=ppa)))
+        self.assertIsNotNone(ppa.getAuthToken(person))
+        person_id = person.id
+        account_id = person.account.id
+        script = self.makeScript([six.ensure_str(person.name)])
+        with dbuser('launchpad'):
+            self.runScript(script)
+        self.assertRemoved(account_id, person_id)
+        self.assertEqual(
+            [],
+            list(archive_subscriber_set.getBySubscriber(person, archive=ppa)))
+        self.assertIsNotNone(ppa.getAuthToken(person))
+
+    def test_handles_hardware_submissions(self):
+        person = self.factory.makePerson()
+        submission = self.factory.makeHWSubmission(
+            emailaddress=person.preferredemail.email)
+        key = submission.submission_key
+        hw_submission_set = getUtility(IHWSubmissionSet)
+        self.assertNotEqual([], list(hw_submission_set.getByOwner(person)))
+        self.assertIsNotNone(hw_submission_set.getBySubmissionKey(key))
+        person_id = person.id
+        account_id = person.account.id
+        script = self.makeScript([six.ensure_str(person.name)])
+        with dbuser('launchpad'):
+            self.runScript(script)
+        self.assertRemoved(account_id, person_id)
+        self.assertEqual([], list(hw_submission_set.getByOwner(person)))
+        self.assertIsNone(hw_submission_set.getBySubmissionKey(key))


Follow ups