# include <QHBoxLayout>
# include <QLabel>
# include <QPushButton>
# include <QState>
# include <QStateMachine>
# include <QNetworkReply>
# 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
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 : 60 px ;
margin : 0 px ;
padding : 15 px ;
border - radius : 25 px ;
color : # dddddd ;
background - color : # 444444 ;
}
) " );
setLayout ( slayout ) ;
//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 ( ) ;
}
void SSH : : checkForSSHKey ( ) {
QString SSHKey = QString : : fromStdString ( Params ( ) . get ( " GithubSshKeys " ) ) ;
if ( SSHKey . length ( ) ) {
emit SSHAdded ( ) ;
} else {
emit NoSSHAdded ( ) ;
}
}
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 ( ) ) ) ;
networkTimer - > start ( ) ;
}
void SSH : : timeout ( ) {
aborted = true ;
reply - > abort ( ) ;
}
void SSH : : parseResponse ( ) {
if ( ! aborted ) {
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 " ) ;
} else {
emit failedResponse ( " Username " + usernameGitHub + " doesn't exist " ) ;
}
} else {
emit failedResponse ( " Request timed out " ) ;
}
reply - > deleteLater ( ) ;
reply = nullptr ;
}