Further implemented Flow v2 Login

This commit is contained in:
Scharel Clemens 2020-01-14 17:04:09 +01:00
parent 58ae28dbe6
commit ecebd90dcb
5 changed files with 96 additions and 38 deletions

View file

@ -38,6 +38,10 @@ Dialog {
notesApi.host = value("server", "", String)
}
Timer {
id: loginPollTimer
}
SilicaFlickable {
anchors.fill: parent
contentHeight: column.height + Theme.paddingLarge
@ -118,7 +122,10 @@ Dialog {
id: loginButton
anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("Login")
onClicked: pageStack.push(Qt.resolvedUrl("LoginWebView.qml"), { server: serverField.text })
onClicked: {
//pageStack.push(Qt.resolvedUrl("LoginWebView.qml"), { loginUrl: serverField.text })
}
}
SectionHeader {

View file

@ -3,8 +3,7 @@ import Sailfish.Silica 1.0
Page {
id: loginWebView
property string server
property url ncurl: (account.allowUnecrypted ? "http://" : "https://") + server + "/index.php/login/flow"
property url loginUrl
Component.onCompleted: {
var req = new XMLHttpRequest()
@ -22,28 +21,20 @@ Page {
}
SilicaWebView {
id: ncFlowWebView
id: ncFlow2WebView
anchors.fill: parent
//url: ncurl
//experimental.userAgent: "SailfishBrowser 1 - Sailfish" //"Mozilla/5.0 (U; Linux; Maemo; Jolla; Sailfish; like Android 4.3) " + "AppleWebKit/" + wkversion + " (KHTML, like Gecko) WebPirate/" + version + " like Mobile Safari/" + wkversion + " (compatible)"
onNavigationRequested: {
console.log(url)
if (url.toString().indexOf("nc://login") === 0) {
var credentials = url.split("/", 1)
console.log(credentials)
}
}
url: loginUrl
header: PageHeader {
title: ncFlowWebView.title
description: loginWebView.ncurl
title: ncFlow2WebView.title
description: url
BusyIndicator {
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: Theme.horizontalPageMargin
size: BusyIndicatorSize.Medium
running: ncFlowWebView.loading
running: ncFlow2WebView.loading
}
}
}

View file

@ -148,13 +148,26 @@ bool NotesApi::ready() const {
bool NotesApi::busy() const {
bool busy = false;
for (int i = 0; i < m_replies.size(); ++i) {
busy |= m_replies[i]->isRunning();
QVector<QNetworkReply*> replies;
replies << m_replies << m_status_replies << m_login_replies;
for (int i = 0; i < replies.size(); ++i) {
busy |= replies[i]->isRunning();
}
return busy;
}
void NotesApi::getStatus() {
QUrl url = m_url;
url.setPath("/index.php/login/v2");
if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) {
qDebug() << "POST" << url.toDisplayString();
m_request.setUrl(url);
m_login_replies << m_manager.post(m_request, QByteArray());
emit busyChanged(busy());
}
}
void NotesApi::initiateFlowV2Login() {
QUrl url = m_url;
url.setPath("/status.php");
if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) {
@ -266,6 +279,11 @@ void NotesApi::replyFinished(QNetworkReply *reply) {
emit error(NoError);
QByteArray data = reply->readAll();
QJsonDocument json = QJsonDocument::fromJson(data);
if (m_login_replies.contains(reply)) {
if (json.isObject()) {
updateLogin(json.object());
}
}
if (m_status_replies.contains(reply)) {
if (json.isObject()) {
updateStatus(json.object());
@ -285,8 +303,9 @@ void NotesApi::replyFinished(QNetworkReply *reply) {
emit error(AuthenticationError);
else
emit error(CommunicationError);
m_replies.removeAll(reply);
m_login_replies.removeAll(reply);
m_status_replies.removeAll(reply);
m_replies.removeAll(reply);
reply->deleteLater();
emit busyChanged(busy());
}
@ -353,6 +372,31 @@ void NotesApi::updateStatus(const QJsonObject &status) {
}
}
void NotesApi::updateLogin(const QJsonObject &login) {
QUrl url;
QString token;
if (!login.isEmpty()) {
url = login.value("login").toString();
if (m_login_loginUrl != url && url.isValid()) {
m_login_loginUrl = url;
emit loginLoginUrlChanged(m_login_loginUrl);
}
QJsonObject poll = login.value("poll").toObject();
if (!poll.isEmpty()) {
url = poll.value("endpoint").toString() ;
if (m_login_pollUrl != url && urlValid()) {
m_login_pollUrl = url;
emit loginPollUrlChanged(m_login_pollUrl);
}
token = poll.value("token").toString();
if (m_login_pollToken != token) {
m_login_pollToken = token;
emit loginPollTokenChanged(m_login_pollToken);
}
}
}
}
const QString NotesApi::errorMessage(int error) const {
QString message;
switch (error) {

View file

@ -83,8 +83,15 @@ public:
QString statusProductName() const { return m_status_productname; }
Q_PROPERTY(bool statusExtendedSupport READ statusExtendedSupport NOTIFY statusExtendedSupportChanged)
bool statusExtendedSupport() const { return m_status_extendedSupport; }
Q_PROPERTY(QUrl loginPollUrl READ loginPollUrl NOTIFY loginPollUrlChanged)
QUrl loginPollUrl() const { return m_login_pollUrl; }
Q_PROPERTY(QString loginPollToken READ loginPollToken NOTIFY loginPollTokenChanged)
QString loginPollToken() const { return m_login_pollToken; }
Q_PROPERTY(QUrl loginLoginUrl READ loginLoginUrl NOTIFY loginLoginUrlChanged)
QUrl loginLoginUrl() const { return m_login_loginUrl; }
Q_INVOKABLE void getStatus();
Q_INVOKABLE void initiateFlowV2Login();
Q_INVOKABLE void getAllNotes(QStringList excludeFields = QStringList());
Q_INVOKABLE void getNote(double noteId, QStringList excludeFields = QStringList());
Q_INVOKABLE void createNote(QVariantMap fields = QVariantMap());
@ -126,6 +133,9 @@ signals:
void statusEditionChanged(QString edition);
void statusProductNameChanged(QString productName);
void statusExtendedSupportChanged(bool extendedSupport);
void loginPollUrlChanged(QUrl url);
void loginPollTokenChanged(QString token);
void loginLoginUrlChanged(QUrl url);
void error(int error);
public slots:
@ -159,6 +169,12 @@ private:
QString m_status_edition;
QString m_status_productname;
bool m_status_extendedSupport;
void updateLogin(const QJsonObject &login);
QVector<QNetworkReply*> m_login_replies;
QUrl m_login_pollUrl;
QString m_login_pollToken;
QUrl m_login_loginUrl;
};
#endif // NOTESAPI_H

View file

@ -125,58 +125,58 @@
<context>
<name>LoginDialog</name>
<message>
<location filename="../qml/pages/LoginDialog.qml" line="51"/>
<location filename="../qml/pages/LoginDialog.qml" line="120"/>
<location filename="../qml/pages/LoginDialog.qml" line="55"/>
<location filename="../qml/pages/LoginDialog.qml" line="124"/>
<source>Login</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/pages/LoginDialog.qml" line="51"/>
<location filename="../qml/pages/LoginDialog.qml" line="55"/>
<source>Save</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/pages/LoginDialog.qml" line="67"/>
<location filename="../qml/pages/LoginDialog.qml" line="71"/>
<source>Account name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/pages/LoginDialog.qml" line="82"/>
<location filename="../qml/pages/LoginDialog.qml" line="86"/>
<source>Nextcloud server</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/pages/LoginDialog.qml" line="97"/>
<location filename="../qml/pages/LoginDialog.qml" line="101"/>
<source>Username</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/pages/LoginDialog.qml" line="110"/>
<location filename="../qml/pages/LoginDialog.qml" line="114"/>
<source>Password</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/pages/LoginDialog.qml" line="125"/>
<location filename="../qml/pages/LoginDialog.qml" line="132"/>
<source>Security</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/pages/LoginDialog.qml" line="132"/>
<location filename="../qml/pages/LoginDialog.qml" line="139"/>
<source>&lt;strong&gt;CAUTION: Your password will be saved without any encryption on the device!&lt;/strong&gt;&lt;br&gt;Please consider creating a dedicated app password! Open your Nextcloud in a browser and go to &lt;i&gt;Settings&lt;/i&gt; &lt;i&gt;Security&lt;/i&gt;.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/pages/LoginDialog.qml" line="136"/>
<location filename="../qml/pages/LoginDialog.qml" line="143"/>
<source>Do not check certificates</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/pages/LoginDialog.qml" line="137"/>
<location filename="../qml/pages/LoginDialog.qml" line="144"/>
<source>Enable this option to allow selfsigned certificates</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/pages/LoginDialog.qml" line="143"/>
<location filename="../qml/pages/LoginDialog.qml" line="150"/>
<source>Allow unencrypted connections</source>
<translation type="unfinished"></translation>
</message>
@ -263,37 +263,37 @@
<context>
<name>NotesApi</name>
<message>
<location filename="../src/notesapi.cpp" line="362"/>
<location filename="../src/notesapi.cpp" line="406"/>
<source>No network connection available</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/notesapi.cpp" line="365"/>
<location filename="../src/notesapi.cpp" line="409"/>
<source>Failed to communicate with the Nextcloud server</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/notesapi.cpp" line="368"/>
<location filename="../src/notesapi.cpp" line="412"/>
<source>An error happened while reading from the local storage</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/notesapi.cpp" line="371"/>
<location filename="../src/notesapi.cpp" line="415"/>
<source>An error happened while writing to the local storage</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/notesapi.cpp" line="374"/>
<location filename="../src/notesapi.cpp" line="418"/>
<source>An error occured while establishing an encrypted connection</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/notesapi.cpp" line="377"/>
<location filename="../src/notesapi.cpp" line="421"/>
<source>Could not authenticate to the Nextcloud instance</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/notesapi.cpp" line="380"/>
<location filename="../src/notesapi.cpp" line="424"/>
<source>Unknown error</source>
<translation type="unfinished"></translation>
</message>