1
Copyright 2010 Canonical Ltd. This software is licensed under the
2
GNU Affero General Public License version 3 (see the file LICENSE).
4
= Managing Email Addresses =
6
Single sign on users can manage the email addresses associated with
7
their account through the web. First lets create a user:
9
>>> browser = setupBrowser()
10
>>> browser.open('http://openid.launchpad.dev')
11
>>> browser.getLink('New account').click()
12
>>> browser.getControl(name='email').value = 'new-user@example.com'
13
>>> browser.getControl(name='continue').click()
14
>>> soup = find_main_content(browser.contents)
15
>>> print soup.find('h2').renderContents()
16
Registration mail sent
18
>>> from identityprovider.models.const import LoginTokenType
19
>>> from identityprovider.models import AuthToken
20
>>> token = AuthToken.objects.filter(
21
... email='new-user@example.com',
22
... token_type=LoginTokenType.NEWPERSONLESSACCOUNT,
23
... date_consumed=None).order_by('-date_created')[0].token
24
>>> link = 'http://openid.launchpad.dev/token/%s' % token
25
>>> browser.open(link)
27
http://openid.launchpad.dev/token/.../+newaccount
29
>>> browser.getControl('Full name').value = 'New User'
30
>>> browser.getControl('Choose password').value = 'test'
31
>>> browser.getControl('Retype password').value = 'test'
32
>>> browser.getControl(name='continue').click()
34
The user will now be on the front page, which includes a list of the
35
email addresses associated with their account:
38
http://openid.launchpad.dev/
39
>>> print extract_text(find_tag_by_id(browser.contents, 'content'))
48
== Adding a new email address ==
50
The user can add a new email address by clicking on "Add another email":
52
>>> browser.getLink("Add another email").click()
53
>>> soup = find_main_content(browser.contents)
54
>>> print soup.find('h2').renderContents()
55
Add an email address to your account
56
>>> browser.getControl(name='newemail').value = 'second-email@example.com'
57
>>> browser.getControl(name='continue').click()
59
http://openid.launchpad.dev/+email-sent
60
>>> soup = find_main_content(browser.contents)
61
>>> print soup.find('h2').renderContents()
62
Validate your e-mail address
63
>>> browser.open('http://openid.launchpad.dev')
65
The new email address is now listed on the form, but not confirmed as
66
belonging to the user:
68
>>> print extract_text(find_tag_by_id(browser.contents, 'content'))
72
second-email@example.com Verify
75
To validate the new address, the user will need to respond to the
78
>>> token = AuthToken.objects.filter(
79
... email='second-email@example.com',
80
... token_type=LoginTokenType.VALIDATEEMAIL,
81
... date_consumed=None).order_by('-date_created')[0].token
82
>>> link = 'http://openid.launchpad.dev/token/%s' % token
83
>>> browser.open(link)
85
http://openid.launchpad.dev/
87
>>> for msg in get_feedback_messages(browser.contents):
89
The email address, second-email@example.com, has been validated
91
We can now see that the user owns the new address:
93
>>> print extract_text(find_tag_by_id(browser.contents, 'content'))
97
second-email@example.com
101
== Changing the Contact Email Address ==
103
The user can also change the preferred email address:
105
>>> print extract_text(find_tag_by_id(browser.contents, 'id_preferred_email'))
107
second-email@example.com
108
>>> browser.getControl('second-email@example.com').selected = True
109
>>> browser.getControl(name='update').click()
111
>>> for msg in get_feedback_messages(browser.contents):
113
Your account details have been successfully updated
114
>>> print extract_text(find_tag_by_id(browser.contents, 'id_preferred_email'))
115
second-email@example.com
119
== Removing an Email Address ==
121
The user can also remove email addresses other than their contact address.
123
#>>> browser.open('http://openid.launchpad.dev/+edit-emails')
124
#>>> browser.getControl('second-email@example.com').selected = True
125
#>>> browser.getControl('Remove', index=0).click()
126
#>>> for msg in get_feedback_messages(browser.contents):
129
You can't remove second-email@example.com because it's your
130
contact email address.
132
Removing other addresses works though:
134
#>>> browser.open('http://openid.launchpad.dev/+edit-emails')
135
#>>> browser.getControl('new-user@example.com').selected = True
136
#>>> browser.getControl('Remove', index=0).click()
137
#>>> for msg in get_feedback_messages(browser.contents):
139
The email address 'new-user@example.com' has been removed.
142
== Removing an Unvalidated Address ==
144
It is possible for a user to remove an unvalidated email address from
145
their account. First lets add an address:
147
>>> browser.open('http://openid.launchpad.dev/')
148
>>> browser.getLink("Add another email").click()
149
>>> browser.getControl(name='newemail').value = 'unvalidated@example.com'
150
>>> browser.getControl(name='continue').click()
151
>>> browser.open('http://openid.launchpad.dev')
153
The address now shows up as an unvalidated address, which we can remove:
155
>>> print extract_text(find_tag_by_id(browser.contents, 'unverified-emails'))
156
unvalidated@example.com Verify
157
>>> browser.getControl('Remove', index=0).click()
158
>>> print browser.url
159
http://openid.launchpad.dev/+edit-emails
160
>>> for msg in get_feedback_messages(browser.contents):
162
The email address 'unvalidated@example.com' has been removed.
164
If we try to validate the email address using the token from the first
165
step, we will now get an error:
167
>>> from_addr, to_addr, msg = stub.test_emails.pop()
168
>>> token_url = get_token_url_from_email(msg)
169
>>> browser.open(token_url)
170
Traceback (most recent call last):
175
== Attempting to Add Existing Addresses ==
177
A user can't add an email address that has already been claimed.
178
There are a number of different states the other address could be in:
180
=== Attempting to Add Own Address ===
182
An error will be produced if a user attempts to add an address they
185
>>> browser.open('http://openid.launchpad.dev/+edit-emails')
186
>>> browser.getControl('Add a new address').value = (
187
... 'second-email@example.com')
188
>>> browser.getControl('Add', index=1).click()
189
>>> print browser.url
190
http://openid.launchpad.dev/+edit-emails
191
>>> for msg in get_feedback_messages(browser.contents):
194
The email address 'second-email@example.com' is already registered
195
as your email address.
198
=== Attempting to Add a Guessed Address ===
200
If the user attempts to add a guessed address associated with
201
their account, it will send out another confirmation email to let them
204
>>> import transaction
205
>>> from zope.component import getUtility
206
>>> from canonical.launchpad.interfaces.account import IAccountSet
207
>>> from canonical.launchpad.interfaces.emailaddress import (
208
... EmailAddressStatus)
209
>>> from canonical.launchpad.ftests import login, logout, ANONYMOUS
210
>>> from lp.testing.factory import LaunchpadObjectFactory
213
>>> account = getUtility(IAccountSet).getByEmail('new-user@example.com')
214
>>> factory = LaunchpadObjectFactory()
215
>>> email = factory.makeEmail(
216
... 'guessed-email@example.com', person=None, account=account,
217
... email_status=EmailAddressStatus.NEW)
219
>>> transaction.commit()
221
>>> browser.open('http://openid.launchpad.dev/+edit-emails')
222
>>> browser.getControl('Add a new address').value = (
223
... 'guessed-email@example.com')
224
>>> browser.getControl('Add', index=1).click()
225
>>> print browser.url
226
http://openid.launchpad.dev/+edit-emails
227
>>> for msg in get_feedback_messages(browser.contents):
229
A confirmation message has been sent to ...
231
The guessed address can then be confirmed:
233
>>> from_addr, to_addr, msg = stub.test_emails.pop()
234
>>> token_url = get_token_url_from_email(msg)
235
>>> browser.open(token_url)
236
>>> browser.getControl('Continue').click()
237
>>> print browser.url
238
http://openid.launchpad.dev/
239
>>> for msg in get_feedback_messages(browser.contents):
241
Email address successfully confirmed.
244
=== Attempting to Add an Address Owned By Another Account ===
246
If a user tries to add an address belonging to another account, it
250
>>> factory = LaunchpadObjectFactory()
251
>>> account = factory.makeAccount(
252
... 'Some Other User', 'some-other-user@example.com')
254
>>> transaction.commit()
256
>>> browser.open('http://openid.launchpad.dev/+edit-emails')
257
>>> browser.getControl('Add a new address').value = (
258
... 'some-other-user@example.com')
259
>>> browser.getControl('Add', index=1).click()
260
>>> print browser.url
261
http://openid.launchpad.dev/+edit-emails
262
>>> for msg in get_feedback_messages(browser.contents):
265
The email address 'some-other-user@example.com' is registered to
269
=== Attempting to Add an Address Owned By A Launchpad User ===
271
If a user tries to add an address belonging to another user that is
272
using Launchpad, they'll be directed to the Launchpad merge person
275
>>> browser.open('http://openid.launchpad.dev/+edit-emails')
276
>>> browser.getControl('Add a new address').value = (
277
... 'test@canonical.com')
278
>>> browser.getControl('Add', index=1).click()
279
>>> print browser.url
280
http://openid.launchpad.dev/+edit-emails
281
>>> for msg in get_feedback_messages(browser.contents):
284
The email address 'test@canonical.com' is already registered to
285
Sample Person. If you think that is a duplicated account, you can
286
merge it into your account.
287
>>> print browser.getLink('merge it').url
288
http://launchpad.dev/people/+requestmerge?field.dupe_person=name12
291
=== Attempting to Add an Address Owned By A Launchpad Team ===
293
If a user tries to add an address belonging to a Launchpad team,
294
they'll get a similar error:
296
>>> browser.open('http://openid.launchpad.dev/+edit-emails')
297
>>> browser.getControl('Add a new address').value = (
298
... 'support@ubuntu.com')
299
>>> browser.getControl('Add', index=1).click()
300
>>> print browser.url
301
http://openid.launchpad.dev/+edit-emails
302
>>> for msg in get_feedback_messages(browser.contents):
305
The email address 'support@ubuntu.com' is already registered to
306
the Launchpad team Ubuntu Team.