← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:archiveauthtoken-multiple-subscriptions into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:archiveauthtoken-multiple-subscriptions into launchpad:master.

Commit message:
Fix ArchiveAuthToken lookup with multiple subscriptions

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #1922258 in Launchpad itself: "Access to private PPA with multiple subscription OOPS"
  https://bugs.launchpad.net/launchpad/+bug/1922258

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/400549

When querying for tokens with current subscriptions, `ArchiveAuthTokenSet.getByArchive` could return multiple rows even though there was only a single token due to the additional joins.  Add `DISTINCT` to avoid this.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:archiveauthtoken-multiple-subscriptions into launchpad:master.
diff --git a/lib/lp/soyuz/doc/archiveauthtoken.txt b/lib/lp/soyuz/doc/archiveauthtoken.txt
index c6c3fa3..c02db56 100644
--- a/lib/lp/soyuz/doc/archiveauthtoken.txt
+++ b/lib/lp/soyuz/doc/archiveauthtoken.txt
@@ -21,7 +21,7 @@ New tokens are created using IArchive.newAuthToken() but this is only
 possible if there is already a valid subscription for the user for
 that archive.
 
-Create Brad, and his team:
+Create Brad, and his teams:
 
     >>> login("admin@xxxxxxxxxxxxx")
     >>> bradsmith = factory.makePerson(
@@ -29,6 +29,8 @@ Create Brad, and his team:
     ...     email="brad@xxxxxxxxxxx")
     >>> teambrad = factory.makeTeam(
     ...     owner=bradsmith, displayname="Team Brad", name='teambrad')
+    >>> teambrad2 = factory.makeTeam(
+    ...     owner=bradsmith, displayname="Team Brad 2", name='teambrad2')
 
 Create a subscription for Team Brad to joe's archive:
 
@@ -169,6 +171,19 @@ Tokens are only returned if they match a current subscription:
     >>> removeSecurityProxy(subscription_to_joe_private_ppa).status = (
     ...     ArchiveSubscriberStatus.CURRENT)
 
+Retrieving tokens works even if the user is subscribed to the archive via
+multiple paths:
+
+    >>> _ = login_person(joe)
+    >>> _ = joe_private_ppa.newSubscription(teambrad2, joe)
+    >>> login("brad@xxxxxxxxxxx")
+    >>> print(token_set.getActiveTokenForArchiveAndPerson(
+    ...     new_token.archive, new_token.person).token)
+    testtoken
+    >>> print(token_set.getActiveTokenForArchiveAndPersonName(
+    ...     new_token.archive, "bradsmith").token)
+    testtoken
+
 
 == Amending Tokens ==
 
diff --git a/lib/lp/soyuz/model/archiveauthtoken.py b/lib/lp/soyuz/model/archiveauthtoken.py
index 2dfe646..3d39143 100644
--- a/lib/lp/soyuz/model/archiveauthtoken.py
+++ b/lib/lp/soyuz/model/archiveauthtoken.py
@@ -103,7 +103,7 @@ class ArchiveAuthTokenSet:
                 ArchiveSubscriber.subscriber_id == TeamParticipation.teamID,
                 TeamParticipation.personID == ArchiveAuthToken.person_id,
                 ])
-        return store.find(ArchiveAuthToken, *clauses)
+        return store.find(ArchiveAuthToken, *clauses).config(distinct=True)
 
     def getActiveTokenForArchiveAndPerson(self, archive, person):
         """See `IArchiveAuthTokenSet`."""