1
Copyright 2010 Canonical Ltd. This software is licensed under the
2
GNU Affero General Public License version 3 (see the file LICENSE).
4
===============================================
5
Testing Authentication Requirements For Methods
6
===============================================
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.
13
First of all import all required bits here:
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
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
29
Test When No Credentials Are Supplied
30
=====================================
32
Check that user without any credentials (`None`) can access
33
methods: ``registrations.register`` and ``captchas.new``
35
>>> credentials = None
36
>>> api = ServiceRoot(credentials, 'http://openid.launchpad.dev/api/1.0')
37
>>> api.registrations.register
38
<lazr.restfulclient.resource.NamedOperation ...>
40
<lazr.restfulclient.resource.NamedOperation ...>
42
But all other methods are inaccessible:
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:
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
60
api.accounts.validate_email 401
63
Test When Basic Auth Credentials For Normal Users Are Supplied
64
==============================================================
66
Set up an account first, if we're not using the mock provider...
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,
75
... emailaddress__email='blu@example.com'
78
... emailobj = account.emailaddress_set.create(
79
... email='blu@example.com',
80
... status=EmailStatus.NEW
82
... password = encrypt_launchpad_password('logdf3D')
83
... password_obj = AccountPassword.objects.create(
84
... password=password,
88
Basic Authentication credentials are only good for accessing
89
``authentications.authenticate`` method:
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 ...>
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).
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:
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 ...>
115
api.accounts.validate_email 401
117
Ok, so you can access the rest of the authentication calls, but you can't
120
>>> api.authentications.list_tokens(consumer_key='myopenid')
121
Traceback (most recent call last):
123
HTTPError: HTTP Error 403: Forbidden
125
>>> api.authentications.invalidate_token(consumer_key='myopenid',
127
Traceback (most recent call last):
129
HTTPError: HTTP Error 403: Forbidden
131
>>> api.authentications.validate_token(consumer_key='myopenid',
133
Traceback (most recent call last):
135
HTTPError: HTTP Error 403: Forbidden
138
Test When OAuth Auth Credentials For Normal Users Are Supplied
139
==============================================================
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``.
145
>>> if real_webservice:
146
... tokenobj = create_oauth_token_for_account(account, 'this-machine')
147
... token = tokenobj.serialize()
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"}
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')
159
Now only ``accounts.me`` and ``accounts.validate_email`` should be
163
<lazr.restfulclient.resource.NamedOperation ...>
164
>>> api.accounts.validate_email
165
<lazr.restfulclient.resource.NamedOperation ...>
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',
173
>>> for method_name in methods:
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
184
Test When Basic Auth Credentials For Server API User Are Supplied
185
=================================================================
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)
193
By providing credentials for API user you should get access to
194
different set of API calls:
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 ...>
205
Rest of the methods should be inaccessible:
207
>>> methods = ['api.authentications.authenticate',
208
... 'api.accounts.me',
209
... 'api.accounts.validate_email']
210
>>> for method_name in methods:
212
... exec 'print ' + method_name
213
... except HTTPError, e:
214
... print "%s %s" % (method_name, e.response.status)
215
<lazr.restfulclient.resource.NamedOperation ...>
217
api.accounts.validate_email 401
218
>>> api.authentications.authenticate(token_name='this-machine')
219
Traceback (most recent call last):
221
HTTPError: HTTP Error 403: Forbidden