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

« back to all changes in this revision

Viewing changes to doctests/stories/api-authentications.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
===============================================
 
5
Testing Authentication Requirements For Methods
 
6
===============================================
 
7
 
 
8
 
 
9
Check that authentication restrictions are enforced for given api
 
10
methods. This is done for every type of user there is in the system
 
11
and for every exposed method.
 
12
 
 
13
First of all import all required bits here:
 
14
 
 
15
    >>> from lazr.restfulclient.resource import ServiceRoot
 
16
    >>> from lazr.restfulclient.errors import HTTPError
 
17
    >>> from lazr.restfulclient.authorize import BasicHttpAuthorizer
 
18
    >>> from oauth.oauth import OAuthToken
 
19
    >>> from lazr.restfulclient.authorize.oauth import OAuthAuthorizer
 
20
 
 
21
If we're not testing against the mock service, we'll also need these:
 
22
    >>> if real_webservice:
 
23
    ...     from identityprovider.models import (Account, EmailAddress,
 
24
    ...         AccountPassword, APIUser, create_oauth_token_for_account)
 
25
    ...     from identityprovider.models.const import (AccountStatus,
 
26
    ...         AccountCreationRationale, EmailStatus)
 
27
    ...     from identityprovider.utils import encrypt_launchpad_password
 
28
 
 
29
Test When No Credentials Are Supplied
 
30
=====================================
 
31
 
 
32
Check that user without any credentials (`None`) can access
 
33
methods: ``registrations.register`` and ``captchas.new``
 
34
 
 
35
    >>> credentials = None
 
36
    >>> api = ServiceRoot(credentials, 'http://openid.launchpad.dev/api/1.0')
 
37
    >>> api.registrations.register
 
38
    <lazr.restfulclient.resource.NamedOperation ...>
 
39
    >>> api.captchas.new
 
40
    <lazr.restfulclient.resource.NamedOperation ...>
 
41
 
 
42
But all other methods are inaccessible:
 
43
 
 
44
    >>> methods = ['api.authentications.authenticate',
 
45
    ...            'api.authentications.invalidate_token',
 
46
    ...            'api.authentications.validate_token',
 
47
    ...            'api.authentications.list_tokens',
 
48
    ...            'api.accounts.me',
 
49
    ...            'api.accounts.validate_email']
 
50
    >>> for method_name in methods:
 
51
    ...     try:
 
52
    ...         exec method_name
 
53
    ...     except HTTPError, e:
 
54
    ...         print "%s %s" % (method_name, e.response.status)
 
55
    api.authentications.authenticate 401
 
56
    api.authentications.invalidate_token 401
 
57
    api.authentications.validate_token 401
 
58
    api.authentications.list_tokens 401
 
59
    api.accounts.me 401
 
60
    api.accounts.validate_email 401
 
61
 
 
62
 
 
63
Test When Basic Auth Credentials For Normal Users Are Supplied
 
64
==============================================================
 
65
 
 
66
Set up an account first, if we're not using the mock provider...
 
67
 
 
68
    >>> if real_webservice:
 
69
    ...     account, created = Account.objects.get_or_create(
 
70
    ...         defaults={'creation_rationale':
 
71
    ...             AccountCreationRationale.OWNER_CREATED_LAUNCHPAD,
 
72
    ...             'status': AccountStatus.ACTIVE,
 
73
    ...             },
 
74
    ...         displayname='',
 
75
    ...         emailaddress__email='blu@example.com'
 
76
    ...         )
 
77
    ...     if created:
 
78
    ...         emailobj = account.emailaddress_set.create(
 
79
    ...             email='blu@example.com',
 
80
    ...             status=EmailStatus.NEW
 
81
    ...             )
 
82
    ...         password = encrypt_launchpad_password('logdf3D')
 
83
    ...         password_obj = AccountPassword.objects.create(
 
84
    ...             password=password,
 
85
    ...             account=account,
 
86
    ...             )
 
87
 
 
88
Basic Authentication credentials are only good for accessing
 
89
``authentications.authenticate`` method:
 
90
 
 
91
    >>> authorizer = BasicHttpAuthorizer('blu@example.com', 'logdf3D')
 
92
    >>> api = ServiceRoot(authorizer, 'http://openid.launchpad.dev/api/1.0')
 
93
    >>> api.authentications.authenticate
 
94
    <lazr.restfulclient.resource.NamedOperation ...>
 
95
 
 
96
But rest of ``authentications`` calls are protected
 
97
(``registrations.register`` is not protected by anything which means
 
98
that it doesn't care about ``WWW-Authenticate`` header so it is always
 
99
accessible, no matter which ahtuentication mechanism you're using).
 
100
 
 
101
    >>> methods = ['api.authentications.list_tokens',
 
102
    ...            'api.authentications.invalidate_token',
 
103
    ...            'api.authentications.validate_token',
 
104
    ...            'api.accounts.me',
 
105
    ...            'api.accounts.validate_email']
 
106
    >>> for method_name in methods:
 
107
    ...     try:
 
108
    ...         exec 'print ' + method_name
 
109
    ...     except HTTPError, e:
 
110
    ...         print "%s %s" % (method_name, e.response.status)
 
111
    <lazr.restfulclient.resource.NamedOperation ...>
 
112
    <lazr.restfulclient.resource.NamedOperation ...>
 
113
    <lazr.restfulclient.resource.NamedOperation ...>
 
114
    api.accounts.me 401
 
115
    api.accounts.validate_email 401
 
116
 
 
117
Ok, so you can access the rest of the authentication calls, but you can't
 
118
actually call them.
 
119
 
 
120
    >>> api.authentications.list_tokens(consumer_key='myopenid')
 
121
    Traceback (most recent call last):
 
122
    ...
 
123
    HTTPError: HTTP Error 403: Forbidden
 
124
    ...
 
125
    >>> api.authentications.invalidate_token(consumer_key='myopenid',
 
126
    ...     token='mytoken')
 
127
    Traceback (most recent call last):
 
128
    ...
 
129
    HTTPError: HTTP Error 403: Forbidden
 
130
    ...
 
131
    >>> api.authentications.validate_token(consumer_key='myopenid',
 
132
    ...     token='mytoken')
 
133
    Traceback (most recent call last):
 
134
    ...
 
135
    HTTPError: HTTP Error 403: Forbidden
 
136
    ...
 
137
 
 
138
Test When OAuth Auth Credentials For Normal Users Are Supplied
 
139
==============================================================
 
140
 
 
141
After going through ``authentications.authenticate`` you'll have ``OAuth``
 
142
token and be able to access only ``accounts.me`` and
 
143
``accounts.validate_email``.
 
144
 
 
145
    >>> if real_webservice:
 
146
    ...     tokenobj = create_oauth_token_for_account(account, 'this-machine')
 
147
    ...     token = tokenobj.serialize()
 
148
    ... else:
 
149
    ...     token = {"token": "this-is-a-valid-token",
 
150
    ...              "token_secret": "this-is-a-valid-token-secret",
 
151
    ...              "consumer_key": "consumer",
 
152
    ...              "consumer_secret": "big-secret"}
 
153
 
 
154
    >>> oauth_token = OAuthToken(token['token'], token['token_secret'])
 
155
    >>> authorizer = OAuthAuthorizer(token['consumer_key'],
 
156
    ...    token['consumer_secret'], oauth_token)
 
157
    >>> api = ServiceRoot(authorizer, 'http://openid.launchpad.dev/api/1.0')
 
158
 
 
159
Now only ``accounts.me`` and ``accounts.validate_email`` should be
 
160
accessible:
 
161
 
 
162
    >>> api.accounts.me
 
163
    <lazr.restfulclient.resource.NamedOperation ...>
 
164
    >>> api.accounts.validate_email
 
165
    <lazr.restfulclient.resource.NamedOperation ...>
 
166
 
 
167
Rest of the API calls should return 401 error:
 
168
    >>> methods = ['api.authentications.authenticate',
 
169
    ...            'api.authentications.invalidate_token',
 
170
    ...            'api.authentications.validate_token',
 
171
    ...            'api.authentications.list_tokens',
 
172
    ...           ]
 
173
    >>> for method_name in methods:
 
174
    ...     try:
 
175
    ...         exec method_name
 
176
    ...     except HTTPError, e:
 
177
    ...         print "%s %s" % (method_name, e.response.status)
 
178
    api.authentications.authenticate 401
 
179
    api.authentications.invalidate_token 401
 
180
    api.authentications.validate_token 401
 
181
    api.authentications.list_tokens 401
 
182
 
 
183
 
 
184
Test When Basic Auth Credentials For Server API User Are Supplied
 
185
=================================================================
 
186
 
 
187
Set up an API user first if we're not using the mock service...
 
188
    >>> if real_webservice:
 
189
    ...     password = encrypt_launchpad_password('password')
 
190
    ...     user, created = APIUser.objects.get_or_create(
 
191
    ...         username='MyUsername', password=password)
 
192
 
 
193
By providing credentials for API user you should get access to
 
194
different set of API calls:
 
195
 
 
196
    >>> authorizer = BasicHttpAuthorizer('MyUsername', 'password')
 
197
    >>> api = ServiceRoot(authorizer, 'http://openid.launchpad.dev/api/1.0')
 
198
    >>> api.authentications.validate_token
 
199
    <lazr.restfulclient.resource.NamedOperation ...>
 
200
    >>> api.authentications.list_tokens
 
201
    <lazr.restfulclient.resource.NamedOperation ...>
 
202
    >>> api.authentications.invalidate_token
 
203
    <lazr.restfulclient.resource.NamedOperation ...>
 
204
 
 
205
Rest of the methods should be inaccessible:
 
206
 
 
207
    >>> methods = ['api.authentications.authenticate',
 
208
    ...            'api.accounts.me',
 
209
    ...            'api.accounts.validate_email']
 
210
    >>> for method_name in methods:
 
211
    ...     try:
 
212
    ...         exec 'print ' + method_name
 
213
    ...     except HTTPError, e:
 
214
    ...         print "%s %s" % (method_name, e.response.status)
 
215
    <lazr.restfulclient.resource.NamedOperation ...>
 
216
    api.accounts.me 401
 
217
    api.accounts.validate_email 401
 
218
    >>> api.authentications.authenticate(token_name='this-machine')
 
219
    Traceback (most recent call last):
 
220
    ...
 
221
    HTTPError: HTTP Error 403: Forbidden
 
222
    ...