From b95028e33e2f8aaea255379a559fd7e93b14b838 Mon Sep 17 00:00:00 2001 From: blue Date: Sat, 11 Apr 2020 01:15:08 +0300 Subject: [PATCH] testing, ability to build without kwallet, translations, disabling unsupported storage types in combobox --- CHANGELOG.md | 1 + CMakeLists.txt | 30 +++- README.md | 10 ++ core/CMakeLists.txt | 8 +- core/passwordStorageEngines/CMakeLists.txt | 50 +++--- core/passwordStorageEngines/kwallet.cpp | 7 +- core/squawk.cpp | 20 ++- core/squawk.h | 5 + shared/global.cpp | 101 +++++++---- shared/global.h | 9 + translations/squawk.ru.ts | 196 +++++++++++---------- ui/widgets/account.cpp | 16 +- ui/widgets/account.h | 4 + ui/widgets/account.ui | 20 ++- ui/widgets/accounts.cpp | 1 + 15 files changed, 315 insertions(+), 163 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b993919..11177e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - store it in plain text with the config (like it always was) - store it in config jammed (local hashing with the constant seed, not secure at all but might look like it is) - ask the account password on each program launch + - store it in KWallet which is dynamically loaded ### Bug fixes - never updating MUC avatars now update diff --git a/CMakeLists.txt b/CMakeLists.txt index aac3e75..20ae092 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,15 +62,39 @@ add_custom_target(translations ALL DEPENDS ${QM_FILES}) qt5_add_resources(RCC resources/resources.qrc) -add_executable(squawk ${squawk_SRC} ${squawk_HEAD} ${RCC}) -target_link_libraries(squawk Qt5::Widgets) - option(SYSTEM_QXMPP "Use system qxmpp lib" ON) +option(WITH_KWALLET "Build KWallet support module" ON) + +if (SYSTEM_QXMPP) + find_package(QXmpp CONFIG) + + if (NOT QXmpp_FOUND) + set(SYSTEM_QXMPP OFF) + message("QXmpp package wasn't found, trying to build with bundled QXmpp") + else() + message("Building with system QXmpp") + endif() +endif() if(NOT SYSTEM_QXMPP) add_subdirectory(external/qxmpp) endif() +if (WITH_KWALLET) + find_package(KF5Wallet CONFIG) + + if (NOT KF5Wallet_FOUND) + set(WITH_KWALLET OFF) + message("KWallet package wasn't found, KWallet support module wouldn't be built") + else() + add_definitions(-DWITH_KWALLET) + message("Building with support of KWallet") + endif() +endif() + +add_executable(squawk ${squawk_SRC} ${squawk_HEAD} ${RCC}) +target_link_libraries(squawk Qt5::Widgets) + add_subdirectory(ui) add_subdirectory(core) diff --git a/README.md b/README.md index 1366c96..c820ccd 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,16 @@ $ cmake .. -D SYSTEM_QXMPP=False $ cmake --build . ``` +### List of keys + +Here is the list of keys you can pass to configuration phase of `cmake ..`. +- `CMAKE_BUILD_TYPE` - `Debug` just builds showing all warnings, `Release` builds with no warnings and applies optimizations (default is `Debug`) +- `SYSTEM_QXMPP` - `True` tries to link against `qxmpp` installed in the system, `False` builds bundled `qxmpp` library (default is `True`) +- `WITH_KWALLET` - `True` builds the `KWallet` capability module if `KWallet` is installed and if not goes to `False`. `False` disables `KWallet` support (default is `True`) + + +Each key is supposed to be passed like that + ## License This project is licensed under the GPLv3 License - see the [LICENSE.md](LICENSE.md) file for details diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 32d61b9..c9c573b 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -20,13 +20,13 @@ set(squawkCORE_SRC adapterFuctions.cpp ) +add_subdirectory(passwordStorageEngines) + # Tell CMake to create the helloworld executable add_library(squawkCORE ${squawkCORE_SRC}) -add_subdirectory(passwordStorageEngines) if(SYSTEM_QXMPP) - find_package(QXmpp CONFIG REQUIRED) get_target_property(QXMPP_INTERFACE_INCLUDE_DIRECTORIES QXmpp::QXmpp INTERFACE_INCLUDE_DIRECTORIES) target_include_directories(squawkCORE PUBLIC ${QXMPP_INTERFACE_INCLUDE_DIRECTORIES}) endif() @@ -39,4 +39,6 @@ target_link_libraries(squawkCORE Qt5::Xml) target_link_libraries(squawkCORE qxmpp) target_link_libraries(squawkCORE lmdb) target_link_libraries(squawkCORE simpleCrypt) -target_link_libraries(squawkCORE kwalletPSE) +if (WITH_KWALLET) + target_link_libraries(squawkCORE kwalletPSE) +endif() diff --git a/core/passwordStorageEngines/CMakeLists.txt b/core/passwordStorageEngines/CMakeLists.txt index 9527238..36f67b1 100644 --- a/core/passwordStorageEngines/CMakeLists.txt +++ b/core/passwordStorageEngines/CMakeLists.txt @@ -1,36 +1,42 @@ cmake_minimum_required(VERSION 3.0) project(pse) -set(CMAKE_AUTOMOC ON) -find_package(Qt5Core CONFIG REQUIRED) -find_package(Qt5Gui CONFIG REQUIRED) -find_package(KF5Wallet CONFIG REQUIRED) +if (WITH_KWALLET) + set(CMAKE_AUTOMOC ON) -get_target_property(KWALLET_INTERFACE_INCLUDE_DIRECTORIES KF5::Wallet INTERFACE_INCLUDE_DIRECTORIES) -get_target_property(Qt5GUI_INTERFACE_INCLUDE_DIRECTORIES Qt5::Gui INTERFACE_INCLUDE_DIRECTORIES) + find_package(Qt5Core CONFIG REQUIRED) + find_package(Qt5Gui CONFIG REQUIRED) -set(kwalletPSE_SRC - kwallet.cpp -) + get_target_property(KWALLET_INTERFACE_INCLUDE_DIRECTORIES KF5::Wallet INTERFACE_INCLUDE_DIRECTORIES) + get_target_property(Qt5GUI_INTERFACE_INCLUDE_DIRECTORIES Qt5::Gui INTERFACE_INCLUDE_DIRECTORIES) -add_library(kwalletPSE ${kwalletPSE_SRC}) + set(kwalletPSE_SRC + kwallet.cpp + ) + + add_library(kwalletPSE ${kwalletPSE_SRC}) + + target_include_directories(kwalletPSE PUBLIC ${KWALLET_INTERFACE_INCLUDE_DIRECTORIES}) + target_include_directories(kwalletPSE PUBLIC ${Qt5GUI_INTERFACE_INCLUDE_DIRECTORIES}) -target_include_directories(kwalletPSE PUBLIC ${KWALLET_INTERFACE_INCLUDE_DIRECTORIES}) -target_include_directories(kwalletPSE PUBLIC ${Qt5GUI_INTERFACE_INCLUDE_DIRECTORIES}) + target_link_libraries(kwalletPSE Qt5::Core) -target_link_libraries(kwalletPSE Qt5::Core) + set(kwalletW_SRC + wrappers/kwallet.cpp + ) -set(kwalletW_SRC - wrappers/kwallet.cpp -) + add_library(kwalletWrapper SHARED ${kwalletW_SRC}) + + target_include_directories(kwalletWrapper PUBLIC ${KWALLET_INTERFACE_INCLUDE_DIRECTORIES}) + target_include_directories(kwalletWrapper PUBLIC ${Qt5GUI_INTERFACE_INCLUDE_DIRECTORIES}) + + target_link_libraries(kwalletWrapper KF5::Wallet) + target_link_libraries(kwalletWrapper Qt5::Core) + + install(TARGETS kwalletWrapper DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() -add_library(kwalletWrapper SHARED ${kwalletW_SRC}) -target_include_directories(kwalletWrapper PUBLIC ${KWALLET_INTERFACE_INCLUDE_DIRECTORIES}) -target_include_directories(kwalletWrapper PUBLIC ${Qt5GUI_INTERFACE_INCLUDE_DIRECTORIES}) -target_link_libraries(kwalletWrapper KF5::Wallet) -target_link_libraries(kwalletWrapper Qt5::Core) -install(TARGETS kwalletWrapper DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/core/passwordStorageEngines/kwallet.cpp b/core/passwordStorageEngines/kwallet.cpp index ddfb466..fe05a2c 100644 --- a/core/passwordStorageEngines/kwallet.cpp +++ b/core/passwordStorageEngines/kwallet.cpp @@ -28,7 +28,7 @@ Core::PSE::KWallet::CreateFolder Core::PSE::KWallet::createFolder = 0; Core::PSE::KWallet::SetFolder Core::PSE::KWallet::setFolder = 0; Core::PSE::KWallet::SupportState Core::PSE::KWallet::sState = Core::PSE::KWallet::initial; -QLibrary Core::PSE::KWallet::lib("./libkwalletWrapper.so"); +QLibrary Core::PSE::KWallet::lib("kwalletWrapper"); Core::PSE::KWallet::KWallet(): QObject(), @@ -41,6 +41,11 @@ Core::PSE::KWallet::KWallet(): if (sState == initial) { lib.load(); + if (!lib.isLoaded()) { //fallback from the build directory + lib.setFileName("./core/passwordStorageEngines/libkwalletWrapper.so"); + lib.load(); + } + if (lib.isLoaded()) { openWallet = (OpenWallet) lib.resolve("openWallet"); networkWallet = (NetworkWallet) lib.resolve("networkWallet"); diff --git a/core/squawk.cpp b/core/squawk.cpp index abd8977..8a486c0 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -27,8 +27,10 @@ Core::Squawk::Squawk(QObject* parent): accounts(), amap(), network(), - waitingForAccounts(0), - kwallet() + waitingForAccounts(0) +#ifdef WITH_KWALLET + ,kwallet() +#endif { connect(&network, &NetworkAccess::fileLocalPathResponse, this, &Squawk::fileLocalPathResponse); connect(&network, &NetworkAccess::downloadFileProgress, this, &Squawk::downloadFileProgress); @@ -36,13 +38,15 @@ Core::Squawk::Squawk(QObject* parent): connect(&network, &NetworkAccess::uploadFileProgress, this, &Squawk::uploadFileProgress); connect(&network, &NetworkAccess::uploadFileError, this, &Squawk::uploadFileError); - +#ifdef WITH_KWALLET if (kwallet.supportState() == PSE::KWallet::success) { - qDebug() << "KWallet support detected"; connect(&kwallet, &PSE::KWallet::opened, this, &Squawk::onWalletOpened); connect(&kwallet, &PSE::KWallet::rejectPassword, this, &Squawk::onWalletRejectPassword); connect(&kwallet, &PSE::KWallet::responsePassword, this, &Squawk::onWalletResponsePassword); + + Shared::Global::setSupported("KWallet", true); } +#endif } Core::Squawk::~Squawk() @@ -236,9 +240,11 @@ void Core::Squawk::onAccountConnectionStateChanged(Shared::ConnectionState p_sta } break; case Shared::ConnectionState::connected: +#ifdef WITH_KWALLET if (acc->getPasswordType() == Shared::AccountPassword::kwallet && kwallet.supportState() == PSE::KWallet::success) { kwallet.requestWritePassword(acc->getName(), acc->getPassword(), true); } +#endif break; default: break; @@ -415,12 +421,14 @@ void Core::Squawk::modifyAccountRequest(const QString& name, const QMapsetPasswordType(Shared::Global::fromInt(mItr->toInt())); } +#ifdef WITH_KWALLET if (acc->getPasswordType() == Shared::AccountPassword::kwallet && kwallet.supportState() == PSE::KWallet::success && !needToReconnect ) { kwallet.requestWritePassword(acc->getName(), acc->getPassword(), true); } +#endif emit changeAccount(name, map); } @@ -716,11 +724,15 @@ void Core::Squawk::parseAccount( break; case Shared::AccountPassword::kwallet: { addAccount(login, server, QString(), name, resource, passwordType); +#ifdef WITH_KWALLET if (kwallet.supportState() == PSE::KWallet::success) { kwallet.requestReadPassword(name); } else { +#endif emit requestPassword(name); +#ifdef WITH_KWALLET } +#endif } } } diff --git a/core/squawk.h b/core/squawk.h index b1fa492..31812d2 100644 --- a/core/squawk.h +++ b/core/squawk.h @@ -34,7 +34,9 @@ #include "networkaccess.h" #include "external/simpleCrypt/simplecrypt.h" +#ifdef WITH_KWALLET #include "passwordStorageEngines/kwallet.h" +#endif namespace Core { @@ -116,7 +118,10 @@ private: Shared::Availability state; NetworkAccess network; uint8_t waitingForAccounts; + +#ifdef WITH_KWALLET PSE::KWallet kwallet; +#endif private slots: void addAccount( diff --git a/shared/global.cpp b/shared/global.cpp index c974eaf..c8e5cf2 100644 --- a/shared/global.cpp +++ b/shared/global.cpp @@ -24,53 +24,62 @@ Shared::Global* Shared::Global::instance = 0; Shared::Global::Global(): availability({ - tr("Online"), - tr("Away"), - tr("Absent"), - tr("Busy"), - tr("Chatty"), - tr("Invisible"), - tr("Offline") + tr("Online", "Availability"), + tr("Away", "Availability"), + tr("Absent", "Availability"), + tr("Busy", "Availability"), + tr("Chatty", "Availability"), + tr("Invisible", "Availability"), + tr("Offline", "Availability") }), connectionState({ - tr("Disconnected"), - tr("Connecting"), - tr("Connected"), - tr("Error") + tr("Disconnected", "ConnectionState"), + tr("Connecting", "ConnectionState"), + tr("Connected", "ConnectionState"), + tr("Error", "ConnectionState") }), subscriptionState({ - tr("None"), - tr("From"), - tr("To"), - tr("Both"), - tr("Unknown") + tr("None", "SubscriptionState"), + tr("From", "SubscriptionState"), + tr("To", "SubscriptionState"), + tr("Both", "SubscriptionState"), + tr("Unknown", "SubscriptionState") }), affiliation({ - tr("Unspecified"), - tr("Outcast"), - tr("Nobody"), - tr("Member"), - tr("Admin"), - tr("Owner") + tr("Unspecified", "Affiliation"), + tr("Outcast", "Affiliation"), + tr("Nobody", "Affiliation"), + tr("Member", "Affiliation"), + tr("Admin", "Affiliation"), + tr("Owner", "Affiliation") }), role({ - tr("Unspecified"), - tr("Nobody"), - tr("Visitor"), - tr("Participant"), - tr("Moderator") + tr("Unspecified", "Role"), + tr("Nobody", "Role"), + tr("Visitor", "Role"), + tr("Participant", "Role"), + tr("Moderator", "Role") }), messageState({ - tr("Pending"), - tr("Sent"), - tr("Delivered"), - tr("Error") + tr("Pending", "MessageState"), + tr("Sent", "MessageState"), + tr("Delivered", "MessageState"), + tr("Error", "MessageState") }), accountPassword({ - tr("Plain"), - tr("Jammed"), - tr("Always Ask"), - tr("KWallet") + tr("Plain", "AccountPassword"), + tr("Jammed", "AccountPassword"), + tr("Always Ask", "AccountPassword"), + tr("KWallet", "AccountPassword") + }), + accountPasswordDescription({ + tr("Your password is going to be stored in config file in plain text", "AccountPasswordDescription"), + tr("Your password is going to be stored in config file but jammed with constant encryption key you can find in program source code. It might look like encryption but it's not", "AccountPasswordDescription"), + tr("Squawk is going to query you for the password on every start of the program", "AccountPasswordDescription"), + tr("Your password is going to be stored in KDE wallet storage (KWallet). You're going to be queried for permissions", "AccountPasswordDescription") + }), + pluginSupport({ + {"KWallet", false} }) { if (instance != 0) { @@ -120,6 +129,28 @@ QString Shared::Global::getName(Shared::AccountPassword ap) return instance->accountPassword[static_cast(ap)]; } +void Shared::Global::setSupported(const QString& pluginName, bool support) +{ + std::map::iterator itr = instance->pluginSupport.find(pluginName); + if (itr != instance->pluginSupport.end()) { + itr->second = support; + } +} + +bool Shared::Global::supported(const QString& pluginName) +{ + std::map::iterator itr = instance->pluginSupport.find(pluginName); + if (itr != instance->pluginSupport.end()) { + return itr->second; + } + return false; +} + +QString Shared::Global::getDescription(Shared::AccountPassword ap) +{ + return instance->accountPasswordDescription[static_cast(ap)]; +} + #define FROM_INT_INPL(Enum) \ template<> \ Enum Shared::Global::fromInt(int src) \ diff --git a/shared/global.h b/shared/global.h index 3ea6147..481ac01 100644 --- a/shared/global.h +++ b/shared/global.h @@ -45,6 +45,8 @@ namespace Shared { static QString getName(Message::State rl); static QString getName(AccountPassword ap); + static QString getDescription(AccountPassword ap); + const std::deque availability; const std::deque connectionState; const std::deque subscriptionState; @@ -53,6 +55,11 @@ namespace Shared { const std::deque messageState; const std::deque accountPassword; + const std::deque accountPasswordDescription; + + static bool supported(const QString& pluginName); + static void setSupported(const QString& pluginName, bool support); + template static T fromInt(int src); @@ -74,6 +81,8 @@ namespace Shared { private: static Global* instance; + + std::map pluginSupport; }; } diff --git a/translations/squawk.ru.ts b/translations/squawk.ru.ts index 8a733f2..32efc46 100644 --- a/translations/squawk.ru.ts +++ b/translations/squawk.ru.ts @@ -67,7 +67,7 @@ Password storage - + Хранение пароля @@ -122,173 +122,200 @@ p, li { white-space: pre-wrap; } Global - - Disconnected - Отключен - - - Connecting - Подключается - - - Connected - Подключен - - - Error - Ошибка - Online + Availability В сети Away + Availability Отошел - - Busy - Занят - Absent + Availability Недоступен + + Busy + Availability + Занят + Chatty + Availability Готов поболтать Invisible + Availability Невидимый Offline + Availability Отключен + + Disconnected + ConnectionState + Отключен + + + Connecting + ConnectionState + Подключается + + + Connected + ConnectionState + Подключен + + + Error + ConnectionState + Ошибка + None + SubscriptionState Нет From + SubscriptionState Входящая To + SubscriptionState Исходящая Both + SubscriptionState Взаимная Unknown + SubscriptionState Неизвестно Unspecified + Affiliation Не назначено Outcast + Affiliation Изгой Nobody + Affiliation Никто Member + Affiliation Участник Admin + Affiliation Администратор Owner + Affiliation Владелец + + Unspecified + Role + Не назначено + + + Nobody + Role + Никто + Visitor + Role Гость Participant + Role Участник Moderator + Role Модератор - - Not specified - Не указан - - - Personal - Личный - - - Business - Рабочий - - - Fax - Факс - - - Pager - Пэйджер - - - Voice - Стационарный - - - Cell - Мобильный - - - Video - Видеофон - - - Modem - Модем - - - Other - Другой - Pending - В процессе + MessageState + В процессе отправки Sent + MessageState Отправлено Delivered + MessageState Доставлено + + Error + MessageState + Ошибка + Plain - + AccountPassword + Открытый текст Jammed - - - - KWallet - + AccountPassword + Обфусцированный Always Ask - + AccountPassword + Всегда спрашивать + + + KWallet + AccountPassword + KWallet + + + Your password is going to be stored in config file but jammed with constant encryption key you can find in program source code. It might look like encryption but it's not + AccountPasswordDescription + Ваш пароль будет храниться в обфусцированном виде в конфигурационном файле. Обфускация производится с помощью постоянного числа, которое можно найти в исходном коде программы. Это может и выглядит как шифрование но им не является + + + Squawk is going to query you for the password on every start of the program + AccountPasswordDescription + Squawk будет спрашивать пароль от этой учетной записи каждый раз при запуске + + + Your password is going to be stored in config file in plain text + AccountPasswordDescription + Ваш пароль будет храниться в конфигурационном файле открытым текстром + + + Your password is going to be stored in KDE wallet storage (KWallet). You're going to be queried for permissions + AccountPasswordDescription + Ваш пароль будет храниться в бумажнике KDE (KWallet). В первый раз программа попросит разрешения для доступа к бумажнику @@ -337,10 +364,6 @@ p, li { white-space: pre-wrap; } Message - - Download - Скачать - Open Открыть @@ -383,25 +406,6 @@ You can try again Загружается... - - Models::Accounts - - Name - Имя - - - Server - Сервер - - - State - Состояние - - - Error - Ошибка - - Models::Room @@ -625,6 +629,14 @@ to be displayed as %1 Attached file Прикрепленный файл + + Input the password for account %1 + Введите пароль для учетной записи %1 + + + Password for account %1 + Пароль для учетной записи %1 + VCard diff --git a/ui/widgets/account.cpp b/ui/widgets/account.cpp index d417d4f..ba3af6b 100644 --- a/ui/widgets/account.cpp +++ b/ui/widgets/account.cpp @@ -23,13 +23,21 @@ Account::Account(): QDialog(), m_ui(new Ui::Account) { - m_ui->setupUi (this); + m_ui->setupUi(this); + + connect(m_ui->passwordType, qOverload(&QComboBox::currentIndexChanged), this, &Account::onComboboxChange); for (int i = static_cast(Shared::AccountPasswordLowest); i < static_cast(Shared::AccountPasswordHighest) + 1; ++i) { Shared::AccountPassword ap = static_cast(i); m_ui->passwordType->addItem(Shared::Global::getName(ap)); } m_ui->passwordType->setCurrentIndex(static_cast(Shared::AccountPassword::plain)); + + if (!Shared::Global::supported("KWallet")) { + QStandardItemModel *model = static_cast(m_ui->passwordType->model()); + QStandardItem *item = model->item(static_cast(Shared::AccountPassword::kwallet)); + item->setFlags(item->flags() & ~Qt::ItemIsEnabled); + } } Account::~Account() @@ -63,3 +71,9 @@ void Account::setData(const QMap& data) m_ui->resource->setText(data.value("resource").toString()); m_ui->passwordType->setCurrentIndex(data.value("passwordType").toInt()); } + +void Account::onComboboxChange(int index) +{ + QString description = Shared::Global::getDescription(Shared::Global::fromInt(index)); + m_ui->comment->setText(description); +} diff --git a/ui/widgets/account.h b/ui/widgets/account.h index 9732224..cbe8b9c 100644 --- a/ui/widgets/account.h +++ b/ui/widgets/account.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "shared/global.h" @@ -44,6 +45,9 @@ public: void setData(const QMap& data); void lockId(); +private slots: + void onComboboxChange(int index); + private: QScopedPointer m_ui; }; diff --git a/ui/widgets/account.ui b/ui/widgets/account.ui index 28cb389..a1879bc 100644 --- a/ui/widgets/account.ui +++ b/ui/widgets/account.ui @@ -114,14 +114,14 @@ - + Resource - + A resource name like "Home" or "Work" @@ -141,6 +141,22 @@ + + + + + 0 + 0 + + + + + + + true + + + diff --git a/ui/widgets/accounts.cpp b/ui/widgets/accounts.cpp index 626915e..7f4a135 100644 --- a/ui/widgets/accounts.cpp +++ b/ui/widgets/accounts.cpp @@ -37,6 +37,7 @@ Accounts::Accounts(Models::Accounts* p_model, QWidget *parent) : m_ui->tableView->setModel(model); connect(m_ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &Accounts::onSelectionChanged); connect(p_model, &Models::Accounts::changed, this, &Accounts::updateConnectButton); + connect(m_ui->tableView, &QTableView::doubleClicked, this, &Accounts::onEditButton); } Accounts::~Accounts() = default;