Implemented the most important features in NextcloudApi
This commit is contained in:
parent
e44af7ec7a
commit
1b0b3b957d
3 changed files with 158 additions and 231 deletions
|
@ -10,21 +10,14 @@ NextcloudApi::NextcloudApi(QObject *parent) : QObject(parent)
|
||||||
setCababilitiesStatus(ApiCallStatus::ApiUnknown);
|
setCababilitiesStatus(ApiCallStatus::ApiUnknown);
|
||||||
setUserListStatus(ApiCallStatus::ApiUnknown);
|
setUserListStatus(ApiCallStatus::ApiUnknown);
|
||||||
setUserMetaStatus(ApiCallStatus::ApiUnknown);
|
setUserMetaStatus(ApiCallStatus::ApiUnknown);
|
||||||
m_status_installed = false;
|
|
||||||
m_status_maintenance = false;
|
|
||||||
m_status_needsDbUpgrade = false;
|
|
||||||
m_status_extendedSupport = false;
|
|
||||||
|
|
||||||
// Add capabilities functions for server apps
|
// Verify URL
|
||||||
m_appCapabilities["notes"] = &NextcloudApi::updateNoteCapabilities;
|
connect(this, SIGNAL(urlChanged(QUrl)), this, SLOT(verifyUrl(QUrl)));
|
||||||
|
|
||||||
// Login Flow V2 poll timer
|
// Login Flow V2 poll timer
|
||||||
m_loginPollTimer.setInterval(LOGIN_FLOWV2_POLL_INTERVALL);
|
m_loginPollTimer.setInterval(LOGIN_FLOWV2_POLL_INTERVALL);
|
||||||
connect(&m_loginPollTimer, SIGNAL(timeout()), this, SLOT(pollLoginUrl()));
|
connect(&m_loginPollTimer, SIGNAL(timeout()), this, SLOT(pollLoginUrl()));
|
||||||
|
|
||||||
// Verify URL
|
|
||||||
connect(this, SIGNAL(urlChanged(QUrl)), this, SLOT(verifyUrl(QUrl)));
|
|
||||||
|
|
||||||
// Listen to signals of the QNetworkAccessManager class
|
// Listen to signals of the QNetworkAccessManager class
|
||||||
connect(&m_manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(requireAuthentication(QNetworkReply*,QAuthenticator*)));
|
connect(&m_manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(requireAuthentication(QNetworkReply*,QAuthenticator*)));
|
||||||
connect(&m_manager, SIGNAL(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)), this, SLOT(onNetworkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)));
|
connect(&m_manager, SIGNAL(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)), this, SLOT(onNetworkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)));
|
||||||
|
@ -61,16 +54,13 @@ void NextcloudApi::setVerifySsl(bool verify) {
|
||||||
|
|
||||||
void NextcloudApi::setUrl(QUrl url) {
|
void NextcloudApi::setUrl(QUrl url) {
|
||||||
if (url != m_url) {
|
if (url != m_url) {
|
||||||
QString oldServer = server();
|
|
||||||
setScheme(url.scheme());
|
setScheme(url.scheme());
|
||||||
setHost(url.host());
|
setHost(url.host());
|
||||||
setPort(url.port());
|
setPort(url.port());
|
||||||
setUsername(url.userName());
|
setUsername(url.userName());
|
||||||
setPassword(url.password());
|
setPassword(url.password());
|
||||||
setPath(url.path());
|
setPath(url.path());
|
||||||
if (server() != oldServer)
|
emit urlChanged(&m_url);
|
||||||
emit serverChanged(server());
|
|
||||||
emit urlChanged(m_url);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,36 +87,28 @@ void NextcloudApi::setServer(QString serverUrl) {
|
||||||
void NextcloudApi::setScheme(QString scheme) {
|
void NextcloudApi::setScheme(QString scheme) {
|
||||||
if (scheme != m_url.scheme() && (scheme == "http" || scheme == "https")) {
|
if (scheme != m_url.scheme() && (scheme == "http" || scheme == "https")) {
|
||||||
m_url.setScheme(scheme);
|
m_url.setScheme(scheme);
|
||||||
emit schemeChanged(m_url.scheme());
|
emit urlChanged(&m_url);
|
||||||
emit serverChanged(server());
|
|
||||||
emit urlChanged(m_url);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NextcloudApi::setHost(QString host) {
|
void NextcloudApi::setHost(QString host) {
|
||||||
if (host != m_url.host()) {
|
if (host != m_url.host()) {
|
||||||
m_url.setHost(host);
|
m_url.setHost(host);
|
||||||
emit hostChanged(m_url.host());
|
emit urlChanged(&m_url);
|
||||||
emit serverChanged(server());
|
|
||||||
emit urlChanged(m_url);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NextcloudApi::setPort(int port) {
|
void NextcloudApi::setPort(int port) {
|
||||||
if (port != m_url.port() && port >= 1 && port <= 65535) {
|
if (port != m_url.port() && port >= 1 && port <= 65535) {
|
||||||
m_url.setPort(port);
|
m_url.setPort(port);
|
||||||
emit portChanged(m_url.port());
|
emit urlChanged(&m_url);
|
||||||
emit serverChanged(server());
|
|
||||||
emit urlChanged(m_url);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NextcloudApi::setPath(QString path) {
|
void NextcloudApi::setPath(QString path) {
|
||||||
if (path != m_url.path()) {
|
if (path != m_url.path()) {
|
||||||
m_url.setPath(path);
|
m_url.setPath(path);
|
||||||
emit pathChanged(m_url.path());
|
emit urlChanged(&m_url);
|
||||||
emit serverChanged(server());
|
|
||||||
emit urlChanged(m_url);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,8 +119,7 @@ void NextcloudApi::setUsername(QString username) {
|
||||||
QByteArray data = concatenated.toLocal8Bit().toBase64();
|
QByteArray data = concatenated.toLocal8Bit().toBase64();
|
||||||
QString headerData = "Basic " + data;
|
QString headerData = "Basic " + data;
|
||||||
m_authenticatedRequest.setRawHeader("Authorization", headerData.toLocal8Bit());
|
m_authenticatedRequest.setRawHeader("Authorization", headerData.toLocal8Bit());
|
||||||
emit usernameChanged(m_url.userName());
|
emit urlChanged(&m_url);
|
||||||
emit urlChanged(m_url);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,8 +130,7 @@ void NextcloudApi::setPassword(QString password) {
|
||||||
QByteArray data = concatenated.toLocal8Bit().toBase64();
|
QByteArray data = concatenated.toLocal8Bit().toBase64();
|
||||||
QString headerData = "Basic " + data;
|
QString headerData = "Basic " + data;
|
||||||
m_authenticatedRequest.setRawHeader("Authorization", headerData.toLocal8Bit());
|
m_authenticatedRequest.setRawHeader("Authorization", headerData.toLocal8Bit());
|
||||||
emit passwordChanged(m_url.password());
|
emit urlChanged(&m_url);
|
||||||
emit urlChanged(m_url);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,36 +279,38 @@ void NextcloudApi::abortFlowV2Login() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NextcloudApi::verifyLogin() {
|
bool NextcloudApi::verifyLogin() {
|
||||||
return get(USER_METADATA_ENDPOINT.arg(username()), true);
|
return getUserMetaData(username());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NextcloudApi::getAppPassword() {
|
bool NextcloudApi::getAppPassword() {
|
||||||
return get(GET_APPPASSWORD_ENDPOINT, true);
|
return get(GET_APPPASSWORD_ENDPOINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NextcloudApi::deleteAppPassword() {
|
bool NextcloudApi::deleteAppPassword() {
|
||||||
return del(DEL_APPPASSWORD_ENDPOINT, true);
|
return del(DEL_APPPASSWORD_ENDPOINT);
|
||||||
}
|
|
||||||
|
|
||||||
bool NextcloudApi::getUserList() {
|
|
||||||
return false; // TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NextcloudApi::getUserMetaData(const QString& user) {
|
bool NextcloudApi::getUserMetaData(const QString& user) {
|
||||||
return false; // TODO
|
if (!user.isEmpty() || !username().isEmpty())
|
||||||
|
return get(USER_METADATA_ENDPOINT.arg(user.isEmpty() ? username() : user));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NextcloudApi::getUserList() {
|
||||||
|
return get(LIST_USERS_ENDPOINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NextcloudApi::getCapabilities() {
|
bool NextcloudApi::getCapabilities() {
|
||||||
return false; // TODO
|
return get(CAPABILITIES_ENDPOINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NextcloudApi::verifyUrl(QUrl url) {
|
void NextcloudApi::verifyUrl(QUrl *url) {
|
||||||
emit urlValidChanged(
|
emit urlValidChanged(
|
||||||
url.isValid()&&
|
url->isValid()&&
|
||||||
!url.isRelative() &&
|
!url->isRelative() &&
|
||||||
!url.userName().isEmpty() &&
|
!url->userName().isEmpty() &&
|
||||||
!url.password().isEmpty() &&
|
!url->password().isEmpty() &&
|
||||||
!url.host().isEmpty());
|
!url->host().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void NextcloudApi::requireAuthentication(QNetworkReply *reply, QAuthenticator *authenticator) {
|
void NextcloudApi::requireAuthentication(QNetworkReply *reply, QAuthenticator *authenticator) {
|
||||||
|
@ -385,18 +367,22 @@ void NextcloudApi::replyFinished(QNetworkReply* reply) {
|
||||||
qDebug() << "App password received";
|
qDebug() << "App password received";
|
||||||
updateAppPassword(json.object());
|
updateAppPassword(json.object());
|
||||||
}
|
}
|
||||||
else if (reply->url().toString().endsWith(LIST_USERS_ENDPOINT)) {
|
|
||||||
qDebug() << "User list received";
|
|
||||||
updateUserList(json.object());
|
|
||||||
}
|
|
||||||
else if (reply->url().toString().contains(USER_METADATA_ENDPOINT)) {
|
else if (reply->url().toString().contains(USER_METADATA_ENDPOINT)) {
|
||||||
qDebug() << "User metadata for" << reply->url().toString().split('/').last() << "received";
|
qDebug() << "User metadata for" << reply->url().toString().split('/').last() << "received";
|
||||||
updateUserMeta(json.object());
|
updateUserMeta(json.object());
|
||||||
}
|
}
|
||||||
|
else if (reply->url().toString().endsWith(LIST_USERS_ENDPOINT)) {
|
||||||
|
qDebug() << "User list received";
|
||||||
|
updateUserList(json.object());
|
||||||
|
}
|
||||||
else if (reply->url().toString().endsWith(CAPABILITIES_ENDPOINT)) {
|
else if (reply->url().toString().endsWith(CAPABILITIES_ENDPOINT)) {
|
||||||
qDebug() << "Capabilites received";
|
qDebug() << "Capabilites received";
|
||||||
updateCapabilities(json.object());
|
updateCapabilities(json.object());
|
||||||
}
|
}
|
||||||
|
else if (reply->url().toString().endsWith(USER_NOTIFICATION_ENDPOINT)) {
|
||||||
|
qDebug() << "Notifications are not yet implemented!";
|
||||||
|
qDebug() << json.object().value("ocs").toObject().value("data").toArray();
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
qDebug() << "GET reply received";
|
qDebug() << "GET reply received";
|
||||||
emit getFinished(reply);
|
emit getFinished(reply);
|
||||||
|
@ -407,7 +393,7 @@ void NextcloudApi::replyFinished(QNetworkReply* reply) {
|
||||||
break;
|
break;
|
||||||
case QNetworkAccessManager::PutOperation:
|
case QNetworkAccessManager::PutOperation:
|
||||||
if (reply->url().toString().endsWith(DIRECT_DOWNLOAD_ENDPOINT)) {
|
if (reply->url().toString().endsWith(DIRECT_DOWNLOAD_ENDPOINT)) {
|
||||||
qDebug() << "This function is not yet implemented!";
|
qDebug() << "Direct download is not yet implemented!";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
qDebug() << "PUT reply received";
|
qDebug() << "PUT reply received";
|
||||||
|
@ -474,51 +460,20 @@ void NextcloudApi::replyFinished(QNetworkReply* reply) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NextcloudApi::setStatusStatus(ApiCallStatus status, bool *changed) {
|
||||||
|
if (status != m_statusStatus) {
|
||||||
|
m_statusStatus = status;
|
||||||
|
if (changed) *changed = true;
|
||||||
|
emit statusStatusChanged(m_statusStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool NextcloudApi::updateStatus(const QJsonObject &json) {
|
bool NextcloudApi::updateStatus(const QJsonObject &json) {
|
||||||
bool tmpBool;
|
|
||||||
QString tmpString;
|
|
||||||
QVersionNumber tmpVersion;
|
|
||||||
if (!json.isEmpty()) {
|
if (!json.isEmpty()) {
|
||||||
setStatusStatus(ApiSuccess);
|
setStatusStatus(ApiSuccess);
|
||||||
tmpBool = json.value("installed").toBool();
|
if (json != m_status) {
|
||||||
if (m_status_installed != tmpBool) {
|
m_status = json;
|
||||||
m_status_installed = tmpBool;
|
emit statusChanged();
|
||||||
emit statusInstalledChanged(m_status_installed);
|
|
||||||
}
|
|
||||||
tmpBool = json.value("maintenance").toBool();
|
|
||||||
if (m_status_maintenance != tmpBool) {
|
|
||||||
m_status_maintenance = tmpBool;
|
|
||||||
emit statusMaintenanceChanged(m_status_maintenance);
|
|
||||||
}
|
|
||||||
tmpBool = json.value("needsDbUpgrade").toBool();
|
|
||||||
if (m_status_needsDbUpgrade != tmpBool) {
|
|
||||||
m_status_needsDbUpgrade = tmpBool;
|
|
||||||
emit statusNeedsDbUpgradeChanged(m_status_needsDbUpgrade);
|
|
||||||
}
|
|
||||||
tmpVersion = QVersionNumber::fromString(json.value("version").toString());
|
|
||||||
if (m_status_version != tmpVersion) {
|
|
||||||
m_status_version = tmpVersion;
|
|
||||||
emit statusVersionChanged(m_status_version.toString());
|
|
||||||
}
|
|
||||||
tmpString = json.value("versionstring").toString();
|
|
||||||
if (m_status_versionstring != tmpString) {
|
|
||||||
m_status_versionstring = tmpString;
|
|
||||||
emit statusVersionStringChanged(m_status_versionstring);
|
|
||||||
}
|
|
||||||
tmpString = json.value("edition").toString();
|
|
||||||
if (m_status_edition != tmpString) {
|
|
||||||
m_status_edition = tmpString;
|
|
||||||
emit statusEditionChanged(m_status_edition);
|
|
||||||
}
|
|
||||||
tmpString = json.value("productname").toString();
|
|
||||||
if (m_status_productname != tmpString) {
|
|
||||||
m_status_productname = tmpString;
|
|
||||||
emit statusProductNameChanged(m_status_productname);
|
|
||||||
}
|
|
||||||
tmpBool = json.value("extendedSupport").toBool();
|
|
||||||
if (m_status_extendedSupport != tmpBool) {
|
|
||||||
m_status_extendedSupport = tmpBool;
|
|
||||||
emit statusExtendedSupportChanged(m_status_extendedSupport);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -528,11 +483,11 @@ bool NextcloudApi::updateStatus(const QJsonObject &json) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NextcloudApi::setStatusStatus(ApiCallStatus status, bool *changed) {
|
void NextcloudApi::setLoginStatus(LoginStatus status, bool *changed) {
|
||||||
if (status != m_statusStatus) {
|
if (status != m_loginStatus) {
|
||||||
m_statusStatus = status;
|
m_loginStatus = status;
|
||||||
if (changed) *changed = true;
|
if (changed) *changed = true;
|
||||||
emit statusStatusChanged(m_statusStatus);
|
emit loginStatusChanged(m_loginStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,7 +501,7 @@ bool NextcloudApi::updateLoginFlow(const QJsonObject &json) {
|
||||||
if (m_pollUrl.isValid() && !m_pollToken.isEmpty() && loginUrl.isValid()) {
|
if (m_pollUrl.isValid() && !m_pollToken.isEmpty() && loginUrl.isValid()) {
|
||||||
if (m_loginUrl != loginUrl) {
|
if (m_loginUrl != loginUrl) {
|
||||||
m_loginUrl = loginUrl;
|
m_loginUrl = loginUrl;
|
||||||
emit loginUrlChanged(m_loginUrl);
|
emit loginUrlChanged(&m_loginUrl);
|
||||||
}
|
}
|
||||||
setLoginStatus(LoginStatus::LoginFlowV2Polling);
|
setLoginStatus(LoginStatus::LoginFlowV2Polling);
|
||||||
m_loginPollTimer.start();
|
m_loginPollTimer.start();
|
||||||
|
@ -595,13 +550,47 @@ bool NextcloudApi::updateAppPassword(const QJsonObject &json) {
|
||||||
|
|
||||||
bool NextcloudApi::deleteAppPassword(const QJsonObject &json) {
|
bool NextcloudApi::deleteAppPassword(const QJsonObject &json) {
|
||||||
setPassword(QString());
|
setPassword(QString());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NextcloudApi::setLoginStatus(LoginStatus status, bool *changed) {
|
void NextcloudApi::setUserMetaStatus(ApiCallStatus status, bool *changed) {
|
||||||
if (status != m_loginStatus) {
|
if (status != m_userMetaStatus) {
|
||||||
m_loginStatus = status;
|
m_userMetaStatus = status;
|
||||||
if (changed) *changed = true;
|
if (changed) *changed = true;
|
||||||
emit loginStatusChanged(m_loginStatus);
|
emit userMetaStatusChanged(m_userMetaStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NextcloudApi::updateUserMeta(const QJsonObject &json) {
|
||||||
|
QJsonObject ocs = json.value("ocs").toObject();
|
||||||
|
QJsonObject meta = ocs.value("meta").toObject();
|
||||||
|
QJsonObject data = ocs.value("data").toObject();
|
||||||
|
QString user = data.value("id").toString();
|
||||||
|
if (!user.isEmpty() && user == username()) {
|
||||||
|
setLoginStatus(LoginSuccess);
|
||||||
|
}
|
||||||
|
if (meta.value("statuscode").toInt() == 100) {
|
||||||
|
setUserMetaStatus(ApiSuccess);
|
||||||
|
if (!data.isEmpty() && data != m_userMeta[user]) {
|
||||||
|
m_userMeta[user] = data;
|
||||||
|
emit userMetaChanged(user);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (meta.value("statuscode").toInt() == 404) {
|
||||||
|
setUserMetaStatus(ApiSuccess);
|
||||||
|
m_userMeta.remove(user);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
setUserMetaStatus(ApiFailed);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NextcloudApi::setUserListStatus(ApiCallStatus status, bool *changed) {
|
||||||
|
if (status != m_userListStatus) {
|
||||||
|
m_userListStatus = status;
|
||||||
|
if (changed) *changed = true;
|
||||||
|
emit userListStatusChanged(m_userListStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -621,7 +610,7 @@ bool NextcloudApi::updateUserList(const QJsonObject &json) {
|
||||||
if (userList != m_userList && !userList.isEmpty()) {
|
if (userList != m_userList && !userList.isEmpty()) {
|
||||||
setUserListStatus(ApiSuccess);
|
setUserListStatus(ApiSuccess);
|
||||||
m_userList = userList;
|
m_userList = userList;
|
||||||
emit userListChanged(m_userList);
|
emit userListChanged(&m_userList);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -629,62 +618,6 @@ bool NextcloudApi::updateUserList(const QJsonObject &json) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NextcloudApi::setUserListStatus(ApiCallStatus status, bool *changed) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NextcloudApi::updateUserMeta(const QJsonObject &json) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void NextcloudApi::setUserMetaStatus(ApiCallStatus status, bool *changed) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NextcloudApi::updateCapabilities(const QJsonObject &json) {
|
|
||||||
QJsonObject ocs = json.value("ocs").toObject();
|
|
||||||
QJsonObject data = ocs.value("data").toObject();
|
|
||||||
QJsonObject preCapabilities = m_capabilities;
|
|
||||||
QJsonObject newCapabilities = data.value("capabilities").toObject();
|
|
||||||
if (!newCapabilities.isEmpty()) {
|
|
||||||
setCababilitiesStatus(ApiSuccess);
|
|
||||||
if (newCapabilities != preCapabilities) {
|
|
||||||
m_capabilities = newCapabilities;
|
|
||||||
|
|
||||||
QStringList apps = newCapabilities.keys();
|
|
||||||
QStringList::const_iterator app;
|
|
||||||
for (app = apps.constBegin(); app != apps.constEnd(); ++app) {
|
|
||||||
if (m_appCapabilities.contains(*app)) {
|
|
||||||
qDebug() << "Updating \"" << *app << "\" capabilities";
|
|
||||||
(this->*m_appCapabilities[*app])(newCapabilities.value(*app).toObject(), preCapabilities.value(*app).toObject());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
qDebug() << "Capabilities for " << *app << " not implemented!";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
setCababilitiesStatus(ApiFailed);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NextcloudApi::updateNoteCapabilities(const QJsonObject &newObject, const QJsonObject &preObject) {
|
|
||||||
qDebug() << "Updating \"notes\" capabilities";
|
|
||||||
if (newObject.isEmpty() != preObject.isEmpty())
|
|
||||||
emit notesAppInstalledChanged(notesAppInstalled());
|
|
||||||
|
|
||||||
QStringList preVersions;
|
|
||||||
QJsonArray preApiVersion = preObject.value("api_version").toArray();
|
|
||||||
QJsonArray::const_iterator i;
|
|
||||||
for (i = preApiVersion.constBegin(); i != preApiVersion.constEnd(); ++i) {
|
|
||||||
if (i->isString())
|
|
||||||
preVersions << i->toString();
|
|
||||||
}
|
|
||||||
if (preVersions != notesAppApiVersions())
|
|
||||||
emit notesAppApiVersionsChanged(notesAppApiVersions());
|
|
||||||
}
|
|
||||||
|
|
||||||
void NextcloudApi::setCababilitiesStatus(ApiCallStatus status, bool *changed) {
|
void NextcloudApi::setCababilitiesStatus(ApiCallStatus status, bool *changed) {
|
||||||
if (status != m_capabilitiesStatus) {
|
if (status != m_capabilitiesStatus) {
|
||||||
m_capabilitiesStatus = status;
|
m_capabilitiesStatus = status;
|
||||||
|
@ -692,3 +625,20 @@ void NextcloudApi::setCababilitiesStatus(ApiCallStatus status, bool *changed) {
|
||||||
emit capabilitiesStatusChanged(m_capabilitiesStatus);
|
emit capabilitiesStatusChanged(m_capabilitiesStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NextcloudApi::updateCapabilities(const QJsonObject &json) {
|
||||||
|
QJsonObject ocs = json.value("ocs").toObject();
|
||||||
|
QJsonObject data = ocs.value("data").toObject();
|
||||||
|
QJsonObject capabilities = data.value("capabilities").toObject();
|
||||||
|
// TODO update version
|
||||||
|
if (!capabilities.isEmpty()) {
|
||||||
|
setCababilitiesStatus(ApiSuccess);
|
||||||
|
if (capabilities != m_capabilities) {
|
||||||
|
m_capabilities = capabilities;
|
||||||
|
emit capabilitiesChanged(&m_capabilities);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
setCababilitiesStatus(ApiFailed);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -18,11 +18,11 @@ const QString STATUS_ENDPOINT("/status.php");
|
||||||
|
|
||||||
// OCS APIs endpoints
|
// OCS APIs endpoints
|
||||||
// https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html
|
// https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html
|
||||||
const QString CAPABILITIES_ENDPOINT("/ocs/v2.php/cloud/capabilities");
|
|
||||||
const QString LIST_USERS_ENDPOINT("/ocs/v2.php/cloud/users");
|
|
||||||
const QString USER_METADATA_ENDPOINT("/ocs/v2.php/cloud/users/%1");
|
const QString USER_METADATA_ENDPOINT("/ocs/v2.php/cloud/users/%1");
|
||||||
const QString USER_NOTIFICATION_ENDPOINT("/ocs/v2.php/apps/notifications/api/v2/notifications");
|
const QString LIST_USERS_ENDPOINT("/ocs/v2.php/cloud/users");
|
||||||
|
const QString CAPABILITIES_ENDPOINT("/ocs/v2.php/cloud/capabilities");
|
||||||
const QString DIRECT_DOWNLOAD_ENDPOINT("/ocs/v2.php/apps/dav/api/v1/direct");
|
const QString DIRECT_DOWNLOAD_ENDPOINT("/ocs/v2.php/apps/dav/api/v1/direct");
|
||||||
|
const QString USER_NOTIFICATION_ENDPOINT("/ocs/v2.php/apps/notifications/api/v2/notifications");
|
||||||
|
|
||||||
// Login Flow endpoints
|
// Login Flow endpoints
|
||||||
// https://docs.nextcloud.com/server/latest/developer_manual/client_apis/LoginFlow/index.html
|
// https://docs.nextcloud.com/server/latest/developer_manual/client_apis/LoginFlow/index.html
|
||||||
|
@ -42,14 +42,14 @@ class NextcloudApi : public QObject
|
||||||
// Generic API properties
|
// Generic API properties
|
||||||
Q_PROPERTY(bool verifySsl READ verifySsl WRITE setVerifySsl NOTIFY verifySslChanged) // to allow selfsigned certificates
|
Q_PROPERTY(bool verifySsl READ verifySsl WRITE setVerifySsl NOTIFY verifySslChanged) // to allow selfsigned certificates
|
||||||
Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) // complete nextcloud URL = <scheme>://<username>:<password>@<host>[:<port>]/<path>
|
Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) // complete nextcloud URL = <scheme>://<username>:<password>@<host>[:<port>]/<path>
|
||||||
Q_PROPERTY(QString server READ server WRITE setServer NOTIFY serverChanged) // url without username and password = <scheme>://<host>[:<port>]/<path>
|
Q_PROPERTY(QString server READ server WRITE setServer NOTIFY urlChanged) // url without username and password = <scheme>://<host>[:<port>]/<path>
|
||||||
// the following properties will update the url and server properties and vice versa
|
// the following properties will update the url and server properties and vice versa
|
||||||
Q_PROPERTY(QString scheme READ scheme WRITE setScheme NOTIFY schemeChanged)
|
Q_PROPERTY(QString scheme READ scheme WRITE setScheme NOTIFY urlChanged)
|
||||||
Q_PROPERTY(QString host READ host WRITE setHost NOTIFY hostChanged)
|
Q_PROPERTY(QString host READ host WRITE setHost NOTIFY urlChanged)
|
||||||
Q_PROPERTY(int port READ port WRITE setPort NOTIFY portChanged)
|
Q_PROPERTY(int port READ port WRITE setPort NOTIFY urlChanged)
|
||||||
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
|
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY urlChanged)
|
||||||
Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged)
|
Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY urlChanged)
|
||||||
Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged)
|
Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY urlChanged)
|
||||||
|
|
||||||
// Networking status information
|
// Networking status information
|
||||||
Q_PROPERTY(bool ready READ ready NOTIFY readyChanged) // when all needed properties are set
|
Q_PROPERTY(bool ready READ ready NOTIFY readyChanged) // when all needed properties are set
|
||||||
|
@ -59,14 +59,14 @@ class NextcloudApi : public QObject
|
||||||
|
|
||||||
// Nextcloud status (status.php), these properties will be automatically updated on changes of the generic properties
|
// Nextcloud status (status.php), these properties will be automatically updated on changes of the generic properties
|
||||||
Q_PROPERTY(ApiCallStatus statusStatus READ statusStatus NOTIFY statusStatusChanged)
|
Q_PROPERTY(ApiCallStatus statusStatus READ statusStatus NOTIFY statusStatusChanged)
|
||||||
Q_PROPERTY(bool statusInstalled READ statusInstalled NOTIFY statusInstalledChanged)
|
Q_PROPERTY(bool statusInstalled READ statusInstalled NOTIFY statusChanged)
|
||||||
Q_PROPERTY(bool statusMaintenance READ statusMaintenance NOTIFY statusMaintenanceChanged)
|
Q_PROPERTY(bool statusMaintenance READ statusMaintenance NOTIFY statusChanged)
|
||||||
Q_PROPERTY(bool statusNeedsDbUpgrade READ statusNeedsDbUpgrade NOTIFY statusNeedsDbUpgradeChanged)
|
Q_PROPERTY(bool statusNeedsDbUpgrade READ statusNeedsDbUpgrade NOTIFY statusChanged)
|
||||||
Q_PROPERTY(QString statusVersion READ statusVersion NOTIFY statusVersionChanged)
|
Q_PROPERTY(QString statusVersion READ statusVersion NOTIFY statusChanged)
|
||||||
Q_PROPERTY(QString statusVersionString READ statusVersionString NOTIFY statusVersionStringChanged)
|
Q_PROPERTY(QString statusVersionString READ statusVersionString NOTIFY statusChanged)
|
||||||
Q_PROPERTY(QString statusEdition READ statusEdition NOTIFY statusEditionChanged)
|
Q_PROPERTY(QString statusEdition READ statusEdition NOTIFY statusChanged)
|
||||||
Q_PROPERTY(QString statusProductName READ statusProductName NOTIFY statusProductNameChanged)
|
Q_PROPERTY(QString statusProductName READ statusProductName NOTIFY statusChanged)
|
||||||
Q_PROPERTY(bool statusExtendedSupport READ statusExtendedSupport NOTIFY statusExtendedSupportChanged)
|
Q_PROPERTY(bool statusExtendedSupport READ statusExtendedSupport NOTIFY statusChanged)
|
||||||
|
|
||||||
// Login status
|
// Login status
|
||||||
Q_PROPERTY(LoginStatus loginStatus READ loginStatus NOTIFY loginStatusChanged)
|
Q_PROPERTY(LoginStatus loginStatus READ loginStatus NOTIFY loginStatusChanged)
|
||||||
|
@ -81,8 +81,8 @@ class NextcloudApi : public QObject
|
||||||
|
|
||||||
// Nextcloud capabilities
|
// Nextcloud capabilities
|
||||||
Q_PROPERTY(ApiCallStatus capabilitiesStatus READ capabilitiesStatus NOTIFY capabilitiesStatusChanged)
|
Q_PROPERTY(ApiCallStatus capabilitiesStatus READ capabilitiesStatus NOTIFY capabilitiesStatusChanged)
|
||||||
Q_PROPERTY(bool notesAppInstalled READ notesAppInstalled NOTIFY notesAppInstalledChanged)
|
Q_PROPERTY(bool notesAppInstalled READ notesAppInstalled NOTIFY capabilitiesChanged)
|
||||||
Q_PROPERTY(QStringList notesAppApiVersions READ notesAppApiVersions NOTIFY notesAppApiVersionsChanged)
|
Q_PROPERTY(QStringList notesAppApiVersions READ notesAppApiVersions NOTIFY capabilitiesChanged)
|
||||||
// TODO other property for server capabilities
|
// TODO other property for server capabilities
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -145,14 +145,14 @@ public:
|
||||||
|
|
||||||
// Nextcloud status (status.php)
|
// Nextcloud status (status.php)
|
||||||
ApiCallStatus statusStatus() const { return m_statusStatus; }
|
ApiCallStatus statusStatus() const { return m_statusStatus; }
|
||||||
bool statusInstalled() const { return m_status_installed; }
|
bool statusInstalled() const { return m_status.value("installed").toBool(); }
|
||||||
bool statusMaintenance() const { return m_status_maintenance; }
|
bool statusMaintenance() const { return m_status.value("maintenance").toBool(); }
|
||||||
bool statusNeedsDbUpgrade() const { return m_status_needsDbUpgrade; }
|
bool statusNeedsDbUpgrade() const { return m_status.value("needsDbUpgrade").toBool(); }
|
||||||
QString statusVersion() const { return m_status_version.toString(); }
|
QString statusVersion() const { return m_status.value("version").toString(); }
|
||||||
QString statusVersionString() const { return m_status_versionstring; }
|
QString statusVersionString() const { return m_status.value("versionstring").toString(); }
|
||||||
QString statusEdition() const { return m_status_edition; }
|
QString statusEdition() const { return m_status.value("edition").toString(); }
|
||||||
QString statusProductName() const { return m_status_productname; }
|
QString statusProductName() const { return m_status.value("productname").toString(); }
|
||||||
bool statusExtendedSupport() const { return m_status_extendedSupport; }
|
bool statusExtendedSupport() const { return m_status.value("extendedSupport").toBool(); }
|
||||||
|
|
||||||
// Login status
|
// Login status
|
||||||
LoginStatus loginStatus() const { return m_loginStatus; }
|
LoginStatus loginStatus() const { return m_loginStatus; }
|
||||||
|
@ -193,21 +193,14 @@ public slots:
|
||||||
Q_INVOKABLE bool verifyLogin();
|
Q_INVOKABLE bool verifyLogin();
|
||||||
Q_INVOKABLE bool getAppPassword();
|
Q_INVOKABLE bool getAppPassword();
|
||||||
Q_INVOKABLE bool deleteAppPassword();
|
Q_INVOKABLE bool deleteAppPassword();
|
||||||
Q_INVOKABLE bool getUserList();
|
|
||||||
Q_INVOKABLE bool getUserMetaData(const QString& user = QString());
|
Q_INVOKABLE bool getUserMetaData(const QString& user = QString());
|
||||||
|
Q_INVOKABLE bool getUserList();
|
||||||
Q_INVOKABLE bool getCapabilities();
|
Q_INVOKABLE bool getCapabilities();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// Generic API properties
|
// Generic API properties
|
||||||
void verifySslChanged(bool verify);
|
void verifySslChanged(bool verify);
|
||||||
void urlChanged(QUrl url);
|
void urlChanged(QUrl* url);
|
||||||
void serverChanged(QString server);
|
|
||||||
void schemeChanged(QString scheme);
|
|
||||||
void hostChanged(QString host);
|
|
||||||
void portChanged(int port);
|
|
||||||
void pathChanged(QString path);
|
|
||||||
void usernameChanged(QString username);
|
|
||||||
void passwordChanged(QString password);
|
|
||||||
|
|
||||||
// Class status information
|
// Class status information
|
||||||
void readyChanged(bool ready);
|
void readyChanged(bool ready);
|
||||||
|
@ -217,29 +210,22 @@ signals:
|
||||||
|
|
||||||
// Nextcloud status (status.php)
|
// Nextcloud status (status.php)
|
||||||
void statusStatusChanged(ApiCallStatus status);
|
void statusStatusChanged(ApiCallStatus status);
|
||||||
void statusInstalledChanged(bool installed);
|
void statusChanged();
|
||||||
void statusMaintenanceChanged(bool maintenance);
|
|
||||||
void statusNeedsDbUpgradeChanged(bool needsDbUpgrade);
|
|
||||||
void statusVersionChanged(QString version);
|
|
||||||
void statusVersionStringChanged(QString versionString);
|
|
||||||
void statusEditionChanged(QString edition);
|
|
||||||
void statusProductNameChanged(QString productName);
|
|
||||||
void statusExtendedSupportChanged(bool extendedSupport);
|
|
||||||
|
|
||||||
// Login status
|
// Login status
|
||||||
void loginFlowV2PossibleChanged(bool loginV2possible);
|
|
||||||
void loginUrlChanged(QUrl url);
|
|
||||||
void loginStatusChanged(LoginStatus status);
|
void loginStatusChanged(LoginStatus status);
|
||||||
|
void loginFlowV2PossibleChanged(bool loginV2possible);
|
||||||
|
void loginUrlChanged(QUrl* url);
|
||||||
|
|
||||||
// User(s) status
|
// User(s) status
|
||||||
void userListStatusChanged(ApiCallStatus status);
|
|
||||||
void userListChanged(QStringList users);
|
|
||||||
void userMetaStatusChanged(ApiCallStatus status);
|
void userMetaStatusChanged(ApiCallStatus status);
|
||||||
|
void userMetaChanged(QString username);
|
||||||
|
void userListStatusChanged(ApiCallStatus status);
|
||||||
|
void userListChanged(QStringList* users);
|
||||||
|
|
||||||
// Nextcloud capabilities
|
// Nextcloud capabilities
|
||||||
void capabilitiesStatusChanged(ApiCallStatus status);
|
void capabilitiesStatusChanged(ApiCallStatus status);
|
||||||
void notesAppInstalledChanged(bool installed);
|
void capabilitiesChanged(QJsonObject* json);
|
||||||
void notesAppApiVersionsChanged(QStringList versions);
|
|
||||||
|
|
||||||
// API helper updates
|
// API helper updates
|
||||||
void getFinished(QNetworkReply* reply);
|
void getFinished(QNetworkReply* reply);
|
||||||
|
@ -249,7 +235,7 @@ signals:
|
||||||
void apiError(ErrorCodes error);
|
void apiError(ErrorCodes error);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void verifyUrl(QUrl url);
|
void verifyUrl(QUrl* url);
|
||||||
void requireAuthentication(QNetworkReply * reply, QAuthenticator * authenticator);
|
void requireAuthentication(QNetworkReply * reply, QAuthenticator * authenticator);
|
||||||
void onNetworkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility accessible);
|
void onNetworkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility accessible);
|
||||||
bool pollLoginUrl();
|
bool pollLoginUrl();
|
||||||
|
@ -267,14 +253,7 @@ private:
|
||||||
bool updateStatus(const QJsonObject &json);
|
bool updateStatus(const QJsonObject &json);
|
||||||
void setStatusStatus(ApiCallStatus status, bool *changed = NULL);
|
void setStatusStatus(ApiCallStatus status, bool *changed = NULL);
|
||||||
ApiCallStatus m_statusStatus;
|
ApiCallStatus m_statusStatus;
|
||||||
bool m_status_installed;
|
QJsonObject m_status;
|
||||||
bool m_status_maintenance;
|
|
||||||
bool m_status_needsDbUpgrade;
|
|
||||||
QVersionNumber m_status_version;
|
|
||||||
QString m_status_versionstring;
|
|
||||||
QString m_status_edition;
|
|
||||||
QString m_status_productname;
|
|
||||||
bool m_status_extendedSupport;
|
|
||||||
|
|
||||||
// Nextcloud Login Flow v2
|
// Nextcloud Login Flow v2
|
||||||
// https://docs.nextcloud.com/server/latest/developer_manual/client_apis/LoginFlow/index.html#login-flow-v2
|
// https://docs.nextcloud.com/server/latest/developer_manual/client_apis/LoginFlow/index.html#login-flow-v2
|
||||||
|
@ -289,22 +268,20 @@ private:
|
||||||
QUrl m_pollUrl;
|
QUrl m_pollUrl;
|
||||||
QString m_pollToken;
|
QString m_pollToken;
|
||||||
|
|
||||||
// Nextcloud users list
|
|
||||||
bool updateUserList(const QJsonObject &json);
|
|
||||||
void setUserListStatus(ApiCallStatus status, bool *changed = NULL);
|
|
||||||
ApiCallStatus m_userListStatus;
|
|
||||||
QStringList m_userList;
|
|
||||||
|
|
||||||
// Nextcloud user metadata
|
// Nextcloud user metadata
|
||||||
bool updateUserMeta(const QJsonObject &json);
|
bool updateUserMeta(const QJsonObject &json);
|
||||||
void setUserMetaStatus(ApiCallStatus status, bool *changed = NULL);
|
void setUserMetaStatus(ApiCallStatus status, bool *changed = NULL);
|
||||||
ApiCallStatus m_userMetaStatus;
|
ApiCallStatus m_userMetaStatus;
|
||||||
QHash<QString, QJsonObject> m_userMeta;
|
QHash<QString, QJsonObject> m_userMeta;
|
||||||
|
|
||||||
|
// Nextcloud users list
|
||||||
|
bool updateUserList(const QJsonObject &json);
|
||||||
|
void setUserListStatus(ApiCallStatus status, bool *changed = NULL);
|
||||||
|
ApiCallStatus m_userListStatus;
|
||||||
|
QStringList m_userList;
|
||||||
|
|
||||||
// Nextcloud capabilities
|
// Nextcloud capabilities
|
||||||
bool updateCapabilities(const QJsonObject &json);
|
bool updateCapabilities(const QJsonObject &json);
|
||||||
QMap<QString, updateAppCapabilities> m_appCapabilities;
|
|
||||||
void updateNoteCapabilities(const QJsonObject &newObject, const QJsonObject &preObject = QJsonObject());
|
|
||||||
void setCababilitiesStatus(ApiCallStatus status, bool *changed = NULL);
|
void setCababilitiesStatus(ApiCallStatus status, bool *changed = NULL);
|
||||||
ApiCallStatus m_capabilitiesStatus;
|
ApiCallStatus m_capabilitiesStatus;
|
||||||
QJsonObject m_capabilities;
|
QJsonObject m_capabilities;
|
||||||
|
|
|
@ -275,32 +275,32 @@
|
||||||
<context>
|
<context>
|
||||||
<name>NextcloudApi</name>
|
<name>NextcloudApi</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/nextcloudapi.cpp" line="158"/>
|
<location filename="../src/nextcloudapi.cpp" line="180"/>
|
||||||
<source>No error</source>
|
<source>No error</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/nextcloudapi.cpp" line="161"/>
|
<location filename="../src/nextcloudapi.cpp" line="183"/>
|
||||||
<source>No network connection available</source>
|
<source>No network connection available</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/nextcloudapi.cpp" line="164"/>
|
<location filename="../src/nextcloudapi.cpp" line="186"/>
|
||||||
<source>Failed to communicate with the Nextcloud server</source>
|
<source>Failed to communicate with the Nextcloud server</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/nextcloudapi.cpp" line="167"/>
|
<location filename="../src/nextcloudapi.cpp" line="189"/>
|
||||||
<source>An error occured while establishing an encrypted connection</source>
|
<source>An error occured while establishing an encrypted connection</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/nextcloudapi.cpp" line="170"/>
|
<location filename="../src/nextcloudapi.cpp" line="192"/>
|
||||||
<source>Could not authenticate to the Nextcloud instance</source>
|
<source>Could not authenticate to the Nextcloud instance</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/nextcloudapi.cpp" line="173"/>
|
<location filename="../src/nextcloudapi.cpp" line="195"/>
|
||||||
<source>Unknown error</source>
|
<source>Unknown error</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
Loading…
Reference in a new issue