Skip to content
This repository was archived by the owner on Sep 24, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ find_package(KF5IconThemes CONFIG REQUIRED)
find_package(KF5TextWidgets CONFIG REQUIRED)
find_package(KF5WidgetsAddons CONFIG REQUIRED)
find_package(KF5WindowSystem CONFIG REQUIRED)
find_package(KF5Wallet CONFIG REQUIRED)
find_package(KF5ConfigWidgets CONFIG REQUIRED)

# KDChart is potentially a dependency of KDReports
Expand Down Expand Up @@ -96,6 +95,8 @@ set_package_properties(ICU PROPERTIES
PURPOSE "Required to localize country names"
)

find_package(Qt5Keychain REQUIRED)

if(PhoneNumber_FOUND AND ICU_FOUND)
set(USE_PHONENUMBER 1)
else()
Expand Down
11 changes: 0 additions & 11 deletions resources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,5 @@ endif()

include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})

if(APPLE OR WIN32)
set(_default_kwallet_option 0)
else()
set(_default_kwallet_option 1)
endif()
option(USE_KWALLET "Use KWallet for password storage (default 1 on Unix, 0 on Windows/Mac)" ${_default_kwallet_option})
if(USE_KWALLET)
find_package(KF5Wallet ${KF5_VERSION} CONFIG REQUIRED)
endif()
configure_file(config-kwallet.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kwallet.h)

add_subdirectory(salesforce)
add_subdirectory(sugarcrm)
1 change: 0 additions & 1 deletion resources/config-kwallet.h.cmake

This file was deleted.

7 changes: 2 additions & 5 deletions resources/sugarcrm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ target_link_libraries(akonadi_sugarcrm_resource_private
KF5::CalendarCore
KF5::AkonadiContact
KF5::WindowSystem
qt5keychain
PUBLIC
KF5::AkonadiAgentBase
KF5::Contacts
Expand All @@ -81,11 +82,7 @@ if(KCALENDARCORE_REQUIRES_KDE4SUPPORT)
KF5::KDELibs4Support
)
endif()
if(USE_KWALLET)
target_link_libraries(akonadi_sugarcrm_resource_private PRIVATE
KF5::Wallet
)
endif()

target_link_libraries(akonadi_sugarcrm_resource_private PRIVATE KDReports::kdreports)

target_link_libraries(akonadi_sugarcrm_resource PRIVATE
Expand Down
142 changes: 53 additions & 89 deletions resources/sugarcrm/passwordhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,79 +22,65 @@
#include "sugarcrmresource_debug.h"
#include <settings.h>

#if USE_KWALLET
#include <KWallet/KWallet>
using KWallet::Wallet;
#include <qt5keychain/keychain.h>

static const char s_walletFolderName[] = "SugarCRM";
#endif
static const char s_keychainFolderName[] = "SugarCRM";

// Implementation inspired from kdepim-runtime/resources/imap/settings.cpp branch KDE/4.14

PasswordHandler::PasswordHandler(const QString &resourceId, QObject *parent) :
QObject(parent),
mResourceId(resourceId)
{
#if USE_KWALLET
// We have no GUI to use on startup
// We could at least use the config dialog though.
m_winId = 0;
mWalletOpened = false;

Wallet *wallet = Wallet::openWallet( Wallet::NetworkWallet(), m_winId, Wallet::Asynchronous );
if (wallet) {
connect(wallet, SIGNAL(walletOpened(bool)),
this, SLOT(onWalletOpened(bool)));
} else {
qCWarning(FATCRM_SUGARCRMRESOURCE_LOG) << "openWallet(Asynchronous) failed!";
}
#endif
auto *job = new QKeychain::ReadPasswordJob(s_keychainFolderName);

job->setKey(resourceId);

connect(job, &QKeychain::Job::finished, this, [this, job] {
if (job->error()) {
qWarning() << "Error reading password for" << mResourceId << job->errorString();

if (job->error() == QKeychain::AccessDeniedByUser) {
mDeniedByUser = true;
}
} else {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should there be a mDeniedByUser = false; here?

mPassword = job->textData();
mKeychainOpened = true;
Q_EMIT passwordAvailable();
}
});

job->start();
}

bool PasswordHandler::isPasswordAvailable()
{
#if USE_KWALLET
if (!mWalletOpened)
return false;
QScopedPointer<Wallet> wallet(Wallet::openWallet(Wallet::NetworkWallet(), m_winId));
return wallet && wallet->isOpen();
#else
return true;
#endif
return mKeychainOpened;
}

QString PasswordHandler::password(bool *userRejected)
{
if (userRejected != nullptr) {
*userRejected = false;
}
*userRejected = mDeniedByUser;

if (!mPassword.isEmpty())
return mPassword;
#if USE_KWALLET
QScopedPointer<Wallet> wallet(Wallet::openWallet(Wallet::NetworkWallet(), m_winId));
if (wallet && wallet->isOpen()) {
if (wallet->hasFolder(QString(s_walletFolderName))) {
wallet->setFolder(QString(s_walletFolderName));
wallet->readPassword(mResourceId, mPassword);
} else {
wallet->createFolder(QString(s_walletFolderName));
if (mDeniedByUser) {
return QString();
}
// Initial migration: password not in wallet yet
if (mPassword.isEmpty()) {
mPassword = Settings::password();
if (!mPassword.isEmpty()) {
savePassword();
}
}

if (!mKeychainOpened) {
return QString();
}

// Initial migration: password not in keychain yet
if (mPassword.isEmpty()) {
mPassword = Settings::password();
if (!mPassword.isEmpty()) {
savePassword();
}
} else if (userRejected != nullptr) {
*userRejected = true;
}
#else
mPassword = Settings::password();
#endif
return mPassword;

return mPassword;
}

void PasswordHandler::setPassword(const QString &password)
Expand All @@ -103,47 +89,25 @@ void PasswordHandler::setPassword(const QString &password)
return;

mPassword = password;

#if USE_KWALLET
savePassword();
#else
Settings::setPassword(mPassword);
Settings::self()->writeConfig();
#endif
}

void PasswordHandler::onWalletOpened(bool success)
{
#if USE_KWALLET
Wallet *wallet = qobject_cast<Wallet*>( sender() );
mWalletOpened = success;
if (wallet && success) {
// read and store the password
password();
emit passwordAvailable();
}
if (wallet) {
wallet->deleteLater();
}
#else
Q_UNUSED(success);
#endif
}

#if USE_KWALLET
bool PasswordHandler::savePassword()
{
QScopedPointer<Wallet> wallet(Wallet::openWallet(Wallet::NetworkWallet(), m_winId));
if (wallet && wallet->isOpen()) {
if (!wallet->hasFolder(QString(s_walletFolderName)))
wallet->createFolder(QString(s_walletFolderName));
wallet->setFolder(QString(s_walletFolderName));
wallet->writePassword(mResourceId, mPassword);
wallet->sync();
Settings::setPassword(QString()); // ensure no plain-text password from before in the config file
Settings::self()->save();
return true;
}
return false;
auto *job = new QKeychain::WritePasswordJob(s_keychainFolderName);
job->setKey(mResourceId);
job->setTextData(mPassword);

connect(job, &QKeychain::Job::finished, this, [this, job] {
if (job->error()) {
qWarning() << "password save error" << job->errorString();
}
});

job->start();

Settings::setPassword(QString()); // ensure no plain-text password from before in the config file

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be kept in the case the write job fails? I'd say security over keeping the password at all costs though.

Settings::self()->save();

return true;
}
#endif
12 changes: 2 additions & 10 deletions resources/sugarcrm/passwordhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
#include <QObject>
#include <QWidget>

#include <config-kwallet.h>

class PasswordHandler : public QObject
{
Q_OBJECT
Expand All @@ -39,18 +37,12 @@ class PasswordHandler : public QObject
Q_SIGNALS:
void passwordAvailable();

private Q_SLOTS:
void onWalletOpened(bool success);

private:
#if USE_KWALLET
bool savePassword();

WId m_winId;
bool mWalletOpened;
#endif
QString mPassword;
const QString mResourceId;
bool mKeychainOpened = false;
bool mDeniedByUser = false;
};

#endif // PASSWORDHANDLER_H