Merge lp:~mandel/ubuntu-sso-client/libsoup-ssl-dialog into lp:ubuntu-sso-client

Proposed by Manuel de la Peña on 2012-03-12
Status: Rejected
Rejected by: Manuel de la Peña on 2012-04-02
Proposed branch: lp:~mandel/ubuntu-sso-client/libsoup-ssl-dialog
Merge into: lp:ubuntu-sso-client
Diff against target: 197 lines (+65/-18)
5 files modified
ubuntu_sso/qt/ssl_dialog.py (+1/-1)
ubuntu_sso/utils/webclient/common.py (+10/-0)
ubuntu_sso/utils/webclient/libsoup.py (+41/-7)
ubuntu_sso/utils/webclient/tests/__init__.py (+9/-6)
ubuntu_sso/utils/webclient/tests/test_webclient.py (+4/-4)
To merge this branch: bzr merge lp:~mandel/ubuntu-sso-client/libsoup-ssl-dialog
Reviewer Review Type Date Requested Status
Manuel de la Peña (community) Disapprove on 2012-04-02
Natalia Bidart 2012-03-12 Pending
Alejandro J. Cura 2012-03-12 Pending
Review via email: mp+97057@code.launchpad.net

Commit Message

- Added the required logic to allow the libsoup weclient implementation to spawn the ssl dialog that will allow the user to accept an ssl cert with errors (LP: #939671)

Description of the Change

- Added the required logic to allow the libsoup weclient implementation to spawn the ssl dialog that will allow the user to accept an ssl cert with errors (LP: #939671)

To post a comment you must log in.
948. By Manuel de la Peña on 2012-03-14

Merged with trunk.

949. By Manuel de la Peña on 2012-03-15

Merged with trunk.

Manuel de la Peña (mandel) wrote :

Rejecting since we wont use this code.

review: Disapprove

Unmerged revisions

949. By Manuel de la Peña on 2012-03-15

Merged with trunk.

948. By Manuel de la Peña on 2012-03-14

Merged with trunk.

947. By Manuel de la Peña on 2012-03-12

Reduced diff size.

946. By Manuel de la Peña on 2012-03-12

Reduced diff size.

945. By Manuel de la Peña on 2012-03-12

Merged with trunk.

944. By Manuel de la Peña on 2012-03-12

Added the required code to let the libsoup webclient implementation deal with ssl cert errors.

943. By Manuel de la Peña on 2012-03-12

Made changes to the tests so that they work correctly.

942. By Manuel de la Peña on 2012-03-09

Commit to share progress.

941. By Manuel de la Peña on 2012-03-09

Merged with parent and fixed conflicts.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ubuntu_sso/qt/ssl_dialog.py'
2--- ubuntu_sso/qt/ssl_dialog.py 2012-03-06 14:13:10 +0000
3+++ ubuntu_sso/qt/ssl_dialog.py 2012-03-15 11:28:19 +0000
4@@ -63,7 +63,7 @@
5
6
7 class SSLDialog(QDialog):
8- """"Dialog used to show SSL exceptions."""
9+ """Dialog used to show SSL exceptions."""
10
11 def __init__(self, app_name, domain=None, details=None, parent=None):
12 """Create a new instance."""
13
14=== modified file 'ubuntu_sso/utils/webclient/common.py'
15--- ubuntu_sso/utils/webclient/common.py 2012-03-09 12:04:31 +0000
16+++ ubuntu_sso/utils/webclient/common.py 2012-03-15 11:28:19 +0000
17@@ -47,6 +47,16 @@
18 """Failure raised when there is an issue with the proxy auth."""
19
20
21+class SSLCertError(WebClientError):
22+ """Failure raised when there is an issue with the ssl cert."""
23+
24+ def __init__(self, message, ssl_details=None, response=None):
25+ """Create a new insance with the given details."""
26+ super(SSLCertError, self).__init__(message)
27+ self.ssl_details = ssl_details
28+ self.response = response
29+
30+
31 class Response(object):
32 """A response object."""
33
34
35=== modified file 'ubuntu_sso/utils/webclient/libsoup.py'
36--- ubuntu_sso/utils/webclient/libsoup.py 2012-03-09 11:47:38 +0000
37+++ ubuntu_sso/utils/webclient/libsoup.py 2012-03-15 11:28:19 +0000
38@@ -17,6 +17,7 @@
39
40 import httplib
41
42+from OpenSSL.crypto import load_certificate, FILETYPE_PEM
43 from twisted.internet import defer
44
45 from ubuntu_sso.logger import setup_logging
46@@ -25,6 +26,7 @@
47 HeaderDict,
48 Response,
49 ProxyUnauthorizedError,
50+ SSLCertError,
51 UnauthorizedError,
52 WebClientError,
53 )
54@@ -48,17 +50,37 @@
55 self.session.add_feature(SoupGNOME.ProxyResolverGNOME())
56 self.session.connect("authenticate", self._on_authenticate)
57
58+ def _get_response(self, message):
59+ """Return a response from a SoupMessage."""
60+ headers = HeaderDict()
61+ response_headers = message.get_property("response-headers")
62+ add_header = lambda key, value, _: headers[key].append(value)
63+ response_headers.foreach(add_header, None)
64+ content = message.response_body.flatten().get_data()
65+ response = Response(content, headers)
66+ return response
67+
68 def _on_message(self, session, message, d):
69 """Handle the result of an http message."""
70 logger.debug('_on_message status code is %s', message.status_code)
71+ is_ssl, raw_cert, errors = message.get_https_status()
72 if message.status_code == httplib.OK:
73- headers = HeaderDict()
74- response_headers = message.get_property("response-headers")
75- add_header = lambda key, value, _: headers[key].append(value)
76- response_headers.foreach(add_header, None)
77- content = message.response_body.flatten().get_data()
78- response = Response(content, headers)
79- d.callback(response)
80+ response = self._get_response(message)
81+ if is_ssl and errors.real != 0:
82+ cert = load_certificate(FILETYPE_PEM,
83+ raw_cert.props.certificate_pem)
84+ cert_subject = cert.get_subject()
85+ ssl_details = dict(organization=cert_subject.O,
86+ common_name=cert_subject.CN,
87+ locality_name=cert_subject.L,
88+ unit=cert_subject.OU,
89+ country_name=cert_subject.C,
90+ state_name=cert_subject.ST)
91+ e = SSLCertError(message.reason_phrase,
92+ ssl_details=ssl_details, response=response)
93+ d.errback(e)
94+ else:
95+ d.callback(response)
96 elif message.status_code == httplib.UNAUTHORIZED:
97 e = UnauthorizedError(message.reason_phrase)
98 d.errback(e)
99@@ -109,6 +131,17 @@
100 defer.returnValue(response)
101
102 @defer.inlineCallbacks
103+ def _on_ssl_error(self, failure):
104+ """Deal with SSL errors."""
105+ failure.trap(SSLCertError)
106+ logger.debug('SSL cert errors found.')
107+ trust_cert = yield self.request_ssl_cert_approval(
108+ failure.value.ssl_details['common_name'],
109+ self.format_ssl_details(failure.value.ssl_details))
110+ if trust_cert:
111+ defer.returnValue(failure.value.response)
112+
113+ @defer.inlineCallbacks
114 def request(self, iri, method="GET", extra_headers=None,
115 oauth_credentials=None, post_content=None):
116 """Return a deferred that will be fired with a Response object."""
117@@ -136,6 +169,7 @@
118 self.session.queue_message(message, self._on_message, d)
119 d.addErrback(self._on_proxy_authenticate, iri, method, extra_headers,
120 oauth_credentials, post_content)
121+ d.addErrback(self._on_ssl_error)
122 response = yield d
123 defer.returnValue(response)
124
125
126=== modified file 'ubuntu_sso/utils/webclient/tests/__init__.py'
127--- ubuntu_sso/utils/webclient/tests/__init__.py 2012-03-09 12:04:31 +0000
128+++ ubuntu_sso/utils/webclient/tests/__init__.py 2012-03-15 11:28:19 +0000
129@@ -17,7 +17,7 @@
130 """Tests for the proxy-aware webclient."""
131
132 from twisted.application import internet, service
133-from twisted.internet import ssl
134+from twisted.internet import defer, ssl
135 from twisted.web import http, server
136
137
138@@ -62,12 +62,12 @@
139 class SaveHTTPChannel(http.HTTPChannel):
140 """A save protocol to be used in tests."""
141
142- protocolInstance = None
143+ protocolInstances = []
144
145 # pylint: disable=C0103
146 def connectionMade(self):
147 """Keep track of the given protocol."""
148- SaveHTTPChannel.protocolInstance = self
149+ SaveHTTPChannel.protocolInstances.append(self)
150 http.HTTPChannel.connectionMade(self)
151
152
153@@ -137,9 +137,12 @@
154 return self.ssl_server._port.getHost().port
155 # pylint: enable=W0212
156
157+ @defer.inlineCallbacks
158 def stop(self):
159 """Shut it down."""
160 #pylint: disable=E1101
161- if self.site.protocol.protocolInstance:
162- self.site.protocol.protocolInstance.timeoutConnection()
163- return self.service_collection.stopService()
164+ for protocol in self.site.protocol.protocolInstances:
165+ protocol.timeoutConnection()
166+ if self.ssl_server:
167+ yield self.ssl_server.stopService()
168+ yield self.service_collection.stopService()
169
170=== modified file 'ubuntu_sso/utils/webclient/tests/test_webclient.py'
171--- ubuntu_sso/utils/webclient/tests/test_webclient.py 2012-03-12 23:15:45 +0000
172+++ ubuntu_sso/utils/webclient/tests/test_webclient.py 2012-03-15 11:28:19 +0000
173@@ -1015,11 +1015,12 @@
174
175 def test_ssl_fail_dialog_user_accepts(self):
176 """Test showing the dialog and accepting."""
177- self._assert_ssl_fail_user_accepts()
178+ return self._assert_ssl_fail_user_accepts()
179
180 def test_ssl_fail_dialog_user_accepts_via_proxy(self):
181 """Test showing the dialog and accepting when using a proxy."""
182- self._assert_ssl_fail_user_accepts(self.get_nonauth_proxy_settings())
183+ return self._assert_ssl_fail_user_accepts(
184+ self.get_nonauth_proxy_settings())
185
186 def test_ssl_fail_dialog_user_rejects(self):
187 """Test showing the dialog and rejecting."""
188@@ -1032,8 +1033,7 @@
189 self.assertEqual(details,
190 self.wc.format_ssl_details(self.cert_details))
191
192- if (WEBCLIENT_MODULE_NAME.endswith(".txweb") or
193- WEBCLIENT_MODULE_NAME.endswith(".libsoup")):
194+ if WEBCLIENT_MODULE_NAME.endswith(".txweb"):
195 reason = 'SSL support has not yet been implemented.'
196 test_ssl_fail_dialog_user_accepts.skip = reason
197 test_ssl_fail_dialog_user_accepts_via_proxy.skip = reason

Subscribers

People subscribed via source and target branches