From cd38b27338295dd5166f318cf0e9423076861957 Mon Sep 17 00:00:00 2001 From: grekiki Date: Thu, 25 Feb 2021 18:27:00 +0100 Subject: [PATCH] Qt-UI fix ssh username (#20159) * Fix SSH username. Squased Gregor's commits. * revert keyboard size * reduce diff * fix build * whitespace Co-authored-by: Willem Melching old-commit-hash: 4c99d83474336420badb2a12335b745c9c301ce6 --- selfdrive/ui/qt/widgets/input_field.cc | 12 +++ selfdrive/ui/qt/widgets/input_field.hpp | 6 ++ selfdrive/ui/qt/widgets/ssh_keys.cc | 113 ++++++++++++++---------- selfdrive/ui/qt/widgets/ssh_keys.hpp | 18 +++- 4 files changed, 99 insertions(+), 50 deletions(-) diff --git a/selfdrive/ui/qt/widgets/input_field.cc b/selfdrive/ui/qt/widgets/input_field.cc index f1f48a466..402b50a88 100644 --- a/selfdrive/ui/qt/widgets/input_field.cc +++ b/selfdrive/ui/qt/widgets/input_field.cc @@ -26,6 +26,7 @@ InputDialog::InputDialog(QString prompt_text, QWidget *parent): QDialog(parent) )"); header_layout->addWidget(cancel_btn, 0, Qt::AlignRight); QObject::connect(cancel_btn, SIGNAL(released()), this, SLOT(reject())); + QObject::connect(cancel_btn, SIGNAL(released()), this, SIGNAL(cancel())); layout->addLayout(header_layout); @@ -81,6 +82,7 @@ void InputDialog::handleInput(QString s) { if (!QString::compare(s,"⏎")) { done(QDialog::Accepted); + emitText(line->text()); } QVector control_buttons {"⇧", "↑", "ABC", "⏎", "#+=", "⌫", "123"}; @@ -93,3 +95,13 @@ void InputDialog::handleInput(QString s) { line->insert(s.left(1)); } +void InputDialog::show(){ + setMainWindow(this); +} + +void InputDialog::setMessage(QString message, bool clearInputField){ + label->setText(message); + if (clearInputField){ + line->setText(""); + } +} diff --git a/selfdrive/ui/qt/widgets/input_field.hpp b/selfdrive/ui/qt/widgets/input_field.hpp index 5543eff39..118347aa1 100644 --- a/selfdrive/ui/qt/widgets/input_field.hpp +++ b/selfdrive/ui/qt/widgets/input_field.hpp @@ -16,6 +16,8 @@ public: explicit InputDialog(QString prompt_text, QWidget* parent = 0); static QString getText(QString prompt); QString text(); + void show(); + void setMessage(QString message, bool clearInputField=true); private: QLineEdit *line; @@ -28,4 +30,8 @@ public slots: private slots: void handleInput(QString s); + +signals: + void cancel(); + void emitText(QString text); }; diff --git a/selfdrive/ui/qt/widgets/ssh_keys.cc b/selfdrive/ui/qt/widgets/ssh_keys.cc index 64c1a67b0..e8002b68f 100644 --- a/selfdrive/ui/qt/widgets/ssh_keys.cc +++ b/selfdrive/ui/qt/widgets/ssh_keys.cc @@ -1,12 +1,19 @@ +#include #include #include #include #include #include -#include "common/params.h" #include "widgets/ssh_keys.hpp" #include "widgets/input_field.hpp" +#include "common/params.h" + +QWidget* layout_to_widget(QLayout* l){ + QWidget* q = new QWidget; + q->setLayout(l); + return q; +} SSH::SSH(QWidget* parent) : QWidget(parent){ // init variables @@ -16,24 +23,37 @@ SSH::SSH(QWidget* parent) : QWidget(parent){ networkTimer->setInterval(5000); connect(networkTimer, SIGNAL(timeout()), this, SLOT(timeout())); - // Layout on entering - QVBoxLayout* main_layout = new QVBoxLayout; - main_layout->setMargin(50); + dialog = new InputDialog(""); + // Construct the layouts to display + slayout = new QStackedLayout(this); // Initial screen, input, waiting for response + //Layout on entering + QVBoxLayout* initialLayout = new QVBoxLayout; + initialLayout->setContentsMargins(80, 80, 80, 80); + + QHBoxLayout* header = new QHBoxLayout; QPushButton* exitButton = new QPushButton("BACK", this); exitButton->setFixedSize(500, 100); - main_layout->addWidget(exitButton, 0, Qt::AlignLeft | Qt::AlignTop); - connect(exitButton, SIGNAL(released()), this, SIGNAL(closeSSHSettings())); + header->addWidget(exitButton, 0, Qt::AlignLeft | Qt::AlignTop); + initialLayout->addWidget(layout_to_widget(header)); - QLabel* wallOfText = new QLabel("Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own."); - wallOfText->setAlignment(Qt::AlignHCenter); + QLabel* title = new QLabel("Authorize SSH keys"); + title->setStyleSheet(R"(font-size: 75px;)"); + header->addWidget(title, 0, Qt::AlignRight | Qt::AlignTop); + + QLabel* wallOfText = new QLabel("Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A Comma employee will NEVER ask you to add their GitHub username."); wallOfText->setWordWrap(true); wallOfText->setStyleSheet(R"(font-size: 60px;)"); - main_layout->addWidget(wallOfText, 0); + initialLayout->addWidget(wallOfText, 0); QPushButton* actionButton = new QPushButton; actionButton->setFixedHeight(100); - main_layout->addWidget(actionButton, 0, Qt::AlignBottom); + initialLayout->addWidget(actionButton, 0, Qt::AlignBottom); + + slayout->addWidget(layout_to_widget(initialLayout)); + + QLabel* loading = new QLabel("Loading SSH keys from GitHub."); + slayout->addWidget(loading); setStyleSheet(R"( QPushButton { @@ -45,61 +65,60 @@ SSH::SSH(QWidget* parent) : QWidget(parent){ background-color: #444444; } )"); - setLayout(main_layout); + setLayout(slayout); - // Initialize the state machine and states + + //Initialize the state machine and states QStateMachine* state = new QStateMachine(this); QState* initialState = new QState(); //State when entering the widget QState* initialStateNoGithub = new QState(); //Starting state, key not connected QState* initialStateConnected = new QState(); //Starting state, ssh connected + QState* quitState = new QState(); // State when exiting the widget QState* removeSSH_State = new QState(); // State when user wants to remove the SSH keys + QState* defaultInputFieldState = new QState(); // State when we want the user to give us the username QState* loadingState = new QState(); // State while waiting for the network response + // Adding states to the state machine and adding the transitions state->addState(initialState); - connect(initialState, &QState::entered, [=](){ - checkForSSHKey(); - }); + connect(initialState, &QState::entered, [=](){checkForSSHKey(); slayout->setCurrentIndex(0);}); initialState->addTransition(this, &SSH::NoSSHAdded, initialStateNoGithub); initialState->addTransition(this, &SSH::SSHAdded, initialStateConnected); + + state->addState(quitState); + connect(quitState, &QState::entered, [=](){emit closeSSHSettings();}); + quitState->addTransition(quitState, &QState::entered, initialState); + state->addState(initialStateConnected); - connect(initialStateConnected, &QState::entered, [=](){ - actionButton->setText("Clear SSH keys"); - actionButton->setStyleSheet(R"(background-color: #750c0c;)"); - }); + connect(initialStateConnected, &QState::entered, [=](){actionButton->setText("Remove GitHub SSH keys"); actionButton->setStyleSheet(R"(background-color: #750c0c;)");}); + initialStateConnected->addTransition(exitButton, &QPushButton::released, quitState); initialStateConnected->addTransition(actionButton, &QPushButton::released, removeSSH_State); state->addState(removeSSH_State); - connect(removeSSH_State, &QState::entered, [=](){ - Params().delete_db_value("GithubSshKeys"); - }); + connect(removeSSH_State, &QState::entered, [=](){Params().delete_db_value("GithubSshKeys");}); removeSSH_State->addTransition(removeSSH_State, &QState::entered, initialState); state->addState(initialStateNoGithub); - connect(initialStateNoGithub, &QState::entered, [=](){ - actionButton->setText("Link GitHub SSH keys"); - actionButton->setStyleSheet(R"(background-color: #444444;)"); - }); - initialStateNoGithub->addTransition(actionButton, &QPushButton::released, loadingState); + connect(initialStateNoGithub, &QState::entered, [=](){actionButton->setText("Link GitHub SSH keys"); actionButton->setStyleSheet(R"(background-color: #444444;)");}); + initialStateNoGithub->addTransition(exitButton, &QPushButton::released, quitState); + initialStateNoGithub->addTransition(actionButton, &QPushButton::released, defaultInputFieldState); + connect(actionButton, &QPushButton::released, [=](){dialog->setMessage("Enter your GitHub username");}); + + state->addState(defaultInputFieldState); + connect(defaultInputFieldState, &QState::entered, [=](){dialog->show();}); + connect(dialog, &InputDialog::emitText, [=](QString a){usernameGitHub = a;}); + defaultInputFieldState->addTransition(dialog, &InputDialog::cancel, initialState); + defaultInputFieldState->addTransition(dialog, &InputDialog::emitText, loadingState); + state->addState(loadingState); - connect(loadingState, &QState::entered, [=](){ - QString user = InputDialog::getText("Enter your GitHub username"); - if (user.size()) { - getSSHKeys(user); - } - }); - connect(this, &SSH::failedResponse, [=](QString message){ - QString user = InputDialog::getText(message); - if (user.size()) { - getSSHKeys(user); - } - }); - loadingState->addTransition(loadingState, &QState::entered, initialState); - loadingState->addTransition(this, &SSH::failedResponse, initialState); + connect(loadingState, &QState::entered, [=](){slayout->setCurrentIndex(1); getSSHKeys();}); + connect(this, &SSH::failedResponse, [=](QString message){dialog->setMessage(message);}); + loadingState->addTransition(this, &SSH::failedResponse, defaultInputFieldState); loadingState->addTransition(this, &SSH::gotSSHKeys, initialState); + state->setInitialState(initialState); state->start(); } @@ -113,8 +132,8 @@ void SSH::checkForSSHKey(){ } } -void SSH::getSSHKeys(QString username){ - QString url = "https://github.com/" + username + ".keys"; +void SSH::getSSHKeys(){ + QString url = "https://github.com/" + usernameGitHub + ".keys"; aborted = false; reply = manager->get(QNetworkRequest(QUrl(url))); connect(reply, SIGNAL(finished()), this, SLOT(parseResponse())); @@ -133,12 +152,14 @@ void SSH::parseResponse(){ if (reply->error() == QNetworkReply::NoError && response.length()) { Params().write_db_value("GithubSshKeys", response.toStdString()); emit gotSSHKeys(); + } else if(reply->error() == QNetworkReply::NoError){ + emit failedResponse("Username " + usernameGitHub + " has no keys on GitHub"); } else { - emit failedResponse("Username doesn't exist"); + emit failedResponse("Username " + usernameGitHub + " doesn't exist"); } - } else { + }else{ emit failedResponse("Request timed out"); } reply->deleteLater(); - reply = NULL; + reply = nullptr; } diff --git a/selfdrive/ui/qt/widgets/ssh_keys.hpp b/selfdrive/ui/qt/widgets/ssh_keys.hpp index 3082a43d6..7eb977f8c 100644 --- a/selfdrive/ui/qt/widgets/ssh_keys.hpp +++ b/selfdrive/ui/qt/widgets/ssh_keys.hpp @@ -1,8 +1,14 @@ #pragma once -#include #include +#include +#include +#include +#include +#include #include +#include +#include "input_field.hpp" class SSH : public QWidget { Q_OBJECT @@ -11,22 +17,26 @@ public: explicit SSH(QWidget* parent = 0); private: + QStackedLayout* slayout; + InputDialog* dialog; QNetworkAccessManager* manager; + + QString usernameGitHub; QNetworkReply* reply; QTimer* networkTimer; bool aborted; - void getSSHKeys(QString user); - signals: + void closeSSHSettings(); void NoSSHAdded(); void SSHAdded(); void failedResponse(QString errorString); void gotSSHKeys(); - void closeSSHSettings(); private slots: void checkForSSHKey(); + void getSSHKeys(); void timeout(); void parseResponse(); }; +