This repository was archived by the owner on Mar 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathsetup.h
416 lines (366 loc) · 15.9 KB
/
setup.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
#ifndef QTDATASYNC_SETUP_H
#define QTDATASYNC_SETUP_H
#include <functional>
#include <ratio>
#include <QtCore/qobject.h>
#include <QtCore/qlogging.h>
#include <QtCore/qurl.h>
class QLockFile;
#include <QtNetwork/qsslconfiguration.h>
#include "QtDataSync/qtdatasync_global.h"
#include "QtDataSync/exception.h"
#include "QtDataSync/remoteconfig.h"
class QJsonSerializer;
namespace QtDataSync {
//! @private
template<typename TRatio>
Q_DECL_CONSTEXPR inline int ratioBytes(intmax_t value);
//! Interprets value as kilobytes and returns it converted to bytes
Q_DECL_CONSTEXPR inline int KB(intmax_t value);
//! Interprets value as megabytes and returns it converted to bytes
Q_DECL_CONSTEXPR inline int MB(intmax_t value);
//! Interprets value as gigabytes and returns it converted to bytes
Q_DECL_CONSTEXPR inline int GB(intmax_t value);
#if __cplusplus >= 201402L
//! Sub namespace that defines the literals for MB, KB, GB
namespace literals {
//! literal for kilobytes
Q_DECL_CONSTEXPR inline int operator "" _kb(unsigned long long x) {
return KB(static_cast<intmax_t>(x));
}
//! literal for megabytes
Q_DECL_CONSTEXPR inline int operator "" _mb(unsigned long long x) {
return MB(static_cast<intmax_t>(x));
}
//! literal for gigabytes
Q_DECL_CONSTEXPR inline int operator "" _gb(unsigned long long x) {
return GB(static_cast<intmax_t>(x));
}
}
#endif
class ConflictResolver;
class KeyStore;
class SetupPrivate;
//! The class to setup and create datasync instances
class Q_DATASYNC_EXPORT Setup
{
Q_GADGET
Q_DISABLE_COPY(Setup)
//! The local storage directoy used by the instance
Q_PROPERTY(QString localDir READ localDir WRITE setLocalDir RESET resetLocalDir)
//! The url to be used to host the remote object sources, and to connect to to acquire the replicas
Q_PROPERTY(QUrl remoteObjectHost READ remoteObjectHost WRITE setRemoteObjectHost RESET resetRemoteObjectHost)
//! The serializer to be used to serialize and deserialize data to and from the store
Q_PROPERTY(QJsonSerializer* serializer READ serializer WRITE setSerializer RESET resetSerializer)
//! An optional conflict resolver to handle merge conflicts
Q_PROPERTY(QtDataSync::ConflictResolver* conflictResolver READ conflictResolver WRITE setConflictResolver RESET resetConflictResolver)
//! An alternative handler for fatal errors
Q_PROPERTY(FatalErrorHandler fatalErrorHandler READ fatalErrorHandler WRITE setFatalErrorHandler RESET resetFatalErrorHandler)
//! The size of the internal database cache, in bytes
Q_PROPERTY(int cacheSize READ cacheSize WRITE setCacheSize RESET resetCacheSize)
//! Specify whether deleted datasets should persist
Q_PROPERTY(bool persistDeletedVersion READ persistDeletedVersion WRITE setPersistDeletedVersion RESET resetPersistDeletedVersion)
//! The policiy for how to handle conflicts
Q_PROPERTY(SyncPolicy syncPolicy READ syncPolicy WRITE setSyncPolicy RESET resetSyncPolicy)
//! The ssl configuration to be used to connect to the remote
Q_PROPERTY(QSslConfiguration sslConfiguration READ sslConfiguration WRITE setSslConfiguration RESET resetSslConfiguration)
//! The configuration to be used to connect to the remote
Q_PROPERTY(QtDataSync::RemoteConfig remoteConfiguration READ remoteConfiguration WRITE setRemoteConfiguration RESET resetRemoteConfiguration)
//! The name of the preferred keystore provider
Q_PROPERTY(QString keyStoreProvider READ keyStoreProvider WRITE setKeyStoreProvider RESET resetKeyStoreProvider)
//! The algorithmic scheme to be used for new signature keys
Q_PROPERTY(SignatureScheme signatureScheme READ signatureScheme WRITE setSignatureScheme RESET resetSignatureScheme)
//! The generation parameter for the signature key
Q_PROPERTY(QVariant signatureKeyParam READ signatureKeyParam WRITE setSignatureKeyParam RESET resetSignatureKeyParam)
//! The algorithmic scheme to be used for new encryption keys
Q_PROPERTY(EncryptionScheme encryptionScheme READ encryptionScheme WRITE setEncryptionScheme RESET resetEncryptionScheme)
//! The generation parameter for the encryption key
Q_PROPERTY(QVariant encryptionKeyParam READ encryptionKeyParam WRITE setEncryptionKeyParam RESET resetEncryptionKeyParam)
//! The algorithmic scheme to be used for new secret exchange keys (which are symmetric)
Q_PROPERTY(CipherScheme cipherScheme READ cipherScheme WRITE setCipherScheme RESET resetCipherScheme)
//! The size in bytes for the secret exchange key (which is symmetric)
Q_PROPERTY(qint32 cipherKeySize READ cipherKeySize WRITE setCipherKeySize RESET resetCipherKeySize) //MAJOR make uint
//! The logging mode for database change events
Q_PROPERTY(EventMode eventLoggingMode READ eventLoggingMode WRITE setEventLoggingMode RESET resetEventLoggingMode REVISION 2)
public:
//! Typedef of an error handler function. See Setup::fatalErrorHandler
using FatalErrorHandler = std::function<void (QString, QString, const QMessageLogContext &)>;
//! Defines the possible policies on how to treat merge conflicts between change and delete
enum SyncPolicy {
PreferChanged, //!< Keep the changed entry
PreferDeleted //! < Discard the change and keep the entry deleted
};
Q_ENUM(SyncPolicy)
//! The signature schemes supported for Setup::signatureScheme
enum SignatureScheme {
RSA_PSS_SHA3_512, //!< RSA in PSS mode with Sha3 hash of 512 bits
ECDSA_ECP_SHA3_512, //!< ECDSA on prime curves with Sha3 hash of 512 bits
ECNR_ECP_SHA3_512, //!< ECNR on prime curves with Sha3 hash of 512 bits
ED25519 //!< ed25519 signature scheme based on the ed25519 curve (Requires at least crypto++ 8.0)
};
Q_ENUM(SignatureScheme)
//! The encryption schemes supported for Setup::encryptionScheme
enum EncryptionScheme {
RSA_OAEP_SHA3_512, //!< RSA in OAEP mode with Sha3 hash of 512 bits
ECIES_ECP_SHA3_512 //!< ECIES on prime curves with Sha3 hash of 512 bits (Requires at least crypto++ 6.0)
};
Q_ENUM(EncryptionScheme)
//! The symmetric cipher schemes supported for Setup::cipherScheme
enum CipherScheme {
AES_EAX, //!< AES operating in EAX authenticated encryption mode
AES_GCM, //!< AES operating in GCM authenticated encryption mode
TWOFISH_EAX, //!< Twofish operating in EAX authenticated encryption mode
TWOFISH_GCM, //!< Twofish operating in GCM authenticated encryption mode
SERPENT_EAX, //!< Serpent operating in EAX authenticated encryption mode
SERPENT_GCM, //!< Serpent operating in GCM authenticated encryption mode
IDEA_EAX, //!< IDEA operating in EAX authenticated encryption mode
};
Q_ENUM(CipherScheme)
//! Elliptic curves supported as key parameter for Setup::signatureKeyParam and Setup::encryptionKeyParam in case an ECC scheme is used
enum EllipticCurve {
secp112r1,
secp128r1,
secp160r1,
secp192r1,
secp224r1,
secp256r1,
secp384r1,
secp521r1,
brainpoolP160r1,
brainpoolP192r1,
brainpoolP224r1,
brainpoolP256r1,
brainpoolP320r1,
brainpoolP384r1,
brainpoolP512r1,
secp112r2,
secp128r2,
secp160r2,
secp160k1,
secp192k1,
secp224k1,
secp256k1
};
Q_ENUM(EllipticCurve)
//! Possible values for the event logging mode change
enum class EventMode {
Unchanged, //!< Keep as is. If it was previously enabled, it stays enabled. Same goes for the disabled state
Enabled, //!< Enable event logging, regardless of the previous state
Disabled //!< Disable event logging, regardless of the previous state
};
Q_ENUM(EventMode)
//! Checks if a setup for the given name does already exist
static bool exists(const QString &name = DefaultSetup);
//! Sets the maximum timeout for shutting down setups
static void setCleanupTimeout(unsigned long timeout);
//! Stops the datasync instance and removes it
static void removeSetup(const QString &name, bool waitForFinished = false);
//! Returns a list of all keystore providers defined via the plugins
static QStringList keystoreProviders();
//! Returns a list of all keystore providers that are actually available for use
static QStringList availableKeystores();
//! Checks if the given keystore provider is available
static bool keystoreAvailable(const QString &provider);
//! Returns the default provider to be used based on the current platform and the available providers
static QString defaultKeystoreProvider();
//! Create and load akeystore instance from the default provider
static KeyStore *loadKeystore(QObject *parent = nullptr, const QString &setupName = DefaultSetup);
//! Create and load akeystore instance from the given provider
static KeyStore *loadKeystore(const QString &provider, QObject *parent = nullptr, const QString &setupName = DefaultSetup);
Setup();
//! Move constructor
Setup(Setup &&other) noexcept;
//! Move assignment operator
Setup &operator=(Setup &&other) noexcept;
~Setup();
//! @readAcFn{Setup::localDir}
QString localDir() const;
//! @readAcFn{Setup::remoteObjectHost}
QUrl remoteObjectHost() const;
//! @readAcFn{Setup::serializer}
QJsonSerializer *serializer() const;
//! @readAcFn{Setup::conflictResolver}
ConflictResolver* conflictResolver() const;
//! @readAcFn{Setup::fatalErrorHandler}
FatalErrorHandler fatalErrorHandler() const;
//! @readAcFn{Setup::cacheSize}
int cacheSize() const;
//! @readAcFn{Setup::persistDeletedVersion}
bool persistDeletedVersion() const;
//! @readAcFn{Setup::syncPolicy}
SyncPolicy syncPolicy() const;
//! @readAcFn{Setup::sslConfiguration}
QSslConfiguration sslConfiguration() const;
//! @readAcFn{Setup::remoteConfiguration}
RemoteConfig remoteConfiguration() const;
//! @readAcFn{Setup::keyStoreProvider}
QString keyStoreProvider() const;
//! @readAcFn{Setup::signatureScheme}
SignatureScheme signatureScheme() const;
//! @readAcFn{Setup::signatureKeyParam}
QVariant signatureKeyParam() const;
//! @readAcFn{Setup::encryptionScheme}
EncryptionScheme encryptionScheme() const;
//! @readAcFn{Setup::encryptionKeyParam}
QVariant encryptionKeyParam() const;
//! @readAcFn{Setup::cipherScheme}
CipherScheme cipherScheme() const;
//! @readAcFn{Setup::cipherKeySize}
qint32 cipherKeySize() const;
//! @readAcFn{Setup::eventLoggingMode}
EventMode eventLoggingMode() const;
//! @writeAcFn{Setup::localDir}
Setup &setLocalDir(QString localDir);
//! @writeAcFn{Setup::remoteObjectHost}
Setup &setRemoteObjectHost(QUrl remoteObjectHost);
//! @writeAcFn{Setup::serializer}
Setup &setSerializer(QJsonSerializer *serializer);
//! @writeAcFn{Setup::conflictResolver}
Setup &setConflictResolver(ConflictResolver* conflictResolver);
//! @writeAcFn{Setup::fatalErrorHandler}
Setup &setFatalErrorHandler(const FatalErrorHandler &fatalErrorHandler);
//! @writeAcFn{Setup::cacheSize}
Setup &setCacheSize(int cacheSize);
//! @writeAcFn{Setup::persistDeletedVersion}
Setup &setPersistDeletedVersion(bool persistDeletedVersion);
//! @writeAcFn{Setup::syncPolicy}
Setup &setSyncPolicy(SyncPolicy syncPolicy);
//! @writeAcFn{Setup::sslConfiguration}
Setup &setSslConfiguration(QSslConfiguration sslConfiguration);
//! @writeAcFn{Setup::remoteConfiguration}
Setup &setRemoteConfiguration(RemoteConfig remoteConfiguration);
//! @writeAcFn{Setup::keyStoreProvider}
Setup &setKeyStoreProvider(QString keyStoreProvider);
//! @writeAcFn{Setup::signatureScheme}
Setup &setSignatureScheme(SignatureScheme signatureScheme);
//! @writeAcFn{Setup::signatureKeyParam}
Setup &setSignatureKeyParam(QVariant signatureKeyParam);
//! @writeAcFn{Setup::encryptionScheme}
Setup &setEncryptionScheme(EncryptionScheme encryptionScheme);
//! @writeAcFn{Setup::encryptionKeyParam}
Setup &setEncryptionKeyParam(QVariant encryptionKeyParam);
//! @writeAcFn{Setup::cipherScheme}
Setup &setCipherScheme(CipherScheme cipherScheme);
//! @writeAcFn{Setup::cipherKeySize}
Setup &setCipherKeySize(qint32 cipherKeySize);
//! @writeAcFn{Setup::eventLoggingMode}
Setup &setEventLoggingMode(EventMode eventLoggingMode);
//! @resetAcFn{Setup::localDir}
Setup &resetLocalDir();
//! @resetAcFn{Setup::remoteObjectHost}
Setup &resetRemoteObjectHost();
//! @resetAcFn{Setup::serializer}
Setup &resetSerializer();
//! @resetAcFn{Setup::conflictResolver}
Setup &resetConflictResolver();
//! @resetAcFn{Setup::fatalErrorHandler}
Setup &resetFatalErrorHandler();
//! @resetAcFn{Setup::cacheSize}
Setup &resetCacheSize();
//! @resetAcFn{Setup::persistDeletedVersion}
Setup &resetPersistDeletedVersion();
//! @resetAcFn{Setup::syncPolicy}
Setup &resetSyncPolicy();
//! @resetAcFn{Setup::sslConfiguration}
Setup &resetSslConfiguration();
//! @resetAcFn{Setup::remoteConfiguration}
Setup &resetRemoteConfiguration();
//! @resetAcFn{Setup::keyStoreProvider}
Setup &resetKeyStoreProvider();
//! @resetAcFn{Setup::signatureScheme}
Setup &resetSignatureScheme();
//! @resetAcFn{Setup::signatureKeyParam}
Setup &resetSignatureKeyParam();
//! @resetAcFn{Setup::encryptionScheme}
Setup &resetEncryptionScheme();
//! @resetAcFn{Setup::encryptionKeyParam}
Setup &resetEncryptionKeyParam();
//! @resetAcFn{Setup::cipherScheme}
Setup &resetCipherScheme();
//! @resetAcFn{Setup::cipherKeySize}
Setup &resetCipherKeySize();
//! @resetAcFn{Setup::resetEventLoggingMode}
Setup &resetEventLoggingMode();
//! Sets an account to be imported on creation of the instance
Setup &setAccount(const QJsonObject &importData, bool keepData = false, bool allowFailure = false);
//! @copydoc Setup::setAccount(const QJsonObject &, bool, bool)
Setup &setAccount(const QByteArray &importData, bool keepData = false, bool allowFailure = false);
//! @copybrief Setup::setAccount(const QJsonObject &, bool, bool)
Setup &setAccountTrusted(const QJsonObject &importData, const QString &password, bool keepData = false, bool allowFailure = false);
//! @copydoc Setup::setAccountTrusted(const QJsonObject &, const QString &, bool, bool)
Setup &setAccountTrusted(const QByteArray &importData, const QString &password, bool keepData = false, bool allowFailure = false);
//! Creates a datasync instance from this setup with the given name
void create(const QString &name = DefaultSetup);
//! Creates a passive setup with the given name that connects to the primary datasync instance
bool createPassive(const QString &name = DefaultSetup, int timeout = 30000);
private:
QScopedPointer<SetupPrivate> d;
};
//! Exception throw if Setup::create fails
class Q_DATASYNC_EXPORT SetupException : public Exception
{
protected:
//! @private
SetupException(const QString &setupName, const QString &message);
//! @private
SetupException(const SetupException * const other);
};
//! Exception thrown if a setup with the same name already exsits
class Q_DATASYNC_EXPORT SetupExistsException : public SetupException
{
public:
//! Constructor with setup name
SetupExistsException(const QString &setupName);
QByteArray className() const noexcept override;
void raise() const final;
QException *clone() const final;
protected:
//! @private
SetupExistsException(const SetupExistsException * const other);
};
//! Exception thrown if a setups storage directory is locked by another instance
class Q_DATASYNC_EXPORT SetupLockedException : public SetupException
{
public:
//! Constructor with setup name
SetupLockedException(QLockFile *lockfile, const QString &setupName);
//! The process if of the process that is locking the setup
qint64 pid() const;
//! The hostname of the machine that is running the process that is locking the setup
QString hostname() const;
//! The name of the application that is locking the setup
QString appname() const;
QByteArray className() const noexcept override;
QString qWhat() const override;
void raise() const final;
QException *clone() const final;
protected:
//! @private
SetupLockedException(const SetupLockedException *cloneFrom);
//! @private
qint64 _pid = -1;
//! @private
QString _hostname;
//! @private
QString _appname;
};
// ------------- Generic Implementation -------------
template<typename TRatio>
Q_DECL_CONSTEXPR inline int ratioBytes(intmax_t value)
{
return static_cast<int>(qMin(TRatio().num * value, static_cast<intmax_t>(INT_MAX)));
}
Q_DECL_CONSTEXPR inline int KB(intmax_t value)
{
return ratioBytes<std::kilo>(value);
}
Q_DECL_CONSTEXPR inline int MB(intmax_t value)
{
return ratioBytes<std::mega>(value);
}
Q_DECL_CONSTEXPR inline int GB(intmax_t value)
{
return ratioBytes<std::giga>(value);
}
}
#endif // QTDATASYNC_SETUP_H