diff --git a/CMakeLists.txt b/CMakeLists.txt index 93dbe00..812e1de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,9 @@ add_executable(emailQt main.cpp Email.cpp Email.hpp EmailDetails.cpp - EmailDetails.hpp) + EmailDetails.hpp + KeychainClass.cpp + KeychainClass.hpp) target_link_libraries(emailQt PRIVATE Qt6::Core Qt6::Gui diff --git a/KeychainClass.cpp b/KeychainClass.cpp new file mode 100644 index 0000000..94bd3aa --- /dev/null +++ b/KeychainClass.cpp @@ -0,0 +1,33 @@ +#include "KeychainClass.hpp" + +KeychainClass::KeychainClass(QObject *parent) + : QObject(parent), + readCredentialJob(QLatin1String(Keychain::url)), + writeCredentialJob(QLatin1String(Keychain::url)), + deleteCredentialJob(QLatin1String(Keychain::url)) { + readCredentialJob.setAutoDelete(false); + writeCredentialJob.setAutoDelete(false); + deleteCredentialJob.setAutoDelete(false); +} + +void KeychainClass::readKey(QString const &key) { + readCredentialJob.setKey(key); + connect(&readCredentialJob, &QKeychain::ReadPasswordJob::finished, this, [this, key]() { + if (readCredentialJob.error()) + return; + emit keyRead(key, readCredentialJob.textData()); + }); + + readCredentialJob.start(); +} + +void KeychainClass::writeKey(QString const &key, QString const &value) { + writeCredentialJob.setKey(key); + writeCredentialJob.setTextData(value); + writeCredentialJob.start(); +} + +void KeychainClass::deleteKey(QString const &key) { + deleteCredentialJob.setKey(key); + deleteCredentialJob.start(); +} diff --git a/KeychainClass.hpp b/KeychainClass.hpp new file mode 100644 index 0000000..78047b8 --- /dev/null +++ b/KeychainClass.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +#include + +namespace Keychain { + constexpr char url[]{"keychain.emailQt.kvuj.app"}; + const QString passKey("Password"); +} + +class KeychainClass : public QObject { + Q_OBJECT + +public: + explicit KeychainClass(QObject *parent = nullptr); + + void readKey(const QString &key); + void writeKey(const QString &key, const QString &value); + void deleteKey(const QString &key); + +signals: + void keyRead(const QString &key, const QString &value); + +private: + QKeychain::ReadPasswordJob readCredentialJob; + QKeychain::WritePasswordJob writeCredentialJob; + QKeychain::DeletePasswordJob deleteCredentialJob; +}; diff --git a/ParametersProvider.cpp b/ParametersProvider.cpp index 874052d..693f9b0 100644 --- a/ParametersProvider.cpp +++ b/ParametersProvider.cpp @@ -12,10 +12,10 @@ ParametersProvider::ParametersProvider(QWidget *parent) passField->setEchoMode(QLineEdit::Password); auto *imap = new QLabel("IMAP Server", this); - imapField = new QLineEdit("imap.gmail.com"); + imapField = new QLineEdit; auto *port = new QLabel("Port", this); - portField = new QLineEdit("993"); + portField = new QLineEdit; portField->setValidator(new QIntValidator(1, 1000, this)); auto *startButton = new QPushButton("OK", this); @@ -36,6 +36,25 @@ ParametersProvider::ParametersProvider(QWidget *parent) resize(300, 450); connect(startButton, &QPushButton::clicked, this, &ParametersProvider::start); + + // Keychain + connect(&keychain, &KeychainClass::keyRead, this, &ParametersProvider::keyRead); + keychain.readKey(Keychain::passKey); + + // Ne pas overrider les defaults + userField->setText(mSettings.value("Username").toString()); + imapField->setText(mSettings.value("Server").toString()); + portField->setText(mSettings.value("Port").toString()); + + if (imapField->text().isEmpty()) + imapField->setText("imap.gmail.com"); + if (portField->text().isEmpty()) + portField->setText("993"); +} + +void ParametersProvider::keyRead(const QString &key, const QString &value) { + if (key == Keychain::passKey) + passField->setText(value); } void ParametersProvider::start() { @@ -43,6 +62,13 @@ void ParametersProvider::start() { sett.userS = userField->text().toStdString(); sett.passS = passField->text().toStdString(); sett.imapS = imapField->text().toStdString(); + + // Saved login data + keychain.writeKey(Keychain::passKey, QString::fromStdString(sett.passS)); + mSettings.setValue("Username", QString::fromStdString(sett.userS)); + mSettings.setValue("Server", QString::fromStdString(sett.imapS)); + mSettings.setValue("Port", QString::fromStdString(std::to_string(sett.port))); + close(); emit done(); } @@ -54,4 +80,4 @@ void ParametersProvider::setFocusInternal() { const ParametersProvider::settings &ParametersProvider::getSettings() { return sett; -} +} \ No newline at end of file diff --git a/ParametersProvider.hpp b/ParametersProvider.hpp index 7b3d43f..95858ac 100644 --- a/ParametersProvider.hpp +++ b/ParametersProvider.hpp @@ -5,7 +5,12 @@ #include #include #include +#include +#include #include +#include + +#include "KeychainClass.hpp" class ParametersProvider : public QDialog { Q_OBJECT @@ -19,14 +24,23 @@ public: explicit ParametersProvider(QWidget *parent = nullptr); ~ParametersProvider() = default; - void start(); void setFocusInternal(); const settings &getSettings(); signals: void done(); +public slots: + // Keychain to save password + void keyRead(const QString &key, const QString &value); + + // When clicking OK + void start(); + private: settings sett; QLineEdit *userField, *passField, *imapField, *portField; + + KeychainClass keychain; + QSettings mSettings; };