From 5f5277199a72b23f936ea00f8882fa71516ffd3b Mon Sep 17 00:00:00 2001 From: Daniel Tartavel Date: Wed, 8 Mar 2023 16:03:24 +0100 Subject: [PATCH] correction of password managment --- RsyncUI.pro | 1 - RsyncUI.pro.user | 2 +- downloadfile.cpp | 23 ------ login.ui | 144 --------------------------------- mainwindow.cpp | 204 +++++++++++++++++++++++++++++++++-------------- mainwindow.h | 20 ++--- tools.cpp | 16 +--- 7 files changed, 161 insertions(+), 249 deletions(-) delete mode 100644 login.ui diff --git a/RsyncUI.pro b/RsyncUI.pro index 9eb187b..51c292f 100644 --- a/RsyncUI.pro +++ b/RsyncUI.pro @@ -31,7 +31,6 @@ HEADERS += \ FORMS += \ about.ui \ configuration.ui \ - login.ui \ mainwindow.ui TRANSLATIONS += \ diff --git a/RsyncUI.pro.user b/RsyncUI.pro.user index 8882a05..372b13c 100644 --- a/RsyncUI.pro.user +++ b/RsyncUI.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/downloadfile.cpp b/downloadfile.cpp index 4dce85a..732eb54 100644 --- a/downloadfile.cpp +++ b/downloadfile.cpp @@ -125,26 +125,3 @@ void MainWindow::readRsyncOutput() } } } - -/*void MainWindow::downloadProcessError(QProcess::ProcessError error) -{ - QMessageBox::warning( - this, - "RsyncUI", - downloadProcessErrorString[error].toStdString().c_str() - ); -}*/ - -// process raise error -void MainWindow::downloadProcessStderr() -{ - QByteArray errorLine; - - errorLine = this->downloading.process->readAllStandardError(); - QMessageBox::warning( - this, - "RsyncUI", - errorLine - ); -} - diff --git a/login.ui b/login.ui deleted file mode 100644 index 1a2851f..0000000 --- a/login.ui +++ /dev/null @@ -1,144 +0,0 @@ - - - LoginDialog - - - Qt::ApplicationModal - - - - 0 - 0 - 400 - 194 - - - - RsyncUI request - - - true - - - - - 50 - 150 - 341 - 32 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - 10 - 10 - 381 - 121 - - - - - - - Login name - - - Qt::PlainText - - - Qt::NoTextInteraction - - - - - - - false - - - Qt::TabFocus - - - false - - - - - - 32767 - - - Enter login - - - - - - - Password - - - - - - - Qt::TabFocus - - - false - - - QLineEdit::Password - - - Enter password - - - - - - - - - - loginBox - accepted() - LoginDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - loginBox - rejected() - LoginDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/mainwindow.cpp b/mainwindow.cpp index a5b28c8..1b61aed 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -68,7 +68,8 @@ MainWindow::MainWindow(QWidget *parent) connect(this, &MainWindow::stopDownloading, this, &MainWindow::cancelled); connect(config.buttonBox, SIGNAL(accepted()), this, SLOT(on_buttonBox_accepted())); connect(config.comboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &MainWindow::on_comboBox_currentIndexChanged); - connect(loginD.loginBox, SIGNAL(accepted()), this, SLOT(on_loginBox_accepted())); +// connect(loginD.loginBox, SIGNAL(accepted()), this, SLOT(on_loginBox_accepted())); +// connect(this, SIGNAL(passwordReady()), this, SLOT(waitPasswword())); loadSettings(); @@ -292,7 +293,7 @@ void MainWindow::populateTree() { // server is validated, scanning directory path = this->connexion.service + "/"; - scanDir(this->connexion.server, this->connexion.port, nullptr, path); + scanDir(this->connexion.server, this->connexion.port, nullptr, path); } // Restoring cursor QGuiApplication::restoreOverrideCursor(); @@ -303,6 +304,7 @@ void MainWindow::populateTree() void MainWindow::populateList() { QString server; + QString service; QStringList hidden; int port; int i; @@ -353,18 +355,70 @@ void MainWindow::populateList() } } this->settings.endGroup(); - this->settings.beginGroup("Hidden/"); + this->settings.beginGroup("Hidden/" + server); hidden = this->settings.allKeys(); + this->settings.endGroup(); for (i = 0; i < hidden.size(); i++) { + service = hidden.at(i); //TODO detect if service is already present - ui->listWidget->addItem(this->settings.value(hidden.at(i)).toString() + "\n\t"); + if (testServicePresence(service, false)) + { + ui->listWidget->addItem(service + "\n\t"); + } } QGuiApplication::restoreOverrideCursor(); //setting cursor to default - this->settings.endGroup(); } } +// Test if service is already present on the server +bool MainWindow::testServicePresence(QString service, bool askPassword) +{ + QString cmd; + QStringList param; + QString line; + QString errorRsync; + QStringList v; + QProcess *myProcess; + bool returnValue = false; + QEventLoop loop; + + cmd = "/usr/bin/rsync"; + param << "--contimeout=10" << "-nq" << "--port=" + QString::number(this->connexion.port) << this->connexion.server + "::" + service; + myProcess = new QProcess(this); + myProcess->setProcessChannelMode(QProcess::MergedChannels); + myProcess->start(cmd, param); + myProcess->waitForStarted(); + myProcess->write("\n"); + //myProcess->waitForFinished(12000); + while(myProcess->waitForReadyRead(10000)) + { + while(1) + { + // line empty then buffer is empty so returning to wait new datas + line = QString::fromUtf8(myProcess->readLine()); + if (line.isEmpty()) + { + break; + } + if (line.contains("auth failed")) + { + if (askPassword) + { + getUserPassword(&this->connexion); + } + returnValue = true; + } + } + } + if (myProcess->exitCode() == 0) + { + returnValue = true; + } + myProcess->close(); + return returnValue; +} + //list services of the rsync server void MainWindow::listServices() { @@ -425,13 +479,15 @@ bool MainWindow::scanDir(QString server, int portN, QTreeWidgetItem *parent, QSt QString fileType; QString date; QProcess * myProcess; + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); bool isDir = false; bool flag = false; bool readOk = false; + bool passwdOk = false; int nChild = 0; - QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); myProcess = new QProcess(this); + myProcess->setProcessChannelMode(QProcess::MergedChannels); if (parent != nullptr) { @@ -470,12 +526,19 @@ bool MainWindow::scanDir(QString server, int portN, QTreeWidgetItem *parent, QSt flag = true; break; } + if (line.contains("auth failed")) + { + myProcess->readAllStandardOutput(); + getUserPassword(&this->connexion); + this->rescan = true; + return 0; + } + // extracting name, size and if is dir/file line = line.simplified(); filename = line.section(" ", 4); if (filename != '.') { - size = line.section(" ", 1, 1); fullsize = size; fullsize.remove(","); @@ -484,7 +547,8 @@ bool MainWindow::scanDir(QString server, int portN, QTreeWidgetItem *parent, QSt { size = sizeA.at(0) + " " + UnitText[0] + " "; }else - { + { myProcess->setProcessEnvironment(env); + size = sizeA.at(0) + "," + sizeA.at(1).left(2) + " " + UnitText[sizeA.count()-1] + " "; } @@ -498,6 +562,11 @@ bool MainWindow::scanDir(QString server, int portN, QTreeWidgetItem *parent, QSt date = line.section(' ', 2, 2); fileType = getFileType(filename); addTreeItem(filename, size, fullsize, fileType, date, isDir, parent); + if (passwdOk == false and !this->connexion.password.isEmpty()) + { + this->settings.setValue("Passwords/" + this->connexion.server + "/" + this->connexion.service + "/" + this->connexion.user, this->connexion.password); + this->settings.sync(); + } } } flag = false; @@ -655,6 +724,7 @@ void MainWindow::addTreeItem(QString name, QString fileSize, QString fullsize, Q void MainWindow::on_listWidget_clicked() { this->connexion.service = ui->listWidget->currentItem()->text().section("\n", 0 ,0); + ui->treeWidget->clear(); preparePopulateTree(); } @@ -674,65 +744,72 @@ void MainWindow::preparePopulateTree() this->downloading.savePath = this->settings.value(str).toString(); } - getUserPassword(false); - //this->settings.beginGroup("Passwords/" + this->connexion.server + "/" + this->connexion.service); - //logins = this->settings.allKeys(); - //if (logins.count() != 0) - //{ - // this->connexion.user = logins[0]; - // this->connexion.password = this->settings.value(logins[0]).toString(); - //} - this->settings.endGroup(); + getUserPassword(&this->connexion); + populateTree(); } // get password and user login // if object = false ==> searching from connexion object // else searching from downloading object -bool MainWindow::getUserPassword(bool object = false) +bool MainWindow::getUserPassword(Connexion * object) { QStringList logins; QString login; - bool returnValue; + QString password; + QString server; + QString service; + + bool returnValue = false; bool ok = false; - if (object == false) - { - this->settings.beginGroup("Passwords/" + this->connexion.server + "/" + this->connexion.service); - }else - { - this->settings.beginGroup("Passwords/" + this->downloading.server + "/" + this->downloading.service); - } - logins = this->settings.allKeys(); + server = object->server; + service = object->service; - //TODO choose login in case of multiples logins - if (logins.count() != 0) + object->user = ""; + object->password = ""; + + this->settings.beginGroup("Passwords/" + server + "/" + service); + logins = this->settings.allKeys(); + if (logins.count() != 1) { + //choose login in case of multiples logins + loginD.loginEdit->setHistoryItems(logins); login = QInputDialog::getItem(this, - "RsincUI", - tr("There is many users for this service.\nSelect user you want to connect with."), - logins, - 0, - true, - &ok, - Qt::Popup, - Qt::ImhNoPredictiveText + "RsincUI", + tr("Select the user you want to connect with or enter a new one"), + logins, + 0, + true, + &ok, + Qt::Popup, + Qt::ImhNoPredictiveText ); - if (object == false) + if (ok and !login.isEmpty()) { - this->connexion.user = logins[0]; - this->connexion.password = this->settings.value(logins[0]).toString(); - }else - { - this->downloading.user = logins[0]; - this->downloading.password = this->settings.value(logins[0]).toString(); + if (!logins.contains(login)) + { + password = QInputDialog::getText(this, + tr("RsyncUI Request"), + tr("Enter password"), QLineEdit::Password, + "", &ok, Qt::Popup, + Qt::ImhNoPredictiveText); + if (!ok or password.isEmpty()) + { + password = ""; + } + }else + { + password = this->settings.value(login).toString(); + } + object->user = login; + object->password = password; } - returnValue = true; }else { - this->downloading.user = nullptr; - this->downloading.password = nullptr; - returnValue = false; + object->user = logins.at(0); + object->password = this->settings.value(object->user).toString(); + returnValue = true; } this->settings.endGroup(); return returnValue; @@ -866,7 +943,7 @@ void MainWindow::startDownloading() ui->progressBar->setValue(0); ui->progressBar->show(); - getUserPassword(false); + //getUserPassword(); //QtConcurrent::run(&this->downloadO, &downloadFile::download, this); this->download(); @@ -905,7 +982,7 @@ void MainWindow::downloadFinished(int exitCode, QProcess::ExitStatus exitStatus) aborted = tr("stopped by user"); }else if (exitCode == 5) // password asked { - loginDialog.show(); + getUserPassword(&this->downloading); retry = true; } @@ -927,7 +1004,7 @@ void MainWindow::downloadFinished(int exitCode, QProcess::ExitStatus exitStatus) // disconnecting signals to slots disconnect(this->downloading.process, 0, 0, 0); - // reset variables and window + // reset variables and window, close process this->downloading.process->close(); ui->progressBar->hide(); @@ -949,7 +1026,9 @@ void MainWindow::downloadFinished(int exitCode, QProcess::ExitStatus exitStatus) this->downloading.server = path.midRef(pos+4).toString(); path.resize(pos); this->downloading.path = path; - getUserPassword(true); + + //getUserPassword(true); + testServicePresence(this->downloading.service, true); // savepath exists in settings ? str = "Folder/" + this->downloading.server + "/" + this->downloading.service; @@ -1202,7 +1281,7 @@ void MainWindow::loadDownloadList() } // clear object downloading -void Downloading::clear() +void Connexion::clear() { this->path.clear(); this->server.clear(); @@ -1248,21 +1327,30 @@ void MainWindow::on_actionExit_triggered() void MainWindow::on_loginBox_accepted() { - if (!loginD.loginEdit->text().isEmpty()) + /*Connexion * conn = this->passwordConnexion; + + if (!loginD.loginEdit->currentText().isEmpty()) { - this->connexion.user = loginD.loginEdit->text(); + QString path; + conn->user = loginD.loginEdit->currentText(); + path = "Passwords/" + conn->server + "/" + conn->service + "/" + conn->user; + if (!loginD.passwordEdit->text().isEmpty()) { - this->connexion.password = loginD.passwordEdit->text(); - this->settings.setValue("Passwords/" + this->connexion.server + "/" + this->connexion.service + "/" + this->connexion.user, this->connexion.password); + conn->password = loginD.passwordEdit->text(); + this->settings.setValue("Passwords/" + conn->server + "/" + conn->service + "/" + conn->user, conn->password); this->settings.sync(); if (this->rescan == true) { this->rescan = false; populateTree(); } + }else if (this->settings.contains(path)) + { + conn->password = this->settings.value(path).toString(); } } + emit passwordReady();*/ } void MainWindow::setDlSpeed(QString speed) @@ -1281,7 +1369,7 @@ void MainWindow::on_actionHiddenService_triggered() if (ok && !text.isEmpty()) { this->connexion.service = text; - this->settings.setValue("Hidden/" + this->connexion.server, text); + this->settings.setValue("Hidden/" + this->connexion.server + "/" + text, true); preparePopulateTree(); } } diff --git a/mainwindow.h b/mainwindow.h index 72527c9..eba1061 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -46,6 +46,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } @@ -61,10 +62,15 @@ class Connexion int contimeout = 20; QString server; QString service; + QString path; + QString savePath; QString user; QString password; + QProcess * process = nullptr; int port = 873; bool comboboxChanged; + bool quit = false; + void clear(); }; class Downloading @@ -104,7 +110,7 @@ class MainWindow : public QMainWindow ~MainWindow(); QProgressDialog *progress; Connexion connexion; - Downloading downloading; + Connexion downloading; QSettings settings; About about; QDialog Configuration; @@ -117,6 +123,7 @@ class MainWindow : public QMainWindow QSystemTrayIcon * trayIcon; QString icon = "/usr/share/icons/RsyncUI.png"; bool rescan = false; + bool passwordReturned; QList UnitText { tr("B"), @@ -151,8 +158,6 @@ class MainWindow : public QMainWindow bool validateServer(QString server); bool isIpAddress(QString server); void addTreeItem(QString name, QString fileSize, QString fullsize, QString type, QString date, bool isDir, QTreeWidgetItem *parent); - //QTreeWidgetItem * addTreeRoot(QString name, QString size, QString fullsize, bool isDir); - //QTreeWidgetItem * addTreeChild(QTreeWidgetItem *parent, QString name, QString size, QString fullsize, bool isDir); bool scanDir(QString server, int portN, QTreeWidgetItem *parent = NULL, QString path = "" ); void startDownloading(); void loadSettings(); @@ -165,8 +170,9 @@ class MainWindow : public QMainWindow void hideWindow(); void showWindow(); void init(); - bool getUserPassword(bool); + bool getUserPassword(Connexion *); void preparePopulateTree(); + bool testServicePresence(QString, bool=false); private slots: @@ -176,10 +182,6 @@ class MainWindow : public QMainWindow void downloadFinished(int exitCode, QProcess::ExitStatus exitStatus); -// void downloadProcessError(QProcess::ProcessError error); - - void downloadProcessStderr(); - void readRsyncOutput(); void stoppingDownload(); @@ -226,7 +228,7 @@ class MainWindow : public QMainWindow void speed(QString); void finishedSignal(bool = true); void fileName(QString); - //void errorSignal(QString); + void passwordReady(); }; #endif // MAINWINDOW_H diff --git a/tools.cpp b/tools.cpp index 8777029..648e00d 100644 --- a/tools.cpp +++ b/tools.cpp @@ -44,29 +44,18 @@ const vector explode(const string& s, const char& c, int n = 0) } // test return code of rsync +// return true in case of error bool testRsyncReturn(MainWindow * w, QProcess * myProcess) { if (myProcess->exitStatus() != 0) { QMessageBox::warning( - NULL, + w, "RsyncUI", myProcess->errorString(), QMessageBox::Ok, QMessageBox::Ok); return true; - }else if (myProcess->exitCode() == 5) - { - w->loginDialog.show(); - }else if (myProcess->exitCode() != 0) - { - QMessageBox::warning( - NULL, - "RsyncUI", - rsyncErrorStrings[myProcess->exitCode()], - QMessageBox::Ok, - QMessageBox::Ok); - return true; } return false; } @@ -78,3 +67,4 @@ QString getFileType(QString filename) QString returnValue = mime.name().section('/',0 ,0); return returnValue; } +