diff options
-rw-r--r-- | common/CMakeLists.txt | 3 | ||||
-rw-r--r-- | common/commands.h | 1 | ||||
-rw-r--r-- | common/commands/secret.fbs | 7 | ||||
-rw-r--r-- | common/domain/applicationdomaintype.h | 1 | ||||
-rw-r--r-- | common/genericresource.cpp | 7 | ||||
-rw-r--r-- | common/genericresource.h | 2 | ||||
-rw-r--r-- | common/listener.cpp | 12 | ||||
-rw-r--r-- | common/resource.cpp | 5 | ||||
-rw-r--r-- | common/resource.h | 2 | ||||
-rw-r--r-- | common/resourceaccess.cpp | 22 | ||||
-rw-r--r-- | common/resourceaccess.h | 6 | ||||
-rw-r--r-- | common/secretstore.cpp | 51 | ||||
-rw-r--r-- | common/secretstore.h | 50 | ||||
-rw-r--r-- | common/synchronizer.cpp | 18 | ||||
-rw-r--r-- | common/synchronizer.h | 5 | ||||
-rw-r--r-- | examples/davresource/davresource.cpp | 30 | ||||
-rw-r--r-- | examples/davresource/davresource.h | 5 | ||||
-rw-r--r-- | examples/dummyresource/resourcefactory.cpp | 2 | ||||
-rw-r--r-- | examples/imapresource/imapresource.cpp | 16 | ||||
-rw-r--r-- | examples/imapresource/imapserverproxy.cpp | 3 | ||||
-rw-r--r-- | examples/imapresource/imapserverproxy.h | 1 | ||||
-rw-r--r-- | examples/maildirresource/maildirresource.cpp | 2 |
22 files changed, 226 insertions, 25 deletions
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 8421fc2..b0e0d04 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt | |||
@@ -33,6 +33,7 @@ set(storage_LIBS lmdb) | |||
33 | 33 | ||
34 | set(command_SRCS | 34 | set(command_SRCS |
35 | store.cpp | 35 | store.cpp |
36 | secretstore.cpp | ||
36 | notifier.cpp | 37 | notifier.cpp |
37 | resourcecontrol.cpp | 38 | resourcecontrol.cpp |
38 | modelresult.cpp | 39 | modelresult.cpp |
@@ -97,6 +98,7 @@ generate_flatbuffers( | |||
97 | commands/revisionreplayed | 98 | commands/revisionreplayed |
98 | commands/inspection | 99 | commands/inspection |
99 | commands/flush | 100 | commands/flush |
101 | commands/secret | ||
100 | domain/contact | 102 | domain/contact |
101 | domain/addressbook | 103 | domain/addressbook |
102 | domain/event | 104 | domain/event |
@@ -144,6 +146,7 @@ install(FILES | |||
144 | test.h | 146 | test.h |
145 | log.h | 147 | log.h |
146 | flush.h | 148 | flush.h |
149 | secretstore.h | ||
147 | ${CMAKE_CURRENT_BINARY_DIR}/sink_export.h | 150 | ${CMAKE_CURRENT_BINARY_DIR}/sink_export.h |
148 | DESTINATION ${INCLUDE_INSTALL_DIR}/${PROJECT_NAME} COMPONENT Devel | 151 | DESTINATION ${INCLUDE_INSTALL_DIR}/${PROJECT_NAME} COMPONENT Devel |
149 | ) | 152 | ) |
diff --git a/common/commands.h b/common/commands.h index 1548eac..8ced268 100644 --- a/common/commands.h +++ b/common/commands.h | |||
@@ -48,6 +48,7 @@ enum CommandIds | |||
48 | InspectionCommand, | 48 | InspectionCommand, |
49 | RemoveFromDiskCommand, | 49 | RemoveFromDiskCommand, |
50 | FlushCommand, | 50 | FlushCommand, |
51 | SecretCommand, | ||
51 | CustomCommand = 0xffff | 52 | CustomCommand = 0xffff |
52 | }; | 53 | }; |
53 | 54 | ||
diff --git a/common/commands/secret.fbs b/common/commands/secret.fbs new file mode 100644 index 0000000..5bb2246 --- /dev/null +++ b/common/commands/secret.fbs | |||
@@ -0,0 +1,7 @@ | |||
1 | namespace Sink.Commands; | ||
2 | |||
3 | table Secret { | ||
4 | secret: string; | ||
5 | } | ||
6 | |||
7 | root_type Secret; | ||
diff --git a/common/domain/applicationdomaintype.h b/common/domain/applicationdomaintype.h index f7fd07e..de2b5c9 100644 --- a/common/domain/applicationdomaintype.h +++ b/common/domain/applicationdomaintype.h | |||
@@ -102,6 +102,7 @@ enum SINK_EXPORT ErrorCode { | |||
102 | ConfigurationError, | 102 | ConfigurationError, |
103 | TransmissionError, | 103 | TransmissionError, |
104 | ConnectionLostError, | 104 | ConnectionLostError, |
105 | MissingCredentialsError | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | enum SINK_EXPORT SuccessCode { | 108 | enum SINK_EXPORT SuccessCode { |
diff --git a/common/genericresource.cpp b/common/genericresource.cpp index 7178b3d..b6a8f62 100644 --- a/common/genericresource.cpp +++ b/common/genericresource.cpp | |||
@@ -45,6 +45,13 @@ GenericResource::~GenericResource() | |||
45 | { | 45 | { |
46 | } | 46 | } |
47 | 47 | ||
48 | void GenericResource::setSecret(const QString &s) | ||
49 | { | ||
50 | if (mSynchronizer) { | ||
51 | mSynchronizer->setSecret(s); | ||
52 | } | ||
53 | } | ||
54 | |||
48 | void GenericResource::setupPreprocessors(const QByteArray &type, const QVector<Sink::Preprocessor *> &preprocessors) | 55 | void GenericResource::setupPreprocessors(const QByteArray &type, const QVector<Sink::Preprocessor *> &preprocessors) |
49 | { | 56 | { |
50 | mPipeline->setPreprocessors(type, preprocessors); | 57 | mPipeline->setPreprocessors(type, preprocessors); |
diff --git a/common/genericresource.h b/common/genericresource.h index bffc697..4e86b75 100644 --- a/common/genericresource.h +++ b/common/genericresource.h | |||
@@ -47,6 +47,8 @@ public: | |||
47 | static void removeFromDisk(const QByteArray &instanceIdentifier); | 47 | static void removeFromDisk(const QByteArray &instanceIdentifier); |
48 | static qint64 diskUsage(const QByteArray &instanceIdentifier); | 48 | static qint64 diskUsage(const QByteArray &instanceIdentifier); |
49 | 49 | ||
50 | virtual void setSecret(const QString &s) Q_DECL_OVERRIDE; | ||
51 | |||
50 | //TODO Remove this API, it's only used in tests | 52 | //TODO Remove this API, it's only used in tests |
51 | KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &query); | 53 | KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &query); |
52 | //TODO Remove this API, it's only used in tests | 54 | //TODO Remove this API, it's only used in tests |
diff --git a/common/listener.cpp b/common/listener.cpp index c9fd9d3..c6747cd 100644 --- a/common/listener.cpp +++ b/common/listener.cpp | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "common/revisionupdate_generated.h" | 33 | #include "common/revisionupdate_generated.h" |
34 | #include "common/notification_generated.h" | 34 | #include "common/notification_generated.h" |
35 | #include "common/revisionreplayed_generated.h" | 35 | #include "common/revisionreplayed_generated.h" |
36 | #include "common/secret_generated.h" | ||
36 | 37 | ||
37 | #include <QLocalServer> | 38 | #include <QLocalServer> |
38 | #include <QLocalSocket> | 39 | #include <QLocalSocket> |
@@ -240,6 +241,17 @@ void Listener::processCommand(int commandId, uint messageId, const QByteArray &c | |||
240 | } | 241 | } |
241 | break; | 242 | break; |
242 | } | 243 | } |
244 | case Sink::Commands::SecretCommand: { | ||
245 | flatbuffers::Verifier verifier((const uint8_t *)commandBuffer.constData(), commandBuffer.size()); | ||
246 | if (Sink::Commands::VerifySecretBuffer(verifier)) { | ||
247 | auto buffer = Sink::Commands::GetSecret(commandBuffer.constData()); | ||
248 | loadResource().setSecret(QString{buffer->secret()->c_str()}); | ||
249 | } else { | ||
250 | SinkWarning() << "received invalid command"; | ||
251 | } | ||
252 | break; | ||
253 | } | ||
254 | |||
243 | case Sink::Commands::SynchronizeCommand: | 255 | case Sink::Commands::SynchronizeCommand: |
244 | case Sink::Commands::InspectionCommand: | 256 | case Sink::Commands::InspectionCommand: |
245 | case Sink::Commands::DeleteEntityCommand: | 257 | case Sink::Commands::DeleteEntityCommand: |
diff --git a/common/resource.cpp b/common/resource.cpp index 804f0bf..78cc51b 100644 --- a/common/resource.cpp +++ b/common/resource.cpp | |||
@@ -51,6 +51,11 @@ void Resource::setLowerBoundRevision(qint64 revision) | |||
51 | Q_UNUSED(revision) | 51 | Q_UNUSED(revision) |
52 | } | 52 | } |
53 | 53 | ||
54 | void Resource::setSecret(const QString &s) | ||
55 | { | ||
56 | Q_UNUSED(s) | ||
57 | } | ||
58 | |||
54 | 59 | ||
55 | class ResourceFactory::Private | 60 | class ResourceFactory::Private |
56 | { | 61 | { |
diff --git a/common/resource.h b/common/resource.h index a50ffb5..938f267 100644 --- a/common/resource.h +++ b/common/resource.h | |||
@@ -47,6 +47,8 @@ public: | |||
47 | */ | 47 | */ |
48 | virtual void setLowerBoundRevision(qint64 revision); | 48 | virtual void setLowerBoundRevision(qint64 revision); |
49 | 49 | ||
50 | virtual void setSecret(const QString &s); | ||
51 | |||
50 | signals: | 52 | signals: |
51 | void revisionUpdated(qint64); | 53 | void revisionUpdated(qint64); |
52 | void notify(Notification); | 54 | void notify(Notification); |
diff --git a/common/resourceaccess.cpp b/common/resourceaccess.cpp index 35fa46c..5ed3609 100644 --- a/common/resourceaccess.cpp +++ b/common/resourceaccess.cpp | |||
@@ -32,9 +32,11 @@ | |||
32 | #include "common/revisionreplayed_generated.h" | 32 | #include "common/revisionreplayed_generated.h" |
33 | #include "common/inspection_generated.h" | 33 | #include "common/inspection_generated.h" |
34 | #include "common/flush_generated.h" | 34 | #include "common/flush_generated.h" |
35 | #include "common/secret_generated.h" | ||
35 | #include "common/entitybuffer.h" | 36 | #include "common/entitybuffer.h" |
36 | #include "common/bufferutils.h" | 37 | #include "common/bufferutils.h" |
37 | #include "common/test.h" | 38 | #include "common/test.h" |
39 | #include "common/secretstore.h" | ||
38 | #include "log.h" | 40 | #include "log.h" |
39 | 41 | ||
40 | #include <QCoreApplication> | 42 | #include <QCoreApplication> |
@@ -234,6 +236,12 @@ ResourceAccess::ResourceAccess(const QByteArray &resourceInstanceIdentifier, con | |||
234 | { | 236 | { |
235 | mResourceStatus = Sink::ApplicationDomain::NoStatus; | 237 | mResourceStatus = Sink::ApplicationDomain::NoStatus; |
236 | SinkTrace() << "Starting access"; | 238 | SinkTrace() << "Starting access"; |
239 | |||
240 | QObject::connect(&SecretStore::instance(), &SecretStore::secretAvailable, this, [this] (const QByteArray &resourceId) { | ||
241 | if (resourceId == d->resourceInstanceIdentifier) { | ||
242 | sendSecret(SecretStore::instance().resourceSecret(d->resourceInstanceIdentifier)).exec(); | ||
243 | } | ||
244 | }); | ||
237 | } | 245 | } |
238 | 246 | ||
239 | ResourceAccess::~ResourceAccess() | 247 | ResourceAccess::~ResourceAccess() |
@@ -387,6 +395,15 @@ KAsync::Job<void> ResourceAccess::sendFlushCommand(int flushType, const QByteArr | |||
387 | return sendCommand(Sink::Commands::FlushCommand, fbb); | 395 | return sendCommand(Sink::Commands::FlushCommand, fbb); |
388 | } | 396 | } |
389 | 397 | ||
398 | KAsync::Job<void> ResourceAccess::sendSecret(const QString &secret) | ||
399 | { | ||
400 | flatbuffers::FlatBufferBuilder fbb; | ||
401 | auto s = fbb.CreateString(secret.toStdString()); | ||
402 | auto location = Sink::Commands::CreateSecret(fbb, s); | ||
403 | Sink::Commands::FinishSecretBuffer(fbb, location); | ||
404 | return sendCommand(Sink::Commands::SecretCommand, fbb); | ||
405 | } | ||
406 | |||
390 | void ResourceAccess::open() | 407 | void ResourceAccess::open() |
391 | { | 408 | { |
392 | if (d->socket && d->socket->isValid()) { | 409 | if (d->socket && d->socket->isValid()) { |
@@ -483,6 +500,11 @@ void ResourceAccess::connected() | |||
483 | Commands::write(d->socket.data(), ++d->messageId, Commands::HandshakeCommand, fbb); | 500 | Commands::write(d->socket.data(), ++d->messageId, Commands::HandshakeCommand, fbb); |
484 | } | 501 | } |
485 | 502 | ||
503 | auto secret = SecretStore::instance().resourceSecret(d->resourceInstanceIdentifier); | ||
504 | if (!secret.isEmpty()) { | ||
505 | sendSecret(secret).exec(); | ||
506 | } | ||
507 | |||
486 | // Reenqueue pending commands, we failed to send them | 508 | // Reenqueue pending commands, we failed to send them |
487 | processPendingCommandQueue(); | 509 | processPendingCommandQueue(); |
488 | // Send queued commands | 510 | // Send queued commands |
diff --git a/common/resourceaccess.h b/common/resourceaccess.h index b6a0b34..890cc6d 100644 --- a/common/resourceaccess.h +++ b/common/resourceaccess.h | |||
@@ -80,6 +80,11 @@ public: | |||
80 | return KAsync::null<void>(); | 80 | return KAsync::null<void>(); |
81 | } | 81 | } |
82 | 82 | ||
83 | virtual KAsync::Job<void> sendSecret(const QString &secret) | ||
84 | { | ||
85 | return KAsync::null<void>(); | ||
86 | } | ||
87 | |||
83 | int getResourceStatus() const | 88 | int getResourceStatus() const |
84 | { | 89 | { |
85 | return mResourceStatus; | 90 | return mResourceStatus; |
@@ -121,6 +126,7 @@ public: | |||
121 | KAsync::Job<void> | 126 | KAsync::Job<void> |
122 | sendInspectionCommand(int inspectionType,const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expecedValue) Q_DECL_OVERRIDE; | 127 | sendInspectionCommand(int inspectionType,const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expecedValue) Q_DECL_OVERRIDE; |
123 | KAsync::Job<void> sendFlushCommand(int flushType, const QByteArray &flushId) Q_DECL_OVERRIDE; | 128 | KAsync::Job<void> sendFlushCommand(int flushType, const QByteArray &flushId) Q_DECL_OVERRIDE; |
129 | KAsync::Job<void> sendSecret(const QString &secret) Q_DECL_OVERRIDE; | ||
124 | /** | 130 | /** |
125 | * Tries to connect to server, and returns a connected socket on success. | 131 | * Tries to connect to server, and returns a connected socket on success. |
126 | */ | 132 | */ |
diff --git a/common/secretstore.cpp b/common/secretstore.cpp new file mode 100644 index 0000000..39d5206 --- /dev/null +++ b/common/secretstore.cpp | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) version 3, or any | ||
8 | * later version accepted by the membership of KDE e.V. (or its | ||
9 | * successor approved by the membership of KDE e.V.), which shall | ||
10 | * act as a proxy defined in Section 6 of version 3 of the license. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | ||
20 | |||
21 | #include "secretstore.h" | ||
22 | |||
23 | #include <QGlobalStatic> | ||
24 | #include <QMap> | ||
25 | #include <QString> | ||
26 | #include <QMutexLocker> | ||
27 | |||
28 | using namespace Sink; | ||
29 | |||
30 | QMutex SecretStore::sMutex; | ||
31 | |||
32 | SecretStore &SecretStore::instance() | ||
33 | { | ||
34 | static SecretStore s; | ||
35 | return s; | ||
36 | } | ||
37 | |||
38 | void SecretStore::insert(const QByteArray &resourceId, const QString &secret) | ||
39 | { | ||
40 | QMutexLocker locker{&sMutex}; | ||
41 | mCache.insert(resourceId, secret); | ||
42 | locker.unlock(); | ||
43 | emit secretAvailable(resourceId); | ||
44 | } | ||
45 | |||
46 | QString SecretStore::resourceSecret(const QByteArray &resourceId) | ||
47 | { | ||
48 | QMutexLocker locker{&sMutex}; | ||
49 | return mCache.value(resourceId); | ||
50 | } | ||
51 | |||
diff --git a/common/secretstore.h b/common/secretstore.h new file mode 100644 index 0000000..04fdaba --- /dev/null +++ b/common/secretstore.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) version 3, or any | ||
8 | * later version accepted by the membership of KDE e.V. (or its | ||
9 | * successor approved by the membership of KDE e.V.), which shall | ||
10 | * act as a proxy defined in Section 6 of version 3 of the license. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | ||
20 | |||
21 | #pragma once | ||
22 | |||
23 | #include "sink_export.h" | ||
24 | |||
25 | #include <QObject> | ||
26 | #include <QString> | ||
27 | #include <QMap> | ||
28 | #include <QMutex> | ||
29 | |||
30 | namespace Sink { | ||
31 | |||
32 | class SINK_EXPORT SecretStore : public QObject | ||
33 | { | ||
34 | Q_OBJECT | ||
35 | public: | ||
36 | static SecretStore &instance(); | ||
37 | |||
38 | void insert(const QByteArray &resourceId, const QString &secret); | ||
39 | QString resourceSecret(const QByteArray &resourceId); | ||
40 | |||
41 | Q_SIGNALS: | ||
42 | void secretAvailable(const QByteArray &resourceId); | ||
43 | |||
44 | private: | ||
45 | QMap<QByteArray, QString> mCache; | ||
46 | static QMutex sMutex; | ||
47 | }; | ||
48 | |||
49 | } | ||
50 | |||
diff --git a/common/synchronizer.cpp b/common/synchronizer.cpp index 959cf48..4a0ac46 100644 --- a/common/synchronizer.cpp +++ b/common/synchronizer.cpp | |||
@@ -49,6 +49,20 @@ Synchronizer::~Synchronizer() | |||
49 | 49 | ||
50 | } | 50 | } |
51 | 51 | ||
52 | void Synchronizer::setSecret(const QString &s) | ||
53 | { | ||
54 | mSecret = s; | ||
55 | |||
56 | if (!mSyncRequestQueue.isEmpty()) { | ||
57 | processSyncQueue().exec(); | ||
58 | } | ||
59 | } | ||
60 | |||
61 | QString Synchronizer::secret() const | ||
62 | { | ||
63 | return mSecret; | ||
64 | } | ||
65 | |||
52 | void Synchronizer::setup(const std::function<void(int commandId, const QByteArray &data)> &enqueueCommandCallback, MessageQueue &mq) | 66 | void Synchronizer::setup(const std::function<void(int commandId, const QByteArray &data)> &enqueueCommandCallback, MessageQueue &mq) |
53 | { | 67 | { |
54 | mEnqueue = enqueueCommandCallback; | 68 | mEnqueue = enqueueCommandCallback; |
@@ -474,6 +488,10 @@ void Synchronizer::setBusy(bool busy, const QString &reason, const QByteArray re | |||
474 | 488 | ||
475 | KAsync::Job<void> Synchronizer::processSyncQueue() | 489 | KAsync::Job<void> Synchronizer::processSyncQueue() |
476 | { | 490 | { |
491 | if (secret().isEmpty()) { | ||
492 | SinkLogCtx(mLogCtx) << "Secret not available but required."; | ||
493 | return KAsync::null<void>(); | ||
494 | } | ||
477 | if (mSyncRequestQueue.isEmpty()) { | 495 | if (mSyncRequestQueue.isEmpty()) { |
478 | SinkLogCtx(mLogCtx) << "All requests processed."; | 496 | SinkLogCtx(mLogCtx) << "All requests processed."; |
479 | return KAsync::null<void>(); | 497 | return KAsync::null<void>(); |
diff --git a/common/synchronizer.h b/common/synchronizer.h index cc082be..bd03ba3 100644 --- a/common/synchronizer.h +++ b/common/synchronizer.h | |||
@@ -60,6 +60,8 @@ public: | |||
60 | bool allChangesReplayed() Q_DECL_OVERRIDE; | 60 | bool allChangesReplayed() Q_DECL_OVERRIDE; |
61 | void flushComplete(const QByteArray &flushId); | 61 | void flushComplete(const QByteArray &flushId); |
62 | 62 | ||
63 | void setSecret(const QString &s); | ||
64 | |||
63 | signals: | 65 | signals: |
64 | void notify(Notification); | 66 | void notify(Notification); |
65 | 67 | ||
@@ -78,6 +80,8 @@ protected: | |||
78 | virtual KAsync::Job<QByteArray> replay(const Sink::ApplicationDomain::Mail &, Sink::Operation, const QByteArray &oldRemoteId, const QList<QByteArray> &); | 80 | virtual KAsync::Job<QByteArray> replay(const Sink::ApplicationDomain::Mail &, Sink::Operation, const QByteArray &oldRemoteId, const QList<QByteArray> &); |
79 | virtual KAsync::Job<QByteArray> replay(const Sink::ApplicationDomain::Folder &, Sink::Operation, const QByteArray &oldRemoteId, const QList<QByteArray> &); | 81 | virtual KAsync::Job<QByteArray> replay(const Sink::ApplicationDomain::Folder &, Sink::Operation, const QByteArray &oldRemoteId, const QList<QByteArray> &); |
80 | protected: | 82 | protected: |
83 | QString secret() const; | ||
84 | |||
81 | ///Calls the callback to enqueue the command | 85 | ///Calls the callback to enqueue the command |
82 | void enqueueCommand(int commandId, const QByteArray &data); | 86 | void enqueueCommand(int commandId, const QByteArray &data); |
83 | 87 | ||
@@ -224,6 +228,7 @@ private: | |||
224 | MessageQueue *mMessageQueue; | 228 | MessageQueue *mMessageQueue; |
225 | bool mSyncInProgress; | 229 | bool mSyncInProgress; |
226 | QMultiHash<QByteArray, SyncRequest> mPendingSyncRequests; | 230 | QMultiHash<QByteArray, SyncRequest> mPendingSyncRequests; |
231 | QString mSecret; | ||
227 | }; | 232 | }; |
228 | 233 | ||
229 | } | 234 | } |
diff --git a/examples/davresource/davresource.cpp b/examples/davresource/davresource.cpp index 22c502f..fa5e612 100644 --- a/examples/davresource/davresource.cpp +++ b/examples/davresource/davresource.cpp | |||
@@ -132,8 +132,8 @@ public: | |||
132 | KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &query) Q_DECL_OVERRIDE | 132 | KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &query) Q_DECL_OVERRIDE |
133 | { | 133 | { |
134 | if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Addressbook>()) { | 134 | if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Addressbook>()) { |
135 | SinkLogCtx(mLogCtx) << "Synchronizing addressbooks:" << mResourceUrl.url(); | 135 | SinkLogCtx(mLogCtx) << "Synchronizing addressbooks:" << resourceUrl().url(); |
136 | auto collectionsFetchJob = new KDAV2::DavCollectionsFetchJob(mResourceUrl); | 136 | auto collectionsFetchJob = new KDAV2::DavCollectionsFetchJob(resourceUrl()); |
137 | auto job = runJob(collectionsFetchJob).then([this, collectionsFetchJob] (const KAsync::Error &error) { | 137 | auto job = runJob(collectionsFetchJob).then([this, collectionsFetchJob] (const KAsync::Error &error) { |
138 | if (error) { | 138 | if (error) { |
139 | SinkWarningCtx(mLogCtx) << "Failed to synchronize addressbooks." << collectionsFetchJob->errorString(); | 139 | SinkWarningCtx(mLogCtx) << "Failed to synchronize addressbooks." << collectionsFetchJob->errorString(); |
@@ -147,7 +147,7 @@ public: | |||
147 | auto ridList = QSharedPointer<QByteArrayList>::create(); | 147 | auto ridList = QSharedPointer<QByteArrayList>::create(); |
148 | auto total = QSharedPointer<int>::create(0); | 148 | auto total = QSharedPointer<int>::create(0); |
149 | auto progress = QSharedPointer<int>::create(0); | 149 | auto progress = QSharedPointer<int>::create(0); |
150 | auto collectionsFetchJob = new KDAV2::DavCollectionsFetchJob(mResourceUrl); | 150 | auto collectionsFetchJob = new KDAV2::DavCollectionsFetchJob(resourceUrl()); |
151 | auto job = runJob(collectionsFetchJob).then([this, collectionsFetchJob] { | 151 | auto job = runJob(collectionsFetchJob).then([this, collectionsFetchJob] { |
152 | synchronizeAddressbooks(collectionsFetchJob ->collections()); | 152 | synchronizeAddressbooks(collectionsFetchJob ->collections()); |
153 | return collectionsFetchJob->collections(); | 153 | return collectionsFetchJob->collections(); |
@@ -233,8 +233,20 @@ KAsync::Job<QByteArray> replay(const ApplicationDomain::Contact &contact, Sink:: | |||
233 | return KAsync::null<QByteArray>(); | 233 | return KAsync::null<QByteArray>(); |
234 | } | 234 | } |
235 | 235 | ||
236 | KDAV2::DavUrl resourceUrl() const | ||
237 | { | ||
238 | if (secret().isEmpty()) { | ||
239 | return {}; | ||
240 | } | ||
241 | auto resourceUrl = mServer; | ||
242 | resourceUrl.setUserName(mUsername); | ||
243 | resourceUrl.setPassword(secret()); | ||
244 | return KDAV2::DavUrl{resourceUrl, KDAV2::CardDav}; | ||
245 | } | ||
246 | |||
236 | public: | 247 | public: |
237 | KDAV2::DavUrl mResourceUrl; | 248 | QUrl mServer; |
249 | QString mUsername; | ||
238 | }; | 250 | }; |
239 | 251 | ||
240 | 252 | ||
@@ -242,14 +254,12 @@ DavResource::DavResource(const Sink::ResourceContext &resourceContext) | |||
242 | : Sink::GenericResource(resourceContext) | 254 | : Sink::GenericResource(resourceContext) |
243 | { | 255 | { |
244 | auto config = ResourceConfig::getConfiguration(resourceContext.instanceId()); | 256 | auto config = ResourceConfig::getConfiguration(resourceContext.instanceId()); |
245 | auto resourceUrl = QUrl::fromUserInput(config.value("server").toString()); | 257 | auto server = QUrl::fromUserInput(config.value("server").toString()); |
246 | resourceUrl.setUserName(config.value("username").toString()); | 258 | auto username = config.value("username").toString(); |
247 | resourceUrl.setPassword(config.value("password").toString()); | ||
248 | |||
249 | mResourceUrl = KDAV2::DavUrl(resourceUrl, KDAV2::CardDav); | ||
250 | 259 | ||
251 | auto synchronizer = QSharedPointer<ContactSynchronizer>::create(resourceContext); | 260 | auto synchronizer = QSharedPointer<ContactSynchronizer>::create(resourceContext); |
252 | synchronizer->mResourceUrl = mResourceUrl; | 261 | synchronizer->mServer = server; |
262 | synchronizer->mUsername = username; | ||
253 | setupSynchronizer(synchronizer); | 263 | setupSynchronizer(synchronizer); |
254 | 264 | ||
255 | setupPreprocessors(ENTITY_TYPE_CONTACT, QVector<Sink::Preprocessor*>() << new ContactPropertyExtractor); | 265 | setupPreprocessors(ENTITY_TYPE_CONTACT, QVector<Sink::Preprocessor*>() << new ContactPropertyExtractor); |
diff --git a/examples/davresource/davresource.h b/examples/davresource/davresource.h index db175a4..b4f9e5a 100644 --- a/examples/davresource/davresource.h +++ b/examples/davresource/davresource.h | |||
@@ -44,11 +44,6 @@ class DavResource : public Sink::GenericResource | |||
44 | { | 44 | { |
45 | public: | 45 | public: |
46 | DavResource(const Sink::ResourceContext &resourceContext); | 46 | DavResource(const Sink::ResourceContext &resourceContext); |
47 | |||
48 | private: | ||
49 | QStringList listAvailableFolders(); | ||
50 | |||
51 | KDAV2::DavUrl mResourceUrl; | ||
52 | }; | 47 | }; |
53 | 48 | ||
54 | class DavResourceFactory : public Sink::ResourceFactory | 49 | class DavResourceFactory : public Sink::ResourceFactory |
diff --git a/examples/dummyresource/resourcefactory.cpp b/examples/dummyresource/resourcefactory.cpp index dffdfc9..f3c8be2 100644 --- a/examples/dummyresource/resourcefactory.cpp +++ b/examples/dummyresource/resourcefactory.cpp | |||
@@ -50,7 +50,7 @@ class DummySynchronizer : public Sink::Synchronizer { | |||
50 | DummySynchronizer(const Sink::ResourceContext &context) | 50 | DummySynchronizer(const Sink::ResourceContext &context) |
51 | : Sink::Synchronizer(context) | 51 | : Sink::Synchronizer(context) |
52 | { | 52 | { |
53 | 53 | setSecret("dummy"); | |
54 | } | 54 | } |
55 | 55 | ||
56 | Sink::ApplicationDomain::Event::Ptr createEvent(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data) | 56 | Sink::ApplicationDomain::Event::Ptr createEvent(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data) |
diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp index 3ae7fd7..2aba6b0 100644 --- a/examples/imapresource/imapresource.cpp +++ b/examples/imapresource/imapresource.cpp | |||
@@ -470,7 +470,7 @@ public: | |||
470 | { | 470 | { |
471 | SinkTrace() << "Connecting to:" << mServer << mPort; | 471 | SinkTrace() << "Connecting to:" << mServer << mPort; |
472 | SinkTrace() << "as:" << mUser; | 472 | SinkTrace() << "as:" << mUser; |
473 | return imap->login(mUser, mPassword) | 473 | return imap->login(mUser, secret()) |
474 | .addToContext(imap); | 474 | .addToContext(imap); |
475 | } | 475 | } |
476 | 476 | ||
@@ -513,6 +513,8 @@ public: | |||
513 | return {ApplicationDomain::NoServerError, error.errorMessage}; | 513 | return {ApplicationDomain::NoServerError, error.errorMessage}; |
514 | case Imap::ConnectionLost: | 514 | case Imap::ConnectionLost: |
515 | return {ApplicationDomain::ConnectionLostError, error.errorMessage}; | 515 | return {ApplicationDomain::ConnectionLostError, error.errorMessage}; |
516 | case Imap::MissingCredentialsError: | ||
517 | return {ApplicationDomain::MissingCredentialsError, error.errorMessage}; | ||
516 | default: | 518 | default: |
517 | return {ApplicationDomain::UnknownError, error.errorMessage}; | 519 | return {ApplicationDomain::UnknownError, error.errorMessage}; |
518 | } | 520 | } |
@@ -631,7 +633,7 @@ public: | |||
631 | } | 633 | } |
632 | } | 634 | } |
633 | auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort, &mSessionCache); | 635 | auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort, &mSessionCache); |
634 | auto login = imap->login(mUser, mPassword); | 636 | auto login = imap->login(mUser, secret()); |
635 | KAsync::Job<QByteArray> job = KAsync::null<QByteArray>(); | 637 | KAsync::Job<QByteArray> job = KAsync::null<QByteArray>(); |
636 | if (operation == Sink::Operation_Creation) { | 638 | if (operation == Sink::Operation_Creation) { |
637 | const QString mailbox = syncStore().resolveLocalId(ENTITY_TYPE_FOLDER, mail.getFolder()); | 639 | const QString mailbox = syncStore().resolveLocalId(ENTITY_TYPE_FOLDER, mail.getFolder()); |
@@ -716,7 +718,7 @@ public: | |||
716 | } | 718 | } |
717 | } | 719 | } |
718 | auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort, &mSessionCache); | 720 | auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort, &mSessionCache); |
719 | auto login = imap->login(mUser, mPassword); | 721 | auto login = imap->login(mUser, secret()); |
720 | if (operation == Sink::Operation_Creation) { | 722 | if (operation == Sink::Operation_Creation) { |
721 | QString parentFolder; | 723 | QString parentFolder; |
722 | if (!folder.getParent().isEmpty()) { | 724 | if (!folder.getParent().isEmpty()) { |
@@ -736,7 +738,7 @@ public: | |||
736 | }); | 738 | }); |
737 | } else { //We try to merge special purpose folders first | 739 | } else { //We try to merge special purpose folders first |
738 | auto specialPurposeFolders = QSharedPointer<QHash<QByteArray, QString>>::create(); | 740 | auto specialPurposeFolders = QSharedPointer<QHash<QByteArray, QString>>::create(); |
739 | auto mergeJob = imap->login(mUser, mPassword) | 741 | auto mergeJob = imap->login(mUser, secret()) |
740 | .then(imap->fetchFolders([=](const Imap::Folder &folder) { | 742 | .then(imap->fetchFolders([=](const Imap::Folder &folder) { |
741 | if (SpecialPurpose::isSpecialPurposeFolderName(folder.name())) { | 743 | if (SpecialPurpose::isSpecialPurposeFolderName(folder.name())) { |
742 | specialPurposeFolders->insert(SpecialPurpose::getSpecialPurposeType(folder.name()), folder.path()); | 744 | specialPurposeFolders->insert(SpecialPurpose::getSpecialPurposeType(folder.name()), folder.path()); |
@@ -790,7 +792,6 @@ public: | |||
790 | QString mServer; | 792 | QString mServer; |
791 | int mPort; | 793 | int mPort; |
792 | QString mUser; | 794 | QString mUser; |
793 | QString mPassword; | ||
794 | int mDaysToSync = 0; | 795 | int mDaysToSync = 0; |
795 | QByteArray mResourceInstanceIdentifier; | 796 | QByteArray mResourceInstanceIdentifier; |
796 | Imap::SessionCache mSessionCache; | 797 | Imap::SessionCache mSessionCache; |
@@ -959,7 +960,6 @@ ImapResource::ImapResource(const ResourceContext &resourceContext) | |||
959 | auto server = config.value("server").toString(); | 960 | auto server = config.value("server").toString(); |
960 | auto port = config.value("port").toInt(); | 961 | auto port = config.value("port").toInt(); |
961 | auto user = config.value("username").toString(); | 962 | auto user = config.value("username").toString(); |
962 | auto password = config.value("password").toString(); | ||
963 | if (server.startsWith("imap")) { | 963 | if (server.startsWith("imap")) { |
964 | server.remove("imap://"); | 964 | server.remove("imap://"); |
965 | server.remove("imaps://"); | 965 | server.remove("imaps://"); |
@@ -974,7 +974,6 @@ ImapResource::ImapResource(const ResourceContext &resourceContext) | |||
974 | synchronizer->mServer = server; | 974 | synchronizer->mServer = server; |
975 | synchronizer->mPort = port; | 975 | synchronizer->mPort = port; |
976 | synchronizer->mUser = user; | 976 | synchronizer->mUser = user; |
977 | synchronizer->mPassword = password; | ||
978 | synchronizer->mDaysToSync = 14; | 977 | synchronizer->mDaysToSync = 14; |
979 | setupSynchronizer(synchronizer); | 978 | setupSynchronizer(synchronizer); |
980 | 979 | ||
@@ -982,7 +981,8 @@ ImapResource::ImapResource(const ResourceContext &resourceContext) | |||
982 | inspector->mServer = server; | 981 | inspector->mServer = server; |
983 | inspector->mPort = port; | 982 | inspector->mPort = port; |
984 | inspector->mUser = user; | 983 | inspector->mUser = user; |
985 | inspector->mPassword = password; | 984 | //TODO |
985 | // inspector->mPassword = password; | ||
986 | setupInspector(inspector); | 986 | setupInspector(inspector); |
987 | 987 | ||
988 | setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new SpecialPurposeProcessor << new MailPropertyExtractor); | 988 | setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new SpecialPurposeProcessor << new MailPropertyExtractor); |
diff --git a/examples/imapresource/imapserverproxy.cpp b/examples/imapresource/imapserverproxy.cpp index 16887b1..317fbdc 100644 --- a/examples/imapresource/imapserverproxy.cpp +++ b/examples/imapresource/imapserverproxy.cpp | |||
@@ -139,6 +139,9 @@ ImapServerProxy::ImapServerProxy(const QString &serverUrl, int port, SessionCach | |||
139 | 139 | ||
140 | KAsync::Job<void> ImapServerProxy::login(const QString &username, const QString &password) | 140 | KAsync::Job<void> ImapServerProxy::login(const QString &username, const QString &password) |
141 | { | 141 | { |
142 | if (password.isEmpty()) { | ||
143 | return KAsync::error(Imap::MissingCredentialsError); | ||
144 | } | ||
142 | if (mSessionCache) { | 145 | if (mSessionCache) { |
143 | auto session = mSessionCache->getSession(); | 146 | auto session = mSessionCache->getSession(); |
144 | if (session.isValid()) { | 147 | if (session.isValid()) { |
diff --git a/examples/imapresource/imapserverproxy.h b/examples/imapresource/imapserverproxy.h index 86e3378..9e73f68 100644 --- a/examples/imapresource/imapserverproxy.h +++ b/examples/imapresource/imapserverproxy.h | |||
@@ -35,6 +35,7 @@ enum ErrorCode { | |||
35 | CouldNotConnectError, | 35 | CouldNotConnectError, |
36 | SslHandshakeError, | 36 | SslHandshakeError, |
37 | ConnectionLost, | 37 | ConnectionLost, |
38 | MissingCredentialsError, | ||
38 | UnknownError | 39 | UnknownError |
39 | }; | 40 | }; |
40 | 41 | ||
diff --git a/examples/maildirresource/maildirresource.cpp b/examples/maildirresource/maildirresource.cpp index b406f63..41f2433 100644 --- a/examples/maildirresource/maildirresource.cpp +++ b/examples/maildirresource/maildirresource.cpp | |||
@@ -215,7 +215,7 @@ public: | |||
215 | MaildirSynchronizer(const Sink::ResourceContext &resourceContext) | 215 | MaildirSynchronizer(const Sink::ResourceContext &resourceContext) |
216 | : Sink::Synchronizer(resourceContext) | 216 | : Sink::Synchronizer(resourceContext) |
217 | { | 217 | { |
218 | 218 | setSecret("dummy"); | |
219 | } | 219 | } |
220 | 220 | ||
221 | static QStringList listRecursive( const QString &root, const KPIM::Maildir &dir ) | 221 | static QStringList listRecursive( const QString &root, const KPIM::Maildir &dir ) |