summaryrefslogtreecommitdiffstats
path: root/qt-mobile/qmlmanager.cpp
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2015-12-04 19:34:59 -0800
committerGravatar Dirk Hohndel <dirk@hohndel.org>2015-12-04 19:51:35 -0800
commitfd78f8dc1ae3e64c7e861957d3207923f8df4714 (patch)
tree50cdf60c21ff7ff4f5964368d2e0c0d0afbb7302 /qt-mobile/qmlmanager.cpp
parent426660025402e47e8de89b6e741fd372cbcac8fb (diff)
downloadsubsurface-fd78f8dc1ae3e64c7e861957d3207923f8df4714.tar.gz
QML-UI: re-architect the way we access network resources
We really need to verify that the credentials are valid before trying to access our backend resources. Trying to do so in a clean manner caused quite a bit of changes to how we retrieve the webservice userid and how we load the dive list from cloud storage. So instead of accessing the network resources directly, this adds a handler function that first checks the validity of the credentials (by using the rederict handler on the cloud server), and only calls the function that does the actual work (looks up the web service userid, loads the dives) if that succeeds. Right now there is no good user feedback mechanism - this just gets logged on the log page. But this is a massive improvement if there are issues with network connectivity or if the user mistyped their credentials. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'qt-mobile/qmlmanager.cpp')
-rw-r--r--qt-mobile/qmlmanager.cpp121
1 files changed, 102 insertions, 19 deletions
diff --git a/qt-mobile/qmlmanager.cpp b/qt-mobile/qmlmanager.cpp
index eb0ef7022..c244832da 100644
--- a/qt-mobile/qmlmanager.cpp
+++ b/qt-mobile/qmlmanager.cpp
@@ -2,6 +2,8 @@
#include <QUrl>
#include <QSettings>
#include <QDebug>
+#include <QNetworkAccessManager>
+#include <QAuthenticator>
#include "qt-models/divelistmodel.h"
#include "divelist.h"
@@ -19,21 +21,25 @@ static void appendTextToLogStandalone(const char *text)
}
QMLManager::QMLManager() :
- m_locationServiceEnabled(false)
+ m_locationServiceEnabled(false),
+ reply(0),
+ mgr(0)
{
m_instance = this;
// create location manager service
locationProvider = new GpsLocation(&appendTextToLogStandalone, this);
+}
+void QMLManager::finishSetup()
+{
// Initialize cloud credentials.
setCloudUserName(prefs.cloud_storage_email);
setCloudPassword(prefs.cloud_storage_password);
setSaveCloudPassword(prefs.save_password_local);
// if the cloud credentials are valid, we should get the GPS Webservice ID as well
if (!same_string(prefs.cloud_storage_email, "") &&
- !same_string(prefs.cloud_storage_password, "") &&
- same_string(prefs.userid, ""))
- locationProvider->getUserid(prefs.cloud_storage_email, prefs.cloud_storage_password);
+ !same_string(prefs.cloud_storage_password, ""))
+ tryRetrieveDataFromBackend();
setDistanceThreshold(prefs.distance_threshold);
setTimeThreshold(prefs.time_threshold / 60);
@@ -57,8 +63,12 @@ void QMLManager::savePreferences()
prefs.time_threshold = timeThreshold() * 60;
s.setValue("distance_threshold", distanceThreshold());
prefs.distance_threshold = distanceThreshold();
+ s.sync();
}
+#define CLOUDURL QString(prefs.cloud_base_url)
+#define CLOUDREDIRECTURL CLOUDURL + "/cgi-bin/redirect.pl"
+
void QMLManager::saveCloudCredentials()
{
QSettings s;
@@ -85,31 +95,104 @@ void QMLManager::saveCloudCredentials()
prefs.cloud_storage_password = strdup(qPrintable(cloudPassword()));
}
}
- // if the cloud credentials are valid, we should get the GPS Webservice ID as well
+ if (cloudCredentialsChanged) {
+ free(prefs.userid);
+ prefs.userid = NULL;
+ tryRetrieveDataFromBackend();
+ }
+}
+
+void QMLManager::checkCredentialsAndExecute(execute_function_type execute)
+{
+ // if the cloud credentials are present, we should try to get the GPS Webservice ID
+ // and (if we haven't done so) load the dive list
if (!same_string(prefs.cloud_storage_email, "") &&
!same_string(prefs.cloud_storage_password, "")) {
- if (same_string(prefs.userid, "") || cloudCredentialsChanged) {
- QString userid = locationProvider->getUserid(prefs.cloud_storage_email, prefs.cloud_storage_password);
- if (!userid.isEmpty()) {
- // overwrite the existing userid
- free(prefs.userid);
- prefs.userid = strdup(qPrintable(userid));
- s.setValue("subsurface_webservice_uid", prefs.userid);
- }
- }
+ appendTextToLog("Have credentials, let's see if they are valid");
+ if (!mgr)
+ mgr = new QNetworkAccessManager(this);
+ connect(mgr, &QNetworkAccessManager::authenticationRequired, this, execute, Qt::UniqueConnection);
+ connect(mgr, &QNetworkAccessManager::finished, this, &QMLManager::retrieveUserid, Qt::UniqueConnection);
+ QUrl url(CLOUDREDIRECTURL);
+ request = QNetworkRequest(url);
+ request.setRawHeader("User-Agent", getUserAgent().toUtf8());
+ request.setRawHeader("Accept", "text/html");
+ reply = mgr->get(request);
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(handleError(QNetworkReply::NetworkError)));
+ connect(reply, &QNetworkReply::sslErrors, this, &QMLManager::handleSslErrors);
}
- if (cloudCredentialsChanged)
- loadDives();
+
+}
+
+void QMLManager::tryRetrieveDataFromBackend()
+{
+ checkCredentialsAndExecute(&QMLManager::retrieveUserid);
}
void QMLManager::loadDives()
{
- if (same_string(prefs.cloud_storage_email, "") || same_string(prefs.cloud_storage_password, "")) {
- appendTextToLog("Unable to load dives; cloud storage credentials missing");
+ checkCredentialsAndExecute(&QMLManager::loadDivesWithValidCredentials);
+}
+
+void QMLManager::provideAuth(QNetworkReply *reply, QAuthenticator *auth)
+{
+ if (auth->user() == QString(prefs.cloud_storage_email) &&
+ auth->password() == QString(prefs.cloud_storage_password)) {
+ // OK, credentials have been tried and didn't work, so they are invalid
+ appendTextToLog("Cloud credentials are invalid");
+ reply->disconnect();
+ reply->abort();
+ reply->deleteLater();
return;
}
+ auth->setUser(prefs.cloud_storage_email);
+ auth->setPassword(prefs.cloud_storage_password);
+}
+
+void QMLManager::handleSslErrors(const QList<QSslError> &errors)
+{
+ Q_FOREACH(QSslError e, errors) {
+ qDebug() << e.errorString();
+ }
+ reply->abort();
+ reply->deleteLater();
+}
- appendTextToLog("Loading dives...");
+void QMLManager::handleError(QNetworkReply::NetworkError nError)
+{
+ qDebug() << "handleError" << nError << reply->errorString();
+ reply->abort();
+ reply->deleteLater();
+}
+
+void QMLManager::retrieveUserid()
+{
+ if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) != 302) {
+ appendTextToLog(QString("Cloud storage connection not working correctly: ") + reply->readAll());
+ return;
+ }
+ QString userid(prefs.userid);
+ if (userid.isEmpty())
+ userid = locationProvider->getUserid(prefs.cloud_storage_email, prefs.cloud_storage_password);
+ if (!userid.isEmpty()) {
+ // overwrite the existing userid
+ free(prefs.userid);
+ prefs.userid = strdup(qPrintable(userid));
+ QSettings s;
+ s.setValue("subsurface_webservice_uid", prefs.userid);
+ s.sync();
+ }
+ if (!loadFromCloud())
+ loadDivesWithValidCredentials();
+}
+
+void QMLManager::loadDivesWithValidCredentials()
+{
+ if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) != 302) {
+ appendTextToLog(QString("Cloud storage connection not working correctly: ") + reply->readAll());
+ return;
+ }
+ appendTextToLog("Cloud credentials valid, loading dives...");
QString url;
if (getCloudURL(url)) {
appendTextToLog(get_error_string());