diff options
Diffstat (limited to 'common')
-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 |
15 files changed, 192 insertions, 0 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 | } |