Merge lp:~mardy/account-plugins/nextcloud-1639175 into lp:account-plugins

Proposed by Alberto Mardegan on 2016-11-10
Status: Merged
Approved by: Alberto Mardegan on 2016-11-10
Approved revision: 182
Merged at revision: 180
Proposed branch: lp:~mardy/account-plugins/nextcloud-1639175
Merge into: lp:account-plugins
Prerequisite: lp:~gary-wzl77/account-plugins/onedrive_provider
Diff against target: 433 lines (+312/-3)
11 files modified
.bzrignore (+10/-0)
Makefile.am (+3/-2)
configure.ac (+1/-0)
data/providers/nextcloud.provider.in.in (+13/-0)
debian/account-plugin-nextcloud.install (+3/-0)
debian/account-plugin-owncloud.install (+0/-1)
debian/changelog (+10/-0)
debian/control (+9/-0)
qml/Makefile.am (+2/-0)
qml/nextcloud/Main.qml (+27/-0)
qml/nextcloud/NewAccount.qml (+234/-0)
To merge this branch: bzr merge lp:~mardy/account-plugins/nextcloud-1639175
Reviewer Review Type Date Requested Status
Online Accounts 2016-11-10 Pending
Review via email: mp+310522@code.launchpad.net

Description of the change

Add account plugin for Nextcloud

To post a comment you must log in.
183. By Alberto Mardegan on 2016-11-10

Improve nextcloud icon

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2016-06-16 11:48:50 +0000
3+++ .bzrignore 2016-11-10 13:53:58 +0000
4@@ -21,6 +21,7 @@
5 configure
6 compile
7 /data/providers/*.provider.in
8+/debian/*-stamp
9 /debian/account-plugin-facebook/
10 /debian/account-plugin-flickr/
11 /debian/account-plugin-foursquare/
12@@ -28,7 +29,11 @@
13 /debian/account-plugin-google/
14 /debian/account-plugin-icons/
15 /debian/account-plugin-identica/
16+/debian/account-plugin-instagram/
17+/debian/account-plugin-linkedin/
18 /debian/account-plugin-mcloud/
19+/debian/account-plugin-microsoft/
20+/debian/account-plugin-nextcloud/
21 /debian/account-plugin-owncloud/
22 /debian/account-plugin-sina/
23 /debian/account-plugin-sohu/
24@@ -39,6 +44,11 @@
25 /debian/autoreconf.after
26 /debian/autoreconf.before
27 /debian/files
28+/debian/libaccount-plugin-facebook/
29+/debian/libaccount-plugin-flickr/
30+/debian/libaccount-plugin-generic-oauth/
31+/debian/libaccount-plugin-google/
32+/debian/libaccount-plugin-twitter/
33 /debian/tmp/
34 depcomp
35 install-sh
36
37=== modified file 'Makefile.am'
38--- Makefile.am 2016-11-10 13:53:58 +0000
39+++ Makefile.am 2016-11-10 13:53:58 +0000
40@@ -91,6 +91,7 @@
41 data/providers/instagram.provider.in.in \
42 data/providers/mcloud.provider.in.in \
43 data/providers/microsoft.provider.in.in \
44+ data/providers/nextcloud.provider.in.in \
45 data/providers/owncloud.provider.in.in \
46 data/providers/sina.provider.in.in \
47 data/providers/sohu.provider.in.in \
48@@ -137,12 +138,12 @@
49
50 # Temporary until these bugs are fixed:
51 # https://bugs.launchpad.net/bugs/1567908
52-# https://bugs.launchpad.net/bugs/1571587
53+# https://bugs.launchpad.net/bugs/1640704
54 iconsdir = $(datadir)/icons/hicolor/32x32/apps
55 dist_icons_DATA = \
56 data/icons/mcloud.png \
57 data/icons/microsoft.png \
58- data/icons/owncloud.png \
59+ data/icons/nextcloud.png \
60 data/icons/vk.png
61
62 dist_bin_SCRIPTS = \
63
64=== modified file 'configure.ac'
65--- configure.ac 2016-11-10 13:53:58 +0000
66+++ configure.ac 2016-11-10 13:53:58 +0000
67@@ -268,6 +268,7 @@
68 data/providers/instagram.provider.in
69 data/providers/mcloud.provider.in
70 data/providers/microsoft.provider.in
71+ data/providers/nextcloud.provider.in
72 data/providers/owncloud.provider.in
73 data/providers/sina.provider.in
74 data/providers/sohu.provider.in
75
76=== added file 'data/icons/nextcloud.png'
77Binary files data/icons/nextcloud.png 1970-01-01 00:00:00 +0000 and data/icons/nextcloud.png 2016-11-10 13:53:58 +0000 differ
78=== added file 'data/providers/nextcloud.provider.in.in'
79--- data/providers/nextcloud.provider.in.in 1970-01-01 00:00:00 +0000
80+++ data/providers/nextcloud.provider.in.in 2016-11-10 13:53:58 +0000
81@@ -0,0 +1,13 @@
82+<?xml version="1.0" encoding="UTF-8"?>
83+<provider id="nextcloud">
84+ <name>Nextcloud</name>
85+ <icon>nextcloud</icon>
86+ <translations>account-plugins</translations>
87+
88+ <template>
89+ <group name="auth">
90+ <setting name="method">password</setting>
91+ <setting name="mechanism">password</setting>
92+ </group>
93+ </template>
94+</provider>
95
96=== added file 'debian/account-plugin-nextcloud.install'
97--- debian/account-plugin-nextcloud.install 1970-01-01 00:00:00 +0000
98+++ debian/account-plugin-nextcloud.install 2016-11-10 13:53:58 +0000
99@@ -0,0 +1,3 @@
100+usr/share/accounts/providers/nextcloud.provider
101+usr/share/accounts/qml-plugins/nextcloud/*.qml
102+usr/share/icons/hicolor/32x32/apps/nextcloud.png
103
104=== modified file 'debian/account-plugin-owncloud.install'
105--- debian/account-plugin-owncloud.install 2016-08-01 15:50:48 +0000
106+++ debian/account-plugin-owncloud.install 2016-11-10 13:53:58 +0000
107@@ -1,3 +1,2 @@
108 usr/share/accounts/providers/owncloud.provider
109 usr/share/accounts/qml-plugins/owncloud/*.qml
110-usr/share/icons/hicolor/32x32/apps/owncloud.png
111
112=== modified file 'debian/changelog'
113--- debian/changelog 2016-09-29 09:23:40 +0000
114+++ debian/changelog 2016-11-10 13:53:58 +0000
115@@ -1,3 +1,13 @@
116+account-plugins (0.13+16.10.20160929.1-0ubuntu2) UNRELEASED; urgency=medium
117+
118+ * debian/account-plugin-owncloud.install:
119+ - remove owncloud icon, it's now provided by the theme
120+ * debian/control,debian/account-plugin-nextcloud.install:
121+ - add Nextcloud account plugin
122+ * Add account plugin for Nextcloud (LP: #1639175)
123+
124+ -- Alberto Mardegan <alberto.mardegan@canonical.com> Thu, 10 Nov 2016 11:43:37 +0300
125+
126 account-plugins (0.13+16.10.20160929.1-0ubuntu1) yakkety; urgency=medium
127
128 * Owncloud: properly encode username and password in POST request (LP:
129
130=== modified file 'debian/control'
131--- debian/control 2016-11-10 13:53:58 +0000
132+++ debian/control 2016-11-10 13:53:58 +0000
133@@ -163,6 +163,15 @@
134 This plugin adds support for creating microsoft accounts in the Unity Control
135 Center
136
137+Package: account-plugin-nextcloud
138+Architecture: all
139+Depends: ${misc:Depends},
140+ signon-plugin-password,
141+ ubuntu-system-settings-online-accounts,
142+Description: Online account plugin for Unity - Nextcloud
143+ This plugin adds support for creating Nextcloud accounts in the Unity Control
144+ Center
145+
146 Package: account-plugin-owncloud
147 Architecture: all
148 Depends: ${misc:Depends},
149
150=== modified file 'qml/Makefile.am'
151--- qml/Makefile.am 2016-11-10 13:53:58 +0000
152+++ qml/Makefile.am 2016-11-10 13:53:58 +0000
153@@ -4,6 +4,8 @@
154 google/Main.qml \
155 mcloud/Main.qml \
156 microsoft/Main.qml \
157+ nextcloud/Main.qml \
158+ nextcloud/NewAccount.qml \
159 owncloud/Main.qml \
160 owncloud/NewAccount.qml \
161 twitter/Main.qml \
162
163=== added directory 'qml/nextcloud'
164=== added file 'qml/nextcloud/Main.qml'
165--- qml/nextcloud/Main.qml 1970-01-01 00:00:00 +0000
166+++ qml/nextcloud/Main.qml 2016-11-10 13:53:58 +0000
167@@ -0,0 +1,27 @@
168+import QtQuick 2.0
169+import Ubuntu.OnlineAccounts.Plugin 1.0
170+
171+Flickable {
172+ id: root
173+
174+ property int keyboardSize: Qt.inputMethod.visible ? Qt.inputMethod.keyboardRectangle.height : 0
175+ contentHeight: loader.item.height + keyboardSize
176+
177+ signal finished
178+
179+ Loader {
180+ id: loader
181+ anchors.fill: parent
182+ sourceComponent: newAccountComponent
183+
184+ Connections {
185+ target: loader.item
186+ onFinished: root.finished()
187+ }
188+ }
189+
190+ Component {
191+ id: newAccountComponent
192+ NewAccount {}
193+ }
194+}
195
196=== added file 'qml/nextcloud/NewAccount.qml'
197--- qml/nextcloud/NewAccount.qml 1970-01-01 00:00:00 +0000
198+++ qml/nextcloud/NewAccount.qml 2016-11-10 13:53:58 +0000
199@@ -0,0 +1,234 @@
200+import QtQuick 2.0
201+import Ubuntu.Components 1.3
202+import Ubuntu.OnlineAccounts 0.1
203+
204+Item {
205+ id: root
206+
207+ signal finished
208+
209+ height: contents.height
210+
211+ property var __account: account
212+ property string __host: ""
213+ property bool __busy: false
214+ property string __hostError: i18n.dtr("account-plugins", "Invalid host URL")
215+
216+ Column {
217+ id: contents
218+ anchors {
219+ top: parent.top
220+ left: parent.left
221+ right: parent.right
222+ margins: units.gu(2)
223+ }
224+ spacing: units.gu(2)
225+
226+ Label {
227+ id: errorLabel
228+ anchors { left: parent.left; right: parent.right }
229+ font.bold: true
230+ color: UbuntuColors.red
231+ wrapMode: Text.Wrap
232+ visible: !__busy && text != ""
233+ }
234+
235+ Label {
236+ anchors { left: parent.left; right: parent.right }
237+ text: i18n.dtr("account-plugins", "URL:")
238+ }
239+
240+ TextField {
241+ id: urlField
242+ anchors { left: parent.left; right: parent.right }
243+ placeholderText: i18n.dtr("account-plugins", "http://myserver.com/nextcloud")
244+ focus: true
245+ enabled: !__busy
246+
247+ inputMethodHints: Qt.ImhUrlCharactersOnly
248+ }
249+
250+ Label {
251+ anchors { left: parent.left; right: parent.right }
252+ text: i18n.dtr("account-plugins", "Username:")
253+ }
254+
255+ TextField {
256+ id: usernameField
257+ anchors { left: parent.left; right: parent.right }
258+ placeholderText: i18n.dtr("account-plugins", "Your username")
259+ enabled: !__busy
260+ inputMethodHints: Qt.ImhNoAutoUppercase + Qt.ImhNoPredictiveText + Qt.ImhPreferLowercase
261+
262+ KeyNavigation.tab: passwordField
263+ }
264+
265+ Label {
266+ anchors { left: parent.left; right: parent.right }
267+ text: i18n.dtr("account-plugins", "Password:")
268+ }
269+
270+ TextField {
271+ id: passwordField
272+ anchors { left: parent.left; right: parent.right }
273+ placeholderText: i18n.dtr("account-plugins", "Your password")
274+ echoMode: TextInput.Password
275+ enabled: !__busy
276+
277+ inputMethodHints: Qt.ImhSensitiveData
278+ Keys.onReturnPressed: login()
279+ }
280+
281+ Row {
282+ id: buttons
283+ anchors { left: parent.left; right: parent.right }
284+ height: units.gu(5)
285+ spacing: units.gu(1)
286+ Button {
287+ id: btnCancel
288+ text: i18n.dtr("account-plugins", "Cancel")
289+ height: parent.height
290+ width: (parent.width / 2) - 0.5 * parent.spacing
291+ onClicked: finished()
292+ }
293+ Button {
294+ id: btnContinue
295+ text: i18n.dtr("account-plugins", "Continue")
296+ color: UbuntuColors.green
297+ height: parent.height
298+ width: (parent.width / 2) - 0.5 * parent.spacing
299+ onClicked: login()
300+ enabled: !__busy
301+ }
302+ }
303+ }
304+
305+ ActivityIndicator {
306+ anchors.centerIn: parent
307+ running: __busy
308+ }
309+
310+ Credentials {
311+ id: creds
312+ caption: account.provider.id
313+ acl: [ "unconfined" ]
314+ storeSecret: true
315+ onCredentialsIdChanged: root.credentialsStored()
316+ }
317+
318+ AccountService {
319+ id: globalAccountSettings
320+ objectHandle: account.accountServiceHandle
321+ autoSync: false
322+ }
323+
324+ function login() {
325+ __host = cleanUrl(urlField.text)
326+ var username = usernameField.text
327+ var password = passwordField.text
328+
329+ errorLabel.text = ""
330+ __busy = true
331+ var host = __host
332+ var tryHttp = false
333+ if (__host.indexOf("http") != 0) {
334+ host = "https://" + __host
335+ tryHttp = true
336+ }
337+
338+ checkAccount(host, username, password, function cb(success) {
339+ console.log("callback called: " + success)
340+ if (success) {
341+ saveData(host, username, password)
342+ } else if (tryHttp) {
343+ host = "http://" + __host
344+ tryHttp = false
345+ checkAccount(host, username, password, cb)
346+ } else {
347+ __busy = false
348+ }
349+ })
350+ }
351+
352+ function saveData(host, username, password) {
353+ __host = host
354+ var strippedHost = __host.replace(/^https?:\/\//, '')
355+ account.updateDisplayName(username + '@' + strippedHost)
356+ creds.userName = username
357+ creds.secret = password
358+ creds.sync()
359+ }
360+
361+ function findChild(node, tagName) {
362+ if (!node) return node;
363+ var children = node.childNodes
364+ for (var i = 0; i < children.length; i++) {
365+ if (children[i].nodeName == tagName) {
366+ return children[i]
367+ }
368+ }
369+ return null
370+ }
371+
372+ function checkAccount(host, username, password, callback) {
373+ console.log("Trying host " + host + " as " + username + ':' + password)
374+ var request = new XMLHttpRequest();
375+ request.onreadystatechange = function() {
376+ if (request.readyState === XMLHttpRequest.DONE) {
377+ console.log("response: " + request.responseText)
378+ if (request.status == 200) {
379+ var root = request.responseXML ? request.responseXML.documentElement : null
380+ var metaElement = findChild(root, "meta")
381+ var statusElement = findChild(metaElement, "status")
382+ if (statusElement && statusElement.childNodes.length > 0 &&
383+ statusElement.childNodes[0].nodeValue == "ok") {
384+ callback(true)
385+ } else {
386+ var statusCodeElement = findChild(metaElement, "statuscode")
387+ var statusCode = (statusCodeElement && statusCodeElement.childNodes.length > 0) ?
388+ statusCodeElement.childNodes[0].nodeValue : "999"
389+ if (statusCode == "999") {
390+ showError(__hostError)
391+ } else {
392+ showError(i18n.dtr("account-plugins", "Invalid username or password"))
393+ }
394+ callback(false)
395+ }
396+ } else {
397+ showError(__hostError)
398+ callback(false)
399+ }
400+ }
401+ }
402+ request.open("POST", host + "/ocs/v1.php/person/check", true);
403+ request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
404+ var body = "login=" + encodeURIComponent(username) + "&password=" + encodeURIComponent(password)
405+ request.send(body);
406+ }
407+
408+ function showError(message) {
409+ if (!errorLabel.text) errorLabel.text = message
410+ }
411+
412+ function credentialsStored() {
413+ console.log("Credentials stored, id: " + creds.credentialsId)
414+ if (creds.credentialsId == 0) return
415+
416+ globalAccountSettings.updateServiceEnabled(true)
417+ globalAccountSettings.credentials = creds
418+ globalAccountSettings.updateSettings({
419+ "host": __host
420+ })
421+ account.synced.connect(finished)
422+ account.sync()
423+ __busy = false
424+ }
425+
426+ // check host url for http
427+ function cleanUrl(url) {
428+ var host = url.trim()
429+ // if the user typed trailing '/' or "index.php", strip that
430+ return host.replace(/\/(index.php)?\/*$/, '')
431+ }
432+
433+}

Subscribers

People subscribed via source and target branches

to all changes: