~ubuntuone-pqm-team/canonical-identity-provider/trunk

« back to all changes in this revision

Viewing changes to doctests/stories/openid/per-version/sso-workflow-register.txt

  • Committer: Danny Tamez
  • Date: 2010-04-21 15:29:24 UTC
  • Revision ID: danny.tamez@canonical.com-20100421152924-lq1m92tstk2iz75a
Canonical SSO Provider (Open Source) - Initial Commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Copyright 2010 Canonical Ltd.  This software is licensed under the
 
2
GNU Affero General Public License version 3 (see the file LICENSE).
 
3
 
 
4
= Launchpad Single-Signon Workflow: Registration =
 
5
 
 
6
If a user wants to use a Launchpad-SSO web site, but does not have a
 
7
Launchpad account, they can register directly from the login page.
 
8
 
 
9
First we will set up the helper view that lets us test the final
 
10
portion of the authentication process:
 
11
 
 
12
    >>> from openid.consumer.consumer import Consumer
 
13
    >>> from openid.fetchers import setDefaultFetcher
 
14
    >>> from openid.store.memstore import MemoryStore
 
15
    >>> from canonical.signon.testing.openidhelpers import (
 
16
    ...     complete_from_browser, make_identifier_select_endpoint,
 
17
    ...     PublisherFetcher)
 
18
    >>> setDefaultFetcher(PublisherFetcher())
 
19
 
 
20
The authentication process is started by the relying party issuing a
 
21
checkid_setup request, sending the user to Launchpad:
 
22
 
 
23
    >>> openid_store = MemoryStore()
 
24
    >>> consumer = Consumer(session={}, store=openid_store)
 
25
 
 
26
    >>> request = consumer.beginWithoutDiscovery(
 
27
    ...     make_identifier_select_endpoint(PROTOCOL_URI))
 
28
    >>> browser.open(request.redirectURL(
 
29
    ...     'http://launchpad.dev/', 'http://launchpad.dev/+openid-consumer'))
 
30
 
 
31
When a new account is created we'll use the creation rationale specified for
 
32
the trust_root given by the relying party.  We will set up an RP
 
33
configuration that uses the UBUNTU_SHOP creation rationale:
 
34
 
 
35
    >>> from identityprovider.models import OpenIDRPConfig
 
36
    >>> from identityprovider.models.const import AccountCreationRationale
 
37
    >>> rpconfig = OpenIDRPConfig.objects.create(
 
38
    ...     trust_root='http://launchpad.dev/',
 
39
    ...     displayname='The Ubuntu Store from Canonical',
 
40
    ...     description="For the Ubuntu Store, you need a Launchpad account "
 
41
    ...         "so we can remember your order details and keep in "
 
42
    ...         "touch with you about your orders.",
 
43
    ...     creation_rationale=AccountCreationRationale.OWNER_CREATED_UBUNTU_SHOP)
 
44
 
 
45
At this point, we are at the login page.  Lets try to create a new
 
46
account for an email address that has already been registered. This
 
47
shouldn't result in an error, because we don't want to reveal
 
48
(non-)existing email addresses:
 
49
 
 
50
    >>> from BeautifulSoup import BeautifulSoup
 
51
    >>> browser.getLink('New account').click()
 
52
    >>> browser.getControl(name='email').value = 'test@canonical.com'
 
53
    >>> browser.getControl(name='continue').click()
 
54
    >>> soup = BeautifulSoup(browser.contents)
 
55
    >>> print soup.find('h2').renderContents()
 
56
    Registration mail sent
 
57
 
 
58
If we instead pick a new email address, we can register an account:
 
59
 
 
60
    >>> browser.open(request.redirectURL(
 
61
    ...     'http://launchpad.dev/', 'http://launchpad.dev/+openid-consumer'))
 
62
    >>> browser.getLink('New account').click()
 
63
    >>> browser.getControl(name='email').value = 'new-user@example.com'
 
64
    >>> browser.getControl(name='continue').click()
 
65
    >>> soup = BeautifulSoup(browser.contents)
 
66
    >>> print soup.find('h2').renderContents()
 
67
    Registration mail sent
 
68
 
 
69
The user would then check their email, and find a message:
 
70
 
 
71
Let's extract the URL from the email and follow the link:
 
72
 
 
73
    >>> from identityprovider.models.const import LoginTokenType
 
74
    >>> from identityprovider.models import AuthToken
 
75
    >>> token = AuthToken.objects.filter(
 
76
    ...     email='new-user@example.com',
 
77
    ...     token_type=LoginTokenType.NEWPERSONLESSACCOUNT,
 
78
    ...     date_consumed=None).order_by('-date_created')[0].token
 
79
    >>> link = 'http://openid.launchpad.dev/token/%s' % token
 
80
    >>> browser.open(link)
 
81
    >>> print browser.url
 
82
    http://openid.launchpad.dev/token/.../+newaccount
 
83
 
 
84
The user can enter their full name and password, to complete the
 
85
registration:
 
86
 
 
87
    >>> browser.getControl(name='displayname').value = 'New User'
 
88
    >>> browser.getControl(name='password').value = 'testP4ss'
 
89
    >>> browser.getControl(name='passwordconfirm').value = 'testP4ss'
 
90
    >>> browser.getControl(name='continue').click()
 
91
 
 
92
Now the user is logged in with their new account, and has been
 
93
directed back to the original site:
 
94
 
 
95
    >>> soup = BeautifulSoup(browser.contents)
 
96
    >>> print soup.find('h2').renderContents()
 
97
    Sign in to The Ubuntu Store from Canonical
 
98
    >>> browser.getControl(name='yes').click()
 
99
    >>> print browser.url
 
100
    http://launchpad.dev/+openid-consumer?...
 
101
 
 
102
The creation rationale has been set correctly:
 
103
 
 
104
    >>> from identityprovider.models import Account
 
105
    >>> account = Account.objects.get_by_email('new-user@example.com')
 
106
    >>> expected_claimed_id = (
 
107
    ...     'http://openid.launchpad.dev/+id/' + account.openid_identifier)
 
108
    >>> print account.creation_rationale
 
109
    12
 
110
 
 
111
And the response matches the new OpenID:
 
112
 
 
113
    >>> info = complete_from_browser(consumer, browser, expected_claimed_id)
 
114
    >>> print info.status
 
115
    success
 
116
    >>> info.endpoint.claimed_id == expected_claimed_id
 
117
    True
 
118
 
 
119
Since this account was created using OpenID, we will not create an entry in
 
120
the Person table for it -- it will only be created when the user logs into
 
121
Launchpad.
 
122
 
 
123
    >>> print account.person
 
124
    None
 
125
 
 
126
 
 
127
== Cleanup ==
 
128
 
 
129
    >>> from identityprovider.models import EmailAddress
 
130
    >>> setDefaultFetcher(None)
 
131
    >>> AuthToken.objects.filter(email='new-user@example.com').delete()
 
132
    >>> account = Account.objects.get_by_email('new-user@example.com')
 
133
    >>> account.emailaddress_set.all()[0].delete()
 
134
    >>> print EmailAddress.objects.filter(email='new-user@example.com')
 
135
    []
 
136
    >>> account.delete()
 
137
    >>> print Account.objects.filter(displayname='New User')
 
138
    []
 
139
    >>> rpconfig.delete()