/**
* This file is part of GpgFrontend.
*
* GpgFrontend 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 3 of the License, or
* (at your option) any later version.
*
* Foobar 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 Foobar. If not, see .
*
* The initial version of the source code is inherited from gpg4usb-team.
* Their source code version also complies with GNU General Public License.
*
* The source code version of this software was modified and released
* by Saturneric starting on May 12, 2021.
*
*/
#include "SettingsKeyServer.h"
#include "GlobalSettingStation.h"
#include "ui_KeyServerSettings.h"
namespace GpgFrontend::UI {
KeyserverTab::KeyserverTab(QWidget* parent)
: QWidget(parent), ui(std::make_shared()) {
ui->setupUi(this);
ui->keyServerListTable->setSizeAdjustPolicy(
QAbstractScrollArea::AdjustToContents);
connect(ui->addKeyServerPushButton, &QPushButton::clicked, this,
&KeyserverTab::addKeyServer);
connect(ui->testKeyServerButton, &QPushButton::clicked, this,
&KeyserverTab::slotTestListedKeyServer);
ui->keyServerListGroupBox->setTitle(_("Keyserver List"));
ui->operationsGroupBox->setTitle(_("Operations"));
ui->keyServerListTable->horizontalHeaderItem(0)->setText(_("Default"));
ui->keyServerListTable->horizontalHeaderItem(1)->setText(
_("Keyserver Address"));
ui->keyServerListTable->horizontalHeaderItem(2)->setText(_("Security"));
ui->keyServerListTable->horizontalHeaderItem(3)->setText(_("Available"));
ui->addKeyServerPushButton->setText(_("Add"));
ui->testKeyServerButton->setText(_("Test Listed Keyserver"));
ui->tipsLabel->setText(_("Tips: Please Double-click table item to edit it."));
ui->actionDelete_Selected_Key_Server->setText(_("Delete Selected"));
ui->actionDelete_Selected_Key_Server->setToolTip(
_("Delete Selected Key Server"));
ui->actionSet_As_Default->setText(_("Set As Default"));
ui->actionSet_As_Default->setToolTip(_("Set As Default"));
popupMenu = new QMenu(this);
popupMenu->addAction(ui->actionSet_As_Default);
popupMenu->addAction(ui->actionDelete_Selected_Key_Server);
connect(ui->keyServerListTable, &QTableWidget::itemChanged,
[=](QTableWidgetItem* item) {
LOG(INFO) << "item edited" << item->column();
if (item->column() != 1) return;
const auto row_size = ui->keyServerListTable->rowCount();
// Update Actions
if (row_size > 0) {
keyServerStrList.clear();
for (int i = 0; i < row_size; i++) {
const auto key_server =
ui->keyServerListTable->item(i, 1)->text();
keyServerStrList.append(key_server);
}
}
});
connect(ui->actionSet_As_Default, &QAction::triggered, [=]() {
const auto row_size = ui->keyServerListTable->rowCount();
for (int i = 0; i < row_size; i++) {
const auto item = ui->keyServerListTable->item(i, 1);
if (!item->isSelected()) continue;
this->defaultKeyServer = item->text();
}
this->refreshTable();
});
connect(ui->actionDelete_Selected_Key_Server, &QAction::triggered, [=]() {
const auto row_size = ui->keyServerListTable->rowCount();
for (int i = 0; i < row_size; i++) {
const auto item = ui->keyServerListTable->item(i, 1);
if (!item->isSelected()) continue;
this->keyServerStrList.removeAt(i);
break;
}
this->refreshTable();
});
// Read key-list from ini-file and fill it into combobox
setSettings();
refreshTable();
}
/**********************************
* Read the settings from config
* and set the buttons and checkboxes
* appropriately
**********************************/
void KeyserverTab::setSettings() {
auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
try {
auto& server_list = settings.lookup("keyserver.server_list");
const auto server_list_size = server_list.getLength();
for (int i = 0; i < server_list_size; i++) {
std::string server_url = server_list[i];
keyServerStrList.append(server_url.c_str());
}
} catch (...) {
LOG(ERROR) << _("Setting Operation Error") << _("server_list");
}
try {
std::string default_server = settings.lookup("keyserver.default_server");
if (!keyServerStrList.contains(default_server.c_str()))
keyServerStrList.append(default_server.c_str());
defaultKeyServer = QString::fromStdString(default_server);
} catch (...) {
LOG(ERROR) << _("Setting Operation Error") << _("default_server");
}
}
void KeyserverTab::addKeyServer() {
auto target_url = ui->addKeyServerEdit->text();
if (url_reg.match(target_url).hasMatch()) {
if (target_url.startsWith("https://")) {
;
} else if (target_url.startsWith("http://")) {
QMessageBox::warning(
this, _("Insecure keyserver address"),
_("For security reasons, using HTTP as the communication protocol "
"with "
"the key server is not recommended. It is recommended to use "
"HTTPS."));
}
keyServerStrList.append(ui->addKeyServerEdit->text());
} else {
auto ret = QMessageBox::warning(
this, _("Warning"),
_("You may not use HTTPS or HTTP as the protocol for communicating "
"with the key server, which may not be wrong. But please check the "
"address you entered again to make sure it is correct. Are you "
"sure "
"that want to add it into the keyserver list?"),
QMessageBox::Ok | QMessageBox::Cancel);
if (ret == QMessageBox::Cancel)
return;
else
keyServerStrList.append(ui->addKeyServerEdit->text());
}
refreshTable();
}
void KeyserverTab::applySettings() {
auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
if (!settings.exists("keyserver") ||
settings.lookup("keyserver").getType() != libconfig::Setting::TypeGroup)
settings.add("keyserver", libconfig::Setting::TypeGroup);
auto& keyserver = settings["keyserver"];
if (keyserver.exists("server_list")) keyserver.remove("server_list");
keyserver.add("server_list", libconfig::Setting::TypeList);
const auto row_size = ui->keyServerListTable->rowCount();
auto& server_list = keyserver["server_list"];
for (int i = 0; i < row_size; i++) {
const auto key_server = ui->keyServerListTable->item(i, 1)->text();
server_list.add(libconfig::Setting::TypeString) = key_server.toStdString();
}
if (!keyserver.exists("default_server")) {
keyserver.add("default_server", libconfig::Setting::TypeString) =
defaultKeyServer.toStdString();
} else {
keyserver["default_server"] = defaultKeyServer.toStdString();
}
}
void KeyserverTab::refreshTable() {
LOG(INFO) << "Start Refreshing Key Server Table";
ui->keyServerListTable->blockSignals(true);
ui->keyServerListTable->setRowCount(keyServerStrList.size());
int index = 0;
for (const auto& server : keyServerStrList) {
auto* tmp1 =
new QTableWidgetItem(server == defaultKeyServer ? "*" : QString{});
tmp1->setTextAlignment(Qt::AlignCenter);
ui->keyServerListTable->setItem(index, 0, tmp1);
tmp1->setFlags(tmp1->flags() ^ Qt::ItemIsEditable);
auto* tmp2 = new QTableWidgetItem(server);
tmp2->setTextAlignment(Qt::AlignCenter);
ui->keyServerListTable->setItem(index, 1, tmp2);
auto* tmp3 = new QTableWidgetItem(server.startsWith("https") ? _("true")
: _("false"));
tmp3->setTextAlignment(Qt::AlignCenter);
ui->keyServerListTable->setItem(index, 2, tmp3);
tmp3->setFlags(tmp3->flags() ^ Qt::ItemIsEditable);
auto* tmp4 = new QTableWidgetItem(_("unknown"));
tmp4->setTextAlignment(Qt::AlignCenter);
ui->keyServerListTable->setItem(index, 3, tmp4);
tmp4->setFlags(tmp3->flags() ^ Qt::ItemIsEditable);
index++;
}
const auto column_count = ui->keyServerListTable->columnCount();
for (int i = 0; i < column_count; i++) {
ui->keyServerListTable->resizeColumnToContents(i);
}
ui->keyServerListTable->blockSignals(false);
}
void KeyserverTab::slotTestListedKeyServer() {
ui->keyServerListTable->blockSignals(true);
auto timeout =
QInputDialog::getInt(this, _("Set TCP Timeout"), tr("timeout(ms): "),
QLineEdit::Normal, 500, 2000);
const auto row_size = ui->keyServerListTable->rowCount();
for (int i = 0; i < row_size; i++) {
const auto keyserver = ui->keyServerListTable->item(i, 1)->text();
const auto status = ui->keyServerListTable->item(i, 3);
if (keyserver == nullptr || status == nullptr) continue;
auto key_url = QUrl{keyserver};
LOG(INFO) << "key domain" << key_url.host().toStdString();
QTcpSocket socket(this);
socket.abort();
socket.connectToHost(key_url.host(), 80);
if (socket.waitForConnected(timeout)) {
status->setText(_("Reachable"));
status->setForeground(QBrush(QColor::fromRgb(0, 255, 0)));
} else {
status->setText(_("Not Reachable"));
status->setForeground(QBrush(QColor::fromRgb(255, 0, 0)));
}
socket.close();
}
ui->keyServerListTable->blockSignals(false);
}
void KeyserverTab::contextMenuEvent(QContextMenuEvent* event) {
QWidget::contextMenuEvent(event);
if (ui->keyServerListTable->selectedItems().length() > 0) {
popupMenu->exec(event->globalPos());
}
}
} // namespace GpgFrontend::UI