Merge lp:~alecu/ubuntuone-client/txweb-ssl-3-0 into lp:ubuntuone-client/stable-3-0

Proposed by Alejandro J. Cura
Status: Merged
Approved by: Alejandro J. Cura
Approved revision: 1193
Merged at revision: 1193
Proposed branch: lp:~alecu/ubuntuone-client/txweb-ssl-3-0
Merge into: lp:ubuntuone-client/stable-3-0
Diff against target: 156 lines (+78/-22)
2 files modified
tests/syncdaemon/test_action_queue.py (+67/-12)
ubuntuone/syncdaemon/action_queue.py (+11/-10)
To merge this branch: bzr merge lp:~alecu/ubuntuone-client/txweb-ssl-3-0
Reviewer Review Type Date Requested Status
Roberto Alsina (community) Approve
dobey (community) Approve
Review via email: mp+110165@code.launchpad.net

Commit message

- Add SSL verification to webapi calls (LP: #882062).

To post a comment you must log in.
Revision history for this message
dobey (dobey) :
review: Approve
Revision history for this message
Roberto Alsina (ralsina) wrote :

+1 on code review

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/syncdaemon/test_action_queue.py'
2--- tests/syncdaemon/test_action_queue.py 2012-05-16 22:01:56 +0000
3+++ tests/syncdaemon/test_action_queue.py 2012-06-13 20:39:18 +0000
4@@ -329,6 +329,8 @@
5
6 class BasicTests(BasicTestCase):
7 """Basic tests to check ActionQueue."""
8+ fake_host = "fake_host"
9+ fake_iri = u"http://%s/" % fake_host
10
11 def test_implements_interface(self):
12 """Verify ActionQueue and FakeActionQueue interface."""
13@@ -433,19 +435,54 @@
14 self.assertEqual(set(defined_args[1:]), set(evtargs))
15
16 @defer.inlineCallbacks
17+ def test_get_webclient_called_with_iri(self):
18+ """The call to get_webclient includes the iri."""
19+ called_args = []
20+ real_get_webclient = action_queue.ActionQueue.get_webclient
21+
22+ def fake_get_webclient(aq, *args):
23+ """A fake get_webclient."""
24+ called_args.append(args)
25+ return real_get_webclient(aq, *args)
26+
27+ self.patch(action_queue.ActionQueue, "get_webclient",
28+ fake_get_webclient)
29+ self.patch(action_queue.txweb.WebClient, "request",
30+ lambda *args, **kwargs: defer.succeed(None))
31+
32+ yield self.action_queue.webcall(self.fake_iri)
33+ self.assertEqual(called_args, [(self.fake_iri,)])
34+
35+ @defer.inlineCallbacks
36 def test_get_webclient(self):
37- """The webclient is created if it does not exist."""
38- self.assertEqual(self.action_queue.webclient, None)
39- webclient = yield self.action_queue.get_webclient()
40- self.assertNotEqual(webclient, None)
41-
42- @defer.inlineCallbacks
43- def test_get_webclient_existing(self):
44- """The webclient is not created again if it exists."""
45- fake_wc = object()
46- self.patch(self.action_queue, "webclient", fake_wc)
47- webclient = yield self.action_queue.get_webclient()
48- self.assertEqual(webclient, fake_wc)
49+ """The webclient is created every time."""
50+ webclient1 = yield self.action_queue.get_webclient(self.fake_iri)
51+ webclient2 = yield self.action_queue.get_webclient(self.fake_iri)
52+ self.assertNotEqual(webclient1, webclient2)
53+
54+ @defer.inlineCallbacks
55+ def test_get_webclient_creates_context_with_host(self):
56+ """The ssl context is created with the right host."""
57+ used_host = []
58+
59+ def fake_get_ssl_context(disable_ssl_verify, host):
60+ """The host is used to call get_ssl_context."""
61+ used_host.append(host)
62+
63+ self.patch(action_queue, "get_ssl_context", fake_get_ssl_context)
64+ yield self.action_queue.get_webclient(self.fake_iri)
65+ self.assertEqual(used_host, [self.fake_host])
66+
67+ @defer.inlineCallbacks
68+ def test_get_webclient_uses_just_created_context(self):
69+ """The freshly created context is used to create the webclient."""
70+ calls = []
71+ fake_context = object()
72+ self.patch(action_queue, "get_ssl_context", lambda *args: fake_context)
73+ self.patch(action_queue.txweb.WebClient, "__init__",
74+ lambda *args, **kwargs: calls.append(kwargs))
75+ yield self.action_queue.get_webclient(self.fake_iri)
76+ self.assertEqual(calls[1]["context_factory"], fake_context)
77
78
79 class TestLoggingStorageClient(TwistedTestCase):
80@@ -1395,6 +1432,24 @@
81 "connectSSL is called on the client.")
82
83
84+class ContextRequestedWithHost(FactoryBaseTestCase):
85+ """Test that the context is requested passing the host."""
86+
87+ tunnel_runner_class = SavingConnectionTunnelRunner
88+
89+ @defer.inlineCallbacks
90+ def test_context_request_passes_host(self):
91+ """The context is requested passing the host."""
92+ fake_host = "fake_host"
93+
94+ def fake_get_ssl_context(disable_ssl_verify, host):
95+ """The host is used to call get_ssl_context."""
96+ self.assertEqual(host, fake_host)
97+
98+ self.patch(action_queue, "get_ssl_context", fake_get_ssl_context)
99+ yield self.action_queue._make_connection((fake_host, 1234))
100+
101+
102 class ConnectedBaseTestCase(FactoryBaseTestCase):
103 """Base test case generating a connected factory."""
104
105
106=== modified file 'ubuntuone/syncdaemon/action_queue.py'
107--- ubuntuone/syncdaemon/action_queue.py 2012-06-06 20:55:28 +0000
108+++ ubuntuone/syncdaemon/action_queue.py 2012-06-13 20:39:18 +0000
109@@ -43,7 +43,7 @@
110 from collections import deque, defaultdict
111 from functools import partial
112 from urllib import urlencode
113-from urlparse import urljoin
114+from urlparse import urljoin, urlparse
115
116 import OpenSSL.SSL
117
118@@ -697,7 +697,6 @@
119 self.token = None
120 self.consumer = None
121 self.credentials = None
122- self.webclient = None
123
124 self.client = None # an instance of self.protocol
125
126@@ -836,20 +835,22 @@
127 @defer.inlineCallbacks
128 def webcall(self, iri, **kwargs):
129 """Perform a web call to the api servers."""
130- webclient = yield self.get_webclient()
131+ webclient = yield self.get_webclient(iri)
132 response = yield webclient.request(iri,
133 oauth_credentials=self.credentials, **kwargs)
134 defer.returnValue(response)
135
136 @defer.inlineCallbacks
137- def get_webclient(self):
138+ def get_webclient(self, iri):
139 """Get the webclient, creating it if needed."""
140- if self.webclient is None:
141- client = yield self.tunnel_runner.get_client()
142- self.webclient = txweb.WebClient(connector=client,
143- appname="Ubuntu One",
144- oauth_sign_plain=True)
145- defer.returnValue(self.webclient)
146+ uri = txweb.WebClient().iri_to_uri(iri)
147+ host = urlparse(uri).netloc.split(":")[0]
148+ ssl_context = get_ssl_context(self.disable_ssl_verify, host)
149+ connector = yield self.tunnel_runner.get_client()
150+ webclient = txweb.WebClient(connector=connector, appname="Ubuntu One",
151+ oauth_sign_plain=True,
152+ context_factory=ssl_context)
153+ defer.returnValue(webclient)
154
155 @defer.inlineCallbacks
156 def _make_connection(self, result):

Subscribers

People subscribed via source and target branches