Merge lp:~jonas-drange/ubuntu-settings-components/vpn into lp:~registry/ubuntu-settings-components/trunk

Proposed by Jonas G. Drange
Status: Merged
Approved by: Nick Dedekind
Approved revision: 134
Merged at revision: 112
Proposed branch: lp:~jonas-drange/ubuntu-settings-components/vpn
Merge into: lp:~registry/ubuntu-settings-components/trunk
Diff against target: 3473 lines (+3263/-0)
39 files modified
debian/control (+1/-0)
examples/VpnComponents.qml (+141/-0)
plugins/Ubuntu/Settings/CMakeLists.txt (+1/-0)
plugins/Ubuntu/Settings/Vpn/CMakeLists.txt (+23/-0)
plugins/Ubuntu/Settings/Vpn/DialogFile.qml (+176/-0)
plugins/Ubuntu/Settings/Vpn/DialogFileProperties.qml (+22/-0)
plugins/Ubuntu/Settings/Vpn/FileSelector.qml (+94/-0)
plugins/Ubuntu/Settings/Vpn/Openvpn/CMakeLists.txt (+3/-0)
plugins/Ubuntu/Settings/Vpn/Openvpn/Editor.qml (+426/-0)
plugins/Ubuntu/Settings/Vpn/Openvpn/Preview.qml (+81/-0)
plugins/Ubuntu/Settings/Vpn/Pptp/CMakeLists.txt (+3/-0)
plugins/Ubuntu/Settings/Vpn/Pptp/Editor.qml (+379/-0)
plugins/Ubuntu/Settings/Vpn/Pptp/Preview.qml (+61/-0)
plugins/Ubuntu/Settings/Vpn/PreviewDialog/AllTrafficWithDns.qml (+47/-0)
plugins/Ubuntu/Settings/Vpn/PreviewDialog/AllTrafficWithoutDns.qml (+53/-0)
plugins/Ubuntu/Settings/Vpn/PreviewDialog/CMakeLists.txt (+3/-0)
plugins/Ubuntu/Settings/Vpn/PreviewDialog/InvalidCert.qml (+69/-0)
plugins/Ubuntu/Settings/Vpn/PreviewDialog/NoCert.qml (+35/-0)
plugins/Ubuntu/Settings/Vpn/PreviewDialog/NotInstalledWithRoutes.qml (+59/-0)
plugins/Ubuntu/Settings/Vpn/PreviewDialog/NotInstalledWithoutRoutes.qml (+59/-0)
plugins/Ubuntu/Settings/Vpn/PreviewDialog/SetUpUnused.qml (+56/-0)
plugins/Ubuntu/Settings/Vpn/PreviewDialog/SomeTraffic.qml (+41/-0)
plugins/Ubuntu/Settings/Vpn/VpnEditor.qml (+161/-0)
plugins/Ubuntu/Settings/Vpn/VpnList.qml (+68/-0)
plugins/Ubuntu/Settings/Vpn/VpnPreviewDialog.qml (+116/-0)
plugins/Ubuntu/Settings/Vpn/VpnRoutesField.qml (+83/-0)
plugins/Ubuntu/Settings/Vpn/VpnTypeField.qml (+54/-0)
plugins/Ubuntu/Settings/Vpn/plugin.cpp (+36/-0)
plugins/Ubuntu/Settings/Vpn/plugin.h (+30/-0)
plugins/Ubuntu/Settings/Vpn/qmldir (+10/-0)
plugins/Ubuntu/Settings/Vpn/ubuntusettingsvpn.cpp (+56/-0)
plugins/Ubuntu/Settings/Vpn/ubuntusettingsvpn.h (+46/-0)
tests/qmltests/CMakeLists.txt (+6/-0)
tests/qmltests/Vpn/tst_VpnEditor.qml (+87/-0)
tests/qmltests/Vpn/tst_VpnList.qml (+132/-0)
tests/qmltests/Vpn/tst_VpnOpenvpnEditor.qml (+183/-0)
tests/qmltests/Vpn/tst_VpnPptpEditor.qml (+145/-0)
tests/qmltests/Vpn/tst_VpnPreviewDialog.qml (+142/-0)
tests/qmltests/Vpn/tst_VpnPreviewDialogCertificateChecks.qml (+75/-0)
To merge this branch: bzr merge lp:~jonas-drange/ubuntu-settings-components/vpn
Reviewer Review Type Date Requested Status
Nick Dedekind (community) Approve
PS Jenkins bot (community) continuous-integration Needs Fixing
Ubuntu Unity PS integration team changed debian/control Pending
Review via email: mp+286353@code.launchpad.net

Commit message

New plugins Ubuntu.Settings.Vpn, Ubuntu.Settings.Vpn.Openvpn and Ubuntu.Settings.Vpn.Pptp for creating, deleting and configuring VPN connections, implicitly using the Connectivity API.

Description of the change

* Are there any related MPs required for this MP to build/function as expected? Please list.
None, but you need indicator-network >= 0.7.1

 * Did you perform an exploratory manual test run of your code change and any related functionality?
Yes (silo 38)

 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
Added dep on qtquick layouts

 * If you changed the UI, has there been a design review?
No changed UIs, only additions.

Instructions:

Run QML tests:
make testVpnEditor testVpnList testVpnOpenvpnEditor testVpnPptpEditor testVpnPreviewDialog testVpnPreviewDialogCertificateChecks

Run example:
if nm-applet runs, kill it
start indicator-network && start indicator-network-secret-agent
qmlscene examples/VpnComponents.qml

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
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)
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

It would be very helpful if you added something to the examples to demonstrate the exported components you added. Otherwise we don't have anything to test in isolation of USS or Unity8.

And on testing note; could you add some automated tests please?

Couple of pre-test comments attached.

review: Needs Fixing
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)
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)
131. By Jonas G. Drange

don't prompt for reconnection if the connection is inactive, and store the full path always in fileselector

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
132. By Jonas G. Drange

sync with trunk

133. By Jonas G. Drange

use the u-s-c domain for translations we want to export

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

Some comments attached.

Revision history for this message
Nick Dedekind (nick-dedekind) :
review: Needs Fixing
134. By Jonas G. Drange

use binding as in vpn editor

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

Looks fine.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2015-10-20 11:52:12 +0000
3+++ debian/control 2016-03-15 13:35:14 +0000
4@@ -11,6 +11,7 @@
5 qtdeclarative5-dev,
6 qtdeclarative5-dev-tools,
7 qtdeclarative5-qtquick2-plugin,
8+ qtdeclarative5-quicklayouts-plugin,
9 qtdeclarative5-test-plugin,
10 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.1) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.1),
11 suru-icon-theme,
12
13=== added file 'examples/VpnComponents.qml'
14--- examples/VpnComponents.qml 1970-01-01 00:00:00 +0000
15+++ examples/VpnComponents.qml 2016-03-15 13:35:14 +0000
16@@ -0,0 +1,141 @@
17+/*
18+ * Copyright (C) 2016 Canonical Ltd.
19+ *
20+ * This program is free software: you can redistribute it and/or modify it
21+ * under the terms of the GNU Lesser General Public License version 3,
22+ * as published by the Free Software Foundation.
23+ *
24+ * This program is distributed in the hope that it will be useful,
25+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27+ * GNU Lesser General Public License for more details.
28+ *
29+ * You should have received a copy of the GNU Lesser General Public License
30+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
31+ *
32+ * Authored by Jonas G. Drange <jonas.drange@canonical.com>
33+ *
34+ * For a demonstration of the VPN components, you will need the Connectivity
35+ * module installed on your system.
36+ */
37+
38+import QtQuick 2.4
39+import Ubuntu.Components 1.3
40+import Ubuntu.Components.ListItems 1.3 as ListItem
41+import Ubuntu.Components.Popups 1.3
42+import Ubuntu.Connectivity 1.0
43+import Ubuntu.Settings.Vpn 0.1
44+
45+MainView {
46+ width: units.gu(50)
47+ height: units.gu(90)
48+
49+ PageStack {
50+ id: pageStack
51+ Component.onCompleted: push(root)
52+
53+ Page {
54+ id: root
55+ title: i18n.tr("VPN")
56+ flickable: scrollWidget
57+ visible: false
58+
59+ property var diag
60+
61+ function openConnection(connection, isNew) {
62+ pageStack.push(vpnEditorDialog, {
63+ "connection": connection,
64+ "isNew": isNew
65+ });
66+ }
67+
68+ function previewConnection(connection) {
69+ diag = PopupUtils.open(vpnPreviewDialog, root, {"connection": connection});
70+ }
71+
72+ Flickable {
73+ id: scrollWidget
74+ anchors {
75+ fill: parent
76+ topMargin: units.gu(1)
77+ bottomMargin: units.gu(1)
78+ }
79+ contentHeight: contentItem.childrenRect.height
80+ boundsBehavior: (contentHeight > root.height) ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds
81+
82+ Column {
83+ anchors { left: parent.left; right: parent.right }
84+
85+ VpnList {
86+ id: list
87+ anchors { left: parent.left; right: parent.right }
88+ model: Connectivity.vpnConnections
89+
90+ onClickedConnection: root.previewConnection(connection)
91+ }
92+
93+ ListItem.Caption {
94+ // We do not yet support configuration files.
95+ visible: false
96+ anchors {
97+ left: parent.left
98+ right: parent.right
99+ }
100+ text : i18n.tr("To add a VPN configuration, download its config file or configure it manually.")
101+ }
102+
103+ ListItem.SingleControl {
104+ control: Button {
105+ text : i18n.tr("Add Manual Configuration…")
106+ onClicked: Connectivity.vpnConnections.add(VpnConnection.OPENVPN)
107+ }
108+ }
109+ }
110+ }
111+
112+ Component {
113+ id: vpnEditorDialog
114+ VpnEditor {
115+ onTypeChanged: {
116+ connection.remove();
117+ pageStack.pop();
118+ Connectivity.vpnConnections.add(type);
119+ }
120+ onReconnectionPrompt: PopupUtils.open(reconnPrompt)
121+ }
122+ }
123+
124+ Component {
125+ id: vpnPreviewDialog
126+ VpnPreviewDialog {
127+ onChangeClicked: {
128+ PopupUtils.close(root.diag);
129+ root.openConnection(connection);
130+ }
131+ }
132+ }
133+
134+ Component {
135+ id: reconnPrompt
136+ Dialog {
137+ id: reconnPromptDiag
138+ title: i18n.tr("VPN reconnection required.")
139+ text: i18n.tr("You need to reconnect for changes to have an effect.")
140+
141+ ListItem.SingleControl {
142+ control: Button {
143+ width: parent.width
144+ text : i18n.tr("OK")
145+ onClicked: PopupUtils.close(reconnPromptDiag);
146+ }
147+ }
148+ }
149+ }
150+
151+ Connections {
152+ target: Connectivity.vpnConnections
153+ onAddFinished: root.openConnection(connection, true)
154+ }
155+ }
156+ }
157+}
158
159=== modified file 'plugins/Ubuntu/Settings/CMakeLists.txt'
160--- plugins/Ubuntu/Settings/CMakeLists.txt 2015-04-07 09:42:19 +0000
161+++ plugins/Ubuntu/Settings/CMakeLists.txt 2016-03-15 13:35:14 +0000
162@@ -1,2 +1,3 @@
163 add_subdirectory(Components)
164 add_subdirectory(Menus)
165+add_subdirectory(Vpn)
166
167=== added directory 'plugins/Ubuntu/Settings/Vpn'
168=== added file 'plugins/Ubuntu/Settings/Vpn/CMakeLists.txt'
169--- plugins/Ubuntu/Settings/Vpn/CMakeLists.txt 1970-01-01 00:00:00 +0000
170+++ plugins/Ubuntu/Settings/Vpn/CMakeLists.txt 2016-03-15 13:35:14 +0000
171@@ -0,0 +1,23 @@
172+project(UbuntuSettingsVpn)
173+
174+add_subdirectory(Openvpn)
175+add_subdirectory(Pptp)
176+add_subdirectory(PreviewDialog)
177+
178+find_package(Qt5Core REQUIRED)
179+
180+include_directories(
181+ ${CMAKE_CURRENT_SOURCE_DIR}
182+ ${CMAKE_CURRENT_BINARY_DIR}
183+)
184+
185+add_definitions(-DUBUNTUSETTINGSCOMPONENTS_LIBRARY)
186+
187+add_library(UbuntuSettingsVpn MODULE
188+ plugin.cpp
189+ ubuntusettingsvpn.cpp
190+)
191+
192+qt5_use_modules(UbuntuSettingsVpn Core Qml Quick)
193+
194+add_usc_plugin(Ubuntu.Settings.Vpn 0.1 Ubuntu/Settings/Vpn TARGETS UbuntuSettingsVpn)
195
196=== added file 'plugins/Ubuntu/Settings/Vpn/DialogFile.qml'
197--- plugins/Ubuntu/Settings/Vpn/DialogFile.qml 1970-01-01 00:00:00 +0000
198+++ plugins/Ubuntu/Settings/Vpn/DialogFile.qml 2016-03-15 13:35:14 +0000
199@@ -0,0 +1,176 @@
200+/*
201+ * Copyright (C) 2016 Canonical Ltd.
202+ *
203+ * This program is free software: you can redistribute it and/or modify it
204+ * under the terms of the GNU Lesser General Public License version 3,
205+ * as published by the Free Software Foundation.
206+ *
207+ * This program is distributed in the hope that it will be useful,
208+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
209+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
210+ * GNU Lesser General Public License for more details.
211+ *
212+ * You should have received a copy of the GNU Lesser General Public License
213+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
214+ */
215+
216+import QtQuick 2.4
217+import QtQuick.Layouts 1.1
218+import Ubuntu.Components 1.3
219+import Ubuntu.Components.ListItems 1.3 as ListItems
220+import Ubuntu.Components.Popups 1.3
221+import Ubuntu.Settings.Vpn 0.1
222+import Qt.labs.folderlistmodel 2.1
223+
224+Dialog {
225+ objectName: "vpnDialogFile"
226+ id: dialog
227+
228+ property string currentFilePath: ""
229+
230+ signal accept(string path)
231+ signal reject
232+
233+ function hideFunc() {
234+ DialogFileProperties.lastFolder = modelFs.folder
235+ currentFilePath = ""
236+ }
237+
238+ function rejectFunc() {
239+ hideFunc()
240+ dialog.reject()
241+ }
242+
243+ function acceptFunc() {
244+ var path = currentFilePath
245+ hideFunc()
246+ dialog.accept(path)
247+ }
248+
249+ FolderListModel {
250+ id: modelFs
251+ showDirs: true
252+ showFiles: true
253+ showHidden: true
254+ showDirsFirst: true
255+ showDotAndDotDot: false
256+ showOnlyReadable: false
257+ sortField: FolderListModel.Name
258+
259+ folder: (DialogFileProperties.lastFolder === "")? "file:///home/" : DialogFileProperties.lastFolder
260+ }
261+
262+ ColumnLayout {
263+ height: root.height - units.gu(10)
264+ spacing: units.gu(1)
265+
266+ Flow {
267+ spacing: units.gu(1)
268+ Layout.fillWidth: true
269+
270+ Repeater {
271+ model: {
272+ var ret = []
273+ var path = "file:///"
274+ ret.push({ "name" : "/", "url" : path })
275+ var tmp = modelFs.folder.toString().replace("file:///", "").split("/")
276+ for (var idx = 0; idx < tmp.length; idx++) {
277+ var name = tmp[idx] + "/"
278+ if (name !== "/") {
279+ path += name
280+ ret.push({ "name" : name, "url" : path })
281+ }
282+ }
283+ return ret
284+ }
285+ delegate: Row {
286+ spacing: units.gu(0.7)
287+
288+ property bool isCurrent : Positioner.isLastItem
289+
290+ Rectangle {
291+ width: units.gu(0.7)
292+ height: width
293+ color: "gray"
294+ rotation: 45
295+ visible: (model.index > 0)
296+ anchors.verticalCenter: parent.verticalCenter
297+ }
298+ Label {
299+ objectName: "vpnFilePathItem_" + model.modelData["name"]
300+ text: model.modelData["name"]
301+ font.weight: (isCurrent ? Font.Bold : Font.Normal)
302+ font.underline: hoverDetector.containsMouse
303+ color: "darkblue"
304+ anchors.verticalCenter: parent.verticalCenter
305+
306+ MouseArea {
307+ id: hoverDetector
308+ enabled: !isCurrent
309+ hoverEnabled: true
310+ anchors.fill: parent
311+ onClicked: modelFs.folder = model.modelData["url"]
312+ }
313+ }
314+ }
315+ }
316+ }
317+
318+ Rectangle {
319+ Layout.fillWidth: true
320+ Layout.fillHeight: true
321+
322+ border {
323+ width: 1
324+ color: "lightgrey"
325+ }
326+
327+ ListView {
328+ objectName: "vpnFileList"
329+ anchors.fill: parent
330+ anchors.margins: 1
331+ clip: true
332+ model: modelFs
333+
334+ delegate: ListItems.Standard {
335+ objectName: "vpnFileItem_" + model.fileName
336+ text: model.fileName
337+ iconFrame: false
338+ iconName: model.fileIsDir ? "folder" : "empty"
339+
340+ selected: (model.filePath === currentFilePath)
341+
342+ onClicked: {
343+ if (model.fileIsDir) {
344+ modelFs.folder = model.fileURL
345+ } else {
346+ currentFilePath = model.filePath
347+ }
348+ }
349+ }
350+ }
351+ }
352+
353+ RowLayout {
354+ spacing: units.gu(1)
355+ Layout.fillWidth: true
356+
357+ Button {
358+ objectName: "vpnFileCancel"
359+ Layout.fillWidth: true
360+ text: i18n.dtr("ubuntu-settings-components", "Cancel")
361+ onClicked: rejectFunc()
362+ color: UbuntuColors.red
363+ }
364+
365+ Button {
366+ objectName: "vpnFileAccept"
367+ Layout.fillWidth: true
368+ enabled: currentFilePath !== ""
369+ text: i18n.dtr("ubuntu-settings-components", "Accept")
370+ onClicked: acceptFunc()
371+ color: UbuntuColors.green
372+ }
373+ }
374+ }
375+}
376
377=== added file 'plugins/Ubuntu/Settings/Vpn/DialogFileProperties.qml'
378--- plugins/Ubuntu/Settings/Vpn/DialogFileProperties.qml 1970-01-01 00:00:00 +0000
379+++ plugins/Ubuntu/Settings/Vpn/DialogFileProperties.qml 2016-03-15 13:35:14 +0000
380@@ -0,0 +1,22 @@
381+/*
382+ * Copyright (C) 2016 Canonical Ltd.
383+ *
384+ * This program is free software: you can redistribute it and/or modify it
385+ * under the terms of the GNU Lesser General Public License version 3,
386+ * as published by the Free Software Foundation.
387+ *
388+ * This program is distributed in the hope that it will be useful,
389+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
390+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
391+ * GNU Lesser General Public License for more details.
392+ *
393+ * You should have received a copy of the GNU Lesser General Public License
394+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
395+ */
396+
397+pragma Singleton
398+import QtQuick 2.4
399+
400+QtObject {
401+ property string lastFolder
402+}
403
404=== added file 'plugins/Ubuntu/Settings/Vpn/FileSelector.qml'
405--- plugins/Ubuntu/Settings/Vpn/FileSelector.qml 1970-01-01 00:00:00 +0000
406+++ plugins/Ubuntu/Settings/Vpn/FileSelector.qml 2016-03-15 13:35:14 +0000
407@@ -0,0 +1,94 @@
408+/*
409+ * Copyright (C) 2016 Canonical Ltd.
410+ *
411+ * This program is free software: you can redistribute it and/or modify it
412+ * under the terms of the GNU Lesser General Public License version 3,
413+ * as published by the Free Software Foundation.
414+ *
415+ * This program is distributed in the hope that it will be useful,
416+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
417+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
418+ * GNU Lesser General Public License for more details.
419+ *
420+ * You should have received a copy of the GNU Lesser General Public License
421+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
422+ */
423+
424+import QtQuick 2.4
425+import QtQuick.Layouts 1.1
426+import Ubuntu.Components 1.3
427+import Ubuntu.Components.Popups 1.3
428+import Ubuntu.Components.ListItems 1.3 as ListItems
429+
430+ListItems.ItemSelector {
431+ property string path
432+ property string chooseLabel: i18n.dtr("ubuntu-settings-components", "Choose…")
433+
434+ property var __dialog
435+
436+ // FIXME: workaround for lp:1498683. Resetting the model is the only
437+ // thing that will make selectedIndex = 0 work.
438+ function resetModel () {
439+ var m = [];
440+ model = m;
441+ m.push(i18n.dtr("ubuntu-settings-components", "None"));
442+
443+ if (path) {
444+ m.push(path);
445+ }
446+
447+ m.push(chooseLabel);
448+ model = m;
449+
450+ currentlyExpanded = false;
451+ if (path) {
452+ selectedIndex = 1;
453+ }
454+ }
455+
456+ function createDialog() {
457+ __dialog = PopupUtils.open(fileDialogComponent)
458+ __dialog.accept.connect(pathAccepted)
459+ __dialog.reject.connect(pathRejected)
460+ }
461+
462+ function destroyDialog() {
463+ __dialog.accept.disconnect(pathAccepted)
464+ __dialog.reject.disconnect(pathRejected)
465+ PopupUtils.close(__dialog)
466+ }
467+
468+ function pathAccepted(newPath) {
469+ path = newPath
470+ destroyDialog();
471+ resetModel();
472+ }
473+
474+ function pathRejected() {
475+ destroyDialog();
476+ resetModel();
477+ }
478+
479+ Component.onCompleted: resetModel()
480+
481+ delegate: OptionSelectorDelegate {
482+ objectName: "vpnFileSelectorItem" + index
483+ text: {
484+ if (modelData[0] == "/") {
485+ return path.split("/")[path.split("/").length - 1];
486+ } else {
487+ return modelData;
488+ }
489+ }
490+ }
491+
492+ onDelegateClicked: {
493+ if (index === 0) {
494+ path = "";
495+ } else if (index === model.length - 1) {
496+ createDialog();
497+ } else {
498+ path = model[index];
499+ }
500+ }
501+}
502
503=== added directory 'plugins/Ubuntu/Settings/Vpn/Openvpn'
504=== added file 'plugins/Ubuntu/Settings/Vpn/Openvpn/CMakeLists.txt'
505--- plugins/Ubuntu/Settings/Vpn/Openvpn/CMakeLists.txt 1970-01-01 00:00:00 +0000
506+++ plugins/Ubuntu/Settings/Vpn/Openvpn/CMakeLists.txt 2016-03-15 13:35:14 +0000
507@@ -0,0 +1,3 @@
508+project(UbuntuSettingsVpnOpenvpn)
509+
510+export_qmlfiles(Ubuntu.Settings.Vpn.Openvpn Ubuntu/Settings/Vpn/Openvpn DESTINATION ${QT_IMPORTS_DIR} ${ARGN})
511
512=== added file 'plugins/Ubuntu/Settings/Vpn/Openvpn/Editor.qml'
513--- plugins/Ubuntu/Settings/Vpn/Openvpn/Editor.qml 1970-01-01 00:00:00 +0000
514+++ plugins/Ubuntu/Settings/Vpn/Openvpn/Editor.qml 2016-03-15 13:35:14 +0000
515@@ -0,0 +1,426 @@
516+/*
517+ * Copyright (C) 2016 Canonical Ltd.
518+ *
519+ * This program is free software: you can redistribute it and/or modify it
520+ * under the terms of the GNU Lesser General Public License version 3,
521+ * as published by the Free Software Foundation.
522+ *
523+ * This program is distributed in the hope that it will be useful,
524+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
525+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
526+ * GNU Lesser General Public License for more details.
527+ *
528+ * You should have received a copy of the GNU Lesser General Public License
529+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
530+ */
531+
532+import QtQuick 2.4
533+import QtQuick.Layouts 1.1
534+import Ubuntu.Components 1.3
535+import Ubuntu.Components.ListItems 1.3 as ListItems
536+import Ubuntu.Components.Popups 1.3
537+import ".."
538+
539+Column {
540+ id: openVpnEditor
541+
542+ spacing: units.gu(2)
543+
544+ property var connection
545+ property bool changed: getChanges().length > 0
546+ property bool valid: true
547+
548+ states: [
549+ State {
550+ name: "committing"
551+ PropertyChanges {
552+ target: okButtonIndicator
553+ running: true
554+ }
555+ PropertyChanges { target: serverField; enabled: false }
556+ PropertyChanges { target: customPortToggle; enabled: false }
557+ PropertyChanges { target: portField; enabled: false }
558+ PropertyChanges { target: routesField; enabled: false }
559+ PropertyChanges { target: tcpToggle; enabled: false }
560+ PropertyChanges { target: udpToggle; enabled: false }
561+ PropertyChanges { target: certField; enabled: false }
562+ PropertyChanges { target: caField; enabled: false }
563+ PropertyChanges { target: keyField; enabled: false }
564+ PropertyChanges { target: certPassField; enabled: false }
565+ PropertyChanges { target: taField; enabled: false }
566+ PropertyChanges { target: taSetToggle; enabled: false }
567+ PropertyChanges { target: taDirSelector; enabled: false }
568+ PropertyChanges { target: remoteCertSetToggle; enabled: false }
569+ PropertyChanges { target: remoteCertTlsSelector; enabled: false }
570+ PropertyChanges { target: cipherSelector; enabled: false }
571+ PropertyChanges { target: compressionToggle; enabled: false }
572+ PropertyChanges { target: vpnEditorOkayButton; enabled: false }
573+ },
574+ State {
575+ name: "succeeded"
576+ extend: "committing"
577+ PropertyChanges {
578+ target: successIndicator
579+ running: true
580+ }
581+ PropertyChanges {
582+ target: okButtonIndicator
583+ running: false
584+ }
585+ }
586+ ]
587+
588+ // Return a list of pairs, first the server property name, then
589+ // the field value.
590+ function getChanges () {
591+ var fields = [
592+ ["remote", serverField.text],
593+ ["portSet", customPortToggle.checked],
594+ ["port", parseInt(portField.text, 10) || 0],
595+ ["neverDefault", routesField.neverDefault],
596+ ["protoTcp", tcpToggle.checked],
597+ ["cert", certField.path],
598+ ["ca", caField.path],
599+ ["key", keyField.path],
600+ ["certPass", certPassField.text],
601+ ["ta", taField.path],
602+ ["taSet", taSetToggle.checked],
603+ ["taDir", parseInt(taDirSelector.selectedIndex, 10) || 0],
604+ ["remoteCertTlsSet", remoteCertSetToggle.checked],
605+ ["remoteCertTls", parseInt(remoteCertTlsSelector.selectedIndex, 10) || 0],
606+ ["cipher", parseInt(cipherSelector.selectedIndex, 10) || 0],
607+ ["compLzo", compressionToggle.checked]
608+ ]
609+ var changedFields = [];
610+
611+ // Push all fields that differs from the server to chanagedFields.
612+ for (var i = 0; i < fields.length; i++) {
613+ if (connection[fields[i][0]] !== fields[i][1]) {
614+ changedFields.push(fields[i]);
615+ }
616+ }
617+
618+ return changedFields;
619+ }
620+
621+ RowLayout {
622+ anchors { left: parent.left; right: parent.right }
623+
624+ Label {
625+ text: i18n.dtr("ubuntu-settings-components", "Server:")
626+ font.bold: true
627+ color: Theme.palette.normal.baseText
628+ elide: Text.ElideRight
629+ Layout.fillWidth: true
630+ }
631+
632+ // Corresponds to the ":" element in the row of server:port textfields.
633+ Item {
634+ Layout.preferredWidth: units.gu(1)
635+ height: units.gu(1) // Value set for the sake of it being drawn.
636+ }
637+
638+ Label {
639+ text: i18n.dtr("ubuntu-settings-components", "Port:")
640+ font.bold: true
641+ color: Theme.palette.normal.baseText
642+ elide: Text.ElideRight
643+ Layout.preferredWidth: units.gu(10)
644+ }
645+ }
646+
647+ RowLayout {
648+ anchors { left: parent.left; right: parent.right }
649+
650+ TextField {
651+ id: serverField
652+ objectName: "vpnOpenvpnServerField"
653+ inputMethodHints: Qt.ImhNoAutoUppercase
654+ | Qt.ImhNoPredictiveText
655+ | Qt.ImhUrlCharactersOnly
656+ Layout.fillWidth: true
657+ text: connection.remote
658+ Component.onCompleted: forceActiveFocus()
659+ }
660+
661+ Label {
662+ text: ":"
663+ horizontalAlignment: Text.AlignHCenter
664+ verticalAlignment: Text.AlignVCenter
665+ Layout.preferredWidth: units.gu(1)
666+ }
667+
668+ TextField {
669+ id: portField
670+ objectName: "vpnOpenvpnPortField"
671+ maximumLength: 5
672+ validator: portValidator
673+ inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
674+ text: connection.port
675+ Layout.preferredWidth: units.gu(10)
676+ enabled: customPortToggle.checked
677+ }
678+ }
679+
680+ RowLayout {
681+ anchors { left: parent.left; right: parent.right }
682+ CheckBox {
683+ id: customPortToggle
684+ objectName: "vpnOpenvpnCustomPortToggle"
685+ checked: connection.portSet
686+ }
687+
688+ Label {
689+ text: i18n.dtr("ubuntu-settings-components", "Use custom gateway port")
690+ Layout.fillWidth: true
691+ }
692+ }
693+
694+ VpnRoutesField {
695+ objectName: "vpnOpenvpnRoutesField"
696+ anchors { left: parent.left; right: parent.right }
697+ id: routesField
698+ neverDefault: connection.neverDefault
699+ }
700+
701+ RegExpValidator {
702+ id: portValidator
703+ regExp: /([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])/
704+ }
705+
706+ VpnTypeField {
707+ anchors { left: parent.left; right: parent.right }
708+ // type does not notify, so we avoid binding to suppress warnings
709+ Component.onCompleted: type = connection.type
710+ onTypeRequested: {
711+ editor.typeChanged(connection, index);
712+ }
713+ }
714+
715+ RowLayout {
716+ Label {
717+ text: i18n.dtr("ubuntu-settings-components", "Protocol:")
718+ font.bold: true
719+ color: Theme.palette.normal.baseText
720+ elide: Text.ElideRight
721+ }
722+
723+ Label {
724+ id: tcpLabel
725+ text: i18n.dtr("ubuntu-settings-components", "TCP")
726+ }
727+
728+ CheckBox {
729+ id: tcpToggle
730+ objectName: "vpnOpenvpnTcpToggle"
731+ checked: connection.protoTcp
732+ }
733+
734+ Label {
735+ text: i18n.dtr("ubuntu-settings-components", "UDP")
736+ }
737+
738+ CheckBox {
739+ id: udpToggle
740+ objectName: "vpnOpenvpnUdpToggle"
741+ checked: !tcpToggle.checked
742+ onTriggered: {
743+ tcpToggle.checked = !checked;
744+ checked = Qt.binding(function () {
745+ return !tcpToggle.checked
746+ });
747+ }
748+ }
749+ }
750+
751+ Label {
752+ font.bold: true
753+ color: Theme.palette.normal.baseText
754+ elide: Text.ElideRight
755+ text: i18n.dtr("ubuntu-settings-components", "Client certificate:")
756+ }
757+
758+ FileSelector {
759+ anchors { left: parent.left; right: parent.right }
760+ id: certField
761+ objectName: "vpnOpenvpnCertField"
762+ path: connection.cert
763+ chooseLabel: i18n.dtr("ubuntu-settings-components", "Choose Certificate…")
764+ }
765+
766+ Label {
767+ font.bold: true
768+ color: Theme.palette.normal.baseText
769+ elide: Text.ElideRight
770+ text: i18n.dtr("ubuntu-settings-components", "CA certificate:")
771+ }
772+
773+ FileSelector {
774+ id: caField
775+ objectName: "vpnOpenvpnCaField"
776+ anchors { left: parent.left; right: parent.right }
777+ path: connection.ca
778+ chooseLabel: i18n.dtr("ubuntu-settings-components", "Choose Certificate…")
779+ }
780+
781+ Label {
782+ font.bold: true
783+ color: Theme.palette.normal.baseText
784+ elide: Text.ElideRight
785+ text: i18n.dtr("ubuntu-settings-components", "Private key:")
786+ }
787+
788+ FileSelector {
789+ anchors { left: parent.left; right: parent.right }
790+ id: keyField
791+ objectName: "vpnOpenvpnKeyField"
792+ path: connection.key
793+ chooseLabel: i18n.dtr("ubuntu-settings-components", "Choose Key…")
794+ }
795+
796+ Label {
797+ font.bold: true
798+ color: Theme.palette.normal.baseText
799+ elide: Text.ElideRight
800+ text: i18n.dtr("ubuntu-settings-components", "Key password:")
801+ }
802+
803+ TextField {
804+ anchors { left: parent.left; right: parent.right }
805+ id: certPassField
806+ objectName: "vpnOpenvpnCertPassField"
807+ echoMode: TextInput.Password
808+ text: connection.certPass
809+ }
810+
811+ RowLayout {
812+ CheckBox {
813+ id: taSetToggle
814+ objectName: "vpnOpenvpnTaSetToggle"
815+ checked: connection.taSet
816+ onTriggered: connection.taSet = checked
817+ activeFocusOnPress: false
818+ }
819+
820+ Label {
821+ text: i18n.dtr("ubuntu-settings-components", "Use additional TLS authentication:")
822+ Layout.fillWidth: true
823+ }
824+ }
825+
826+ Label {
827+ font.bold: true
828+ color: Theme.palette.normal.baseText
829+ elide: Text.ElideRight
830+ text: i18n.dtr("ubuntu-settings-components", "TLS key:")
831+ visible: taSetToggle.checked
832+ }
833+
834+ FileSelector {
835+ anchors { left: parent.left; right: parent.right }
836+ id: taField
837+ objectName: "vpnOpenvpnTaField"
838+ path: connection.ta
839+ chooseLabel: i18n.dtr("ubuntu-settings-components", "Choose Key…")
840+ visible: taSetToggle.checked
841+ }
842+
843+ Label {
844+ text: i18n.dtr("ubuntu-settings-components", "Key direction:")
845+ font.bold: true
846+ color: Theme.palette.normal.baseText
847+ elide: Text.ElideRight
848+ visible: taSetToggle.checked
849+ }
850+
851+ ListItems.ItemSelector {
852+ id: taDirSelector
853+ objectName: "vpnOpenvpnTaDirSelector"
854+ model: [
855+ i18n.dtr("ubuntu-settings-components", "None"),
856+ i18n.dtr("ubuntu-settings-components", "0"),
857+ i18n.dtr("ubuntu-settings-components", "1"),
858+ ]
859+ selectedIndex: connection.taDir
860+ visible: taSetToggle.checked
861+ }
862+
863+ RowLayout {
864+ CheckBox {
865+ id: remoteCertSetToggle
866+ objectName: "vpnOpenvpnRemoteCertSetToggle"
867+ checked: connection.remoteCertTlsSet
868+ activeFocusOnPress: false
869+ }
870+
871+ Label {
872+ text: i18n.dtr("ubuntu-settings-components", "Verify peer certificate:")
873+ Layout.fillWidth: true
874+ }
875+ }
876+
877+ Label {
878+ font.bold: true
879+ color: Theme.palette.normal.baseText
880+ elide: Text.ElideRight
881+ text: i18n.dtr("ubuntu-settings-components", "Peer certificate TLS type:")
882+ visible: remoteCertSetToggle.checked
883+ }
884+
885+ ListItems.ItemSelector {
886+ id: remoteCertTlsSelector
887+ objectName: "vpnOpenvpnRemoteCertTlsSelector"
888+ model: [
889+ i18n.dtr("ubuntu-settings-components", "Server"),
890+ i18n.dtr("ubuntu-settings-components", "Client"),
891+ ]
892+ selectedIndex: connection.remoteCertTls
893+ visible: remoteCertSetToggle.checked
894+ }
895+
896+ Label {
897+ font.bold: true
898+ color: Theme.palette.normal.baseText
899+ elide: Text.ElideRight
900+ text: i18n.dtr("ubuntu-settings-components", "Cipher:")
901+ }
902+
903+ ListItems.ItemSelector {
904+ id: cipherSelector
905+ objectName: "vpnOpenvpnCipherSelector"
906+ model: [
907+ i18n.dtr("ubuntu-settings-components", "Default"),
908+ i18n.dtr("ubuntu-settings-components", "DES-CBC"),
909+ i18n.dtr("ubuntu-settings-components", "RC2-CBC"),
910+ i18n.dtr("ubuntu-settings-components", "DES-EDE-CBC"),
911+ i18n.dtr("ubuntu-settings-components", "DES-EDE3-CBC"),
912+ i18n.dtr("ubuntu-settings-components", "DESX-CBC"),
913+ i18n.dtr("ubuntu-settings-components", "RC2-40-CBC"),
914+ i18n.dtr("ubuntu-settings-components", "CAST5-CBC"),
915+ i18n.dtr("ubuntu-settings-components", "AES-128-CBC"),
916+ i18n.dtr("ubuntu-settings-components", "AES-192-CBC"),
917+ i18n.dtr("ubuntu-settings-components", "AES-256-CBC"),
918+ i18n.dtr("ubuntu-settings-components", "CAMELLIA-128-CBC"),
919+ i18n.dtr("ubuntu-settings-components", "CAMELLIA-192-CBC"),
920+ i18n.dtr("ubuntu-settings-components", "CAMELLIA-256-CBC"),
921+ i18n.dtr("ubuntu-settings-components", "SEED-CBC"),
922+ i18n.dtr("ubuntu-settings-components", "AES-128-CBC-HMAC-SHA1"),
923+ i18n.dtr("ubuntu-settings-components", "AES-256-CBC-HMAC-SHA1"),
924+ ]
925+ selectedIndex: connection.cipher
926+ }
927+
928+ RowLayout {
929+ CheckBox {
930+ id: compressionToggle
931+ objectName: "vpnOpenvpnCompressionToggle"
932+ checked: connection.compLzo
933+ activeFocusOnPress: false
934+ }
935+
936+ Label {
937+ text: i18n.dtr("ubuntu-settings-components", "Compress data")
938+ Layout.fillWidth: true
939+ }
940+ }
941+}
942
943=== added file 'plugins/Ubuntu/Settings/Vpn/Openvpn/Preview.qml'
944--- plugins/Ubuntu/Settings/Vpn/Openvpn/Preview.qml 1970-01-01 00:00:00 +0000
945+++ plugins/Ubuntu/Settings/Vpn/Openvpn/Preview.qml 2016-03-15 13:35:14 +0000
946@@ -0,0 +1,81 @@
947+/*
948+ * Copyright (C) 2016 Canonical Ltd.
949+ *
950+ * This program is free software: you can redistribute it and/or modify it
951+ * under the terms of the GNU Lesser General Public License version 3,
952+ * as published by the Free Software Foundation.
953+ *
954+ * This program is distributed in the hope that it will be useful,
955+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
956+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
957+ * GNU Lesser General Public License for more details.
958+ *
959+ * You should have received a copy of the GNU Lesser General Public License
960+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
961+ */
962+
963+import QtQuick 2.4
964+import Ubuntu.Components 1.3
965+import Ubuntu.Settings.Vpn 0.1
966+
967+Column {
968+ property var connection
969+ property bool installed
970+
971+ // The order of which source to load is determined by the order in which
972+ // they appear in the spec (starting with “This VPN is not safe to use.”)
973+ // and ending with “You’re using this VPN for specific services.”.
974+ // We do not currently deal with non-installed VPN connections, so we
975+ // assume the connection to be installed.
976+ function showPreview () {
977+ var c = connection;
978+ // “This VPN is not safe to use.”
979+ if (c.ca) {
980+ var err = UbuntuSettingsVpn.isCertificateValid(c.ca);
981+ switch (err) {
982+ case UbuntuSettingsVpn.CERT_NOT_FOUND:
983+ case UbuntuSettingsVpn.CERT_EMPTY:
984+ //case UbuntuSettingsVpn.CERT_SELFSIGNED:
985+ case UbuntuSettingsVpn.CERT_EXPIRED:
986+ case UbuntuSettingsVpn.CERT_BLACKLISTED:
987+ return contentLoader.setSource(
988+ "../PreviewDialog/InvalidCert.qml",
989+ { error: err }
990+ );
991+ default:
992+ case UbuntuSettingsVpn.CERT_VALID:
993+ break;
994+ }
995+ } else {
996+ return contentLoader.setSource("../PreviewDialog/NoCert.qml");
997+ }
998+
999+ // “You’re using this VPN for all Internet traffic.”
1000+ if (c.active && !c.neverDefault) {
1001+ return contentLoader.setSource(
1002+ "../PreviewDialog/AllTrafficWithoutDns.qml"
1003+ );
1004+ }
1005+
1006+ // “This VPN is set up, but not in use now.”
1007+ if (!c.active) {
1008+ return contentLoader.setSource(
1009+ "../PreviewDialog/SetUpUnused.qml"
1010+ );
1011+ }
1012+
1013+ // “You’re using this VPN for specific services.”
1014+ if (c.active && c.neverDefault) {
1015+ return contentLoader.setSource(
1016+ "../PreviewDialog/SomeTraffic.qml"
1017+ );
1018+ }
1019+ }
1020+
1021+ Component.onCompleted: showPreview()
1022+
1023+ Loader {
1024+ id: contentLoader
1025+ anchors { left: parent.left; right: parent.right; }
1026+ }
1027+}
1028
1029=== added directory 'plugins/Ubuntu/Settings/Vpn/Pptp'
1030=== added file 'plugins/Ubuntu/Settings/Vpn/Pptp/CMakeLists.txt'
1031--- plugins/Ubuntu/Settings/Vpn/Pptp/CMakeLists.txt 1970-01-01 00:00:00 +0000
1032+++ plugins/Ubuntu/Settings/Vpn/Pptp/CMakeLists.txt 2016-03-15 13:35:14 +0000
1033@@ -0,0 +1,3 @@
1034+project(UbuntuSettingsVpnPptp)
1035+
1036+export_qmlfiles(Ubuntu.Settings.Vpn.Pptp Ubuntu/Settings/Vpn/Pptp DESTINATION ${QT_IMPORTS_DIR} ${ARGN})
1037
1038=== added file 'plugins/Ubuntu/Settings/Vpn/Pptp/Editor.qml'
1039--- plugins/Ubuntu/Settings/Vpn/Pptp/Editor.qml 1970-01-01 00:00:00 +0000
1040+++ plugins/Ubuntu/Settings/Vpn/Pptp/Editor.qml 2016-03-15 13:35:14 +0000
1041@@ -0,0 +1,379 @@
1042+/*
1043+ * Copyright (C) 2016 Canonical Ltd.
1044+ *
1045+ * This program is free software: you can redistribute it and/or modify it
1046+ * under the terms of the GNU Lesser General Public License version 3,
1047+ * as published by the Free Software Foundation.
1048+ *
1049+ * This program is distributed in the hope that it will be useful,
1050+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1051+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1052+ * GNU Lesser General Public License for more details.
1053+ *
1054+ * You should have received a copy of the GNU Lesser General Public License
1055+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1056+ */
1057+
1058+import QtQuick 2.4
1059+import QtQuick.Layouts 1.1
1060+import Ubuntu.Components 1.3
1061+import Ubuntu.Components.ListItems 1.3 as ListItems
1062+import Ubuntu.Components.Popups 1.3
1063+import ".."
1064+
1065+Column {
1066+ id: pptpEditor
1067+
1068+ spacing: units.gu(2)
1069+
1070+ property var connection
1071+ property bool changed: getChanges().length > 0
1072+ property bool valid: isValid()
1073+
1074+ states: [
1075+ State {
1076+ name: "committing"
1077+ PropertyChanges {
1078+ target: okButtonIndicator
1079+ running: true
1080+ }
1081+ PropertyChanges { target: gatewayField; enabled: false }
1082+ PropertyChanges { target: routesField; enabled: false }
1083+ PropertyChanges { target: userField; enabled: false }
1084+ PropertyChanges { target: passwordField; enabled: false }
1085+ PropertyChanges { target: domainField; enabled: false }
1086+ PropertyChanges { target: requireMppeToggle; enabled: false }
1087+ PropertyChanges { target: mppeTypeSelector; enabled: false }
1088+ PropertyChanges { target: mppeStatefulToggle; enabled: false }
1089+ PropertyChanges { target: allowPapToggle; enabled: false }
1090+ PropertyChanges { target: allowChapToggle; enabled: false }
1091+ PropertyChanges { target: allowMschapToggle; enabled: false }
1092+ PropertyChanges { target: allowMschapv2Toggle; enabled: false }
1093+ PropertyChanges { target: allowEapToggle; enabled: false }
1094+ PropertyChanges { target: bsdCompressionToggle; enabled: false }
1095+ PropertyChanges { target: deflateCompressionToggle; enabled: false }
1096+ PropertyChanges { target: tcpHeaderCompressionToggle; enabled: false }
1097+ PropertyChanges { target: sendPppEchoPacketsToggle; enabled: false }
1098+ PropertyChanges { target: vpnEditorOkayButton; enabled: false }
1099+ },
1100+ State {
1101+ name: "succeeded"
1102+ extend: "committing"
1103+ PropertyChanges {
1104+ target: okButtonIndicator
1105+ running: false
1106+ }
1107+ PropertyChanges {
1108+ target: successIndicator
1109+ running: true
1110+ }
1111+ }
1112+ ]
1113+
1114+ function isValid () {
1115+ // XXX: Workaround for lp:1551258 where the backend refuses
1116+ // blank passwords.
1117+ return passwordField.text.length > 0;
1118+ }
1119+
1120+ // Return a list of pairs, first the server property name, then
1121+ // the field value.
1122+ function getChanges () {
1123+ var fields = [
1124+ ["gateway", gatewayField.text],
1125+ ["neverDefault", routesField.neverDefault],
1126+ ["user", userField.text],
1127+ ["password", passwordField.text],
1128+ ["domain", domainField.text],
1129+ ["requireMppe", requireMppeToggle.checked],
1130+ ["mppeType", mppeTypeSelector.selectedIndex],
1131+ ["mppeStateful", mppeStatefulToggle.checked],
1132+ ["allowPap", allowPapToggle.checked],
1133+ ["allowChap", allowChapToggle.checked],
1134+ ["allowMschap", allowMschapToggle.checked],
1135+ ["allowMschapv2", allowMschapv2Toggle.checked],
1136+ ["allowEap", allowEapToggle.checked],
1137+ ["bsdCompression", bsdCompressionToggle.checked],
1138+ ["deflateCompression", deflateCompressionToggle.checked],
1139+ ["tcpHeaderCompression", tcpHeaderCompressionToggle.checked],
1140+ ["sendPppEchoPackets", sendPppEchoPacketsToggle.checked]
1141+ ]
1142+ var changedFields = [];
1143+
1144+ // Push all fields that differs from the server to chanagedFields.
1145+ for (var i = 0; i < fields.length; i++) {
1146+ if (connection[fields[i][0]] !== fields[i][1]) {
1147+ changedFields.push(fields[i]);
1148+ }
1149+ }
1150+
1151+ return changedFields;
1152+ }
1153+
1154+ Label {
1155+ text: i18n.dtr("ubuntu-settings-components", "Server:")
1156+ font.bold: true
1157+ color: Theme.palette.normal.baseText
1158+ elide: Text.ElideRight
1159+ }
1160+
1161+ TextField {
1162+ anchors { left: parent.left; right: parent.right }
1163+ id: gatewayField
1164+ objectName: "vpnPptpGatewayField"
1165+ inputMethodHints: Qt.ImhNoAutoUppercase
1166+ | Qt.ImhNoPredictiveText
1167+ | Qt.ImhUrlCharactersOnly
1168+ text: connection.gateway
1169+ Component.onCompleted: forceActiveFocus()
1170+ }
1171+
1172+ VpnRoutesField {
1173+ objectName: "vpnPptpRoutesField"
1174+ anchors { left: parent.left; right: parent.right }
1175+ id: routesField
1176+ neverDefault: connection.neverDefault
1177+ }
1178+
1179+ VpnTypeField {
1180+ anchors { left: parent.left; right: parent.right }
1181+ onTypeRequested: {
1182+ editor.typeChanged(connection, index);
1183+ }
1184+ Component.onCompleted: type = connection.type
1185+ }
1186+
1187+ Label {
1188+ font.bold: true
1189+ color: Theme.palette.normal.baseText
1190+ elide: Text.ElideRight
1191+ text: i18n.dtr("ubuntu-settings-components", "User:")
1192+ }
1193+
1194+ TextField {
1195+ id: userField
1196+ anchors { left: parent.left; right: parent.right }
1197+ objectName: "vpnPptpUserField"
1198+ inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
1199+ text: connection.user
1200+ }
1201+
1202+ Label {
1203+ font.bold: true
1204+ color: Theme.palette.normal.baseText
1205+ elide: Text.ElideRight
1206+ text: i18n.dtr("ubuntu-settings-components", "Password:")
1207+ }
1208+
1209+ TextField {
1210+ id: passwordField
1211+ anchors { left: parent.left; right: parent.right }
1212+ objectName: "vpnPptpPasswordField"
1213+ echoMode: TextInput.Password
1214+ text: connection.password
1215+ }
1216+
1217+ Label {
1218+ font.bold: true
1219+ color: Theme.palette.normal.baseText
1220+ elide: Text.ElideRight
1221+ text: i18n.dtr("ubuntu-settings-components", "NT Domain:")
1222+ }
1223+
1224+ TextField {
1225+ id: domainField
1226+ anchors { left: parent.left; right: parent.right }
1227+ objectName: "vpnPptpDomainField"
1228+ inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
1229+ text: connection.domain
1230+ }
1231+
1232+ Label {
1233+ text: i18n.dtr("ubuntu-settings-components", "Authentication methods:")
1234+ font.bold: true
1235+ color: Theme.palette.normal.baseText
1236+ elide: Text.ElideRight
1237+ }
1238+
1239+ Column {
1240+ anchors { left: parent.left; right: parent.right }
1241+ spacing: units.gu(1)
1242+
1243+ ListItems.ThinDivider {}
1244+
1245+ RowLayout {
1246+ visible: !requireMppeToggle.checked
1247+
1248+ CheckBox {
1249+ id: allowPapToggle
1250+ objectName: "vpnPptpAllowPapToggle"
1251+ checked: connection.allowPap
1252+ activeFocusOnPress: false
1253+ }
1254+
1255+ Label {
1256+ text: "PAP"
1257+ Layout.fillWidth: true
1258+ }
1259+ }
1260+
1261+ RowLayout {
1262+ visible: !requireMppeToggle.checked
1263+
1264+ CheckBox {
1265+ id: allowChapToggle
1266+ objectName: "vpnPptpAllowChapToggle"
1267+ checked: connection.allowChap
1268+ activeFocusOnPress: false
1269+ }
1270+
1271+ Label {
1272+ text: "CHAP"
1273+ Layout.fillWidth: true
1274+ }
1275+ }
1276+
1277+ RowLayout {
1278+ CheckBox {
1279+ id: allowMschapToggle
1280+ objectName: "vpnPptpAllowMschapToggle"
1281+ checked: connection.allowMschap
1282+ activeFocusOnPress: false
1283+ }
1284+
1285+ Label {
1286+ text: "MSCHAP"
1287+ Layout.fillWidth: true
1288+ }
1289+ }
1290+
1291+ RowLayout {
1292+ CheckBox {
1293+ id: allowMschapv2Toggle
1294+ objectName: "vpnPptpAllowMschapv2Toggle"
1295+ checked: connection.allowMschapv2
1296+ activeFocusOnPress: false
1297+ }
1298+
1299+ Label {
1300+ text: "MSCHAPv2"
1301+ Layout.fillWidth: true
1302+ }
1303+ }
1304+
1305+ RowLayout {
1306+ visible: !requireMppeToggle.checked
1307+
1308+ CheckBox {
1309+ id: allowEapToggle
1310+ objectName: "vpnPptpAllowEapToggle"
1311+ checked: connection.allowEap
1312+ activeFocusOnPress: false
1313+ }
1314+
1315+ Label {
1316+ text: "EAP"
1317+ Layout.fillWidth: true
1318+ }
1319+ }
1320+
1321+ ListItems.ThinDivider {}
1322+ }
1323+
1324+ RowLayout {
1325+ CheckBox {
1326+ id: requireMppeToggle
1327+ objectName: "vpnPptpRequireMppeToggle"
1328+ checked: connection.requireMppe
1329+ activeFocusOnPress: false
1330+ }
1331+
1332+ Label {
1333+ text: i18n.dtr("ubuntu-settings-components", "Use Point-to-Point encryption")
1334+ Layout.fillWidth: true
1335+ }
1336+ }
1337+
1338+ ListItems.ItemSelector {
1339+ objectName: "vpnPptpMppeTypeSelector"
1340+ id: mppeTypeSelector
1341+ model: [
1342+ i18n.dtr("ubuntu-settings-components", "All Available (Default)"),
1343+ i18n.dtr("ubuntu-settings-components", "128-bit (most secure)"),
1344+ i18n.dtr("ubuntu-settings-components", "40-bit (less secure)")
1345+ ]
1346+ selectedIndex: connection.mppeType
1347+ enabled: requireMppeToggle.checked
1348+ }
1349+
1350+ RowLayout {
1351+ CheckBox {
1352+ id: mppeStatefulToggle
1353+ objectName: "vpnPptpMppeStatefulToggle"
1354+ checked: connection.mppeStateful
1355+ activeFocusOnPress: false
1356+ enabled: requireMppeToggle.checked
1357+ }
1358+
1359+ Label {
1360+ text: i18n.dtr("ubuntu-settings-components", "Allow stateful encryption")
1361+ Layout.fillWidth: true
1362+ }
1363+ }
1364+
1365+ RowLayout {
1366+ CheckBox {
1367+ id: bsdCompressionToggle
1368+ objectName: "vpnPptpBsdCompressionToggle"
1369+ checked: connection.bsdCompression
1370+ activeFocusOnPress: false
1371+ }
1372+
1373+ Label {
1374+ text: i18n.dtr("ubuntu-settings-components", "Allow BSD data compression")
1375+ Layout.fillWidth: true
1376+ }
1377+ }
1378+
1379+ RowLayout {
1380+ CheckBox {
1381+ id: deflateCompressionToggle
1382+ objectName: "vpnPptpDeflateCompressionToggle"
1383+ checked: connection.deflateCompression
1384+ activeFocusOnPress: false
1385+ }
1386+
1387+ Label {
1388+ text: i18n.dtr("ubuntu-settings-components", "Allow Deflate data compression")
1389+ Layout.fillWidth: true
1390+ }
1391+ }
1392+
1393+ RowLayout {
1394+ CheckBox {
1395+ id: tcpHeaderCompressionToggle
1396+ objectName: "vpnPptpHeaderCompressionToggle"
1397+ checked: connection.tcpHeaderCompression
1398+ activeFocusOnPress: false
1399+ }
1400+
1401+ Label {
1402+ text: i18n.dtr("ubuntu-settings-components", "Use TCP Header compression")
1403+ Layout.fillWidth: true
1404+ }
1405+ }
1406+
1407+ RowLayout {
1408+ CheckBox {
1409+ id: sendPppEchoPacketsToggle
1410+ objectName: "vpnPptpPppEchoPacketsToggle"
1411+ checked: connection.sendPppEchoPackets
1412+ activeFocusOnPress: false
1413+ }
1414+
1415+ Label {
1416+ text: i18n.dtr("ubuntu-settings-components", "Send PPP echo packets")
1417+ Layout.fillWidth: true
1418+ }
1419+ }
1420+}
1421
1422=== added file 'plugins/Ubuntu/Settings/Vpn/Pptp/Preview.qml'
1423--- plugins/Ubuntu/Settings/Vpn/Pptp/Preview.qml 1970-01-01 00:00:00 +0000
1424+++ plugins/Ubuntu/Settings/Vpn/Pptp/Preview.qml 2016-03-15 13:35:14 +0000
1425@@ -0,0 +1,61 @@
1426+/*
1427+ * Copyright (C) 2016 Canonical Ltd.
1428+ *
1429+ * This program is free software: you can redistribute it and/or modify it
1430+ * under the terms of the GNU Lesser General Public License version 3,
1431+ * as published by the Free Software Foundation.
1432+ *
1433+ * This program is distributed in the hope that it will be useful,
1434+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1435+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1436+ * GNU Lesser General Public License for more details.
1437+ *
1438+ * You should have received a copy of the GNU Lesser General Public License
1439+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1440+ */
1441+
1442+import QtQuick 2.4
1443+import Ubuntu.Components 1.3
1444+import Ubuntu.Settings.Vpn 0.1
1445+
1446+Column {
1447+ property var connection
1448+ property bool installed
1449+
1450+ // The order of which source to load is determined by the order in which
1451+ // they appear in the spec (starting with “This VPN is not safe to use.”)
1452+ // and ending with “You’re using this VPN for specific services.”.
1453+ // We do not currently deal with non-installed VPN connections, so we
1454+ // assume the connection to be installed.
1455+ function showPreview () {
1456+ var c = connection;
1457+
1458+ // “You’re using this VPN for all Internet traffic.”
1459+ if (c.active && !c.neverDefault) {
1460+ return contentLoader.setSource(
1461+ "../PreviewDialog/AllTrafficWithoutDns.qml"
1462+ );
1463+ }
1464+
1465+ // “This VPN is set up, but not in use now.”
1466+ if (!c.active) {
1467+ return contentLoader.setSource(
1468+ "../PreviewDialog/SetUpUnused.qml"
1469+ );
1470+ }
1471+
1472+ // “You’re using this VPN for specific services.”
1473+ if (c.active && c.neverDefault) {
1474+ return contentLoader.setSource(
1475+ "../PreviewDialog/SomeTraffic.qml"
1476+ );
1477+ }
1478+ }
1479+
1480+ Component.onCompleted: showPreview()
1481+
1482+ Loader {
1483+ id: contentLoader
1484+ anchors { left: parent.left; right: parent.right; }
1485+ }
1486+}
1487
1488=== added directory 'plugins/Ubuntu/Settings/Vpn/PreviewDialog'
1489=== added file 'plugins/Ubuntu/Settings/Vpn/PreviewDialog/AllTrafficWithDns.qml'
1490--- plugins/Ubuntu/Settings/Vpn/PreviewDialog/AllTrafficWithDns.qml 1970-01-01 00:00:00 +0000
1491+++ plugins/Ubuntu/Settings/Vpn/PreviewDialog/AllTrafficWithDns.qml 2016-03-15 13:35:14 +0000
1492@@ -0,0 +1,47 @@
1493+/*
1494+ * Copyright (C) 2016 Canonical Ltd.
1495+ *
1496+ * This program is free software: you can redistribute it and/or modify it
1497+ * under the terms of the GNU Lesser General Public License version 3,
1498+ * as published by the Free Software Foundation.
1499+ *
1500+ * This program is distributed in the hope that it will be useful,
1501+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1502+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1503+ * GNU Lesser General Public License for more details.
1504+ *
1505+ * You should have received a copy of the GNU Lesser General Public License
1506+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1507+ */
1508+
1509+import QtQuick 2.4
1510+import Ubuntu.Components 1.3
1511+
1512+Column {
1513+ spacing: units.gu(2)
1514+ objectName: "vpnPreviewAllTrafficWithDns"
1515+
1516+ Label {
1517+ wrapMode: Text.WordWrap
1518+ anchors { left: parent.left; right: parent.right; }
1519+ text: i18n.dtr("ubuntu-settings-components", "You’re using this VPN for all Internet traffic.")
1520+ }
1521+
1522+ Label {
1523+ wrapMode: Text.WordWrap
1524+ anchors { left: parent.left; right: parent.right; }
1525+ text: i18n.dtr("ubuntu-settings-components", "Your Wi-Fi/mobile provider can see when and how much you use the Internet, but not what for.")
1526+ }
1527+
1528+ Label {
1529+ wrapMode: Text.WordWrap
1530+ anchors { left: parent.left; right: parent.right; }
1531+ text: i18n.dtr("ubuntu-settings-components", "The VPN provider can see or modify your Internet traffic.")
1532+ }
1533+
1534+ Label {
1535+ wrapMode: Text.WordWrap
1536+ anchors { left: parent.left; right: parent.right; }
1537+ text: i18n.dtr("ubuntu-settings-components", "Web sites and other service providers can still monitor your use.")
1538+ }
1539+}
1540
1541=== added file 'plugins/Ubuntu/Settings/Vpn/PreviewDialog/AllTrafficWithoutDns.qml'
1542--- plugins/Ubuntu/Settings/Vpn/PreviewDialog/AllTrafficWithoutDns.qml 1970-01-01 00:00:00 +0000
1543+++ plugins/Ubuntu/Settings/Vpn/PreviewDialog/AllTrafficWithoutDns.qml 2016-03-15 13:35:14 +0000
1544@@ -0,0 +1,53 @@
1545+/*
1546+ * Copyright (C) 2016 Canonical Ltd.
1547+ *
1548+ * This program is free software: you can redistribute it and/or modify it
1549+ * under the terms of the GNU Lesser General Public License version 3,
1550+ * as published by the Free Software Foundation.
1551+ *
1552+ * This program is distributed in the hope that it will be useful,
1553+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1554+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1555+ * GNU Lesser General Public License for more details.
1556+ *
1557+ * You should have received a copy of the GNU Lesser General Public License
1558+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1559+ */
1560+
1561+import QtQuick 2.4
1562+import Ubuntu.Components 1.3
1563+
1564+Column {
1565+ spacing: units.gu(2)
1566+ objectName: "vpnPreviewAllTrafficWithoutDns"
1567+
1568+ Label {
1569+ wrapMode: Text.WordWrap
1570+ anchors { left: parent.left; right: parent.right; }
1571+ text: i18n.dtr("ubuntu-settings-components", "You’re using this VPN for all Internet traffic.")
1572+ }
1573+
1574+ Label {
1575+ wrapMode: Text.WordWrap
1576+ anchors { left: parent.left; right: parent.right; }
1577+ text: i18n.dtr("ubuntu-settings-components", "Your Wi-Fi/mobile provider can still see when and how much you use the Internet.")
1578+ }
1579+
1580+ Label {
1581+ wrapMode: Text.WordWrap
1582+ anchors { left: parent.left; right: parent.right; }
1583+ text: i18n.dtr("ubuntu-settings-components", "The DNS provider can see which Web sites and other services you use.")
1584+ }
1585+
1586+ Label {
1587+ wrapMode: Text.WordWrap
1588+ anchors { left: parent.left; right: parent.right; }
1589+ text: i18n.dtr("ubuntu-settings-components", "The VPN provider can see or modify your Internet traffic.")
1590+ }
1591+
1592+ Label {
1593+ wrapMode: Text.WordWrap
1594+ anchors { left: parent.left; right: parent.right; }
1595+ text: i18n.dtr("ubuntu-settings-components", "Web sites and other service providers can still monitor your use.")
1596+ }
1597+}
1598
1599=== added file 'plugins/Ubuntu/Settings/Vpn/PreviewDialog/CMakeLists.txt'
1600--- plugins/Ubuntu/Settings/Vpn/PreviewDialog/CMakeLists.txt 1970-01-01 00:00:00 +0000
1601+++ plugins/Ubuntu/Settings/Vpn/PreviewDialog/CMakeLists.txt 2016-03-15 13:35:14 +0000
1602@@ -0,0 +1,3 @@
1603+project(UbuntuSettingsVpnPreviewDialog)
1604+
1605+export_qmlfiles(Ubuntu.Settings.Vpn.PreviewDialog Ubuntu/Settings/Vpn/PreviewDialog DESTINATION ${QT_IMPORTS_DIR} ${ARGN})
1606
1607=== added file 'plugins/Ubuntu/Settings/Vpn/PreviewDialog/InvalidCert.qml'
1608--- plugins/Ubuntu/Settings/Vpn/PreviewDialog/InvalidCert.qml 1970-01-01 00:00:00 +0000
1609+++ plugins/Ubuntu/Settings/Vpn/PreviewDialog/InvalidCert.qml 2016-03-15 13:35:14 +0000
1610@@ -0,0 +1,69 @@
1611+/*
1612+ * Copyright (C) 2016 Canonical Ltd.
1613+ *
1614+ * This program is free software: you can redistribute it and/or modify it
1615+ * under the terms of the GNU Lesser General Public License version 3,
1616+ * as published by the Free Software Foundation.
1617+ *
1618+ * This program is distributed in the hope that it will be useful,
1619+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1620+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1621+ * GNU Lesser General Public License for more details.
1622+ *
1623+ * You should have received a copy of the GNU Lesser General Public License
1624+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1625+ */
1626+
1627+import QtQuick 2.4
1628+import Ubuntu.Components 1.3
1629+import Ubuntu.Settings.Vpn 0.1
1630+
1631+Column {
1632+ property var error
1633+
1634+ spacing: units.gu(2)
1635+ objectName: "vpnPreviewInvalidCert"
1636+
1637+ Label {
1638+ wrapMode: Text.WordWrap
1639+ anchors { left: parent.left; right: parent.right; }
1640+ text: i18n.dtr("ubuntu-settings-components", "This VPN is not safe to use.")
1641+ }
1642+
1643+ Label {
1644+ wrapMode: Text.WordWrap
1645+ anchors { left: parent.left; right: parent.right; }
1646+ text: i18n.dtr("ubuntu-settings-components", "The server certificate is not valid. The VPN provider may be being impersonated.")
1647+ }
1648+
1649+ Label {
1650+ objectName: "vpnPreviewInvalidCertErrorMsg"
1651+ wrapMode: Text.WordWrap
1652+ anchors { left: parent.left; right: parent.right; }
1653+ visible: error
1654+ text: {
1655+ // TRANSLATORS: %1 is a reason for why a VPN certificate was invalid.
1656+ var detailsLabel = i18n.dtr("ubuntu-settings-components", "Details: %1");
1657+ var errorMsg;
1658+
1659+ switch(error) {
1660+ case UbuntuSettingsVpn.CERT_NOT_FOUND:
1661+ errorMsg = i18n.dtr("ubuntu-settings-components", "The certificate was not found.");
1662+ break;
1663+ case UbuntuSettingsVpn.CERT_EMPTY:
1664+ errorMsg = i18n.dtr("ubuntu-settings-components", "The certificate is empty.");
1665+ break;
1666+ case UbuntuSettingsVpn.CERT_SELFSIGNED:
1667+ errorMsg = i18n.dtr("ubuntu-settings-components", "The certificate is self signed.");
1668+ break;
1669+ case UbuntuSettingsVpn.CERT_EXPIRED:
1670+ errorMsg = i18n.dtr("ubuntu-settings-components", "The certificate has expired.");
1671+ break;
1672+ case UbuntuSettingsVpn.CERT_BLACKLISTED:
1673+ errorMsg = i18n.dtr("ubuntu-settings-components", "The certificate is blacklisted.");
1674+ break;
1675+ }
1676+ return errorMsg ? detailsLabel.arg(errorMsg) : "";
1677+ }
1678+ }
1679+}
1680
1681=== added file 'plugins/Ubuntu/Settings/Vpn/PreviewDialog/NoCert.qml'
1682--- plugins/Ubuntu/Settings/Vpn/PreviewDialog/NoCert.qml 1970-01-01 00:00:00 +0000
1683+++ plugins/Ubuntu/Settings/Vpn/PreviewDialog/NoCert.qml 2016-03-15 13:35:14 +0000
1684@@ -0,0 +1,35 @@
1685+/*
1686+ * Copyright (C) 2016 Canonical Ltd.
1687+ *
1688+ * This program is free software: you can redistribute it and/or modify it
1689+ * under the terms of the GNU Lesser General Public License version 3,
1690+ * as published by the Free Software Foundation.
1691+ *
1692+ * This program is distributed in the hope that it will be useful,
1693+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1694+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1695+ * GNU Lesser General Public License for more details.
1696+ *
1697+ * You should have received a copy of the GNU Lesser General Public License
1698+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1699+ */
1700+
1701+import QtQuick 2.4
1702+import Ubuntu.Components 1.3
1703+
1704+Column {
1705+ spacing: units.gu(2)
1706+ objectName: "vpnPreviewNoCert"
1707+
1708+ Label {
1709+ wrapMode: Text.WordWrap
1710+ anchors { left: parent.left; right: parent.right; }
1711+ text: i18n.dtr("ubuntu-settings-components", "This VPN is not safe to use.")
1712+ }
1713+
1714+ Label {
1715+ wrapMode: Text.WordWrap
1716+ anchors { left: parent.left; right: parent.right; }
1717+ text: i18n.dtr("ubuntu-settings-components", "It does not provide a certificate. The VPN provider could be impersonated.")
1718+ }
1719+}
1720
1721=== added file 'plugins/Ubuntu/Settings/Vpn/PreviewDialog/NotInstalledWithRoutes.qml'
1722--- plugins/Ubuntu/Settings/Vpn/PreviewDialog/NotInstalledWithRoutes.qml 1970-01-01 00:00:00 +0000
1723+++ plugins/Ubuntu/Settings/Vpn/PreviewDialog/NotInstalledWithRoutes.qml 2016-03-15 13:35:14 +0000
1724@@ -0,0 +1,59 @@
1725+/*
1726+ * Copyright (C) 2016 Canonical Ltd.
1727+ *
1728+ * This program is free software: you can redistribute it and/or modify it
1729+ * under the terms of the GNU Lesser General Public License version 3,
1730+ * as published by the Free Software Foundation.
1731+ *
1732+ * This program is distributed in the hope that it will be useful,
1733+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1734+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1735+ * GNU Lesser General Public License for more details.
1736+ *
1737+ * You should have received a copy of the GNU Lesser General Public License
1738+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1739+ */
1740+
1741+import QtQuick 2.4
1742+import Ubuntu.Components 1.3
1743+
1744+Column {
1745+ spacing: units.gu(2)
1746+ objectName: "vpnPreviewNotInstalledWithRoutes"
1747+
1748+ Label {
1749+ wrapMode: Text.WordWrap
1750+ anchors { left: parent.left; right: parent.right; }
1751+ text: i18n.dtr("ubuntu-settings-components", "This VPN configuration is not installed.")
1752+ }
1753+
1754+ Label {
1755+ wrapMode: Text.WordWrap
1756+ anchors { left: parent.left; right: parent.right; }
1757+ text: i18n.dtr("ubuntu-settings-components", "If you install it:")
1758+ }
1759+
1760+ Label {
1761+ wrapMode: Text.WordWrap
1762+ anchors { left: parent.left; right: parent.right; }
1763+ text: i18n.dtr("ubuntu-settings-components", "Your Wi-Fi/mobile provider can see when and how much you use the Internet, but not what for.")
1764+ }
1765+
1766+ Label {
1767+ wrapMode: Text.WordWrap
1768+ anchors { left: parent.left; right: parent.right; }
1769+ text: i18n.dtr("ubuntu-settings-components", "The DNS provider can see which Web sites and other services you use.")
1770+ }
1771+
1772+ Label {
1773+ wrapMode: Text.WordWrap
1774+ anchors { left: parent.left; right: parent.right; }
1775+ text: i18n.dtr("ubuntu-settings-components", "The VPN provider can see or modify your Internet traffic.")
1776+ }
1777+
1778+ Label {
1779+ wrapMode: Text.WordWrap
1780+ anchors { left: parent.left; right: parent.right; }
1781+ text: i18n.dtr("ubuntu-settings-components", "Web sites and other service providers can still monitor your use.")
1782+ }
1783+}
1784
1785=== added file 'plugins/Ubuntu/Settings/Vpn/PreviewDialog/NotInstalledWithoutRoutes.qml'
1786--- plugins/Ubuntu/Settings/Vpn/PreviewDialog/NotInstalledWithoutRoutes.qml 1970-01-01 00:00:00 +0000
1787+++ plugins/Ubuntu/Settings/Vpn/PreviewDialog/NotInstalledWithoutRoutes.qml 2016-03-15 13:35:14 +0000
1788@@ -0,0 +1,59 @@
1789+/*
1790+ * Copyright (C) 2016 Canonical Ltd.
1791+ *
1792+ * This program is free software: you can redistribute it and/or modify it
1793+ * under the terms of the GNU Lesser General Public License version 3,
1794+ * as published by the Free Software Foundation.
1795+ *
1796+ * This program is distributed in the hope that it will be useful,
1797+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1798+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1799+ * GNU Lesser General Public License for more details.
1800+ *
1801+ * You should have received a copy of the GNU Lesser General Public License
1802+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1803+ */
1804+
1805+import QtQuick 2.4
1806+import Ubuntu.Components 1.3
1807+
1808+Column {
1809+ spacing: units.gu(2)
1810+ objectName: "vpnPreviewNotInstalledWithoutRoutes"
1811+
1812+ Label {
1813+ wrapMode: Text.WordWrap
1814+ anchors { left: parent.left; right: parent.right; }
1815+ text: i18n.dtr("ubuntu-settings-components", "This VPN configuration is not installed.")
1816+ }
1817+
1818+ Label {
1819+ wrapMode: Text.WordWrap
1820+ anchors { left: parent.left; right: parent.right; }
1821+ text: i18n.dtr("ubuntu-settings-components", "If you install it:")
1822+ }
1823+
1824+ Label {
1825+ wrapMode: Text.WordWrap
1826+ anchors { left: parent.left; right: parent.right; }
1827+ text: i18n.dtr("ubuntu-settings-components", "Your Wi-Fi/mobile provider can see when and how much you use the Internet, but not what for.")
1828+ }
1829+
1830+ Label {
1831+ wrapMode: Text.WordWrap
1832+ anchors { left: parent.left; right: parent.right; }
1833+ text: i18n.dtr("ubuntu-settings-components", "The DNS provider can see which Web sites and other services you use. ")
1834+ }
1835+
1836+ Label {
1837+ wrapMode: Text.WordWrap
1838+ anchors { left: parent.left; right: parent.right; }
1839+ text: i18n.dtr("ubuntu-settings-components", "The VPN provider can see or modify your Internet traffic.")
1840+ }
1841+
1842+ Label {
1843+ wrapMode: Text.WordWrap
1844+ anchors { left: parent.left; right: parent.right; }
1845+ text: i18n.dtr("ubuntu-settings-components", "Web sites and other service providers can still monitor your use.")
1846+ }
1847+}
1848
1849=== added file 'plugins/Ubuntu/Settings/Vpn/PreviewDialog/SetUpUnused.qml'
1850--- plugins/Ubuntu/Settings/Vpn/PreviewDialog/SetUpUnused.qml 1970-01-01 00:00:00 +0000
1851+++ plugins/Ubuntu/Settings/Vpn/PreviewDialog/SetUpUnused.qml 2016-03-15 13:35:14 +0000
1852@@ -0,0 +1,56 @@
1853+/*
1854+ * Copyright (C) 2016 Canonical Ltd.
1855+ *
1856+ * This program is free software: you can redistribute it and/or modify it
1857+ * under the terms of the GNU Lesser General Public License version 3,
1858+ * as published by the Free Software Foundation.
1859+ *
1860+ * This program is distributed in the hope that it will be useful,
1861+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1862+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1863+ * GNU Lesser General Public License for more details.
1864+ *
1865+ * You should have received a copy of the GNU Lesser General Public License
1866+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1867+ */
1868+
1869+import QtQuick 2.4
1870+import Ubuntu.Components 1.3
1871+
1872+Column {
1873+ spacing: units.gu(2)
1874+ objectName: "vpnPreviewSetUpUnused"
1875+
1876+ Label {
1877+ wrapMode: Text.WordWrap
1878+ anchors { left: parent.left; right: parent.right; }
1879+ text: i18n.dtr("ubuntu-settings-components", "This VPN is set up, but not in use now.")
1880+ }
1881+
1882+ Label {
1883+ wrapMode: Text.WordWrap
1884+ anchors { left: parent.left; right: parent.right; }
1885+ text: i18n.dtr("ubuntu-settings-components", "When you use it:")
1886+ }
1887+
1888+ Label {
1889+ wrapMode: Text.WordWrap
1890+ anchors { left: parent.left; right: parent.right; }
1891+ // TRANSLATORS: This describes the effect, should you enable the VPN.
1892+ text: i18n.dtr("ubuntu-settings-components", "Your Wi-Fi/mobile provider can see when and how much you use the Internet, but not what for.")
1893+ }
1894+
1895+ Label {
1896+ wrapMode: Text.WordWrap
1897+ anchors { left: parent.left; right: parent.right; }
1898+ // TRANSLATORS: This describes the effect, should you enable the VPN.
1899+ text: i18n.dtr("ubuntu-settings-components", "The VPN provider can see or modify your Internet traffic.")
1900+ }
1901+
1902+ Label {
1903+ wrapMode: Text.WordWrap
1904+ anchors { left: parent.left; right: parent.right; }
1905+ // TRANSLATORS: This describes the effect, should you enable the VPN.
1906+ text: i18n.dtr("ubuntu-settings-components", "Web sites and other service providers can still monitor your use.")
1907+ }
1908+}
1909
1910=== added file 'plugins/Ubuntu/Settings/Vpn/PreviewDialog/SomeTraffic.qml'
1911--- plugins/Ubuntu/Settings/Vpn/PreviewDialog/SomeTraffic.qml 1970-01-01 00:00:00 +0000
1912+++ plugins/Ubuntu/Settings/Vpn/PreviewDialog/SomeTraffic.qml 2016-03-15 13:35:14 +0000
1913@@ -0,0 +1,41 @@
1914+/*
1915+ * Copyright (C) 2016 Canonical Ltd.
1916+ *
1917+ * This program is free software: you can redistribute it and/or modify it
1918+ * under the terms of the GNU Lesser General Public License version 3,
1919+ * as published by the Free Software Foundation.
1920+ *
1921+ * This program is distributed in the hope that it will be useful,
1922+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1923+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1924+ * GNU Lesser General Public License for more details.
1925+ *
1926+ * You should have received a copy of the GNU Lesser General Public License
1927+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1928+ */
1929+
1930+import QtQuick 2.4
1931+import Ubuntu.Components 1.3
1932+
1933+Column {
1934+ spacing: units.gu(2)
1935+ objectName: "vpnPreviewSomeTraffic"
1936+
1937+ Label {
1938+ wrapMode: Text.WordWrap
1939+ anchors { left: parent.left; right: parent.right; }
1940+ text: i18n.dtr("ubuntu-settings-components", "You’re using this VPN for specific services.")
1941+ }
1942+
1943+ Label {
1944+ wrapMode: Text.WordWrap
1945+ anchors { left: parent.left; right: parent.right; }
1946+ text: i18n.dtr("ubuntu-settings-components", "Your traffic to these services is private to them and the VPN provider.")
1947+ }
1948+
1949+ Label {
1950+ wrapMode: Text.WordWrap
1951+ anchors { left: parent.left; right: parent.right; }
1952+ text: i18n.dtr("ubuntu-settings-components", "Your Wi-Fi/mobile provider can track your use of any other services. ")
1953+ }
1954+}
1955
1956=== added file 'plugins/Ubuntu/Settings/Vpn/VpnEditor.qml'
1957--- plugins/Ubuntu/Settings/Vpn/VpnEditor.qml 1970-01-01 00:00:00 +0000
1958+++ plugins/Ubuntu/Settings/Vpn/VpnEditor.qml 2016-03-15 13:35:14 +0000
1959@@ -0,0 +1,161 @@
1960+/*
1961+ * Copyright (C) 2016 Canonical Ltd.
1962+ *
1963+ * This program is free software: you can redistribute it and/or modify it
1964+ * under the terms of the GNU Lesser General Public License version 3,
1965+ * as published by the Free Software Foundation.
1966+ *
1967+ * This program is distributed in the hope that it will be useful,
1968+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1969+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1970+ * GNU Lesser General Public License for more details.
1971+ *
1972+ * You should have received a copy of the GNU Lesser General Public License
1973+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1974+ */
1975+
1976+import QtQuick 2.4
1977+import QtQuick.Layouts 1.1
1978+import Ubuntu.Components 1.3
1979+import Ubuntu.Components.ListItems 1.3 as ListItems
1980+
1981+Page {
1982+ id: editor
1983+ objectName: "vpnEditor"
1984+ title: i18n.dtr("ubuntu-settings-components", "Set up VPN")
1985+
1986+ property var connection
1987+
1988+ // If isNew, we delete it on cancel.
1989+ property var isNew
1990+
1991+ signal typeChanged(var connection, int type)
1992+ signal reconnectionPrompt()
1993+
1994+ function commit () {
1995+ editorLoader.item.state = 'committing';
1996+ var changes = editorLoader.item.getChanges();
1997+
1998+ for (var i = 0; i < changes.length; i++) {
1999+ var key = changes[i][0];
2000+ var value = changes[i][1];
2001+ connection[key] = value;
2002+ if (key == "gateway" || key == "remote") connection.id = value;
2003+ }
2004+ editorLoader.item.state = 'succeeded';
2005+ }
2006+
2007+ function render () {
2008+ connection.updateSecrets()
2009+
2010+ var props = {"connection": connection}
2011+ switch (connection.type) {
2012+ case 0: // Openvpn
2013+ editorLoader.setSource("Openvpn/Editor.qml", props)
2014+ break
2015+ case 1: // Pptp
2016+ editorLoader.setSource("Pptp/Editor.qml", props)
2017+ break
2018+ }
2019+ }
2020+
2021+ Component.onCompleted: render()
2022+
2023+ header: PageHeader {
2024+ title: editor.title
2025+ flickable: scrollWidget
2026+ leadingActionBar.actions: []
2027+ }
2028+
2029+ Component {
2030+ id: fileDialogComponent
2031+ DialogFile {
2032+ id: fileDialog
2033+ }
2034+ }
2035+
2036+ Flickable {
2037+ id: scrollWidget
2038+ anchors {
2039+ fill: parent
2040+ margins: units.gu(2)
2041+ }
2042+ contentHeight: contentItem.childrenRect.height
2043+ boundsBehavior: (contentHeight > editor.height) ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds
2044+
2045+ Column {
2046+ anchors { left: parent.left; right: parent.right }
2047+ spacing: units.gu(2)
2048+
2049+ Loader {
2050+ id: editorLoader
2051+ objectName: "editorLoader"
2052+ anchors.left: parent.left
2053+ anchors.right: parent.right
2054+ }
2055+
2056+ RowLayout {
2057+ anchors { left: parent.left; right: parent.right }
2058+
2059+ Button {
2060+ objectName: "vpnEditorCancelButton"
2061+ text: i18n.dtr("ubuntu-settings-components", "Cancel")
2062+ onClicked: {
2063+ if (editor.isNew) {
2064+ connection.remove();
2065+ }
2066+ pageStack.pop();
2067+ }
2068+ Layout.fillWidth: true
2069+ }
2070+
2071+ Button {
2072+ id: vpnEditorOkayButton
2073+ objectName: "vpnEditorOkayButton"
2074+ text: i18n.dtr("ubuntu-settings-components", "OK")
2075+ onClicked: editor.commit()
2076+ Layout.fillWidth: true
2077+ enabled: editorLoader.item.changed && editorLoader.item.valid
2078+
2079+ Icon {
2080+ height: parent.height - units.gu(1.5)
2081+ width: parent.height - units.gu(1.5)
2082+ anchors {
2083+ centerIn: parent
2084+ }
2085+ name: "tick"
2086+ color: "green"
2087+ visible: successIndicator.running
2088+ }
2089+
2090+ ActivityIndicator {
2091+ id: okButtonIndicator
2092+ objectName: "okButtonIndicator"
2093+ running: false
2094+ visible: running
2095+ height: parent.height - units.gu(1.5)
2096+ anchors {
2097+ centerIn: parent
2098+ }
2099+ }
2100+ }
2101+ }
2102+ }
2103+ }
2104+
2105+ // Timer that shows a tick in the connect button once we have
2106+ // successfully connected.
2107+ Timer {
2108+ id: successIndicator
2109+ objectName: "successIndicator"
2110+ interval: 2000
2111+ running: false
2112+ repeat: false
2113+ onTriggered: {
2114+ if (connection.active) {
2115+ editor.reconnectionPrompt();
2116+ }
2117+ pageStack.pop();
2118+ }
2119+ }
2120+}
2121
2122=== added file 'plugins/Ubuntu/Settings/Vpn/VpnList.qml'
2123--- plugins/Ubuntu/Settings/Vpn/VpnList.qml 1970-01-01 00:00:00 +0000
2124+++ plugins/Ubuntu/Settings/Vpn/VpnList.qml 2016-03-15 13:35:14 +0000
2125@@ -0,0 +1,68 @@
2126+/*
2127+ * Copyright (C) 2016 Canonical Ltd.
2128+ *
2129+ * This program is free software: you can redistribute it and/or modify it
2130+ * under the terms of the GNU Lesser General Public License version 3,
2131+ * as published by the Free Software Foundation.
2132+ *
2133+ * This program is distributed in the hope that it will be useful,
2134+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2135+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2136+ * GNU Lesser General Public License for more details.
2137+ *
2138+ * You should have received a copy of the GNU Lesser General Public License
2139+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2140+ */
2141+
2142+import QtQuick 2.4
2143+import Ubuntu.Components 1.3
2144+import Ubuntu.Components.Popups 1.3
2145+import Ubuntu.Settings.Vpn 0.1
2146+
2147+ListView {
2148+ objectName: "vpnList"
2149+
2150+ property var diag
2151+
2152+ signal clickedConnection(var connection)
2153+
2154+ anchors {
2155+ left: parent.left
2156+ right: parent.right
2157+ }
2158+
2159+ height: contentItem.height
2160+
2161+ delegate: ListItem {
2162+ objectName: "vpnListConnection" + index
2163+ height: layout.height + divider.height
2164+ onClicked: clickedConnection(connection)
2165+
2166+ ListItemLayout {
2167+ objectName: "vpnLayout"
2168+ id: layout
2169+ title.text: id
2170+
2171+ Switch {
2172+ SlotsLayout.position: SlotsLayout.Trailing;
2173+ id: vpnSwitch
2174+ objectName: "vpnSwitch"
2175+ enabled: activatable
2176+ Binding {target: vpnSwitch; property: "checked"; value: active}
2177+ onTriggered: active = !active
2178+ }
2179+ }
2180+
2181+ divider.visible: true
2182+
2183+ trailingActions: ListItemActions {
2184+ actions: [
2185+ Action {
2186+ iconName: "delete"
2187+ text: i18n.dtr("ubuntu-settings-components", "Delete configuration")
2188+ onTriggered: connection.remove()
2189+ }
2190+ ]
2191+ }
2192+ }
2193+}
2194
2195=== added file 'plugins/Ubuntu/Settings/Vpn/VpnPreviewDialog.qml'
2196--- plugins/Ubuntu/Settings/Vpn/VpnPreviewDialog.qml 1970-01-01 00:00:00 +0000
2197+++ plugins/Ubuntu/Settings/Vpn/VpnPreviewDialog.qml 2016-03-15 13:35:14 +0000
2198@@ -0,0 +1,116 @@
2199+/*
2200+ * Copyright (C) 2016 Canonical Ltd.
2201+ *
2202+ * This program is free software: you can redistribute it and/or modify it
2203+ * under the terms of the GNU Lesser General Public License version 3,
2204+ * as published by the Free Software Foundation.
2205+ *
2206+ * This program is distributed in the hope that it will be useful,
2207+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2208+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2209+ * GNU Lesser General Public License for more details.
2210+ *
2211+ * You should have received a copy of the GNU Lesser General Public License
2212+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2213+ */
2214+
2215+import QtQuick 2.4
2216+import QtQuick.Layouts 1.1
2217+import Ubuntu.Components 1.3
2218+import Ubuntu.Components.Popups 1.3
2219+
2220+Dialog {
2221+ objectName: "vpnPreviewDialog"
2222+ id: preview
2223+
2224+ // A connection we assume to be installed.
2225+ property var connection: null
2226+
2227+ // A configuration we assume is not installed.
2228+ // A configuration is expected to have a set of
2229+ // properties, just like a connection.
2230+ property var configuration: null
2231+
2232+ function getConnection () {
2233+ return connection ? connection : configuration;
2234+ }
2235+
2236+ function isInstalled () {
2237+ return !!connection;
2238+ }
2239+
2240+ signal changeClicked(var connection)
2241+ signal installClicked(var configuration)
2242+
2243+ Component.onCompleted: {
2244+ var source;
2245+ var conn = getConnection();
2246+
2247+ switch (conn.type) {
2248+ case 0: // Openvpn
2249+ source = "Openvpn/Preview.qml";
2250+ // TRANSLATORS: %1 is the hostname of a VPN connection
2251+ if (conn.remote) title = i18n.dtr("ubuntu-settings-components", "VPN “%1”").arg(conn.remote);
2252+ break;
2253+ case 1: // PPTP
2254+ source = "Pptp/Preview.qml";
2255+ // TRANSLATORS: %1 is the hostname of a VPN connection
2256+ if (conn.gateway) title = i18n.dtr("ubuntu-settings-components", "VPN “%1”").arg(conn.gateway);
2257+ break;
2258+ default: // Unknown
2259+ source = "";
2260+ break;
2261+ }
2262+
2263+ contentLoader.setSource(source, {
2264+ connection: getConnection(),
2265+ installed: isInstalled()
2266+ });
2267+ if (!title) title = i18n.dtr("ubuntu-settings-components", "VPN");
2268+ }
2269+
2270+ Loader {
2271+ id: contentLoader
2272+ anchors { left: parent.left; right: parent.right; }
2273+ }
2274+
2275+ RowLayout {
2276+ spacing: units.gu(2)
2277+
2278+ Button {
2279+ objectName: "vpnPreviewRemoveButton"
2280+ Layout.fillWidth: true
2281+ visible: connection !== null
2282+ text: i18n.dtr("ubuntu-settings-components", "Remove")
2283+ color: UbuntuColors.red
2284+ onClicked: {
2285+ connection.remove();
2286+ PopupUtils.close(preview);
2287+ }
2288+ }
2289+
2290+ Button {
2291+ objectName: "vpnPreviewChangeButton"
2292+ Layout.fillWidth: true
2293+ visible: connection !== null
2294+ text: i18n.dtr("ubuntu-settings-components", "Change")
2295+ onClicked: changeClicked(connection)
2296+ }
2297+
2298+ Button {
2299+ objectName: "vpnPreviewCancelButton"
2300+ Layout.fillWidth: true
2301+ visible: configuration !== null
2302+ text: i18n.dtr("ubuntu-settings-components", "Cancel")
2303+ onClicked: PopupUtils.close(preview)
2304+ }
2305+
2306+ Button {
2307+ objectName: "vpnPreviewInstallButton"
2308+ Layout.fillWidth: true
2309+ visible: configuration !== null
2310+ text: i18n.dtr("ubuntu-settings-components", "Install")
2311+ onClicked: installClicked(configuration)
2312+ }
2313+ }
2314+}
2315
2316=== added file 'plugins/Ubuntu/Settings/Vpn/VpnRoutesField.qml'
2317--- plugins/Ubuntu/Settings/Vpn/VpnRoutesField.qml 1970-01-01 00:00:00 +0000
2318+++ plugins/Ubuntu/Settings/Vpn/VpnRoutesField.qml 2016-03-15 13:35:14 +0000
2319@@ -0,0 +1,83 @@
2320+/*
2321+ * Copyright (C) 2016 Canonical Ltd.
2322+ *
2323+ * This program is free software: you can redistribute it and/or modify it
2324+ * under the terms of the GNU Lesser General Public License version 3,
2325+ * as published by the Free Software Foundation.
2326+ *
2327+ * This program is distributed in the hope that it will be useful,
2328+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2329+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2330+ * GNU Lesser General Public License for more details.
2331+ *
2332+ * You should have received a copy of the GNU Lesser General Public License
2333+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2334+ */
2335+
2336+import QtQuick 2.4
2337+import QtQuick.Layouts 1.1
2338+import Ubuntu.Components 1.3
2339+import Ubuntu.Components.ListItems 1.3 as ListItems
2340+
2341+Column {
2342+ id: routes
2343+ spacing: units.gu(1)
2344+
2345+ property alias neverDefault: ownNetworksToggle.checked
2346+ property bool enabled: true
2347+
2348+ Label {
2349+ text: i18n.dtr("ubuntu-settings-components", "Use this VPN for:")
2350+ font.bold: true
2351+ color: Theme.palette.normal.baseText
2352+ elide: Text.ElideRight
2353+ }
2354+
2355+ Column {
2356+ anchors { left: parent.left; right: parent.right }
2357+ spacing: units.gu(1)
2358+
2359+ ListItems.ThinDivider {}
2360+
2361+ RowLayout {
2362+ anchors { left: parent.left; right: parent.right }
2363+
2364+ CheckBox {
2365+ id: allNetworksToggle
2366+ objectName: "vpnAllNetworksToggle"
2367+ checked: !ownNetworksToggle.checked
2368+ onTriggered: {
2369+ ownNetworksToggle.checked = !checked;
2370+ checked = Qt.binding(function () {
2371+ return !ownNetworksToggle.checked
2372+ });
2373+ }
2374+ enabled: routes.enabled
2375+ activeFocusOnPress: false
2376+ }
2377+
2378+ Label {
2379+ text: i18n.dtr("ubuntu-settings-components", "All network connections")
2380+ Layout.fillWidth: true
2381+ }
2382+ }
2383+
2384+ RowLayout {
2385+ anchors { left: parent.left; right: parent.right }
2386+
2387+ CheckBox {
2388+ id: ownNetworksToggle
2389+ objectName: "vpnOwnNetworksToggle"
2390+ enabled: routes.enabled
2391+ activeFocusOnPress: false
2392+ }
2393+
2394+ Label {
2395+ text: i18n.dtr("ubuntu-settings-components", "Its own network")
2396+ Layout.fillWidth: true
2397+ }
2398+ }
2399+
2400+ ListItems.ThinDivider {}
2401+ }
2402+}
2403
2404=== added file 'plugins/Ubuntu/Settings/Vpn/VpnTypeField.qml'
2405--- plugins/Ubuntu/Settings/Vpn/VpnTypeField.qml 1970-01-01 00:00:00 +0000
2406+++ plugins/Ubuntu/Settings/Vpn/VpnTypeField.qml 2016-03-15 13:35:14 +0000
2407@@ -0,0 +1,54 @@
2408+/*
2409+ * Copyright (C) 2016 Canonical Ltd.
2410+ *
2411+ * This program is free software: you can redistribute it and/or modify it
2412+ * under the terms of the GNU Lesser General Public License version 3,
2413+ * as published by the Free Software Foundation.
2414+ *
2415+ * This program is distributed in the hope that it will be useful,
2416+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2417+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2418+ * GNU Lesser General Public License for more details.
2419+ *
2420+ * You should have received a copy of the GNU Lesser General Public License
2421+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2422+ */
2423+
2424+import QtQuick 2.4
2425+import QtQuick.Layouts 1.1
2426+import Ubuntu.Components 1.3
2427+import Ubuntu.Components.ListItems 1.3 as ListItems
2428+
2429+RowLayout {
2430+ spacing: units.gu(1)
2431+
2432+ property alias type: vpnTypeSelector.selectedIndex
2433+
2434+ // XXX: disabled due to lp:1551823 (pptp connections fails on arm)
2435+ property bool enabled: false
2436+ signal typeRequested(int index)
2437+
2438+ Label {
2439+ text: i18n.dtr("ubuntu-settings-components", "Type:")
2440+ enabled: parent.enabled
2441+ font.bold: true
2442+ color: Theme.palette.normal.baseText
2443+ elide: Text.ElideRight
2444+ horizontalAlignment: Text.AlignRight
2445+ Layout.fillWidth: true
2446+ }
2447+
2448+ ListItems.ItemSelector {
2449+ id: vpnTypeSelector
2450+ objectName: "vpnTypeField"
2451+ enabled: parent.enabled
2452+ model: [
2453+ i18n.dtr("ubuntu-settings-components", "OpenVPN"),
2454+ i18n.dtr("ubuntu-settings-components", "Pptp")
2455+ ]
2456+ expanded: false
2457+ onDelegateClicked: typeRequested(index)
2458+ Layout.preferredWidth: units.gu(30)
2459+ Layout.minimumHeight: currentlyExpanded ? itemHeight * model.length : itemHeight
2460+ }
2461+}
2462
2463=== added file 'plugins/Ubuntu/Settings/Vpn/plugin.cpp'
2464--- plugins/Ubuntu/Settings/Vpn/plugin.cpp 1970-01-01 00:00:00 +0000
2465+++ plugins/Ubuntu/Settings/Vpn/plugin.cpp 2016-03-15 13:35:14 +0000
2466@@ -0,0 +1,36 @@
2467+/*
2468+ * Copyright (C) 2016 Canonical, Ltd.
2469+ *
2470+ * This program is free software; you can redistribute it and/or modify
2471+ * it under the terms of the GNU Lesser General Public License as published by
2472+ * the Free Software Foundation; version 3.
2473+ *
2474+ * This program is distributed in the hope that it will be useful,
2475+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2476+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2477+ * GNU Lesser General Public License for more details.
2478+ *
2479+ * You should have received a copy of the GNU Lesser General Public License
2480+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2481+ */
2482+
2483+// local
2484+#include "plugin.h"
2485+#include "ubuntusettingsvpn.h"
2486+
2487+// Qt
2488+#include <QtQml/qqml.h>
2489+
2490+static QObject *ubuntuSettingsVpnSingeltonProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
2491+{
2492+ Q_UNUSED(engine)
2493+ Q_UNUSED(scriptEngine)
2494+
2495+ UbuntuSettingsVpn *vpn = new UbuntuSettingsVpn();
2496+ return vpn;
2497+}
2498+
2499+void UbuntuSettingsVpnPlugin::registerTypes(const char *uri)
2500+{
2501+ qmlRegisterSingletonType<UbuntuSettingsVpn>(uri, 0, 1, "UbuntuSettingsVpn", ubuntuSettingsVpnSingeltonProvider);
2502+}
2503
2504=== added file 'plugins/Ubuntu/Settings/Vpn/plugin.h'
2505--- plugins/Ubuntu/Settings/Vpn/plugin.h 1970-01-01 00:00:00 +0000
2506+++ plugins/Ubuntu/Settings/Vpn/plugin.h 2016-03-15 13:35:14 +0000
2507@@ -0,0 +1,30 @@
2508+/*
2509+ * Copyright (C) 2016 Canonical, Ltd.
2510+ *
2511+ * This program is free software; you can redistribute it and/or modify
2512+ * it under the terms of the GNU Lesser General Public License as published by
2513+ * the Free Software Foundation; version 3.
2514+ *
2515+ * This program is distributed in the hope that it will be useful,
2516+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2517+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2518+ * GNU Lesser General Public License for more details.
2519+ *
2520+ * You should have received a copy of the GNU Lesser General Public License
2521+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2522+ */
2523+
2524+#ifndef UBUNTUSETTINGSVPN_PLUGIN_H
2525+#define UBUNTUSETTINGSVPN_PLUGIN_H
2526+
2527+#include <QtQml/QQmlExtensionPlugin>
2528+
2529+class UbuntuSettingsVpnPlugin : public QQmlExtensionPlugin
2530+{
2531+ Q_OBJECT
2532+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
2533+public:
2534+ void registerTypes(const char *uri);
2535+};
2536+
2537+#endif // UBUNTUSETTINGSVPN_PLUGIN_H
2538
2539=== added file 'plugins/Ubuntu/Settings/Vpn/qmldir'
2540--- plugins/Ubuntu/Settings/Vpn/qmldir 1970-01-01 00:00:00 +0000
2541+++ plugins/Ubuntu/Settings/Vpn/qmldir 2016-03-15 13:35:14 +0000
2542@@ -0,0 +1,10 @@
2543+module Ubuntu.Settings.Vpn
2544+plugin UbuntuSettingsVpn
2545+
2546+singleton DialogFileProperties 0.1 DialogFileProperties.qml
2547+
2548+internal DialogFile DialogFile.qml
2549+
2550+VpnList 0.1 VpnList.qml
2551+VpnEditor 0.1 VpnEditor.qml
2552+VpnPreviewDialog 0.1 VpnPreviewDialog.qml
2553
2554=== added file 'plugins/Ubuntu/Settings/Vpn/ubuntusettingsvpn.cpp'
2555--- plugins/Ubuntu/Settings/Vpn/ubuntusettingsvpn.cpp 1970-01-01 00:00:00 +0000
2556+++ plugins/Ubuntu/Settings/Vpn/ubuntusettingsvpn.cpp 2016-03-15 13:35:14 +0000
2557@@ -0,0 +1,56 @@
2558+/*
2559+ * Copyright (C) 2016 Canonical, Ltd.
2560+ *
2561+ * This program is free software; you can redistribute it and/or modify
2562+ * it under the terms of the GNU Lesser General Public License as published by
2563+ * the Free Software Foundation; version 3.
2564+ *
2565+ * This program is distributed in the hope that it will be useful,
2566+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2567+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2568+ * GNU Lesser General Public License for more details.
2569+ *
2570+ * You should have received a copy of the GNU Lesser General Public License
2571+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2572+ */
2573+#include "ubuntusettingsvpn.h"
2574+
2575+#include <QDateTime>
2576+#include <QDebug>
2577+#include <QProcessEnvironment>
2578+#include <QSslCertificate>
2579+
2580+UbuntuSettingsVpn::UbuntuSettingsVpn(QObject* parent)
2581+ : QObject(parent)
2582+{
2583+}
2584+
2585+UbuntuSettingsVpn::CertificateError UbuntuSettingsVpn::isCertificateValid(const QString &path)
2586+{
2587+ // Allow certificate checks to be turned off.
2588+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
2589+ if (env.value("NO_SSL_CERTIFICATE_CHECK", "0") == "1") {
2590+ return UbuntuSettingsVpn::CertificateError::CERT_VALID;
2591+ }
2592+
2593+ QList<QSslCertificate> certs = QSslCertificate::fromPath(path);
2594+
2595+ if (certs.size() == 0 || certs.size() > 1) {
2596+ qWarning() << "None or multiple certificates found at" << path;
2597+ return UbuntuSettingsVpn::CertificateError::CERT_NOT_FOUND;
2598+ }
2599+
2600+ QSslCertificate cert = certs.at(0);
2601+
2602+ if (cert.isBlacklisted()) {
2603+ return UbuntuSettingsVpn::CertificateError::CERT_BLACKLISTED;
2604+ } else if (cert.isSelfSigned()) {
2605+ return UbuntuSettingsVpn::CertificateError::CERT_SELFSIGNED;
2606+ } else if (cert.expiryDate() < QDateTime::currentDateTime()) {
2607+ return UbuntuSettingsVpn::CertificateError::CERT_EXPIRED;
2608+ } else if (cert.isNull()) {
2609+ return UbuntuSettingsVpn::CertificateError::CERT_EMPTY;
2610+ }
2611+
2612+ return UbuntuSettingsVpn::CertificateError::CERT_VALID;
2613+}
2614
2615=== added file 'plugins/Ubuntu/Settings/Vpn/ubuntusettingsvpn.h'
2616--- plugins/Ubuntu/Settings/Vpn/ubuntusettingsvpn.h 1970-01-01 00:00:00 +0000
2617+++ plugins/Ubuntu/Settings/Vpn/ubuntusettingsvpn.h 2016-03-15 13:35:14 +0000
2618@@ -0,0 +1,46 @@
2619+/*
2620+ * Copyright (C) 2016 Canonical, Ltd.
2621+ *
2622+ * This program is free software; you can redistribute it and/or modify
2623+ * it under the terms of the GNU Lesser General Public License as published by
2624+ * the Free Software Foundation; version 3.
2625+ *
2626+ * This program is distributed in the hope that it will be useful,
2627+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2628+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2629+ * GNU Lesser General Public License for more details.
2630+ *
2631+ * You should have received a copy of the GNU Lesser General Public License
2632+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2633+ */
2634+
2635+#ifndef UBUNTUSETTINGSVPN_H
2636+#define UBUNTUSETTINGSVPN_H
2637+
2638+#include <QObject>
2639+
2640+class UbuntuSettingsVpn : public QObject
2641+{
2642+ Q_OBJECT
2643+
2644+
2645+public:
2646+ explicit UbuntuSettingsVpn(QObject* parent = nullptr);
2647+
2648+ enum CertificateError
2649+ {
2650+ CERT_VALID,
2651+ CERT_NOT_FOUND,
2652+ CERT_EMPTY,
2653+ CERT_SELFSIGNED,
2654+ CERT_EXPIRED,
2655+ CERT_BLACKLISTED
2656+ };
2657+ Q_ENUMS(CertificateError)
2658+
2659+ Q_INVOKABLE CertificateError isCertificateValid(const QString &path);
2660+
2661+private:
2662+};
2663+
2664+#endif // UBUNTUSETTINGSVPN_H
2665
2666=== modified file 'tests/qmltests/CMakeLists.txt'
2667--- tests/qmltests/CMakeLists.txt 2015-04-07 09:42:19 +0000
2668+++ tests/qmltests/CMakeLists.txt 2016-03-15 13:35:14 +0000
2669@@ -34,3 +34,9 @@
2670 add_qml_test(Menus TimeZoneMenu)
2671 add_qml_test(Menus TransferMenu)
2672
2673+add_qml_test(Vpn VpnList)
2674+add_qml_test(Vpn VpnEditor)
2675+add_qml_test(Vpn VpnOpenvpnEditor)
2676+add_qml_test(Vpn VpnPptpEditor)
2677+add_qml_test(Vpn VpnPreviewDialogCertificateChecks)
2678+add_qml_test(Vpn VpnPreviewDialog ENVIRONMENT NO_SSL_CERTIFICATE_CHECK=1)
2679
2680=== added directory 'tests/qmltests/Vpn'
2681=== added file 'tests/qmltests/Vpn/tst_VpnEditor.qml'
2682--- tests/qmltests/Vpn/tst_VpnEditor.qml 1970-01-01 00:00:00 +0000
2683+++ tests/qmltests/Vpn/tst_VpnEditor.qml 2016-03-15 13:35:14 +0000
2684@@ -0,0 +1,87 @@
2685+/*
2686+ * Copyright 2016 Canonical Ltd.
2687+ *
2688+ * This program is free software; you can redistribute it and/or modify
2689+ * it under the terms of the GNU Lesser General Public License as published by
2690+ * the Free Software Foundation; version 3.
2691+ *
2692+ * This program is distributed in the hope that it will be useful,
2693+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2694+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2695+ * GNU Lesser General Public License for more details.
2696+ *
2697+ * You should have received a copy of the GNU Lesser General Public License
2698+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2699+ *
2700+ * Authored by Jonas G. Drange <jonas.drange@canonical.com>
2701+ */
2702+
2703+import QtQuick 2.4
2704+import QtTest 1.0
2705+import Ubuntu.Test 0.1
2706+import Ubuntu.Settings.Vpn 0.1
2707+
2708+Item {
2709+ width: units.gu(42)
2710+ height: units.gu(75)
2711+
2712+ VpnEditor {
2713+ anchors.fill: parent
2714+ id: vpnEditor
2715+ }
2716+
2717+ Component {
2718+ id: vpnEditorPart
2719+ Item {
2720+ property bool changed: false
2721+ property bool valid: false
2722+ property var getChanges
2723+ }
2724+ }
2725+
2726+ UbuntuTestCase {
2727+ name: "VpnPptpEditor"
2728+ when: windowShown
2729+
2730+ function getLoader() {
2731+ return findChild(vpnEditor, "editorLoader");
2732+ }
2733+
2734+ function init() {
2735+ getLoader().sourceComponent = vpnEditorPart;
2736+ }
2737+
2738+ function test_editor_buttons_states_data() {
2739+ return [
2740+ { changed: false, valid: false, okayButtonEnabledTarget: false },
2741+ { changed: true, valid: true, okayButtonEnabledTarget: true },
2742+ { changed: true, valid: false, okayButtonEnabledTarget: false },
2743+ { changed: false, valid: true, okayButtonEnabledTarget: false }
2744+ ]
2745+ }
2746+
2747+ function test_editor_buttons_states(data) {
2748+ var okayButton = findChild(vpnEditor, "vpnEditorOkayButton");
2749+ var part = getLoader().item;
2750+ part.changed = data.changed;
2751+ part.valid = data.valid;
2752+ compare(okayButton.enabled, data.okayButtonEnabledTarget);
2753+ }
2754+
2755+ function test_commit() {
2756+ var item = getLoader().item;
2757+ vpnEditor.connection = { gateway: "old" };
2758+
2759+ // This function gets called by commit() and in it we
2760+ // make sure the state has changed. We also return a change
2761+ // to be committed.
2762+ item.getChanges = function () {
2763+ compare(item.state, "committing");
2764+ return [["gateway", "new"]];
2765+ }
2766+ vpnEditor.commit();
2767+ compare(item.state, "succeeded");
2768+ compare(vpnEditor.connection["gateway"], "new");
2769+ }
2770+ }
2771+}
2772
2773=== added file 'tests/qmltests/Vpn/tst_VpnList.qml'
2774--- tests/qmltests/Vpn/tst_VpnList.qml 1970-01-01 00:00:00 +0000
2775+++ tests/qmltests/Vpn/tst_VpnList.qml 2016-03-15 13:35:14 +0000
2776@@ -0,0 +1,132 @@
2777+/*
2778+ * Copyright 2016 Canonical Ltd.
2779+ *
2780+ * This program is free software; you can redistribute it and/or modify
2781+ * it under the terms of the GNU Lesser General Public License as published by
2782+ * the Free Software Foundation; version 3.
2783+ *
2784+ * This program is distributed in the hope that it will be useful,
2785+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2786+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2787+ * GNU Lesser General Public License for more details.
2788+ *
2789+ * You should have received a copy of the GNU Lesser General Public License
2790+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2791+ *
2792+ * Authored by Jonas G. Drange <jonas.drange@canonical.com>
2793+ */
2794+
2795+import QtQuick 2.4
2796+import QtTest 1.0
2797+import Ubuntu.Test 0.1
2798+import Ubuntu.Settings.Vpn 0.1
2799+
2800+Item {
2801+ width: units.gu(42)
2802+ height: units.gu(75)
2803+
2804+ Flickable {
2805+ id: flickable
2806+
2807+ anchors.fill: parent
2808+ contentWidth: column.width
2809+ contentHeight: column.height
2810+
2811+ Column {
2812+ id: column
2813+
2814+ width: flickable.width
2815+ height: childrenRect.height
2816+
2817+ VpnList {
2818+ id: vpnList
2819+ anchors { left: parent.left; right: parent.right }
2820+ model: ListModel { id: vpnModel }
2821+ }
2822+ }
2823+ }
2824+
2825+ SignalSpy {
2826+ id: connClickedSpy
2827+ signalName: "clickedConnection"
2828+ target: vpnList
2829+ }
2830+
2831+ UbuntuTestCase {
2832+ name: "VpnList"
2833+ when: windowShown
2834+
2835+ function first() {
2836+ return findChild(vpnList, "vpnListConnection" + 0);
2837+ }
2838+
2839+ function cleanup() {
2840+ vpnModel.clear();
2841+ connClickedSpy.clear();
2842+ }
2843+
2844+ function test_list_item_rendering_data() {
2845+ return [
2846+ {
2847+ tag: "inactive",
2848+ connection: {
2849+ id: 'inactive vpn',
2850+ activatable: true,
2851+ active: false
2852+ }
2853+ },
2854+ {
2855+ tag: "enabled",
2856+ connection: {
2857+ id: 'active vpn',
2858+ activatable: true,
2859+ active: true
2860+ }
2861+ },
2862+ {
2863+ tag: "disabled",
2864+ connection: {
2865+ id: 'bad vpn',
2866+ activatable: false,
2867+ active: false
2868+ }
2869+ }
2870+ ]
2871+ }
2872+
2873+ // Test the VPN connection as it appears in the VpnList
2874+ function test_list_item_rendering(data) {
2875+ var c = data.connection;
2876+ vpnModel.append(c);
2877+
2878+ // !! turns first() into a bool, which we compare with the
2879+ // expected value.
2880+ tryCompareFunction(function () { return !!first() }, true);
2881+
2882+ var conn = first();
2883+ var layout = findChild(conn, "vpnLayout");
2884+ var trigger = findChild(conn, "vpnSwitch");
2885+ compare(layout.title.text, c.id);
2886+ compare(trigger.enabled, c.activatable);
2887+ compare(trigger.checked, c.active);
2888+ }
2889+
2890+ function test_custom_click_event_data() {
2891+ return [
2892+ { tag: "openvpn", type: 0, id: "openvpn", active: false, activatable: false, connection: {}},
2893+ { tag: "pptp", type: 1, id: "pptp", active: false, activatable: false, connection: {}}
2894+ ]
2895+ }
2896+
2897+ // Make sure the custom click event is emitted for a connection
2898+ function test_custom_click_event(data) {
2899+ vpnModel.append(data);
2900+ // Wait until first() returns the first vpn list element
2901+ tryCompareFunction(function () { return typeof first() }, "object");
2902+
2903+ var conn = first();
2904+ mouseClick(conn, conn.width / 2, conn.height / 2);
2905+ compare(connClickedSpy.count > 0, true, "connection click should have been triggered");
2906+ }
2907+ }
2908+}
2909
2910=== added file 'tests/qmltests/Vpn/tst_VpnOpenvpnEditor.qml'
2911--- tests/qmltests/Vpn/tst_VpnOpenvpnEditor.qml 1970-01-01 00:00:00 +0000
2912+++ tests/qmltests/Vpn/tst_VpnOpenvpnEditor.qml 2016-03-15 13:35:14 +0000
2913@@ -0,0 +1,183 @@
2914+/*
2915+ * Copyright 2016 Canonical Ltd.
2916+ *
2917+ * This program is free software; you can redistribute it and/or modify
2918+ * it under the terms of the GNU Lesser General Public License as published by
2919+ * the Free Software Foundation; version 3.
2920+ *
2921+ * This program is distributed in the hope that it will be useful,
2922+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2923+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2924+ * GNU Lesser General Public License for more details.
2925+ *
2926+ * You should have received a copy of the GNU Lesser General Public License
2927+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2928+ *
2929+ * Authored by Jonas G. Drange <jonas.drange@canonical.com>
2930+ */
2931+
2932+import QtQuick 2.4
2933+import QtTest 1.0
2934+import Ubuntu.Test 0.1
2935+import Ubuntu.Settings.Vpn 0.1
2936+
2937+Item {
2938+ width: units.gu(42)
2939+ height: units.gu(75)
2940+
2941+ VpnEditor {
2942+ anchors.fill: parent
2943+ id: vpnEditor
2944+ }
2945+
2946+ UbuntuTestCase {
2947+ name: "VpnOpenvpnEditor"
2948+ when: windowShown
2949+
2950+ function getLoader() {
2951+ return findChild(vpnEditor, "editorLoader");
2952+ }
2953+
2954+ function init () {
2955+ waitForRendering(vpnEditor);
2956+ vpnEditor.connection = {
2957+ id: "openvpn connection",
2958+ type: 0, // openvpn
2959+ remote: "",
2960+ portSet: false,
2961+ port: 1194,
2962+ neverDefault: false,
2963+ protoTcp: true,
2964+ cert: "cert.pem",
2965+ ca: "cert.ca",
2966+ key: "cert.key",
2967+ certPass: "foo",
2968+ ta: "cert.ta",
2969+ taSet: true,
2970+ taDir: 1,
2971+ remoteCertTlsSet: true,
2972+ remoteCertTls: 0,
2973+ cipher: 8,
2974+ compLzo: true,
2975+ updateSecrets: function () {}
2976+ }
2977+ vpnEditor.render();
2978+
2979+ // Wait until we've loaded
2980+ tryCompareFunction(function () { return typeof getLoader() }, "object");
2981+ tryCompareFunction(function () { return getLoader().status }, Loader.Ready);
2982+ }
2983+
2984+ function test_fields() {
2985+ var e = getLoader().item;
2986+ var c = vpnEditor.connection;
2987+ var serverField = findChild(e, "vpnOpenvpnServerField");
2988+ var portField = findChild(e, "vpnOpenvpnPortField");
2989+ var portToggle = findChild(e, "vpnOpenvpnCustomPortToggle");
2990+ var routesField = findChild(e, "vpnOpenvpnRoutesField");
2991+ var tcpToggle = findChild(e, "vpnOpenvpnTcpToggle");
2992+ var udpToggle = findChild(e, "vpnOpenvpnUdpToggle");
2993+ var certField = findChild(e, "vpnOpenvpnCertField");
2994+ var caField = findChild(e, "vpnOpenvpnCaField");
2995+ var keyField = findChild(e, "vpnOpenvpnKeyField");
2996+ var certPassField = findChild(e, "vpnOpenvpnCertPassField");
2997+ var taSetToggle = findChild(e, "vpnOpenvpnTaSetToggle");
2998+ var taField = findChild(e, "vpnOpenvpnTaField");
2999+ var taDirSelector = findChild(e, "vpnOpenvpnTaDirSelector");
3000+ var certSetToggle = findChild(e, "vpnOpenvpnRemoteCertSetToggle");
3001+ var certTlsSelector = findChild(e, "vpnOpenvpnRemoteCertTlsSelector");
3002+ var cipherSelector = findChild(e, "vpnOpenvpnCipherSelector");
3003+ var compressionToggle = findChild(e, "vpnOpenvpnCompressionToggle");
3004+
3005+ compare(serverField.text, c.remote);
3006+ compare(parseInt(portField.text, 10), c.port);
3007+ compare(portToggle.checked, c.portSet);
3008+ compare(routesField.neverDefault, c.neverDefault);
3009+ compare(tcpToggle.checked, c.protoTcp);
3010+ compare(udpToggle.checked, !c.protoTcp);
3011+ compare(certField.path, c.cert);
3012+ compare(caField.path, c.ca);
3013+ compare(keyField.path, c.key);
3014+ compare(certPassField.text, c.certPass);
3015+ compare(taSetToggle.checked, c.taSet);
3016+ compare(taField.path, c.ta);
3017+ compare(taDirSelector.selectedIndex, c.taDir);
3018+ compare(certSetToggle.checked, c.remoteCertTlsSet);
3019+ compare(certTlsSelector.selectedIndex, c.remoteCertTls);
3020+ compare(cipherSelector.selectedIndex, c.cipher);
3021+ compare(compressionToggle.checked, c.compLzo);
3022+ }
3023+
3024+ // Test that the two checkboxes function as radio button
3025+ function test_tcp_udp_toggle() {
3026+ var e = getLoader().item;
3027+ var c = vpnEditor.connection;
3028+ var tcpToggle = findChild(e, "vpnOpenvpnTcpToggle");
3029+ var udpToggle = findChild(e, "vpnOpenvpnUdpToggle");
3030+ compare(tcpToggle.checked, c.protoTcp);
3031+ compare(udpToggle.checked, !c.protoTcp);
3032+
3033+ mouseClick(udpToggle, udpToggle.width / 2, udpToggle.height / 2);
3034+ compare(udpToggle.checked, true);
3035+ compare(tcpToggle.checked, false);
3036+ }
3037+
3038+ function test_changes() {
3039+ var e = getLoader().item;
3040+ var c = vpnEditor.connection;
3041+ var serverField = findChild(e, "vpnOpenvpnServerField");
3042+ var portField = findChild(e, "vpnOpenvpnPortField");
3043+ var portToggle = findChild(e, "vpnOpenvpnCustomPortToggle");
3044+
3045+ compare(e.getChanges(), []);
3046+
3047+ // make some changes
3048+ serverField.text = "new remote";
3049+ portToggle.checked = !c.portSet;
3050+ portField.text = "50000";
3051+
3052+ compare(e.getChanges(), [
3053+ ["remote", serverField.text],
3054+ ["portSet", portToggle.checked],
3055+ ["port", parseInt(portField.text, 10)],
3056+ ]);
3057+ }
3058+
3059+ function test_validity() {
3060+ compare(getLoader().item.valid, true);
3061+ }
3062+
3063+ function test_route_toggle() {
3064+ var all = findChild(vpnEditor, "vpnAllNetworksToggle");
3065+ var own = findChild(vpnEditor, "vpnOwnNetworksToggle");
3066+
3067+ verify(all.checked);
3068+ verify(!own.checked);
3069+
3070+ mouseClick(own, own.width / 2, own.height / 2);
3071+
3072+ verify(!all.checked);
3073+ verify(own.checked);
3074+ }
3075+
3076+ function test_file_selector() {
3077+ var selector = findChild(vpnEditor, "vpnOpenvpnCaField");
3078+ var noop = function() {}
3079+ selector.__dialog = {
3080+ accept: { connect: noop, disconnect: noop },
3081+ reject: { connect: noop, disconnect: noop },
3082+ hide: noop
3083+ };
3084+
3085+ compare(selector.model.length, 3);
3086+ compare(selector.model[0], i18n.tr("None"));
3087+ compare(selector.model[1], "cert.ca");
3088+ compare(selector.model[2], i18n.tr("Choose Certificate…"));
3089+
3090+ selector.pathAccepted("");
3091+ compare(selector.model.length, 2);
3092+ compare(selector.model[0], i18n.tr("None"));
3093+ compare(selector.model[1], i18n.tr("Choose Certificate…"));
3094+ }
3095+ }
3096+}
3097
3098=== added file 'tests/qmltests/Vpn/tst_VpnPptpEditor.qml'
3099--- tests/qmltests/Vpn/tst_VpnPptpEditor.qml 1970-01-01 00:00:00 +0000
3100+++ tests/qmltests/Vpn/tst_VpnPptpEditor.qml 2016-03-15 13:35:14 +0000
3101@@ -0,0 +1,145 @@
3102+/*
3103+ * Copyright 2016 Canonical Ltd.
3104+ *
3105+ * This program is free software; you can redistribute it and/or modify
3106+ * it under the terms of the GNU Lesser General Public License as published by
3107+ * the Free Software Foundation; version 3.
3108+ *
3109+ * This program is distributed in the hope that it will be useful,
3110+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3111+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3112+ * GNU Lesser General Public License for more details.
3113+ *
3114+ * You should have received a copy of the GNU Lesser General Public License
3115+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3116+ *
3117+ * Authored by Jonas G. Drange <jonas.drange@canonical.com>
3118+ */
3119+
3120+import QtQuick 2.4
3121+import QtTest 1.0
3122+import Ubuntu.Test 0.1
3123+import Ubuntu.Settings.Vpn 0.1
3124+
3125+Item {
3126+ width: units.gu(42)
3127+ height: units.gu(75)
3128+
3129+ VpnEditor {
3130+ anchors.fill: parent
3131+ id: vpnEditor
3132+ }
3133+
3134+ UbuntuTestCase {
3135+ name: "VpnPptpEditor"
3136+ when: windowShown
3137+
3138+ function getLoader() {
3139+ return findChild(vpnEditor, "editorLoader");
3140+ }
3141+
3142+ function init () {
3143+ waitForRendering(vpnEditor);
3144+ vpnEditor.connection = {
3145+ type: 1, // pptp
3146+ gateway: "",
3147+ neverDefault: false,
3148+ user: "",
3149+ password: "",
3150+ domain: "",
3151+ requireMppe: false,
3152+ mppeType: 0,
3153+ mppeStateful: false,
3154+ allowPap: true,
3155+ allowChap: true,
3156+ allowMschap: true,
3157+ allowMschapv2: true,
3158+ allowEap: true,
3159+ bsdCompression: true,
3160+ deflateCompression: true,
3161+ tcpHeaderCompression: true,
3162+ sendPppEchoPackets: false,
3163+ updateSecrets: function () {}
3164+ }
3165+ vpnEditor.render();
3166+
3167+ // Wait until we've loaded
3168+ tryCompareFunction(function () { return typeof getLoader() }, "object");
3169+ tryCompareFunction(function () { return getLoader().status }, Loader.Ready);
3170+ }
3171+
3172+ function test_fields() {
3173+ var e = getLoader().item;
3174+ var c = vpnEditor.connection;
3175+ var gatewayField = findChild(e, "vpnPptpGatewayField");
3176+ var routesField = findChild(e, "vpnPptpRoutesField");
3177+ var userField = findChild(e, "vpnPptpUserField");
3178+ var passwordField = findChild(e, "vpnPptpPasswordField");
3179+ var domainField = findChild(e, "vpnPptpDomainField");
3180+ var requireMppeToggle = findChild(e, "vpnPptpRequireMppeToggle");
3181+ var mppeTypeSelector = findChild(e, "vpnPptpMppeTypeSelector");
3182+ var mppeStatefulToggle = findChild(e, "vpnPptpMppeStatefulToggle");
3183+ var allowPapToggle = findChild(e, "vpnPptpAllowPapToggle");
3184+ var allowChapToggle = findChild(e, "vpnPptpAllowChapToggle");
3185+ var allowMschapToggle = findChild(e, "vpnPptpAllowMschapToggle");
3186+ var allowMschapv2Toggle = findChild(e, "vpnPptpAllowMschapv2Toggle");
3187+ var allowEapToggle = findChild(e, "vpnPptpAllowEapToggle");
3188+ var bsdCompressionToggle = findChild(e, "vpnPptpBsdCompressionToggle");
3189+ var deflateCompressionToggle = findChild(e, "vpnPptpDeflateCompressionToggle");
3190+ var tcpHeaderCompressionToggle = findChild(e, "vpnPptpHeaderCompressionToggle");
3191+ var sendPppEchoPacketsToggle = findChild(e, "vpnPptpPppEchoPacketsToggle");
3192+
3193+ compare(gatewayField.text, c.gateway);
3194+ compare(routesField.neverDefault, c.neverDefault);
3195+ compare(userField.text, c.user);
3196+ compare(passwordField.text, c.password);
3197+ compare(domainField.text, c.domain);
3198+ compare(requireMppeToggle.checked, c.requireMppe);
3199+ compare(mppeTypeSelector.selectedIndex, c.mppeType);
3200+ compare(mppeStatefulToggle.checked, c.mppeStateful);
3201+ compare(allowPapToggle.checked, c.allowPap);
3202+ compare(allowChapToggle.checked, c.allowChap);
3203+ compare(allowMschapToggle.checked, c.allowMschap);
3204+ compare(allowMschapv2Toggle.checked, c.allowMschapv2);
3205+ compare(allowEapToggle.checked, c.allowEap);
3206+ compare(bsdCompressionToggle.checked, c.bsdCompression);
3207+ compare(deflateCompressionToggle.checked, c.deflateCompression);
3208+ compare(tcpHeaderCompressionToggle.checked, c.tcpHeaderCompression);
3209+ compare(sendPppEchoPacketsToggle.checked, c.sendPppEchoPackets);
3210+ }
3211+
3212+ function test_changes() {
3213+ var e = getLoader().item;
3214+ var c = vpnEditor.connection;
3215+ var gatewayField = findChild(e, "vpnPptpGatewayField");
3216+ var userField = findChild(e, "vpnPptpUserField");
3217+ var passwordField = findChild(e, "vpnPptpPasswordField");
3218+ var bsdCompressionToggle = findChild(e, "vpnPptpBsdCompressionToggle");
3219+
3220+ compare(e.getChanges(), []);
3221+
3222+ // make some changes
3223+ gatewayField.text = "new gateway";
3224+ userField.text = "mark";
3225+ passwordField.text = "1234";
3226+ bsdCompressionToggle.checked = !c.bsdCompression;
3227+
3228+ compare(e.getChanges(), [
3229+ ["gateway", gatewayField.text],
3230+ ["user", userField.text],
3231+ ["password", passwordField.text],
3232+ ["bsdCompression", bsdCompressionToggle.checked]
3233+ ]);
3234+ }
3235+
3236+ function test_validity() {
3237+ var e = getLoader().item;
3238+ compare(getLoader().item.valid, false);
3239+
3240+ // Make valid
3241+ findChild(e, "vpnPptpPasswordField").text = "1234";
3242+
3243+ compare(getLoader().item.valid, true);
3244+ }
3245+ }
3246+}
3247
3248=== added file 'tests/qmltests/Vpn/tst_VpnPreviewDialog.qml'
3249--- tests/qmltests/Vpn/tst_VpnPreviewDialog.qml 1970-01-01 00:00:00 +0000
3250+++ tests/qmltests/Vpn/tst_VpnPreviewDialog.qml 2016-03-15 13:35:14 +0000
3251@@ -0,0 +1,142 @@
3252+/*
3253+ * Copyright 2016 Canonical Ltd.
3254+ *
3255+ * This program is free software; you can redistribute it and/or modify
3256+ * it under the terms of the GNU Lesser General Public License as published by
3257+ * the Free Software Foundation; version 3.
3258+ *
3259+ * This program is distributed in the hope that it will be useful,
3260+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3261+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3262+ * GNU Lesser General Public License for more details.
3263+ *
3264+ * You should have received a copy of the GNU Lesser General Public License
3265+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3266+ *
3267+ * Authored by Jonas G. Drange <jonas.drange@canonical.com>
3268+ */
3269+
3270+import QtQuick 2.4
3271+import QtTest 1.0
3272+import Ubuntu.Components.Popups 1.3
3273+import Ubuntu.Test 0.1
3274+import Ubuntu.Settings.Vpn 0.1
3275+
3276+Item {
3277+ width: units.gu(42)
3278+ height: units.gu(75)
3279+
3280+ id: root
3281+ property var d
3282+
3283+ Component {
3284+ id: diag
3285+ VpnPreviewDialog {
3286+
3287+ }
3288+ }
3289+
3290+ // In these tests, all CA certificates are going to be okay due to
3291+ // NO_SSL_CERTIFICATE_CHECK env variable being set to 1.
3292+ UbuntuTestCase {
3293+ name: "VpnPreviewDialog"
3294+ when: windowShown
3295+
3296+ function cleanup() {
3297+ PopupUtils.close(d);
3298+ }
3299+
3300+ function test_preview_dialog_data() {
3301+ return [
3302+ {
3303+ tag: "openvpn upunused",
3304+ connection: {
3305+ id: 'openvpn unused',
3306+ remote: "ubuntu.com",
3307+ type: 0, // openvpn
3308+ ca: "okay",
3309+ active: false,
3310+ neverDefault: false
3311+ },
3312+ targetObject: "vpnPreviewSetUpUnused"
3313+ },
3314+ {
3315+ tag: "openvpn all",
3316+ connection: {
3317+ id: 'openvpn all',
3318+ remote: "ubuntu.com",
3319+ type: 0, // openvpn
3320+ ca: "okay",
3321+ active: true,
3322+ neverDefault: false
3323+ },
3324+ targetObject: "vpnPreviewAllTrafficWithoutDns"
3325+ },
3326+ {
3327+ tag: "openvpn some",
3328+ connection: {
3329+ id: 'openvpn some',
3330+ remote: "ubuntu.com",
3331+ type: 0, // openvpn
3332+ ca: "okay",
3333+ active: true,
3334+ neverDefault: false
3335+ },
3336+ targetObject: "vpnPreviewAllTrafficWithoutDns"
3337+ },
3338+ {
3339+ tag: "openvpn no ca",
3340+ connection: {
3341+ id: 'openvpn no ca',
3342+ remote: "ubuntu.com",
3343+ type: 0, // openvpn
3344+ active: true,
3345+ neverDefault: false
3346+ },
3347+ targetObject: "vpnPreviewNoCert"
3348+ },
3349+ {
3350+ tag: "pptp all",
3351+ connection: {
3352+ id: 'pptp all',
3353+ gateway: "ubuntu.com",
3354+ type: 1, // pptp
3355+ active: true,
3356+ neverDefault: false
3357+ },
3358+ targetObject: "vpnPreviewAllTrafficWithoutDns"
3359+ },
3360+ {
3361+ tag: "pptp unused",
3362+ connection: {
3363+ id: 'pptp unused',
3364+ gateway: "ubuntu.com",
3365+ type: 1, // pptp
3366+ active: false,
3367+ neverDefault: false
3368+ },
3369+ targetObject: "vpnPreviewSetUpUnused"
3370+ },
3371+ {
3372+ tag: "pptp some",
3373+ connection: {
3374+ id: 'pptp some',
3375+ gateway: "ubuntu.com",
3376+ type: 1, // pptp
3377+ active: true,
3378+ neverDefault: true
3379+ },
3380+ targetObject: "vpnPreviewSomeTraffic"
3381+ }
3382+ ]
3383+ }
3384+
3385+ function test_preview_dialog(data) {
3386+ root.d = PopupUtils.open(diag, null, data);
3387+ waitForRendering(root.d);
3388+ var target = findChild(root.d, data.targetObject);
3389+ verify(target, "found obj " + data.targetObject);
3390+ compare(root.d.title, i18n.tr("VPN “%1”").arg(data.connection.remote || data.connection.gateway));
3391+ }
3392+ }
3393+}
3394
3395=== added file 'tests/qmltests/Vpn/tst_VpnPreviewDialogCertificateChecks.qml'
3396--- tests/qmltests/Vpn/tst_VpnPreviewDialogCertificateChecks.qml 1970-01-01 00:00:00 +0000
3397+++ tests/qmltests/Vpn/tst_VpnPreviewDialogCertificateChecks.qml 2016-03-15 13:35:14 +0000
3398@@ -0,0 +1,75 @@
3399+/*
3400+ * Copyright 2016 Canonical Ltd.
3401+ *
3402+ * This program is free software; you can redistribute it and/or modify
3403+ * it under the terms of the GNU Lesser General Public License as published by
3404+ * the Free Software Foundation; version 3.
3405+ *
3406+ * This program is distributed in the hope that it will be useful,
3407+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3408+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3409+ * GNU Lesser General Public License for more details.
3410+ *
3411+ * You should have received a copy of the GNU Lesser General Public License
3412+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3413+ *
3414+ * Authored by Jonas G. Drange <jonas.drange@canonical.com>
3415+ */
3416+
3417+import QtQuick 2.4
3418+import QtTest 1.0
3419+import Ubuntu.Components.Popups 1.3
3420+import Ubuntu.Test 0.1
3421+import Ubuntu.Settings.Vpn 0.1
3422+
3423+Item {
3424+ width: units.gu(42)
3425+ height: units.gu(75)
3426+
3427+ id: root
3428+ property var d
3429+
3430+ Component {
3431+ id: diag
3432+ VpnPreviewDialog {
3433+
3434+ }
3435+ }
3436+
3437+ // In these tests, all CA certificates are going to be checked.
3438+ UbuntuTestCase {
3439+ name: "VpnPreviewDialogCertificateChecks"
3440+ when: windowShown
3441+
3442+ function cleanup() {
3443+ PopupUtils.close(d);
3444+ }
3445+
3446+ function test_preview_dialog_data() {
3447+ return [
3448+ {
3449+ tag: "openvpn bad cert",
3450+ connection: {
3451+ id: 'openvpn bad cert',
3452+ remote: "ubuntu.com",
3453+ type: 0, // openvpn
3454+ ca: "bad.cert",
3455+ active: false,
3456+ neverDefault: false
3457+ },
3458+ targetObject: "vpnPreviewInvalidCert"
3459+ }
3460+ ]
3461+ }
3462+
3463+ function test_preview_dialog(data) {
3464+ root.d = PopupUtils.open(diag, null, data);
3465+ waitForRendering(root.d);
3466+ var target = findChild(root.d, data.targetObject);
3467+ var errorMsg = findChild(root.d, "vpnPreviewInvalidCertErrorMsg");
3468+ verify(target, "found obj " + data.targetObject);
3469+ compare(root.d.title, i18n.tr("VPN “%1”").arg(data.connection.remote || data.connection.gateway));
3470+ compare(errorMsg.text, i18n.tr("Details: %1").arg(i18n.tr("The certificate was not found.")));
3471+ }
3472+ }
3473+}

Subscribers

People subscribed via source and target branches

to all changes: