Qt UI: SSH keys (#20430)

* rename

* toggle control

* SSH toggle

* hw

* qcom

* lines

* fix that

* start refactoring

* adding keys

* hacky remove

* alerts

* fix qcom ssl

* use the same widgets everywhere

* clean up

* more cleanup

* little more

* bigger

* fix tethering toggleg
old-commit-hash: e547a97216
commatwo_master
Adeeb Shihadeh 4 years ago committed by GitHub
parent c3c741af70
commit c360723411
  1. 15
      selfdrive/hardware/hw.h
  2. 86
      selfdrive/ui/qt/offroad/networking.cc
  3. 13
      selfdrive/ui/qt/offroad/networking.hpp
  4. 50
      selfdrive/ui/qt/offroad/settings.cc
  5. 2
      selfdrive/ui/qt/offroad/settings.hpp
  6. 40
      selfdrive/ui/qt/widgets/controls.hpp
  7. 22
      selfdrive/ui/qt/widgets/input.cc
  8. 2
      selfdrive/ui/qt/widgets/input.hpp
  9. 3
      selfdrive/ui/qt/widgets/keyboard.cc
  10. 193
      selfdrive/ui/qt/widgets/ssh_keys.cc
  11. 49
      selfdrive/ui/qt/widgets/ssh_keys.hpp
  12. 2
      selfdrive/ui/qt/widgets/toggle.hpp

@ -22,6 +22,9 @@ public:
static void reboot() {};
static void poweroff() {};
static void set_brightness(int percent) {};
static bool get_ssh_enabled() { return false; };
static void set_ssh_enabled(bool enabled) {};
};
class HardwareEon : public HardwareNone {
@ -39,6 +42,14 @@ public:
brightness_control.close();
}
};
static bool get_ssh_enabled() {
return std::system("getprop persist.neos.ssh | grep -qF '1'") == 0;
};
static void set_ssh_enabled(bool enabled) {
std::string cmd = util::string_format("setprop persist.neos.ssh %d", enabled ? 1 : 0);
std::system(cmd.c_str());
};
};
class HardwareTici : public HardwareNone {
@ -56,5 +67,7 @@ public:
brightness_control.close();
}
};
};
static bool get_ssh_enabled() { return Params().read_db_bool("SshEnabled"); };
static void set_ssh_enabled(bool enabled) { Params().write_db_value("SshEnabled", (enabled ? "1" : "0")); };
};

@ -3,11 +3,11 @@
#include <QLabel>
#include <QPixmap>
#include <QPushButton>
#include <QLineEdit>
#include <QRandomGenerator>
#include <algorithm>
#include "common/params.h"
#include "hardware/hw.h"
#include "networking.hpp"
#include "util.h"
@ -35,6 +35,7 @@ Networking::Networking(QWidget* parent, bool show_advanced) : QWidget(parent), s
s = new QStackedLayout;
QLabel* warning = new QLabel("Network manager is inactive!");
warning->setAlignment(Qt::AlignCenter);
warning->setStyleSheet(R"(font-size: 65px;)");
s->addWidget(warning);
@ -131,28 +132,18 @@ void Networking::wrongPassword(QString ssid) {
}
}
QFrame* hline(QWidget* parent = 0){
QFrame* line = new QFrame(parent);
line->setFrameShape(QFrame::StyledPanel);
line->setStyleSheet("margin-left: 40px; margin-right: 40px; border-width: 1px; border-bottom-style: solid; border-color: gray;");
line->setFixedHeight(2);
return line;
}
// AdvancedNetworking functions
AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWidget(parent), wifi(wifi){
s = new QStackedLayout; // mainPage, SSH settings
QVBoxLayout* vlayout = new QVBoxLayout;
vlayout->setMargin(40);
// Back button
QHBoxLayout* backLayout = new QHBoxLayout;
QPushButton* back = new QPushButton("Back");
back->setFixedSize(500, 100);
connect(back, &QPushButton::released, [=](){emit backPress();});
backLayout->addWidget(back, 0, Qt::AlignLeft);
vlayout->addWidget(layoutToWidget(backLayout, this), 0, Qt::AlignLeft);
vlayout->addWidget(back, 0, Qt::AlignLeft);
// Enable tethering layout
QHBoxLayout* tetheringToggleLayout = new QHBoxLayout;
@ -164,9 +155,9 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid
if (wifi->tetheringEnabled()) {
toggle_switch->togglePosition();
}
QObject::connect(toggle_switch, SIGNAL(stateChanged(int)), this, SLOT(toggleTethering(int)));
QObject::connect(toggle_switch, SIGNAL(stateChanged(bool)), this, SLOT(toggleTethering(bool)));
vlayout->addWidget(layoutToWidget(tetheringToggleLayout, this), 0);
vlayout->addWidget(hline(), 0);
vlayout->addWidget(horizontal_line(), 0);
// Change tethering password
QHBoxLayout *tetheringPassword = new QHBoxLayout;
@ -181,7 +172,7 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid
});
tetheringPassword->addWidget(editPasswordButton, 1, Qt::AlignRight);
vlayout->addWidget(layoutToWidget(tetheringPassword, this), 0);
vlayout->addWidget(hline(), 0);
vlayout->addWidget(horizontal_line(), 0);
// IP adress
QHBoxLayout* IPlayout = new QHBoxLayout;
@ -190,65 +181,22 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid
ipLabel->setStyleSheet("color: #aaaaaa");
IPlayout->addWidget(ipLabel, 0, Qt::AlignRight);
vlayout->addWidget(layoutToWidget(IPlayout, this), 0);
vlayout->addWidget(hline(), 0);
// Enable SSH
QHBoxLayout* enableSSHLayout = new QHBoxLayout(this);
enableSSHLayout->addWidget(new QLabel("Enable SSH", this));
toggle_switch_SSH = new Toggle(this);
toggle_switch_SSH->setFixedSize(150, 100);
if (isSSHEnabled()) {
toggle_switch_SSH->togglePosition();
}
QObject::connect(toggle_switch_SSH, SIGNAL(stateChanged(int)), this, SLOT(toggleSSH(int)));
enableSSHLayout->addWidget(toggle_switch_SSH);
vlayout->addWidget(layoutToWidget(enableSSHLayout, this));
vlayout->addWidget(hline(), 0);
vlayout->addWidget(horizontal_line(), 0);
// SSH keys
QHBoxLayout* authSSHLayout = new QHBoxLayout(this);
authSSHLayout->addWidget(new QLabel("SSH keys", this));
QPushButton* editAuthSSHButton = new QPushButton("EDIT", this);
editAuthSSHButton->setFixedWidth(500);
connect(editAuthSSHButton, &QPushButton::released, [=](){s->setCurrentWidget(ssh);});
authSSHLayout->addWidget(editAuthSSHButton);
vlayout->addWidget(layoutToWidget(authSSHLayout, this));
vlayout->addSpacing(50);
// //Disconnect or delete connections
// QHBoxLayout* dangerZone = new QHBoxLayout(this);
// QPushButton* disconnect = new QPushButton("Disconnect from WiFi", this);
// dangerZone->addWidget(disconnect);
// QPushButton* deleteAll = new QPushButton("DELETE ALL NETWORKS", this);
// dangerZone->addWidget(deleteAll);
// vlayout->addWidget(layoutToWidget(dangerZone, this));
// vlayout to widget
QWidget* settingsWidget = layoutToWidget(vlayout, this);
settingsWidget->setStyleSheet("margin-left: 40px; margin-right: 40px;");
s->addWidget(settingsWidget);
ssh = new SSH;
connect(ssh, &SSH::closeSSHSettings, [=](){s->setCurrentWidget(settingsWidget);});
s->addWidget(ssh);
setLayout(s);
}
vlayout->addWidget(new SshToggle());
vlayout->addWidget(horizontal_line(), 0);
vlayout->addWidget(new SshControl());
bool AdvancedNetworking::isSSHEnabled(){
return Params().get("SshEnabled") == "1";
setLayout(vlayout);
}
void AdvancedNetworking::refresh(){
ipLabel->setText(wifi->ipv4_address);
if (toggle_switch_SSH->on != isSSHEnabled()) {
toggle_switch_SSH->togglePosition();
}
// Qt can be lazy
repaint();
update();
}
void AdvancedNetworking::toggleTethering(int enable) {
void AdvancedNetworking::toggleTethering(bool enable) {
if (enable) {
wifi->enableTethering();
} else {
@ -257,10 +205,6 @@ void AdvancedNetworking::toggleTethering(int enable) {
editPasswordButton->setEnabled(!enable);
}
void AdvancedNetworking::toggleSSH(int enable) {
Params().write_db_value("SshEnabled", QString::number(enable).toStdString());
}
// WifiUI functions
@ -327,7 +271,7 @@ void WifiUI::refresh() {
vlayout->addLayout(hlayout, 1);
// Don't add the last horizontal line
if (page * networks_per_page <= i+1 && i+1 < (page + 1) * networks_per_page && i+1 < wifi->seen_networks.size()) {
vlayout->addWidget(hline(), 0);
vlayout->addWidget(horizontal_line(), 0);
}
}
i++;

@ -5,7 +5,6 @@
#include <QVBoxLayout>
#include <QStackedWidget>
#include <QPushButton>
#include <QTimer>
#include "wifiManager.hpp"
#include "widgets/input.hpp"
@ -27,14 +26,11 @@ private:
bool tetheringEnabled;
signals:
void openKeyboard();
void closeKeyboard();
void connectToNetwork(Network n);
public slots:
void handleButton(QAbstractButton* m_button);
void refresh();
void prevPage();
void nextPage();
};
@ -43,24 +39,17 @@ class AdvancedNetworking : public QWidget {
Q_OBJECT
public:
explicit AdvancedNetworking(QWidget* parent = 0, WifiManager* wifi = 0);
QStackedLayout* s;
private:
QLabel* ipLabel;
QPushButton* editPasswordButton;
SSH* ssh;
Toggle* toggle_switch_SSH;
WifiManager* wifi = nullptr;
bool isSSHEnabled();
signals:
void backPress();
public slots:
void toggleTethering(int enable);
void toggleSSH(int enable);
void toggleTethering(bool enable);
void refresh();
};

@ -11,6 +11,7 @@
#include "widgets/toggle.hpp"
#include "widgets/offroad_alerts.hpp"
#include "widgets/controls.hpp"
#include "widgets/ssh_keys.hpp"
#include "common/params.h"
#include "common/util.h"
#include "selfdrive/hardware/hw.h"
@ -20,43 +21,43 @@ QWidget * toggles_panel() {
QVBoxLayout *toggles_list = new QVBoxLayout();
toggles_list->setMargin(50);
toggles_list->addWidget(new ToggleControl("OpenpilotEnabledToggle",
toggles_list->addWidget(new ParamControl("OpenpilotEnabledToggle",
"Enable openpilot",
"Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off.",
"../assets/offroad/icon_openpilot.png"
));
toggles_list->addWidget(horizontal_line());
toggles_list->addWidget(new ToggleControl("LaneChangeEnabled",
toggles_list->addWidget(new ParamControl("LaneChangeEnabled",
"Enable Lane Change Assist",
"Perform assisted lane changes with openpilot by checking your surroundings for safety, activating the turn signal and gently nudging the steering wheel towards your desired lane. openpilot is not capable of checking if a lane change is safe. You must continuously observe your surroundings to use this feature.",
"../assets/offroad/icon_road.png"
));
toggles_list->addWidget(horizontal_line());
toggles_list->addWidget(new ToggleControl("IsLdwEnabled",
toggles_list->addWidget(new ParamControl("IsLdwEnabled",
"Enable Lane Departure Warnings",
"Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31mph (50kph).",
"../assets/offroad/icon_warning.png"
));
toggles_list->addWidget(horizontal_line());
toggles_list->addWidget(new ToggleControl("IsRHD",
toggles_list->addWidget(new ParamControl("IsRHD",
"Enable Right-Hand Drive",
"Allow openpilot to obey left-hand traffic conventions and perform driver monitoring on right driver seat.",
"../assets/offroad/icon_openpilot_mirrored.png"
));
toggles_list->addWidget(horizontal_line());
toggles_list->addWidget(new ToggleControl("IsMetric",
toggles_list->addWidget(new ParamControl("IsMetric",
"Use Metric System",
"Display speed in km/h instead of mp/h.",
"../assets/offroad/icon_metric.png"
));
toggles_list->addWidget(horizontal_line());
toggles_list->addWidget(new ToggleControl("CommunityFeaturesToggle",
toggles_list->addWidget(new ParamControl("CommunityFeaturesToggle",
"Enable Community Features",
"Use features from the open source community that are not maintained or supported by comma.ai and have not been confirmed to meet the standard safety model. These features include community supported cars and community supported hardware. Be extra cautious when using these features",
"../assets/offroad/icon_shell.png"
));
ToggleControl *record_toggle = new ToggleControl("RecordFront",
ParamControl *record_toggle = new ParamControl("RecordFront",
"Record and Upload Driver Camera",
"Upload data from the driver facing camera and help improve the driver monitoring algorithm.",
"../assets/offroad/icon_network.png");
@ -188,20 +189,29 @@ QWidget * network_panel(QWidget * parent) {
layout->setMargin(100);
layout->setSpacing(30);
// TODO: can probably use the ndk for this
// simple wifi + tethering buttons
std::vector<std::pair<const char*, const char*>> btns = {
{"WiFi Settings", "am start -n com.android.settings/.wifi.WifiPickerActivity \
-a android.net.wifi.PICK_WIFI_NETWORK \
--ez extra_prefs_show_button_bar true \
--es extra_prefs_set_next_text ''"},
{"Tethering Settings", "am start -n com.android.settings/.TetherSettings \
--ez extra_prefs_show_button_bar true \
--es extra_prefs_set_next_text ''"},
};
for (auto &b : btns) {
layout->addWidget(new ButtonControl(b.first, "OPEN", "", [=]() { std::system(b.second); }));
}
const char* launch_wifi = "am start -n com.android.settings/.wifi.WifiPickerActivity \
-a android.net.wifi.PICK_WIFI_NETWORK \
--ez extra_prefs_show_button_bar true \
--es extra_prefs_set_next_text ''";
layout->addWidget(new ButtonControl("WiFi Settings", "OPEN", "",
[=]() { std::system(launch_wifi); }));
layout->addWidget(horizontal_line());
const char* launch_tethering = "am start -n com.android.settings/.TetherSettings \
--ez extra_prefs_show_button_bar true \
--es extra_prefs_set_next_text ''";
layout->addWidget(new ButtonControl("Tethering Settings", "OPEN", "",
[=]() { std::system(launch_tethering); }));
layout->addWidget(horizontal_line());
// SSH key management
layout->addWidget(new SshToggle());
layout->addWidget(horizontal_line());
layout->addWidget(new SshControl());
layout->addStretch(1);
QWidget *w = new QWidget;

@ -10,6 +10,8 @@
#include "selfdrive/ui/qt/widgets/controls.hpp"
// ********** settings window + top-level panels **********
class DeveloperPanel : public QFrame {
Q_OBJECT
public:

@ -27,6 +27,7 @@ protected:
QLabel *title_label;
};
// widget to display a value
class LabelControl : public AbstractControl {
Q_OBJECT
@ -42,6 +43,7 @@ private:
QLabel label;
};
// widget for a button with a label
class ButtonControl : public AbstractControl {
Q_OBJECT
@ -51,13 +53,13 @@ public:
btn.setText(text);
btn.setStyleSheet(R"(
padding: 0;
border-radius: 40px;
font-size: 30px;
border-radius: 50px;
font-size: 40px;
font-weight: 500;
color: #E4E4E4;
background-color: #393939;
)");
btn.setFixedSize(200, 80);
btn.setFixedSize(250, 100);
QObject::connect(&btn, &QPushButton::released, functor);
hlayout->addWidget(&btn);
}
@ -71,21 +73,37 @@ class ToggleControl : public AbstractControl {
Q_OBJECT
public:
ToggleControl(const QString &param, const QString &title, const QString &desc, const QString &icon) : AbstractControl(title, desc, icon) {
ToggleControl(const QString &title, const QString &desc = "", const QString &icon = "", const bool state = false) : AbstractControl(title, desc, icon) {
toggle.setFixedSize(150, 100);
// set initial state from param
if (Params().read_db_bool(param.toStdString().c_str())) {
if (state) {
toggle.togglePosition();
}
QObject::connect(&toggle, &Toggle::stateChanged, [=](int state) {
char value = state ? '1' : '0';
Params().write_db_value(param.toStdString().c_str(), &value, 1);
});
hlayout->addWidget(&toggle);
QObject::connect(&toggle, &Toggle::stateChanged, this, &ToggleControl::toggleFlipped);
}
void setEnabled(bool enabled) { toggle.setEnabled(enabled); }
private:
signals:
void toggleFlipped(bool state);
protected:
Toggle toggle;
};
// widget to toggle params
class ParamControl : public ToggleControl {
Q_OBJECT
public:
ParamControl(const QString &param, const QString &title, const QString &desc, const QString &icon) : ToggleControl(title, desc, icon) {
// set initial state from param
if (Params().read_db_bool(param.toStdString().c_str())) {
toggle.togglePosition();
}
QObject::connect(this, &ToggleControl::toggleFlipped, [=](int state) {
char value = state ? '1' : '0';
Params().write_db_value(param.toStdString().c_str(), &value, 1);
});
}
};

@ -112,7 +112,6 @@ void InputDialog::setMinLength(int length){
}
ConfirmationDialog::ConfirmationDialog(QString prompt_text, QString confirm_text, QString cancel_text,
QWidget *parent):QDialog(parent) {
setWindowFlags(Qt::Popup);
@ -131,13 +130,17 @@ ConfirmationDialog::ConfirmationDialog(QString prompt_text, QString confirm_text
btn_layout->addStretch(1);
layout->addLayout(btn_layout);
QPushButton* cancel_btn = new QPushButton(cancel_text);
btn_layout->addWidget(cancel_btn, 0, Qt::AlignRight);
QObject::connect(cancel_btn, SIGNAL(released()), this, SLOT(reject()));
if (cancel_text.length()) {
QPushButton* cancel_btn = new QPushButton(cancel_text);
btn_layout->addWidget(cancel_btn, 0, Qt::AlignRight);
QObject::connect(cancel_btn, SIGNAL(released()), this, SLOT(reject()));
}
QPushButton* confirm_btn = new QPushButton(confirm_text);
btn_layout->addWidget(confirm_btn, 0, Qt::AlignRight);
QObject::connect(confirm_btn, SIGNAL(released()), this, SLOT(accept()));
if (confirm_text.length()) {
QPushButton* confirm_btn = new QPushButton(confirm_text);
btn_layout->addWidget(confirm_btn, 0, Qt::AlignRight);
QObject::connect(confirm_btn, SIGNAL(released()), this, SLOT(accept()));
}
setFixedSize(900, 350);
setStyleSheet(R"(
@ -158,6 +161,11 @@ ConfirmationDialog::ConfirmationDialog(QString prompt_text, QString confirm_text
setLayout(layout);
}
bool ConfirmationDialog::alert(const QString prompt_text) {
ConfirmationDialog d = ConfirmationDialog(prompt_text, "Ok", "");
return d.exec();
}
bool ConfirmationDialog::confirm(const QString prompt_text) {
ConfirmationDialog d = ConfirmationDialog(prompt_text);
return d.exec();

@ -38,13 +38,13 @@ signals:
void emitText(QString text);
};
class ConfirmationDialog : public QDialog {
Q_OBJECT
public:
explicit ConfirmationDialog(QString prompt_text, QString confirm_text = "Ok",
QString cancel_text = "Cancel", QWidget* parent = 0);
static bool alert(QString prompt_text);
static bool confirm(QString prompt_text);
private:

@ -41,6 +41,9 @@ KeyboardLayout::KeyboardLayout(QWidget *parent, std::vector<QVector<QString>> la
}
setStyleSheet(R"(
* {
outline: none;
}
QPushButton {
font-size: 65px;
margin: 0px;

@ -1,165 +1,102 @@
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QState>
#include <QStateMachine>
#include <QNetworkReply>
#include "widgets/ssh_keys.hpp"
#include "widgets/input.hpp"
#include "widgets/ssh_keys.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
SshControl::SshControl() : AbstractControl("SSH Keys", "", "") {
// setup widget
btn.setStyleSheet(R"(
padding: 0;
border-radius: 50px;
font-size: 40px;
font-weight: 500;
color: #E4E4E4;
background-color: #393939;
)");
btn.setFixedSize(250, 100);
hlayout->addWidget(&btn);
QObject::connect(&btn, &QPushButton::released, [=]() {
if (btn.text() == "ADD") {
username = InputDialog::getText("Enter your GitHub username");
if (username.length() > 0) {
btn.setText("LOADING");
btn.setEnabled(false);
getUserKeys(username);
}
} else {
Params().delete_db_value("GithubSshKeys");
refresh();
}
});
// setup networking
manager = new QNetworkAccessManager(this);
networkTimer = new QTimer(this);
networkTimer->setSingleShot(true);
networkTimer->setInterval(5000);
connect(networkTimer, SIGNAL(timeout()), this, SLOT(timeout()));
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);
header->addWidget(exitButton, 0, Qt::AlignLeft | Qt::AlignTop);
initialLayout->addWidget(layout_to_widget(header));
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;)");
initialLayout->addWidget(wallOfText, 0);
QPushButton* actionButton = new QPushButton;
actionButton->setFixedHeight(100);
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 {
font-size: 60px;
margin: 0px;
padding: 15px;
border-radius: 25px;
color: #dddddd;
background-color: #444444;
}
)");
setLayout(slayout);
refresh();
//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(); 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("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");});
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(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, [=](){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();
// TODO: add desription through AbstractControl
//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.");
}
void SSH::checkForSSHKey(){
QString SSHKey = QString::fromStdString(Params().get("GithubSshKeys"));
if (SSHKey.length()) {
emit SSHAdded();
void SshControl::refresh() {
QString param = QString::fromStdString(Params().get("GithubSshKeys"));
if (param.length()) {
btn.setText("REMOVE");
} else {
emit NoSSHAdded();
btn.setText("ADD");
}
btn.setEnabled(true);
}
void SSH::getSSHKeys(){
QString url = "https://github.com/" + usernameGitHub + ".keys";
aborted = false;
reply = manager->get(QNetworkRequest(QUrl(url)));
void SshControl::getUserKeys(QString username){
QString url = "https://github.com/" + username + ".keys";
QNetworkRequest request;
request.setUrl(QUrl(url));
#ifdef QCOM
QSslConfiguration ssl = QSslConfiguration::defaultConfiguration();
ssl.setCaCertificates(QSslCertificate::fromPath("/usr/etc/tls/cert.pem",
QSsl::Pem, QRegExp::Wildcard));
request.setSslConfiguration(ssl);
#endif
reply = manager->get(request);
connect(reply, SIGNAL(finished()), this, SLOT(parseResponse()));
networkTimer->start();
}
void SSH::timeout(){
aborted = true;
void SshControl::timeout(){
reply->abort();
}
void SSH::parseResponse(){
if (!aborted) {
void SshControl::parseResponse(){
QString err = "";
if (reply->error() != QNetworkReply::OperationCanceledError) {
networkTimer->stop();
QString response = reply->readAll();
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");
err = "Username '" + username + "' has no keys on GitHub";
} else {
emit failedResponse("Username " + usernameGitHub + " doesn't exist");
err = "Username '" + username + "' doesn't exist on GitHub";
}
}else{
emit failedResponse("Request timed out");
} else {
err = "Request timed out";
}
if (err.length()) {
ConfirmationDialog::alert(err);
}
refresh();
reply->deleteLater();
reply = nullptr;
}

@ -1,42 +1,47 @@
#pragma once
#include <QWidget>
#include <QButtonGroup>
#include <QVBoxLayout>
#include <QStackedWidget>
#include <QPushButton>
#include <QTimer>
#include <QPushButton>
#include <QNetworkAccessManager>
#include <QStackedLayout>
#include "widgets/input.hpp"
class SSH : public QWidget {
#include "widgets/controls.hpp"
#include "selfdrive/hardware/hw.h"
// SSH enable toggle
class SshToggle : public ToggleControl {
Q_OBJECT
public:
SshToggle() : ToggleControl("Enable SSH", "", "", Hardware::get_ssh_enabled()) {
QObject::connect(this, &SshToggle::toggleFlipped, [=](bool state) {
Hardware::set_ssh_enabled(state);
});
}
};
// SSH key management widget
class SshControl : public AbstractControl {
Q_OBJECT
public:
explicit SSH(QWidget* parent = 0);
SshControl();
private:
QStackedLayout* slayout;
InputDialog* dialog;
QNetworkAccessManager* manager;
QPushButton btn;
QString username;
QString usernameGitHub;
QNetworkReply* reply;
// networking
QTimer* networkTimer;
bool aborted;
QNetworkReply* reply;
QNetworkAccessManager* manager;
void refresh();
void getUserKeys(QString username);
signals:
void closeSSHSettings();
void NoSSHAdded();
void SSHAdded();
void failedResponse(QString errorString);
void gotSSHKeys();
private slots:
void checkForSSHKey();
void getSSHKeys();
void timeout();
void parseResponse();
};

@ -37,5 +37,5 @@ private:
QPropertyAnimation *_anim = nullptr;
signals:
void stateChanged(int new_state);
void stateChanged(bool new_state);
};

Loading…
Cancel
Save