Merge lp:~ricardokirkner/u1-test-utils/ssoclient into lp:u1-test-utils

Proposed by Ricardo Kirkner
Status: Merged
Approved by: Ricardo Kirkner
Approved revision: 33
Merged at revision: 31
Proposed branch: lp:~ricardokirkner/u1-test-utils/ssoclient
Merge into: lp:u1-test-utils
Diff against target: 181 lines (+117/-4)
5 files modified
requirements.txt (+1/-0)
u1testutils/sst/sso/client.py (+34/-0)
u1testutils/sst/sso/data.py (+8/-2)
u1testutils/sst/sso/selftests/unit/test_client.py (+67/-0)
u1testutils/sst/sso/selftests/unit/test_data.py (+7/-2)
To merge this branch: bzr merge lp:~ricardokirkner/u1-test-utils/ssoclient
Reviewer Review Type Date Requested Status
Leo Arias (community) Approve
Review via email: mp+148454@code.launchpad.net

Commit message

get a users' openid value when creating an account

Added ssoclient as a new dependency so that the SSO api can be consumed
easily. The current driver for this change is being able to get the openid for
an account.

Description of the change

get a users' openid value when creating an account

Added ssoclient as a new dependency so that the SSO api can be consumed
easily. The current driver for this change is being able to get the openid for
an account.

To post a comment you must log in.
31. By Ricardo Kirkner

switched to absolute import

32. By Ricardo Kirkner

make openid attribute in User constructor optional

33. By Ricardo Kirkner

use proper error response for an invalid login attempt

Revision history for this message
Leo Arias (elopio) wrote :

<elopio> pindonga: on line 56 +from . import client
<elopio> isn't it better to use the full path?
<pindonga> elopio: ok, can change that
<elopio> pindonga: but that's really a question.
<elopio> I got from vila and nessita that it's better, so I try to do it everywhere. I'm not sure why.
<pindonga> it's really the same, I belive
<pindonga> believe
<pindonga> elopio: ack
<pindonga> it is slighlty better, as it's more explicit
<pindonga> but only marginally
<pindonga> imo
<elopio> pindonga: ok. For consitency, I think it would be better to change it.
<elopio> pindonga: andl ine 62 + def __init__(self, full_name, email, password, openid):
<vila> I'm +0 on relative imports, nessita had an argument against them I can't recall right now
<pindonga> elopio: what about that line?
<elopio> to make it compatible with the other projects, openid=None is required.
<pindonga> elopio: ok, fine with me... just made it so, bc I didn't see any other usage of the User molde
<pindonga> model
<pindonga> pushed both changes
<elopio> pindonga: thanks.
<elopio> pindonga: the one I had in mind is here: https://bazaar.launchpad.net/~ubuntuone-pqm-team/ubuntuone-servers/trunk-2a/view/head:/servers/u1servers/web/testing/acceptance/__init__.py
<elopio> pindonga: also I have a question about the client.get_account_openid. What does it return when the user doesn't exist?
<pindonga> elopio: it should return None
<pindonga> bc the response json doc doesn't have a consumer_key value in ther
<pindonga> there is a test for that
<pindonga> I set the response to {'error': {}}
<pindonga> which is to mimick an error response from the login call
<elopio> a right, you have a test for that.
<pindonga> elopio: although I will change that to be the proper response
<elopio> pindonga: +1.
<pindonga> it's not error, but something else
<pindonga> that doesn't include consumer_key :)
<elopio> pindonga: sounds good.
<elopio> pindonga: I'll approve it.
<pindonga> elopio: pushed last revno
<elopio> pindonga: I like it. Thanks.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'requirements.txt'
2--- requirements.txt 2013-02-04 15:36:26 +0000
3+++ requirements.txt 2013-02-14 15:05:22 +0000
4@@ -6,3 +6,4 @@
5 sst
6 Twisted
7 bzr+ssh://bazaar.launchpad.net/~bloodearnest/localmail/trunk
8+bzr+http://bazaar.launchpad.net/~canonical-isd-hackers/canonical-identity-provider/ssoclient@1
9
10=== added file 'u1testutils/sst/sso/client.py'
11--- u1testutils/sst/sso/client.py 1970-01-01 00:00:00 +0000
12+++ u1testutils/sst/sso/client.py 2013-02-14 15:05:22 +0000
13@@ -0,0 +1,34 @@
14+# -*- coding: utf-8 -*-
15+
16+# Copyright 2012, 2013 Canonical Ltd.
17+#
18+# This program is free software: you can redistribute it and/or modify it
19+# under the terms of the GNU Lesser General Public License version 3, as
20+# published by the Free Software Foundation.
21+#
22+# This program is distributed in the hope that it will be useful, but
23+# WITHOUT ANY WARRANTY; without even the implied warranties of
24+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
25+# PURPOSE. See the GNU Lesser General Public License for more details.
26+#
27+# You should have received a copy of the GNU General Public License along
28+# with this program. If not, see <http://www.gnu.org/licenses/>.
29+
30+from sst import actions
31+
32+from ssoclient.v2 import V2ApiClient
33+
34+
35+def get_api_client():
36+ base_url = actions.get_base_url().rstrip('/')
37+ client = V2ApiClient(base_url + '/api/v2')
38+ return client
39+
40+
41+def get_account_openid(email, password, token_name):
42+ client = get_api_client()
43+ response = client.login(email=email, password=password,
44+ token_name=token_name)
45+ data = response.json()
46+ openid = data.get('consumer_key')
47+ return openid
48
49=== modified file 'u1testutils/sst/sso/data.py'
50--- u1testutils/sst/sso/data.py 2013-01-16 15:16:50 +0000
51+++ u1testutils/sst/sso/data.py 2013-02-14 15:05:22 +0000
52@@ -18,13 +18,16 @@
53
54 from django.conf import settings
55
56+from u1testutils.sst.sso import client
57+
58
59 class User(object):
60
61- def __init__(self, full_name, email, password):
62+ def __init__(self, full_name, email, password, openid=None):
63 self.full_name = full_name
64 self.email = email
65 self.password = password
66+ self.openid = openid
67
68 def __repr__(self):
69 return '%s(%r)' % (self.__class__, self.__dict__)
70@@ -49,8 +52,11 @@
71 random_user_uuid = str(uuid.uuid1())
72 full_name = 'Test user ' + random_user_uuid
73 email = settings.EMAIL_ADDRESS_PATTERN % random_user_uuid
74+ token_name = 'token-%s' % random_user_uuid
75 else:
76 full_name = settings.SSO_TEST_ACCOUNT_FULL_NAME
77 email = settings.SSO_TEST_ACCOUNT_EMAIL
78+ token_name = 'token-%s' % full_name
79 password = settings.SSO_TEST_ACCOUNT_PASSWORD
80- return cls(full_name, email, password)
81+ openid = client.get_account_openid(email, password, token_name)
82+ return cls(full_name, email, password, openid)
83
84=== added file 'u1testutils/sst/sso/selftests/unit/test_client.py'
85--- u1testutils/sst/sso/selftests/unit/test_client.py 1970-01-01 00:00:00 +0000
86+++ u1testutils/sst/sso/selftests/unit/test_client.py 2013-02-14 15:05:22 +0000
87@@ -0,0 +1,67 @@
88+# -*- coding: utf-8 -*-
89+
90+# Copyright 2012, 2013 Canonical Ltd.
91+#
92+# This program is free software: you can redistribute it and/or modify it
93+# under the terms of the GNU Lesser General Public License version 3, as
94+# published by the Free Software Foundation.
95+#
96+# This program is distributed in the hope that it will be useful, but
97+# WITHOUT ANY WARRANTY; without even the implied warranties of
98+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
99+# PURPOSE. See the GNU Lesser General Public License for more details.
100+#
101+# You should have received a copy of the GNU General Public License along
102+# with this program. If not, see <http://www.gnu.org/licenses/
103+
104+import unittest
105+
106+from mock import Mock, patch
107+
108+from u1testutils.sst.sso import client
109+from ssoclient.v2 import V2ApiClient
110+
111+
112+class ClientTestCase(unittest.TestCase):
113+
114+ base_namespace = 'u1testutils.sst.sso.client'
115+
116+ def test_get_api_client(self):
117+ mock_get_base_url = Mock(return_value='http://localhost:8000')
118+ with patch(self.base_namespace + '.actions.get_base_url',
119+ mock_get_base_url):
120+ api_client = client.get_api_client()
121+
122+ self.assertTrue(isinstance(api_client, V2ApiClient))
123+ self.assertEqual(api_client.session.endpoint,
124+ 'http://localhost:8000/api/v2/')
125+
126+ def test_get_account_openid(self):
127+ mock_login = Mock()
128+ mock_login.return_value.json.return_value = {
129+ 'consumer_key': 'oid1234',
130+ 'consumer_secret': 'consumer-secret',
131+ 'token_name': 'foo',
132+ 'token_key': 'token-key',
133+ 'token_secret': 'token-secret',
134+ }
135+
136+ with patch(self.base_namespace + '.V2ApiClient.login', mock_login):
137+ openid = client.get_account_openid('email', 'password',
138+ 'token_name')
139+
140+ self.assertEqual(openid, 'oid1234')
141+
142+ def test_get_account_openid_wrong_credentials(self):
143+ mock_login = Mock()
144+ mock_login.return_value.json.return_value = {
145+ "code": "INVALID_CREDENTIALS",
146+ "message": "Your email/password isn't correct.",
147+ "extra": {}
148+ }
149+
150+ with patch(self.base_namespace + '.V2ApiClient.login', mock_login):
151+ openid = client.get_account_openid('email', 'password',
152+ 'token_name')
153+
154+ self.assertIsNone(openid)
155
156=== modified file 'u1testutils/sst/sso/selftests/unit/test_data.py'
157--- u1testutils/sst/sso/selftests/unit/test_data.py 2013-01-21 03:26:21 +0000
158+++ u1testutils/sst/sso/selftests/unit/test_data.py 2013-02-14 15:05:22 +0000
159@@ -17,6 +17,7 @@
160 import unittest
161
162 from django.conf import settings
163+from mock import patch
164
165 from u1testutils.sst.sso import data
166
167@@ -24,8 +25,12 @@
168 class DataTestCase(unittest.TestCase):
169
170 def test_make_exising_user(self):
171- # The DJANGO_SETTINGS_MODULE is set by the test fab task.
172- user = data.User.make_from_configuration()
173+ with patch('u1testutils.sst.sso.data.client') as mock_client:
174+ # The DJANGO_SETTINGS_MODULE is set by the test fab task.
175+ user = data.User.make_from_configuration()
176+
177 self.assertEqual(user.full_name, settings.SSO_TEST_ACCOUNT_FULL_NAME)
178 self.assertEqual(user.email, settings.SSO_TEST_ACCOUNT_EMAIL)
179 self.assertEqual(user.password, settings.SSO_TEST_ACCOUNT_PASSWORD)
180+ self.assertEqual(user.openid,
181+ mock_client.get_account_openid.return_value)

Subscribers

People subscribed via source and target branches

to all changes: