keepassxc/src/core/Metadata.cpp

529 lines
12 KiB
C++
Raw Normal View History

2010-08-07 09:10:44 -04:00
/*
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Metadata.h"
2018-03-31 16:01:30 -04:00
#include <QtCore/QCryptographicHash>
2010-08-07 09:10:44 -04:00
#include "core/Entry.h"
#include "core/Group.h"
#include "core/Tools.h"
2010-08-13 12:08:06 -04:00
2012-07-01 15:58:45 -04:00
const int Metadata::DefaultHistoryMaxItems = 10;
const int Metadata::DefaultHistoryMaxSize = 6 * 1024 * 1024;
Metadata::Metadata(QObject* parent)
2010-08-24 17:12:01 -04:00
: QObject(parent)
, m_customData(new CustomData(this))
, m_updateDatetime(true)
2010-08-07 09:10:44 -04:00
{
m_data.generator = "KeePassXC";
2013-11-22 04:28:11 -05:00
m_data.maintenanceHistoryDays = 365;
m_data.masterKeyChangeRec = -1;
m_data.masterKeyChangeForce = -1;
m_data.historyMaxItems = DefaultHistoryMaxItems;
m_data.historyMaxSize = DefaultHistoryMaxSize;
m_data.recycleBinEnabled = true;
m_data.protectTitle = false;
m_data.protectUsername = false;
m_data.protectPassword = true;
m_data.protectUrl = false;
m_data.protectNotes = false;
2015-07-22 17:48:08 -04:00
QDateTime now = QDateTime::currentDateTimeUtc();
2013-11-22 04:28:11 -05:00
m_data.nameChanged = now;
m_data.descriptionChanged = now;
m_data.defaultUserNameChanged = now;
m_recycleBinChanged = now;
m_entryTemplatesGroupChanged = now;
m_masterKeyChanged = now;
m_settingsChanged = now;
connect(m_customData, SIGNAL(modified()), this, SIGNAL(modified()));
2012-04-11 09:57:11 -04:00
}
template <class P, class V> bool Metadata::set(P& property, const V& value)
{
2012-04-11 09:57:11 -04:00
if (property != value) {
property = value;
emit modified();
2012-04-11 09:57:11 -04:00
return true;
2018-03-31 16:01:30 -04:00
} else {
2012-04-11 09:57:11 -04:00
return false;
}
}
2018-03-31 16:01:30 -04:00
template <class P, class V> bool Metadata::set(P& property, const V& value, QDateTime& dateTime)
{
2012-04-11 09:57:11 -04:00
if (property != value) {
property = value;
if (m_updateDatetime) {
2015-07-22 17:48:08 -04:00
dateTime = QDateTime::currentDateTimeUtc();
2012-04-11 09:57:11 -04:00
}
emit modified();
2012-04-11 09:57:11 -04:00
return true;
2018-03-31 16:01:30 -04:00
} else {
2012-04-11 09:57:11 -04:00
return false;
}
}
2012-06-29 18:22:07 -04:00
void Metadata::setUpdateDatetime(bool value)
{
2012-04-11 09:57:11 -04:00
m_updateDatetime = value;
2010-08-07 09:10:44 -04:00
}
2013-11-22 04:28:11 -05:00
void Metadata::copyAttributesFrom(const Metadata* other)
{
m_data = other->m_data;
}
2010-08-07 09:10:44 -04:00
QString Metadata::generator() const
{
2013-11-22 04:28:11 -05:00
return m_data.generator;
}
2010-08-07 09:10:44 -04:00
QString Metadata::name() const
{
2013-11-22 04:28:11 -05:00
return m_data.name;
}
2010-08-07 09:10:44 -04:00
QDateTime Metadata::nameChanged() const
{
2013-11-22 04:28:11 -05:00
return m_data.nameChanged;
}
2010-08-07 09:10:44 -04:00
QString Metadata::description() const
{
2013-11-22 04:28:11 -05:00
return m_data.description;
}
2010-08-07 09:10:44 -04:00
QDateTime Metadata::descriptionChanged() const
{
2013-11-22 04:28:11 -05:00
return m_data.descriptionChanged;
}
2010-08-07 09:10:44 -04:00
QString Metadata::defaultUserName() const
{
2013-11-22 04:28:11 -05:00
return m_data.defaultUserName;
}
QDateTime Metadata::defaultUserNameChanged() const
{
2013-11-22 04:28:11 -05:00
return m_data.defaultUserNameChanged;
}
2010-08-07 09:10:44 -04:00
int Metadata::maintenanceHistoryDays() const
{
2013-11-22 04:28:11 -05:00
return m_data.maintenanceHistoryDays;
}
2010-08-07 09:10:44 -04:00
QColor Metadata::color() const
{
2013-11-22 04:28:11 -05:00
return m_data.color;
}
2010-08-07 09:10:44 -04:00
bool Metadata::protectTitle() const
{
2013-11-22 04:28:11 -05:00
return m_data.protectTitle;
}
2010-08-07 09:10:44 -04:00
bool Metadata::protectUsername() const
{
2013-11-22 04:28:11 -05:00
return m_data.protectUsername;
}
2010-08-07 09:10:44 -04:00
bool Metadata::protectPassword() const
{
2013-11-22 04:28:11 -05:00
return m_data.protectPassword;
}
2010-08-07 09:10:44 -04:00
bool Metadata::protectUrl() const
{
2013-11-22 04:28:11 -05:00
return m_data.protectUrl;
}
2010-08-07 09:10:44 -04:00
bool Metadata::protectNotes() const
{
2013-11-22 04:28:11 -05:00
return m_data.protectNotes;
}
2010-08-07 09:10:44 -04:00
QImage Metadata::customIcon(const Uuid& uuid) const
2010-09-19 15:22:24 -04:00
{
return m_customIcons.value(uuid);
}
2016-01-24 11:56:35 -05:00
QPixmap Metadata::customIconPixmap(const Uuid& uuid) const
{
QPixmap pixmap;
if (!m_customIcons.contains(uuid)) {
return pixmap;
}
QPixmapCache::Key& cacheKey = m_customIconCacheKeys[uuid];
if (!QPixmapCache::find(cacheKey, &pixmap)) {
pixmap = QPixmap::fromImage(m_customIcons.value(uuid));
cacheKey = QPixmapCache::insert(pixmap);
}
return pixmap;
}
QPixmap Metadata::customIconScaledPixmap(const Uuid& uuid) const
{
QPixmap pixmap;
if (!m_customIcons.contains(uuid)) {
return pixmap;
}
QPixmapCache::Key& cacheKey = m_customIconScaledCacheKeys[uuid];
if (!QPixmapCache::find(cacheKey, &pixmap)) {
QImage image = m_customIcons.value(uuid).scaled(16, 16, Qt::KeepAspectRatio, Qt::SmoothTransformation);
pixmap = QPixmap::fromImage(image);
cacheKey = QPixmapCache::insert(pixmap);
}
return pixmap;
}
bool Metadata::containsCustomIcon(const Uuid& uuid) const
{
return m_customIcons.contains(uuid);
}
QHash<Uuid, QImage> Metadata::customIcons() const
2010-08-07 09:10:44 -04:00
{
return m_customIcons;
}
2010-08-07 09:10:44 -04:00
QHash<Uuid, QPixmap> Metadata::customIconsScaledPixmaps() const
{
QHash<Uuid, QPixmap> result;
for (const Uuid& uuid : m_customIconsOrder) {
result.insert(uuid, customIconScaledPixmap(uuid));
}
return result;
}
QList<Uuid> Metadata::customIconsOrder() const
{
return m_customIconsOrder;
}
2010-08-07 09:10:44 -04:00
bool Metadata::recycleBinEnabled() const
{
2013-11-22 04:28:11 -05:00
return m_data.recycleBinEnabled;
}
2010-08-07 09:10:44 -04:00
Group* Metadata::recycleBin()
{
return m_recycleBin;
}
2010-08-13 12:08:06 -04:00
const Group* Metadata::recycleBin() const
2010-08-07 09:10:44 -04:00
{
2010-08-13 12:08:06 -04:00
return m_recycleBin;
}
2010-08-07 09:10:44 -04:00
QDateTime Metadata::recycleBinChanged() const
{
return m_recycleBinChanged;
}
2010-08-07 09:10:44 -04:00
2010-08-13 12:08:06 -04:00
const Group* Metadata::entryTemplatesGroup() const
2010-08-07 09:10:44 -04:00
{
return m_entryTemplatesGroup;
}
2010-08-07 09:10:44 -04:00
QDateTime Metadata::entryTemplatesGroupChanged() const
{
return m_entryTemplatesGroupChanged;
}
2010-08-07 09:10:44 -04:00
2010-08-13 12:08:06 -04:00
const Group* Metadata::lastSelectedGroup() const
2010-08-07 09:10:44 -04:00
{
return m_lastSelectedGroup;
}
2010-08-07 09:10:44 -04:00
2010-08-13 12:08:06 -04:00
const Group* Metadata::lastTopVisibleGroup() const
2010-08-07 09:10:44 -04:00
{
return m_lastTopVisibleGroup;
}
2010-08-07 09:10:44 -04:00
QDateTime Metadata::masterKeyChanged() const
{
return m_masterKeyChanged;
}
int Metadata::masterKeyChangeRec() const
{
2013-11-22 04:28:11 -05:00
return m_data.masterKeyChangeRec;
}
int Metadata::masterKeyChangeForce() const
{
2013-11-22 04:28:11 -05:00
return m_data.masterKeyChangeForce;
}
int Metadata::historyMaxItems() const
{
2013-11-22 04:28:11 -05:00
return m_data.historyMaxItems;
}
int Metadata::historyMaxSize() const
{
2013-11-22 04:28:11 -05:00
return m_data.historyMaxSize;
}
CustomData* Metadata::customData()
{
return m_customData;
}
const CustomData* Metadata::customData() const
2010-08-07 09:10:44 -04:00
{
return m_customData;
}
2010-08-07 09:10:44 -04:00
void Metadata::setGenerator(const QString& value)
{
2013-11-22 04:28:11 -05:00
set(m_data.generator, value);
2010-08-07 09:10:44 -04:00
}
void Metadata::setName(const QString& value)
{
2013-11-22 04:28:11 -05:00
if (set(m_data.name, value, m_data.nameChanged)) {
emit nameTextChanged();
2012-04-11 09:57:11 -04:00
}
2010-08-07 09:10:44 -04:00
}
void Metadata::setNameChanged(const QDateTime& value)
{
Q_ASSERT(value.timeSpec() == Qt::UTC);
2013-11-22 04:28:11 -05:00
m_data.nameChanged = value;
2010-08-07 09:10:44 -04:00
}
void Metadata::setDescription(const QString& value)
{
2013-11-22 04:28:11 -05:00
set(m_data.description, value, m_data.descriptionChanged);
2010-08-07 09:10:44 -04:00
}
void Metadata::setDescriptionChanged(const QDateTime& value)
{
Q_ASSERT(value.timeSpec() == Qt::UTC);
2013-11-22 04:28:11 -05:00
m_data.descriptionChanged = value;
2010-08-07 09:10:44 -04:00
}
void Metadata::setDefaultUserName(const QString& value)
{
2013-11-22 04:28:11 -05:00
set(m_data.defaultUserName, value, m_data.defaultUserNameChanged);
2010-08-07 09:10:44 -04:00
}
void Metadata::setDefaultUserNameChanged(const QDateTime& value)
{
Q_ASSERT(value.timeSpec() == Qt::UTC);
2013-11-22 04:28:11 -05:00
m_data.defaultUserNameChanged = value;
}
2010-08-07 09:10:44 -04:00
void Metadata::setMaintenanceHistoryDays(int value)
{
2013-11-22 04:28:11 -05:00
set(m_data.maintenanceHistoryDays, value);
2010-08-07 09:10:44 -04:00
}
void Metadata::setColor(const QColor& value)
{
2013-11-22 04:28:11 -05:00
set(m_data.color, value);
}
2010-08-07 09:10:44 -04:00
void Metadata::setProtectTitle(bool value)
{
2013-11-22 04:28:11 -05:00
set(m_data.protectTitle, value);
2010-08-07 09:10:44 -04:00
}
void Metadata::setProtectUsername(bool value)
{
2013-11-22 04:28:11 -05:00
set(m_data.protectUsername, value);
2010-08-07 09:10:44 -04:00
}
void Metadata::setProtectPassword(bool value)
{
2013-11-22 04:28:11 -05:00
set(m_data.protectPassword, value);
2010-08-07 09:10:44 -04:00
}
void Metadata::setProtectUrl(bool value)
{
2013-11-22 04:28:11 -05:00
set(m_data.protectUrl, value);
2010-08-07 09:10:44 -04:00
}
void Metadata::setProtectNotes(bool value)
{
2013-11-22 04:28:11 -05:00
set(m_data.protectNotes, value);
2010-08-07 09:10:44 -04:00
}
void Metadata::addCustomIcon(const Uuid& uuid, const QImage& icon)
2010-08-07 09:10:44 -04:00
{
2010-08-13 12:08:06 -04:00
Q_ASSERT(!uuid.isNull());
2010-08-07 09:10:44 -04:00
Q_ASSERT(!m_customIcons.contains(uuid));
2010-09-19 15:22:24 -04:00
m_customIcons.insert(uuid, icon);
2016-01-24 11:56:35 -05:00
// reset cache in case there is also an icon with that uuid
m_customIconCacheKeys[uuid] = QPixmapCache::Key();
m_customIconScaledCacheKeys[uuid] = QPixmapCache::Key();
m_customIconsOrder.append(uuid);
// Associate image hash to uuid
QByteArray hash = hashImage(icon);
m_customIconsHashes[hash] = uuid;
Q_ASSERT(m_customIcons.count() == m_customIconsOrder.count());
emit modified();
2010-08-07 09:10:44 -04:00
}
void Metadata::addCustomIconScaled(const Uuid& uuid, const QImage& icon)
{
QImage iconScaled;
// scale down to 128x128 if icon is larger
if (icon.width() > 128 || icon.height() > 128) {
2018-03-31 16:01:30 -04:00
iconScaled = icon.scaled(QSize(128, 128), Qt::KeepAspectRatio, Qt::SmoothTransformation);
} else {
iconScaled = icon;
}
addCustomIcon(uuid, iconScaled);
}
2010-08-07 09:10:44 -04:00
void Metadata::removeCustomIcon(const Uuid& uuid)
{
2010-08-13 12:08:06 -04:00
Q_ASSERT(!uuid.isNull());
2010-08-07 09:10:44 -04:00
Q_ASSERT(m_customIcons.contains(uuid));
// Remove hash record only if this is the same uuid
QByteArray hash = hashImage(m_customIcons[uuid]);
if (m_customIconsHashes.contains(hash) && m_customIconsHashes[hash] == uuid) {
m_customIconsHashes.remove(hash);
}
2010-08-07 09:10:44 -04:00
m_customIcons.remove(uuid);
2016-01-24 11:56:35 -05:00
QPixmapCache::remove(m_customIconCacheKeys.value(uuid));
m_customIconCacheKeys.remove(uuid);
QPixmapCache::remove(m_customIconScaledCacheKeys.value(uuid));
m_customIconScaledCacheKeys.remove(uuid);
m_customIconsOrder.removeAll(uuid);
Q_ASSERT(m_customIcons.count() == m_customIconsOrder.count());
emit modified();
2010-08-07 09:10:44 -04:00
}
2018-03-31 16:01:30 -04:00
Uuid Metadata::findCustomIcon(const QImage& candidate)
{
QByteArray hash = hashImage(candidate);
return m_customIconsHashes.value(hash, Uuid());
}
void Metadata::copyCustomIcons(const QSet<Uuid>& iconList, const Metadata* otherMetadata)
{
for (const Uuid& uuid : iconList) {
Q_ASSERT(otherMetadata->containsCustomIcon(uuid));
if (!containsCustomIcon(uuid) && otherMetadata->containsCustomIcon(uuid)) {
addCustomIcon(uuid, otherMetadata->customIcon(uuid));
}
}
}
QByteArray Metadata::hashImage(const QImage& image)
{
2017-10-03 15:40:15 -04:00
auto data = QByteArray(reinterpret_cast<const char*>(image.bits()), image.byteCount());
return QCryptographicHash::hash(data, QCryptographicHash::Md5);
}
2010-08-07 09:10:44 -04:00
void Metadata::setRecycleBinEnabled(bool value)
{
2013-11-22 04:28:11 -05:00
set(m_data.recycleBinEnabled, value);
2010-08-07 09:10:44 -04:00
}
2010-08-13 12:08:06 -04:00
void Metadata::setRecycleBin(Group* group)
2010-08-07 09:10:44 -04:00
{
2012-04-11 09:57:11 -04:00
set(m_recycleBin, group, m_recycleBinChanged);
2010-08-07 09:10:44 -04:00
}
void Metadata::setRecycleBinChanged(const QDateTime& value)
{
Q_ASSERT(value.timeSpec() == Qt::UTC);
2010-08-07 09:10:44 -04:00
m_recycleBinChanged = value;
}
2010-08-13 12:08:06 -04:00
void Metadata::setEntryTemplatesGroup(Group* group)
2010-08-07 09:10:44 -04:00
{
2012-04-11 09:57:11 -04:00
set(m_entryTemplatesGroup, group, m_entryTemplatesGroupChanged);
2010-08-07 09:10:44 -04:00
}
void Metadata::setEntryTemplatesGroupChanged(const QDateTime& value)
{
Q_ASSERT(value.timeSpec() == Qt::UTC);
2010-08-07 09:10:44 -04:00
m_entryTemplatesGroupChanged = value;
}
2010-08-13 12:08:06 -04:00
void Metadata::setLastSelectedGroup(Group* group)
2010-08-07 09:10:44 -04:00
{
2012-04-11 09:57:11 -04:00
set(m_lastSelectedGroup, group);
2010-08-07 09:10:44 -04:00
}
2010-08-13 12:08:06 -04:00
void Metadata::setLastTopVisibleGroup(Group* group)
2010-08-07 09:10:44 -04:00
{
2012-04-11 09:57:11 -04:00
set(m_lastTopVisibleGroup, group);
2010-08-07 09:10:44 -04:00
}
void Metadata::setMasterKeyChanged(const QDateTime& value)
{
Q_ASSERT(value.timeSpec() == Qt::UTC);
m_masterKeyChanged = value;
}
void Metadata::setMasterKeyChangeRec(int value)
{
2013-11-22 04:28:11 -05:00
set(m_data.masterKeyChangeRec, value);
}
void Metadata::setMasterKeyChangeForce(int value)
{
2013-11-22 04:28:11 -05:00
set(m_data.masterKeyChangeForce, value);
}
void Metadata::setHistoryMaxItems(int value)
{
2013-11-22 04:28:11 -05:00
set(m_data.historyMaxItems, value);
}
void Metadata::setHistoryMaxSize(int value)
{
2013-11-22 04:28:11 -05:00
set(m_data.historyMaxSize, value);
}
QDateTime Metadata::settingsChanged() const
2010-08-07 09:10:44 -04:00
{
return m_settingsChanged;
}
void Metadata::setSettingsChanged(const QDateTime& value)
{
Q_ASSERT(value.timeSpec() == Qt::UTC);
m_settingsChanged = value;
}