Add warning for duplicate URLs with Additional URLs list (#9588)

This commit is contained in:
Sami Vänttinen 2023-07-15 22:33:05 +03:00 committed by GitHub
parent 5dea019309
commit 9214ab2038
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 16 deletions

View File

@ -3938,6 +3938,10 @@ Error: %1</source>
<source>Invalid URL</source> <source>Invalid URL</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Duplicate URL</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>EntryView</name> <name>EntryView</name>

View File

@ -326,17 +326,18 @@ void EditEntryWidget::insertURL()
{ {
Q_ASSERT(!m_history); Q_ASSERT(!m_history);
QString name("KP2A_URL"); QString name(BrowserService::ADDITIONAL_URL);
int i = 1; int i = 1;
while (m_entryAttributes->keys().contains(name)) { while (m_entryAttributes->keys().contains(name)) {
name = QString("KP2A_URL_%1").arg(i); name = QString("%1_%2").arg(BrowserService::ADDITIONAL_URL, QString::number(i));
i++; i++;
} }
m_entryAttributes->set(name, tr("<empty URL>")); m_entryAttributes->set(name, tr("<empty URL>"));
QModelIndex index = m_additionalURLsDataModel->indexByKey(name); QModelIndex index = m_additionalURLsDataModel->indexByKey(name);
m_additionalURLsDataModel->setEntryUrl(m_entry->url());
m_browserUi->additionalURLsView->setCurrentIndex(index); m_browserUi->additionalURLsView->setCurrentIndex(index);
m_browserUi->additionalURLsView->edit(index); m_browserUi->additionalURLsView->edit(index);

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2023 KeePassXC Team <team@keepassxc.org>
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de> * Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
* Copyright (C) 2019 KeePassXC Team <team@keepassxc.org>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -18,6 +18,7 @@
#include "EntryURLModel.h" #include "EntryURLModel.h"
#include "browser/BrowserService.h"
#include "core/EntryAttributes.h" #include "core/EntryAttributes.h"
#include "core/Tools.h" #include "core/Tools.h"
#include "gui/Icons.h" #include "gui/Icons.h"
@ -53,7 +54,7 @@ void EntryURLModel::setEntryAttributes(EntryAttributes* entryAttributes)
endResetModel(); endResetModel();
} }
#include <QDebug>
QVariant EntryURLModel::data(const QModelIndex& index, int role) const QVariant EntryURLModel::data(const QModelIndex& index, int role) const
{ {
if (!index.isValid()) { if (!index.isValid()) {
@ -68,13 +69,20 @@ QVariant EntryURLModel::data(const QModelIndex& index, int role) const
const auto value = m_entryAttributes->value(key); const auto value = m_entryAttributes->value(key);
const auto urlValid = Tools::checkUrlValid(value); const auto urlValid = Tools::checkUrlValid(value);
if (role == Qt::BackgroundRole && !urlValid) { // Check for duplicate URLs in the attribute list. Excludes the current key/value from the comparison.
auto customAttributeKeys = m_entryAttributes->customKeys();
customAttributeKeys.removeOne(key);
const auto duplicateUrl = m_entryAttributes->values(customAttributeKeys).contains(value) || value == m_entryUrl;
if (role == Qt::BackgroundRole && (!urlValid || duplicateUrl)) {
StateColorPalette statePalette; StateColorPalette statePalette;
return statePalette.color(StateColorPalette::ColorRole::Error); return statePalette.color(StateColorPalette::ColorRole::Error);
} else if (role == Qt::DecorationRole && !urlValid) { } else if (role == Qt::DecorationRole && (!urlValid || duplicateUrl)) {
return m_errorIcon; return m_errorIcon;
} else if (role == Qt::DisplayRole || role == Qt::EditRole) { } else if (role == Qt::DisplayRole || role == Qt::EditRole) {
return value; return value;
} else if (role == Qt::ToolTipRole && duplicateUrl) {
return tr("Duplicate URL");
} else if (role == Qt::ToolTipRole && !urlValid) { } else if (role == Qt::ToolTipRole && !urlValid) {
return tr("Invalid URL"); return tr("Invalid URL");
} }
@ -82,17 +90,21 @@ QVariant EntryURLModel::data(const QModelIndex& index, int role) const
return {}; return {};
} }
void EntryURLModel::setEntryUrl(const QString& entryUrl)
{
m_entryUrl = entryUrl;
}
bool EntryURLModel::setData(const QModelIndex& index, const QVariant& value, int role) bool EntryURLModel::setData(const QModelIndex& index, const QVariant& value, int role)
{ {
if (!index.isValid() || role != Qt::EditRole || value.type() != QVariant::String || value.toString().isEmpty()) { if (!index.isValid() || role != Qt::EditRole || value.type() != QVariant::String || value.toString().isEmpty()) {
return false; return false;
} }
const int row = index.row(); const auto row = index.row();
const QString key = m_urls.at(row).first; const auto key = m_urls.at(row).first;
const QString oldValue = m_urls.at(row).second;
if (EntryAttributes::isDefaultAttribute(key) || m_entryAttributes->containsValue(value.toString())) { if (EntryAttributes::isDefaultAttribute(key)) {
return false; return false;
} }
@ -113,7 +125,7 @@ QModelIndex EntryURLModel::indexByKey(const QString& key) const
} }
if (row == -1) { if (row == -1) {
return QModelIndex(); return {};
} else { } else {
return index(row, 0); return index(row, 0);
} }
@ -122,7 +134,7 @@ QModelIndex EntryURLModel::indexByKey(const QString& key) const
QString EntryURLModel::keyByIndex(const QModelIndex& index) const QString EntryURLModel::keyByIndex(const QModelIndex& index) const
{ {
if (!index.isValid()) { if (!index.isValid()) {
return QString(); return {};
} else { } else {
return m_urls.at(index.row()).first; return m_urls.at(index.row()).first;
} }
@ -133,9 +145,9 @@ void EntryURLModel::updateAttributes()
clear(); clear();
m_urls.clear(); m_urls.clear();
const QList<QString> attributesKeyList = m_entryAttributes->keys(); const auto attributesKeyList = m_entryAttributes->keys();
for (const QString& key : attributesKeyList) { for (const auto& key : attributesKeyList) {
if (!EntryAttributes::isDefaultAttribute(key) && key.contains("KP2A_URL")) { if (!EntryAttributes::isDefaultAttribute(key) && key.contains(BrowserService::ADDITIONAL_URL)) {
const auto value = m_entryAttributes->value(key); const auto value = m_entryAttributes->value(key);
m_urls.append(qMakePair(key, value)); m_urls.append(qMakePair(key, value));

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2023 KeePassXC Team <team@keepassxc.org>
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de> * Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
* Copyright (C) 2019 KeePassXC Team <team@keepassxc.org>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -19,6 +19,7 @@
#ifndef KEEPASSXC_ENTRYURLMODEL_H #ifndef KEEPASSXC_ENTRYURLMODEL_H
#define KEEPASSXC_ENTRYURLMODEL_H #define KEEPASSXC_ENTRYURLMODEL_H
#include "core/Entry.h"
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
@ -43,8 +44,10 @@ class EntryURLModel : public QStandardItemModel
public: public:
explicit EntryURLModel(QObject* parent = nullptr); explicit EntryURLModel(QObject* parent = nullptr);
void setEntryAttributes(EntryAttributes* entryAttributes); void setEntryAttributes(EntryAttributes* entryAttributes);
void insertRow(const QString& key, const QString& value); void insertRow(const QString& key, const QString& value);
void setEntryUrl(const QString& entryUrl);
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
QVariant data(const QModelIndex& index, int role) const override; QVariant data(const QModelIndex& index, int role) const override;
QModelIndex indexByKey(const QString& key) const; QModelIndex indexByKey(const QString& key) const;
@ -57,6 +60,7 @@ private:
QList<QPair<QString, QString>> m_urls; QList<QPair<QString, QString>> m_urls;
EntryAttributes* m_entryAttributes; EntryAttributes* m_entryAttributes;
QIcon m_errorIcon; QIcon m_errorIcon;
QString m_entryUrl;
}; };
#endif // KEEPASSXC_ENTRYURLMODEL_H #endif // KEEPASSXC_ENTRYURLMODEL_H