Merge lp:~sinzui/launchpad/delete-merged-account into lp:launchpad

Proposed by Curtis Hovey
Status: Merged
Merged at revision: 10836
Proposed branch: lp:~sinzui/launchpad/delete-merged-account
Merge into: lp:launchpad
Diff against target: 119 lines (+47/-11)
3 files modified
database/schema/pending/update-merged-person-accounts.sql (+24/-0)
lib/lp/registry/doc/person-merge.txt (+11/-3)
lib/lp/registry/model/person.py (+12/-8)
To merge this branch: bzr merge lp:~sinzui/launchpad/delete-merged-account
Reviewer Review Type Date Requested Status
Abel Deuring (community) code Approve
Review via email: mp+24898@code.launchpad.net

Description of the change

This is my branch to hide the accounts of merged persons.

    lp:~sinzui/launchpad/delete-merged-account
    Diff size: 119
    Launchpad bug: https://bugs.launchpad.net/bugs/575317
    Test command: ./bin/test -vv -t person-merge
    Pre-implementation: mars. salgado
    Target release: 10.05

Hide the accounts of merged persons
-----------------------------------

Recent changes to SSO require Launchpad to delete the accounts of merged
users.

ISD has its own database now and it is not aware of Launchpad person merges.
The summary of the long conversation is that Lp uses the OpenID identifier
and falls back to email address. Since the merged account has the SSO OpenID
identifier, the wrong account is used. We need to prevent Launchpad from
matching the identifier to an account of a merged person. Launchpad correctly
falls back to email address when there is no account and will update that
account's identifier as needed.

We considered deleting the account, but there are many relationships that are
tied to account. We decided to change the Launchpad account's openid
identifier to one that cannot match any identifier sent from SSO.

Rules
-----

    * Change the account's openid_identifier at the end of Person.merge().
    * Prepare a script to delete delete all merged accounts to
      fix the data.

QA
--

    * On staging, merge an account.
    * Verify it is not in the database afterwards
    * Login using the merged account's email address
    * Verify that you login to the remaining account.

Lint
----

Linting changed files:
  database/schema/pending/update-merged-person-accounts.sql
  lib/lp/registry/doc/person-merge.txt
  lib/lp/registry/model/person.py

Test
----

    * lib/lp/registry/doc/person-merge.txt
      * Updated the test to verify that openid_identifier of the merged
        person is changed.

Implementation
--------------

    * database/schema/pending/update-merged-person-accounts.sql
      * Added a script to fix the existing data, 1500+ accounts.
    * lib/lp/registry/model/person.py
      * Updated Person.merge() to change the openid_identifier of the merged
        person.

To post a comment you must log in.
Revision history for this message
Abel Deuring (adeuring) wrote :

Hi Curtis,

a nice branch. I just have a few nitpicks, see below.

> === added file 'database/schema/pending/update-merged-person-accounts.sql'
> --- database/schema/pending/update-merged-person-accounts.sql 1970-01-01 00:00:00 +0000
> +++ database/schema/pending/update-merged-person-accounts.sql 2010-05-07 14:10:52 +0000
> @@ -0,0 +1,24 @@
> +-- Copyright 2010 Canonical Ltd. This software is licensed under the
> +-- GNU Affero General Public License version 3 (see the file LICENSE).
> +
> +SET client_min_messages=ERROR;
> +
> +SELECT
> + Account.displayname,
> + Account.openid_identifier,
> + 'merged-' || Account.openid_identifier
> +FROM Account
> + JOIN Person ON Account.id = Person.account
> +WHERE
> + Person.merged IS NOT NULL
> +;

I think we don't need the SELECT above.

> +
> +-- Change the openid_identifier of merged Persons to prevent the merged
> +-- person from being selected during login.
> +UPDATE Account
> +SET openid_identifier = 'merged-' || openid_identifier
> +FROM Person
> +WHERE
> + Account.id = Person.account
> + AND Person.merged IS NOT NULL
> +;
>
> === modified file 'lib/lp/registry/doc/person-merge.txt'
> --- lib/lp/registry/doc/person-merge.txt 2010-02-16 20:36:48 +0000
> +++ lib/lp/registry/doc/person-merge.txt 2010-05-07 14:10:52 +0000
> @@ -161,7 +161,7 @@
> >>> sample.karma == sampleperson_old_karma
> True
>
> -A merged account gets a -merged suffix on its name.
> +A merged person gets a -merged suffix on its name.
>
> >>> from storm.store import Store
> >>> store = Store.of(marilize)
> @@ -186,8 +186,8 @@
> >>> results.get_one()[0]
> u'name12'
>
> -The account that has been merged is flagged. We can use this to eliminate
> -merged accounts from lists etc.
> +The person that has been merged is flagged. We can use this to eliminate
> +merged person from lists etc.

s/person/persons/

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'database/schema/pending/update-merged-person-accounts.sql'
2--- database/schema/pending/update-merged-person-accounts.sql 1970-01-01 00:00:00 +0000
3+++ database/schema/pending/update-merged-person-accounts.sql 2010-05-07 20:31:27 +0000
4@@ -0,0 +1,24 @@
5+-- Copyright 2010 Canonical Ltd. This software is licensed under the
6+-- GNU Affero General Public License version 3 (see the file LICENSE).
7+
8+SET client_min_messages=ERROR;
9+
10+--SELECT
11+-- Account.displayname,
12+-- Account.openid_identifier,
13+-- 'merged-' || Account.openid_identifier
14+--FROM Account
15+-- JOIN Person ON Account.id = Person.account
16+--WHERE
17+-- Person.merged IS NOT NULL
18+--;
19+
20+-- Change the openid_identifier of merged Persons to prevent the merged
21+-- person from being selected during login.
22+UPDATE Account
23+SET openid_identifier = 'merged-' || openid_identifier
24+FROM Person
25+WHERE
26+ Account.id = Person.account
27+ AND Person.merged IS NOT NULL
28+;
29
30=== modified file 'lib/lp/registry/doc/person-merge.txt'
31--- lib/lp/registry/doc/person-merge.txt 2010-02-16 20:36:48 +0000
32+++ lib/lp/registry/doc/person-merge.txt 2010-05-07 20:31:27 +0000
33@@ -161,7 +161,7 @@
34 >>> sample.karma == sampleperson_old_karma
35 True
36
37-A merged account gets a -merged suffix on its name.
38+A merged person gets a -merged suffix on its name.
39
40 >>> from storm.store import Store
41 >>> store = Store.of(marilize)
42@@ -186,8 +186,8 @@
43 >>> results.get_one()[0]
44 u'name12'
45
46-The account that has been merged is flagged. We can use this to eliminate
47-merged accounts from lists etc.
48+The person that has been merged is flagged. We can use this to eliminate
49+merged persons from lists etc.
50
51 >>> results = store.execute(
52 ... "SELECT merged FROM Person WHERE name='marilize-merged'")
53@@ -199,6 +199,14 @@
54 >>> results.get_one()[0] is None
55 True
56
57+The openid_identifier of the merged account is changed so that if the user
58+logs in using that SSO account, Launchpad will select the Person by email
59+instead of OpenID. Launchpad will update the OpenID of the remaining account
60+if needed.
61+
62+ >>> print marilize.account.openid_identifier
63+ merged-marilize_oid
64+
65 An email is sent to the user informing him that he should review his email
66 and mailing list subscription settings.
67
68
69=== modified file 'lib/lp/registry/model/person.py'
70--- lib/lp/registry/model/person.py 2010-04-29 23:06:26 +0000
71+++ lib/lp/registry/model/person.py 2010-05-07 20:31:27 +0000
72@@ -277,12 +277,6 @@
73 mugshot = ForeignKey(
74 dbName='mugshot', foreignKey='LibraryFileAlias', default=None)
75
76- # XXX StuartBishop 2008-05-13 bug=237280: The password,
77- # account_status and account_status_comment properties should go. Note
78- # that they override the current strict controls on Account, allowing
79- # access via Person to use the less strict controls on that interface.
80- # Part of the process of removing these methods from Person will be
81- # loosening the permissions on Account or fixing the callsites.
82 def _get_password(self):
83 # We have to remove the security proxy because the password is
84 # needed before we are authenticated. I'm not overly worried because
85@@ -3354,7 +3348,7 @@
86 # from being merged.
87 ('mailinglist', 'team'),
88 # I don't think we need to worry about the votecast and vote
89- # tables, because a real human should never have two accounts
90+ # tables, because a real human should never have two profiles
91 # in Launchpad that are active members of a given team and voted
92 # in a given poll. -- GuilhermeSalgado 2005-07-07
93 # We also can't afford to change poll results after they are
94@@ -3507,7 +3501,7 @@
95 UPDATE Person SET merged=%(to_id)d WHERE id=%(from_id)d
96 ''' % vars())
97
98- # Append a -merged suffix to the account's name.
99+ # Append a -merged suffix to the person's name.
100 name = base = "%s-merged" % from_person.name.encode('ascii')
101 cur.execute("SELECT id FROM Person WHERE name = %s" % sqlvalues(name))
102 i = 1
103@@ -3523,6 +3517,16 @@
104 # flush its caches.
105 store.invalidate()
106
107+ # Change the merged Account's OpenID identifier so that it cannot be
108+ # used to lookup the merged Person; Launchpad will instead select the
109+ # remaining Person based on the email address.
110+ if from_person.account is not None:
111+ account = IMasterObject(from_person.account)
112+ # This works because dashes do not occur in SSO identifiers.
113+ merge_identifier = 'merged-%s' % removeSecurityProxy(
114+ account).openid_identifier
115+ removeSecurityProxy(account).openid_identifier = merge_identifier
116+
117 # Inform the user of the merge changes.
118 if not to_person.isTeam():
119 mail_text = get_email_template('person-merged.txt')