2
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation, either version 2 or (at your option)
7
* version 3 of the License.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19
#include "core/CustomData.h"
20
#include "core/Database.h"
21
#include "core/Group.h"
22
#include "core/Metadata.h"
23
#include "gui/DatabaseIcons.h"
24
#include "keeshare/ShareObserver.h"
28
static const QString KeeShare_Reference("KeeShare/Reference");
31
KeeShare* KeeShare::m_instance = nullptr;
33
KeeShare* KeeShare::instance()
36
qFatal("Race condition: instance wanted before it was initialized, this is a bug.");
42
KeeShare::KeeShare(QObject* parent)
45
connect(config(), &Config::changed, this, &KeeShare::handleSettingsChanged);
48
void KeeShare::init(QObject* parent)
50
Q_ASSERT(!m_instance);
51
m_instance = new KeeShare(parent);
54
KeeShareSettings::Own KeeShare::own()
56
// Read existing own certificate or generate a new one if none available
57
auto own = KeeShareSettings::Own::deserialize(config()->get(Config::KeeShare_Own).toString());
58
if (own.key.isNull()) {
59
own = KeeShareSettings::Own::generate();
65
KeeShareSettings::Active KeeShare::active()
67
return KeeShareSettings::Active::deserialize(config()->get(Config::KeeShare_Active).toString());
70
void KeeShare::setActive(const KeeShareSettings::Active& active)
72
config()->set(Config::KeeShare_Active, KeeShareSettings::Active::serialize(active));
75
void KeeShare::setOwn(const KeeShareSettings::Own& own)
77
config()->set(Config::KeeShare_Own, KeeShareSettings::Own::serialize(own));
80
bool KeeShare::isShared(const Group* group)
82
return group && group->customData()->contains(KeeShare_Reference);
85
KeeShareSettings::Reference KeeShare::referenceOf(const Group* group)
87
static const KeeShareSettings::Reference s_emptyReference;
88
const CustomData* customData = group->customData();
89
if (!customData->contains(KeeShare_Reference)) {
90
return s_emptyReference;
92
const auto encoded = customData->value(KeeShare_Reference);
93
const auto serialized = QString::fromUtf8(QByteArray::fromBase64(encoded.toLatin1()));
94
KeeShareSettings::Reference reference = KeeShareSettings::Reference::deserialize(serialized);
95
if (reference.isNull()) {
96
qWarning("Invalid sharing reference detected - sharing disabled");
97
return s_emptyReference;
102
void KeeShare::setReferenceTo(Group* group, const KeeShareSettings::Reference& reference)
104
CustomData* customData = group->customData();
105
if (reference.isNull()) {
106
customData->remove(KeeShare_Reference);
109
const auto serialized = KeeShareSettings::Reference::serialize(reference);
110
customData->set(KeeShare_Reference, serialized.toUtf8().toBase64());
113
bool KeeShare::isEnabled(const Group* group)
115
const auto reference = KeeShare::referenceOf(group);
116
const auto active = KeeShare::active();
117
return (reference.isImporting() && active.in) || (reference.isExporting() && active.out);
120
const Group* KeeShare::resolveSharedGroup(const Group* group)
122
while (group && group != group->database()->rootGroup()) {
123
if (isShared(group)) {
126
group = group->parentGroup();
132
QString KeeShare::sharingLabel(const Group* group)
134
auto* share = resolveSharedGroup(group);
139
const auto reference = referenceOf(share);
140
if (!reference.isValid()) {
141
return tr("Invalid sharing reference");
143
QStringList messages;
144
switch (reference.type) {
145
case KeeShareSettings::Inactive:
146
messages << tr("Inactive share %1").arg(reference.path);
148
case KeeShareSettings::ImportFrom:
149
messages << tr("Imported from %1").arg(reference.path);
151
case KeeShareSettings::ExportTo:
152
messages << tr("Exported to %1").arg(reference.path);
154
case KeeShareSettings::SynchronizeWith:
155
messages << tr("Synchronized with %1").arg(reference.path);
158
const auto active = KeeShare::active();
159
if (reference.isImporting() && !active.in) {
160
messages << tr("Import is disabled in settings");
162
if (reference.isExporting() && !active.out) {
163
messages << tr("Export is disabled in settings");
165
return messages.join("\n");
168
QPixmap KeeShare::indicatorBadge(const Group* group, QPixmap pixmap)
170
if (!isShared(group)) {
174
if (isEnabled(group)) {
175
return databaseIcons()->applyBadge(pixmap, DatabaseIcons::Badges::ShareActive);
177
return databaseIcons()->applyBadge(pixmap, DatabaseIcons::Badges::ShareInactive);
180
QString KeeShare::referenceTypeLabel(const KeeShareSettings::Reference& reference)
182
switch (reference.type) {
183
case KeeShareSettings::Inactive:
184
return tr("Inactive share");
185
case KeeShareSettings::ImportFrom:
186
return tr("Imported from");
187
case KeeShareSettings::ExportTo:
188
return tr("Exported to");
189
case KeeShareSettings::SynchronizeWith:
190
return tr("Synchronized with");
195
QString KeeShare::indicatorSuffix(const Group* group, const QString& text)
197
// we not adjust the display name for now - it's just an alternative to the icon
202
void KeeShare::connectDatabase(QSharedPointer<Database> newDb, QSharedPointer<Database> oldDb)
204
if (oldDb && m_observersByDatabase.contains(oldDb->uuid())) {
205
QPointer<ShareObserver> observer = m_observersByDatabase.take(oldDb->uuid());
211
if (newDb && !m_observersByDatabase.contains(newDb->uuid())) {
212
QPointer<ShareObserver> observer(new ShareObserver(newDb, this));
213
m_observersByDatabase[newDb->uuid()] = observer;
214
connect(observer.data(),
215
SIGNAL(sharingMessage(QString, MessageWidget::MessageType)),
216
SIGNAL(sharingMessage(QString, MessageWidget::MessageType)));
220
const QString KeeShare::signedContainerFileType()
222
static const QString filetype("kdbx.share");
226
const QString KeeShare::unsignedContainerFileType()
228
static const QString filetype("kdbx");
232
bool KeeShare::isContainerType(const QFileInfo& fileInfo, const QString type)
234
return fileInfo.fileName().endsWith(type, Qt::CaseInsensitive);
237
void KeeShare::handleSettingsChanged(Config::ConfigKey key)
239
if (key == Config::KeeShare_Active) {
240
emit activeChanged();
244
const QString KeeShare::signatureFileName()
246
static const QString fileName("container.share.signature");
250
const QString KeeShare::containerFileName()
252
static const QString fileName("container.share.kdbx");