Merge lp:~osomon/webbrowser-app/http-auth into lp:webbrowser-app

Proposed by Olivier Tilloy
Status: Merged
Approved by: Olivier Tilloy
Approved revision: 1013
Merged at revision: 1178
Proposed branch: lp:~osomon/webbrowser-app/http-auth
Merge into: lp:webbrowser-app
Diff against target: 283 lines (+172/-5)
7 files modified
debian/control (+3/-3)
src/Ubuntu/Web/UbuntuWebView02.qml (+1/-1)
src/app/HttpAuthenticationDialog.qml (+76/-0)
src/app/WebViewImpl.qml (+5/-1)
tests/autopilot/webbrowser_app/emulators/browser.py (+18/-0)
tests/autopilot/webbrowser_app/tests/http_server.py (+20/-0)
tests/autopilot/webbrowser_app/tests/test_basic_authentication.py (+49/-0)
To merge this branch: bzr merge lp:~osomon/webbrowser-app/http-auth
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing
Riccardo Padovani (community) Approve
Ubuntu Phablet Team Pending
Review via email: mp+263561@code.launchpad.net

Commit message

Handle HTTP authentication requests by showing an authentication dialog.

This bumps the build dependency as well as runtime dependency of webbrowser-app and qtdeclarative5-ubuntu-web-plugin on liboxideqt-qmlplugin to 1.9.

Description of the change

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Riccardo Padovani (rpadovani) wrote :

I tested with http://studiare.unife.it and works very well \o/
I hope it lands with OTA-5, I need to be able to take a look to my uni website when I'm on the phone, so thank you very much :-)

The only thing that could be improved it's the support for the 'tab' key to switch between fields. Anyway, this isn't prioritary, so it's a green light for me!

(as usual, I didn't review tests, they looks good but you know I don't know python)

review: Approve
Revision history for this message
Olivier Tilloy (osomon) wrote :

Unfortunately no it won’t land in OTA-5, as it depends on oxide 1.9, to be released in ~ 6 weeks from now.

lp:~osomon/webbrowser-app/http-auth updated
1010. By Olivier Tilloy

Merge the latest changes from trunk and resolve a few minor conflicts.

1011. By Olivier Tilloy

Update imports.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~osomon/webbrowser-app/http-auth updated
1012. By Olivier Tilloy

Merge the latest changes from trunk and resolve a few conflicts.

1013. By Olivier Tilloy

Factor out common code in autopilot tests.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/control'
--- debian/control 2015-08-25 13:56:58 +0000
+++ debian/control 2015-09-01 07:19:36 +0000
@@ -6,7 +6,7 @@
6 debhelper (>= 9),6 debhelper (>= 9),
7 dh-translations,7 dh-translations,
8 hardening-wrapper,8 hardening-wrapper,
9 liboxideqt-qmlplugin (>= 1.8),9 liboxideqt-qmlplugin (>= 1.9),
10 libqt5sql5-sqlite,10 libqt5sql5-sqlite,
11 python3-all,11 python3-all,
12 python3-flake8,12 python3-flake8,
@@ -35,7 +35,7 @@
35Depends: ${misc:Depends},35Depends: ${misc:Depends},
36 ${shlibs:Depends},36 ${shlibs:Depends},
37 fonts-liberation,37 fonts-liberation,
38 liboxideqt-qmlplugin (>= 1.8),38 liboxideqt-qmlplugin (>= 1.9),
39 libqt5sql5-sqlite,39 libqt5sql5-sqlite,
40 qml-module-qt-labs-folderlistmodel,40 qml-module-qt-labs-folderlistmodel,
41 qml-module-qt-labs-settings,41 qml-module-qt-labs-settings,
@@ -97,7 +97,7 @@
97Pre-Depends: ${misc:Pre-Depends}97Pre-Depends: ${misc:Pre-Depends}
98Depends: ${misc:Depends},98Depends: ${misc:Depends},
99 ${shlibs:Depends},99 ${shlibs:Depends},
100 liboxideqt-qmlplugin (>= 1.8),100 liboxideqt-qmlplugin (>= 1.9),
101 qml-module-qtquick2 (>= 5.4),101 qml-module-qtquick2 (>= 5.4),
102 qml-module-qtquick-window2 (>= 5.3),102 qml-module-qtquick-window2 (>= 5.3),
103 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3),103 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3),
104104
=== modified file 'src/Ubuntu/Web/UbuntuWebView02.qml'
--- src/Ubuntu/Web/UbuntuWebView02.qml 2015-08-27 11:36:25 +0000
+++ src/Ubuntu/Web/UbuntuWebView02.qml 2015-09-01 07:19:36 +0000
@@ -18,7 +18,7 @@
1818
19import QtQuick 2.419import QtQuick 2.4
20import QtQuick.Window 2.220import QtQuick.Window 2.2
21import com.canonical.Oxide 1.8 as Oxide21import com.canonical.Oxide 1.9 as Oxide
22import Ubuntu.Components 1.322import Ubuntu.Components 1.3
23import Ubuntu.Components.Popups 1.323import Ubuntu.Components.Popups 1.3
24import "." // QTBUG-3441824import "." // QTBUG-34418
2525
=== added file 'src/app/HttpAuthenticationDialog.qml'
--- src/app/HttpAuthenticationDialog.qml 1970-01-01 00:00:00 +0000
+++ src/app/HttpAuthenticationDialog.qml 2015-09-01 07:19:36 +0000
@@ -0,0 +1,76 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This file is part of webbrowser-app.
5 *
6 * webbrowser-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * webbrowser-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 2.4
20import Ubuntu.Components 1.3
21import Ubuntu.Components.Popups 1.3 as Popups
22
23Popups.Dialog {
24 id: dialog
25 title: i18n.tr("Authentication required.")
26 // TRANSLATORS: %1 refers to the URL of the current website and %2 is a string that the website sends with more information about the authentication challenge (technically called "realm")
27 text: request ? i18n.tr('The website at %1 requires authentication. The website says "%2"').arg(request.host).arg(request.realm) : ""
28
29 property QtObject request: null
30
31 Connections {
32 target: request
33 onCancelled: PopupUtils.close(dialog)
34 }
35
36 TextField {
37 id: usernameInput
38 objectName: "username"
39 placeholderText: i18n.tr("Username")
40 onAccepted: {
41 request.allow(usernameInput.text, passwordInput.text)
42 PopupUtils.close(dialog)
43 }
44 }
45
46 TextField {
47 id: passwordInput
48 objectName: "password"
49 placeholderText: i18n.tr("Password")
50 echoMode: TextInput.Password
51 onAccepted: {
52 request.allow(usernameInput.text, passwordInput.text)
53 PopupUtils.close(dialog)
54 }
55 }
56
57 Button {
58 objectName: "allow"
59 text: i18n.tr("OK")
60 color: UbuntuColors.green
61 onClicked: {
62 request.allow(usernameInput.text, passwordInput.text)
63 PopupUtils.close(dialog)
64 }
65 }
66
67 Button {
68 objectName: "deny"
69 text: i18n.tr("Cancel")
70 color: UbuntuColors.coolGrey
71 onClicked: {
72 request.deny()
73 PopupUtils.close(dialog)
74 }
75 }
76}
077
=== modified file 'src/app/WebViewImpl.qml'
--- src/app/WebViewImpl.qml 2015-08-27 14:00:49 +0000
+++ src/app/WebViewImpl.qml 2015-09-01 07:19:36 +0000
@@ -29,7 +29,6 @@
29 property var currentWebview: webview29 property var currentWebview: webview
3030
31 /*experimental.certificateVerificationDialog: CertificateVerificationDialog {}31 /*experimental.certificateVerificationDialog: CertificateVerificationDialog {}
32 experimental.authenticationDialog: AuthenticationDialog {}
33 experimental.proxyAuthenticationDialog: ProxyAuthenticationDialog {}*/32 experimental.proxyAuthenticationDialog: ProxyAuthenticationDialog {}*/
34 alertDialog: AlertDialog {}33 alertDialog: AlertDialog {}
35 confirmDialog: ConfirmDialog {}34 confirmDialog: ConfirmDialog {}
@@ -82,6 +81,11 @@
82 }81 }
83 }82 }
8483
84 onHttpAuthenticationRequested: {
85 PopupUtils.open(Qt.resolvedUrl("HttpAuthenticationDialog.qml"),
86 webview.currentWebview, {"request": request})
87 }
88
85 Loader {89 Loader {
86 id: filePickerLoader90 id: filePickerLoader
87 source: formFactor == "desktop" ? "FilePickerDialog.qml" : "ContentPickerDialog.qml"91 source: formFactor == "desktop" ? "FilePickerDialog.qml" : "ContentPickerDialog.qml"
8892
=== modified file 'tests/autopilot/webbrowser_app/emulators/browser.py'
--- tests/autopilot/webbrowser_app/emulators/browser.py 2015-08-25 13:56:58 +0000
+++ tests/autopilot/webbrowser_app/emulators/browser.py 2015-09-01 07:19:36 +0000
@@ -115,6 +115,9 @@
115 def get_geolocation_dialog(self):115 def get_geolocation_dialog(self):
116 return self.wait_select_single(GeolocationPermissionRequest)116 return self.wait_select_single(GeolocationPermissionRequest)
117117
118 def get_http_auth_dialog(self):
119 return self.wait_select_single(HttpAuthenticationDialog)
120
118 def get_tabs_view(self):121 def get_tabs_view(self):
119 return self.wait_select_single(TabsList, visible=True)122 return self.wait_select_single(TabsList, visible=True)
120123
@@ -323,6 +326,21 @@
323 return self.select_single("Button", objectName="allow")326 return self.select_single("Button", objectName="allow")
324327
325328
329class HttpAuthenticationDialog(uitk.UbuntuUIToolkitCustomProxyObjectBase):
330
331 def get_deny_button(self):
332 return self.select_single("Button", objectName="deny")
333
334 def get_allow_button(self):
335 return self.select_single("Button", objectName="allow")
336
337 def get_username_field(self):
338 return self.select_single("TextField", objectName="username")
339
340 def get_password_field(self):
341 return self.select_single("TextField", objectName="password")
342
343
326class TabPreview(uitk.UbuntuUIToolkitCustomProxyObjectBase):344class TabPreview(uitk.UbuntuUIToolkitCustomProxyObjectBase):
327345
328 @autopilot.logging.log_action(logger.info)346 @autopilot.logging.log_action(logger.info)
329347
=== modified file 'tests/autopilot/webbrowser_app/tests/http_server.py'
--- tests/autopilot/webbrowser_app/tests/http_server.py 2015-08-24 09:27:53 +0000
+++ tests/autopilot/webbrowser_app/tests/http_server.py 2015-09-01 07:19:36 +0000
@@ -6,6 +6,7 @@
6# under the terms of the GNU General Public License version 3, as published6# under the terms of the GNU General Public License version 3, as published
7# by the Free Software Foundation.7# by the Free Software Foundation.
88
9from base64 import b64decode
9import http.server as http10import http.server as http
10import json11import json
11import logging12import logging
@@ -37,6 +38,12 @@
37 self.end_headers()38 self.end_headers()
38 self.wfile.write(html.encode())39 self.wfile.write(html.encode())
3940
41 def send_auth_request(self):
42 self.send_response(401)
43 self.send_header("WWW-Authenticate", "Basic realm=\"Enter Password\"")
44 self.end_headers()
45 self.send_html("Not Authorized")
46
40 def do_GET(self):47 def do_GET(self):
41 if self.path == "/ping":48 if self.path == "/ping":
42 self.send_response(200)49 self.send_response(200)
@@ -183,6 +190,19 @@
183 self.send_response(200)190 self.send_response(200)
184 name = self.path[len("/tab/"):]191 name = self.path[len("/tab/"):]
185 self.send_html('<html><body>' + name + '</body></html>')192 self.send_html('<html><body>' + name + '</body></html>')
193 elif self.path.startswith("/basicauth"):
194 login = "user"
195 password = "pass"
196 if "Authorization" in self.headers:
197 header = self.headers.get("Authorization")
198 credentials = str(b64decode(header[len("Basic "):])).split(":")
199 if credentials[0] == login and credentials[1] == password:
200 self.send_response(200)
201 self.send_html("Authentication Successful !")
202 else:
203 self.send_auth_request()
204 else:
205 self.send_auth_request()
186 else:206 else:
187 self.send_error(404)207 self.send_error(404)
188208
189209
=== added file 'tests/autopilot/webbrowser_app/tests/test_basic_authentication.py'
--- tests/autopilot/webbrowser_app/tests/test_basic_authentication.py 1970-01-01 00:00:00 +0000
+++ tests/autopilot/webbrowser_app/tests/test_basic_authentication.py 2015-09-01 07:19:36 +0000
@@ -0,0 +1,49 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#
3# Copyright 2015 Canonical
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published
7# by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17from webbrowser_app.tests import StartOpenRemotePageTestCaseBase
18
19
20class TestBasicAuthentication(StartOpenRemotePageTestCaseBase):
21
22 def setUp(self):
23 super(TestBasicAuthentication, self).setUp()
24 self.main_window.go_to_url(self.base_url + "/basicauth")
25 self.dialog = self.main_window.get_http_auth_dialog()
26 self.username = "user"
27 self.password = "pass"
28
29 def test_cancel(self):
30 self.pointing_device.click_object(self.dialog.get_deny_button())
31 self.dialog.wait_until_destroyed()
32
33 def test_right_credentials(self):
34 username = self.dialog.get_username_field()
35 username.write(self.username)
36 password = self.dialog.get_password_field()
37 password.write(self.password)
38 self.pointing_device.click_object(self.dialog.get_allow_button())
39 self.dialog.wait_until_destroyed()
40
41 def test_wrong_credentials(self):
42 username = self.dialog.get_username_field()
43 username.write("x")
44 password = self.dialog.get_password_field()
45 password.write("x")
46 self.pointing_device.click_object(self.dialog.get_allow_button())
47 self.dialog.wait_until_destroyed()
48 # verify that a new dialog has been displayed
49 self.main_window.get_http_auth_dialog()

Subscribers

People subscribed via source and target branches

to status/vote changes: