7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-21 17:03:44 +00:00

Add ability for git to negotiate with agents

Updates the git connection dialog to reflect default agentic behavior,
followed by default keys and only then reverting to a custom selection
if the user desires

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20204
This commit is contained in:
Seth Hillbrand 2025-03-14 13:06:49 -07:00
parent 26c331a837
commit 2c52f98da4
7 changed files with 220 additions and 297 deletions

View File

@ -26,6 +26,7 @@
#include <git2.h>
#include <git/kicad_git_memory.h>
#include <git/kicad_git_common.h>
#include <gestfich.h>
#include <cerrno>
@ -43,9 +44,6 @@ DIALOG_GIT_REPOSITORY::DIALOG_GIT_REPOSITORY( wxWindow* aParent, git_repository*
DIALOG_GIT_REPOSITORY_BASE( aParent ),
m_repository( aRepository ),
m_prevFile( wxEmptyString ),
m_tested( 0 ),
m_failedTest( false ),
m_testError( wxEmptyString ),
m_tempRepo( false )
{
m_txtURL->SetFocus();
@ -69,8 +67,11 @@ DIALOG_GIT_REPOSITORY::DIALOG_GIT_REPOSITORY( wxWindow* aParent, git_repository*
if( !m_txtURL->GetValue().IsEmpty() )
updateURLData();
else
m_ConnType->SetSelection( static_cast<int>( KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_LOCAL ) );
SetupStandardButtons();
SetupStandardButtons( { { wxID_HELP, _( "Test Connection" ) } } );
Layout();
finishDialogSettings();
@ -143,6 +144,13 @@ void DIALOG_GIT_REPOSITORY::setDefaultSSHKey()
}
void DIALOG_GIT_REPOSITORY::onCbCustom( wxCommandEvent& event )
{
updateAuthControls();
event.Skip();
}
void DIALOG_GIT_REPOSITORY::OnUpdateUI( wxUpdateUIEvent& event )
{
// event.Enable( !m_txtName->GetValue().IsEmpty() && !m_txtURL->GetValue().IsEmpty() );
@ -239,7 +247,6 @@ void DIALOG_GIT_REPOSITORY::updateURLData()
if( m_txtName->GetValue().IsEmpty() )
m_txtName->SetValue( get_repo_name( repoAddress ) );
}
}
else if( url.Contains( "ssh://" ) || url.Contains( "git@" ) )
@ -263,6 +270,11 @@ void DIALOG_GIT_REPOSITORY::updateURLData()
void DIALOG_GIT_REPOSITORY::OnTestClick( wxCommandEvent& event )
{
if( m_txtURL->GetValue().Trim().Trim( false ).IsEmpty() )
return;
wxString error;
bool success = false;
git_remote* remote = nullptr;
git_remote_callbacks callbacks;
git_remote_init_callbacks( &callbacks, GIT_REMOTE_CALLBACKS_VERSION );
@ -270,76 +282,31 @@ void DIALOG_GIT_REPOSITORY::OnTestClick( wxCommandEvent& event )
// We track if we have already tried to connect.
// If we have, the server may come back to offer another connection
// type, so we need to keep track of how many times we have tried.
m_tested = 0;
callbacks.credentials = []( git_cred** aOut, const char* aUrl, const char* aUsername,
unsigned int aAllowedTypes, void* aPayload ) -> int
{
DIALOG_GIT_REPOSITORY* dialog = static_cast<DIALOG_GIT_REPOSITORY*>( aPayload );
if( dialog->GetRepoType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_LOCAL )
return GIT_PASSTHROUGH;
if( aAllowedTypes & GIT_CREDTYPE_USERNAME
&& !( dialog->GetTested() & GIT_CREDTYPE_USERNAME ) )
{
wxString username = dialog->GetUsername().Trim().Trim( false );
git_cred_username_new( aOut, username.ToStdString().c_str() );
dialog->GetTested() |= GIT_CREDTYPE_USERNAME;
}
else if( dialog->GetRepoType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_HTTPS
&& ( aAllowedTypes & GIT_CREDTYPE_USERPASS_PLAINTEXT )
&& !( dialog->GetTested() & GIT_CREDTYPE_USERPASS_PLAINTEXT ) )
{
wxString username = dialog->GetUsername().Trim().Trim( false );
wxString password = dialog->GetPassword().Trim().Trim( false );
git_cred_userpass_plaintext_new( aOut, username.ToStdString().c_str(),
password.ToStdString().c_str() );
dialog->GetTested() |= GIT_CREDTYPE_USERPASS_PLAINTEXT;
}
else if( dialog->GetRepoType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_SSH
&& ( aAllowedTypes & GIT_CREDTYPE_SSH_KEY )
&& !( dialog->GetTested() & GIT_CREDTYPE_SSH_KEY ) )
{
// SSH key authentication
wxString sshKey = dialog->GetRepoSSHPath();
wxString sshPubKey = sshKey + ".pub";
wxString username = dialog->GetUsername().Trim().Trim( false );
wxString password = dialog->GetPassword().Trim().Trim( false );
git_cred_ssh_key_new( aOut, username.ToStdString().c_str(),
sshPubKey.ToStdString().c_str(), sshKey.ToStdString().c_str(),
password.ToStdString().c_str() );
dialog->GetTested() |= GIT_CREDTYPE_SSH_KEY;
}
else
{
return GIT_PASSTHROUGH;
}
return GIT_OK;
};
callbacks.payload = this;
KIGIT_COMMON common( m_repository );
callbacks.credentials = credentials_cb;
callbacks.payload = &common;
common.SetPassword( m_txtPassword->GetValue() );
common.SetUsername( m_txtUsername->GetValue() );
common.SetSSHKey( m_fpSSHKey->GetFileName().GetFullPath() );
common.SetConnType( static_cast<KIGIT_COMMON::GIT_CONN_TYPE>( m_ConnType->GetSelection() ) );
wxString txtURL = m_txtURL->GetValue();
git_remote_create_with_fetchspec( &remote, m_repository, "origin", txtURL.ToStdString().c_str(),
git_remote_create_with_fetchspec( &remote, m_repository, "origin", txtURL.mbc_str(),
"+refs/heads/*:refs/remotes/origin/*" );
KIGIT::GitRemotePtr remotePtr( remote );
if( git_remote_connect( remote, GIT_DIRECTION_FETCH, &callbacks, nullptr, nullptr ) != GIT_OK )
SetTestResult( true, git_error_last()->message );
if( git_remote_connect( remote, GIT_DIRECTION_FETCH, &callbacks, nullptr, nullptr ) == GIT_OK )
success = true;
else
SetTestResult( false, wxEmptyString );
error = git_error_last()->message;
git_remote_disconnect( remote );
auto dlg = wxMessageDialog( this, wxEmptyString, _( "Test Connection" ),
wxOK | wxICON_INFORMATION );
if( !m_failedTest )
if( success )
{
dlg.SetMessage( _( "Connection successful" ) );
}
@ -347,7 +314,7 @@ void DIALOG_GIT_REPOSITORY::OnTestClick( wxCommandEvent& event )
{
dlg.SetMessage( wxString::Format( _( "Could not connect to '%s' " ),
m_txtURL->GetValue() ) );
dlg.SetExtendedMessage( m_testError );
dlg.SetExtendedMessage( error );
}
dlg.ShowModal();
@ -450,14 +417,18 @@ void DIALOG_GIT_REPOSITORY::updateAuthControls()
if( m_ConnType->GetSelection() == static_cast<int>( KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_SSH ) )
{
m_fpSSHKey->Enable( true );
m_labelSSH->Enable( true );
m_cbCustom->Enable( true );
m_fpSSHKey->Enable( m_cbCustom->IsChecked() );
m_txtUsername->Enable( m_cbCustom->IsChecked() );
m_txtPassword->Enable( m_cbCustom->IsChecked() );
m_labelPass1->SetLabel( _( "SSH key password:" ) );
}
else
{
m_cbCustom->Enable( false );
m_fpSSHKey->Enable( false );
m_labelSSH->Enable( false );
m_txtUsername->Enable( true );
m_txtPassword->Enable( true );
m_labelPass1->SetLabel( _( "Password:" ) );
setDefaultSSHKey();
}

View File

@ -36,12 +36,6 @@ public:
wxString aURL = wxEmptyString );
~DIALOG_GIT_REPOSITORY() override;
void SetTestResult( bool aFailed, const wxString& aError )
{
m_failedTest = aFailed;
m_testError = aError;
}
void SetRepoType( KIGIT_COMMON::GIT_CONN_TYPE aType )
{
m_ConnType->SetSelection( static_cast<int>( aType ) );
@ -87,8 +81,6 @@ public:
void SetRepoSSHPath( const wxString& aPath ) { m_fpSSHKey->SetFileName( aPath ); m_prevFile = aPath; }
wxString GetRepoSSHPath() const { return m_fpSSHKey->GetFileName().GetFullPath(); }
unsigned& GetTested() { return m_tested; }
void SetEncrypted( bool aEncrypted = true );
private:
@ -100,6 +92,7 @@ private:
void OnTestClick( wxCommandEvent& event ) override;
void OnFileUpdated( wxFileDirPickerEvent& event ) override;
void onCbCustom( wxCommandEvent& event ) override;
void setDefaultSSHKey();
@ -115,10 +108,6 @@ private:
wxString m_prevFile;
unsigned m_tested;
bool m_failedTest;
wxString m_testError;
bool m_tempRepo;
wxString m_tempPath;
};

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -30,20 +30,26 @@ DIALOG_GIT_REPOSITORY_BASE::DIALOG_GIT_REPOSITORY_BASE( wxWindow* parent, wxWind
m_staticText3 = new wxStaticText( this, wxID_ANY, _("Name:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText3->Wrap( -1 );
m_staticText3->Hide();
fgSizer2->Add( m_staticText3, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_txtName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_txtName->Hide();
fgSizer2->Add( m_txtName, 0, wxEXPAND|wxRIGHT, 5 );
m_staticText4 = new wxStaticText( this, wxID_ANY, _("Location:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText4->Wrap( -1 );
fgSizer2->Add( m_staticText4, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
fgSizer2->Add( m_staticText4, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
m_txtURL = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_txtURL, 0, wxEXPAND|wxRIGHT, 5 );
m_staticText9 = new wxStaticText( this, wxID_ANY, _("Connection type:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText9->Wrap( -1 );
m_staticText9->Hide();
fgSizer2->Add( m_staticText9, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
wxBoxSizer* bSizer3;
@ -53,6 +59,8 @@ DIALOG_GIT_REPOSITORY_BASE::DIALOG_GIT_REPOSITORY_BASE( wxWindow* parent, wxWind
int m_ConnTypeNChoices = sizeof( m_ConnTypeChoices ) / sizeof( wxString );
m_ConnType = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_ConnTypeNChoices, m_ConnTypeChoices, 0 );
m_ConnType->SetSelection( 0 );
m_ConnType->Hide();
bSizer3->Add( m_ConnType, 0, wxRIGHT, 5 );
@ -80,23 +88,13 @@ DIALOG_GIT_REPOSITORY_BASE::DIALOG_GIT_REPOSITORY_BASE( wxWindow* parent, wxWind
fgSizer21->SetFlexibleDirection( wxBOTH );
fgSizer21->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_labelSSH = new wxStaticText( m_panelAuth, wxID_ANY, _("SSH private key: "), wxDefaultPosition, wxDefaultSize, 0 );
m_labelSSH->Wrap( -1 );
fgSizer21->Add( m_labelSSH, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
wxBoxSizer* bSizer5;
bSizer5 = new wxBoxSizer( wxHORIZONTAL );
m_cbCustom = new wxCheckBox( m_panelAuth, wxID_ANY, _("SSH private key: "), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer21->Add( m_cbCustom, 0, wxALL, 5 );
m_fpSSHKey = new wxFilePickerCtrl( m_panelAuth, wxID_ANY, wxEmptyString, _("Select SSH private key file"), _("*"), wxDefaultPosition, wxDefaultSize, wxFLP_DEFAULT_STYLE|wxFLP_FILE_MUST_EXIST|wxFLP_OPEN );
m_fpSSHKey->SetMinSize( wxSize( 250,-1 ) );
bSizer5->Add( m_fpSSHKey, 0, wxEXPAND|wxRIGHT, 5 );
m_btnTest = new wxButton( m_panelAuth, wxID_ANY, _("Test"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer5->Add( m_btnTest, 0, wxRIGHT, 5 );
fgSizer21->Add( bSizer5, 0, wxEXPAND, 5 );
fgSizer21->Add( m_fpSSHKey, 0, wxEXPAND|wxRIGHT, 5 );
m_staticText11 = new wxStaticText( m_panelAuth, wxID_ANY, _("User name:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText11->Wrap( -1 );
@ -129,6 +127,8 @@ DIALOG_GIT_REPOSITORY_BASE::DIALOG_GIT_REPOSITORY_BASE( wxWindow* parent, wxWind
m_sdbSizer->AddButton( m_sdbSizerOK );
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizerHelp = new wxButton( this, wxID_HELP );
m_sdbSizer->AddButton( m_sdbSizerHelp );
m_sdbSizer->Realize();
bSizerMain->Add( m_sdbSizer, 0, wxBOTTOM|wxEXPAND|wxTOP, 5 );
@ -145,8 +145,9 @@ DIALOG_GIT_REPOSITORY_BASE::DIALOG_GIT_REPOSITORY_BASE( wxWindow* parent, wxWind
this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnUpdateUI ) );
m_txtURL->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnLocationExit ), NULL, this );
m_ConnType->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnSelectConnType ), NULL, this );
m_cbCustom->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::onCbCustom ), NULL, this );
m_fpSSHKey->Connect( wxEVT_COMMAND_FILEPICKER_CHANGED, wxFileDirPickerEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnFileUpdated ), NULL, this );
m_btnTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnTestClick ), NULL, this );
m_sdbSizerHelp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnTestClick ), NULL, this );
m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnOKClick ), NULL, this );
}
@ -157,8 +158,9 @@ DIALOG_GIT_REPOSITORY_BASE::~DIALOG_GIT_REPOSITORY_BASE()
this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnUpdateUI ) );
m_txtURL->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnLocationExit ), NULL, this );
m_ConnType->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnSelectConnType ), NULL, this );
m_cbCustom->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::onCbCustom ), NULL, this );
m_fpSSHKey->Disconnect( wxEVT_COMMAND_FILEPICKER_CHANGED, wxFileDirPickerEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnFileUpdated ), NULL, this );
m_btnTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnTestClick ), NULL, this );
m_sdbSizerHelp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnTestClick ), NULL, this );
m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnOKClick ), NULL, this );
}

View File

@ -191,7 +191,7 @@
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxFlexGridSizer" expanded="false">
<object class="wxFlexGridSizer" expanded="true">
<property name="cols">2</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols">1</property>
@ -234,7 +234,7 @@
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="hidden">1</property>
<property name="id">wxID_ANY</property>
<property name="label">Name:</property>
<property name="markup">0</property>
@ -296,7 +296,7 @@
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="hidden">1</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
@ -332,7 +332,7 @@
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="false">
<property name="BottomDockable">1</property>
@ -489,7 +489,7 @@
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="hidden">1</property>
<property name="id">wxID_ANY</property>
<property name="label">Connection type:</property>
<property name="markup">0</property>
@ -520,11 +520,11 @@
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="false">
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="false">
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bSizer3</property>
<property name="orient">wxHORIZONTAL</property>
@ -561,7 +561,7 @@
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="hidden">1</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
@ -807,11 +807,77 @@
<property name="permission">none</property>
<property name="rows">0</property>
<property name="vgap">5</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">SSH private key: </property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_cbCustom</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnCheckBox">onCbCustom</event>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
<property name="flag">wxEXPAND|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="false">
<object class="wxFilePickerCtrl" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -840,16 +906,15 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">SSH private key: </property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="message">Select SSH private key file</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="minimum_size">250,-1</property>
<property name="moveable">1</property>
<property name="name">m_labelSSH</property>
<property name="name">m_fpSSHKey</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@ -859,167 +924,20 @@
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="style">wxFLP_DEFAULT_STYLE|wxFLP_FILE_MUST_EXIST|wxFLP_OPEN</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value"></property>
<property name="wildcard">*</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="false">
<property name="minimum_size"></property>
<property name="name">bSizer5</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxFilePickerCtrl" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="message">Select SSH private key file</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">250,-1</property>
<property name="moveable">1</property>
<property name="name">m_fpSSHKey</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxFLP_DEFAULT_STYLE|wxFLP_FILE_MUST_EXIST|wxFLP_OPEN</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value"></property>
<property name="wildcard">*</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnFileChanged">OnFileUpdated</event>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxButton" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Test</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_btnTest</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnTestClick</event>
</object>
</object>
<event name="OnFileChanged">OnFileUpdated</event>
</object>
</object>
<object class="sizeritem" expanded="false">
@ -1299,7 +1217,7 @@
<property name="Apply">0</property>
<property name="Cancel">1</property>
<property name="ContextHelp">0</property>
<property name="Help">0</property>
<property name="Help">1</property>
<property name="No">0</property>
<property name="OK">1</property>
<property name="Save">0</property>
@ -1307,6 +1225,7 @@
<property name="minimum_size"></property>
<property name="name">m_sdbSizer</property>
<property name="permission">protected</property>
<event name="OnHelpButtonClick">OnTestClick</event>
<event name="OnOKButtonClick">OnOKClick</event>
</object>
</object>

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -21,12 +21,10 @@
#include <wx/textctrl.h>
#include <wx/choice.h>
#include <wx/sizer.h>
#include <wx/checkbox.h>
#include <wx/filepicker.h>
#include <wx/button.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/panel.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
@ -51,9 +49,8 @@ class DIALOG_GIT_REPOSITORY_BASE : public DIALOG_SHIM
wxPanel* m_panelAuth;
wxStaticText* m_staticText2;
wxStaticLine* m_staticline2;
wxStaticText* m_labelSSH;
wxCheckBox* m_cbCustom;
wxFilePickerCtrl* m_fpSSHKey;
wxButton* m_btnTest;
wxStaticText* m_staticText11;
wxTextCtrl* m_txtUsername;
wxStaticText* m_labelPass1;
@ -61,12 +58,14 @@ class DIALOG_GIT_REPOSITORY_BASE : public DIALOG_SHIM
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
wxButton* m_sdbSizerHelp;
// Virtual event handlers, override them in your derived class
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnLocationExit( wxFocusEvent& event ) { event.Skip(); }
virtual void OnSelectConnType( wxCommandEvent& event ) { event.Skip(); }
virtual void onCbCustom( wxCommandEvent& event ) { event.Skip(); }
virtual void OnFileUpdated( wxFileDirPickerEvent& event ) { event.Skip(); }
virtual void OnTestClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOKClick( wxCommandEvent& event ) { event.Skip(); }

View File

@ -656,6 +656,59 @@ void KIGIT_COMMON::updateConnectionType()
}
int KIGIT_COMMON::HandleSSHKeyAuthentication( git_cred** aOut, const wxString& aUsername )
{
if( !( m_testedTypes & KIGIT_CREDENTIAL_SSH_AGENT ) )
return HandleSSHAgentAuthentication( aOut, aUsername );
// SSH key authentication with password
wxString sshKey = GetNextPublicKey();
if( sshKey.IsEmpty() )
{
m_testedTypes |= GIT_CREDENTIAL_SSH_KEY;
return GIT_PASSTHROUGH;
}
wxString sshPubKey = sshKey + ".pub";
wxString password = GetPassword();
if( git_credential_ssh_key_new( aOut, aUsername.mbc_str(), sshPubKey.mbc_str(), sshKey.mbc_str(),
password.mbc_str() ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to create SSH key credential for %s: %s",
aUsername, git_error_last()->message );
return GIT_ERROR;
}
return GIT_OK;
}
int KIGIT_COMMON::HandlePlaintextAuthentication( git_cred** aOut, const wxString& aUsername )
{
wxString password = GetPassword();
git_credential_userpass_plaintext_new( aOut, aUsername.mbc_str(), password.mbc_str() );
m_testedTypes |= GIT_CREDENTIAL_USERPASS_PLAINTEXT;
return GIT_OK;
}
int KIGIT_COMMON::HandleSSHAgentAuthentication( git_cred** aOut, const wxString& aUsername )
{
if( git_credential_ssh_key_from_agent( aOut, aUsername.mbc_str() ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to create SSH agent credential for %s: %s",
aUsername, git_error_last()->message );
return GIT_ERROR;
}
m_testedTypes |= KIGIT_CREDENTIAL_SSH_AGENT;
return GIT_OK;
}
extern "C" int fetchhead_foreach_cb( const char*, const char*,
const git_oid* aOID, unsigned int aIsMerge, void* aPayload )
{
@ -789,34 +842,15 @@ extern "C" int credentials_cb( git_cred** aOut, const char* aUrl, const char* aU
&& ( aAllowedTypes & GIT_CREDENTIAL_USERPASS_PLAINTEXT )
&& !( parent->TestedTypes() & GIT_CREDENTIAL_USERPASS_PLAINTEXT ) )
{
wxString username = parent->GetUsername().Trim().Trim( false );
wxString password = parent->GetPassword().Trim().Trim( false );
git_credential_userpass_plaintext_new( aOut, username.ToStdString().c_str(),
password.ToStdString().c_str() );
parent->TestedTypes() |= GIT_CREDENTIAL_USERPASS_PLAINTEXT;
// Plaintext authentication
return parent->HandlePlaintextAuthentication( aOut, aUsername );
}
else if( parent->GetConnType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_SSH
&& ( aAllowedTypes & GIT_CREDENTIAL_SSH_KEY )
&& !( parent->TestedTypes() & GIT_CREDENTIAL_SSH_KEY ) )
{
// SSH key authentication
wxString sshKey = parent->GetNextPublicKey();
if( sshKey.IsEmpty() )
{
parent->TestedTypes() |= GIT_CREDENTIAL_SSH_KEY;
return GIT_PASSTHROUGH;
}
wxString sshPubKey = sshKey + ".pub";
wxString username = parent->GetUsername().Trim().Trim( false );
wxString password = parent->GetPassword().Trim().Trim( false );
git_credential_ssh_key_new( aOut, username.ToStdString().c_str(),
sshPubKey.ToStdString().c_str(),
sshKey.ToStdString().c_str(),
password.ToStdString().c_str() );
return parent->HandleSSHKeyAuthentication( aOut, aUsername );
}
else
{

View File

@ -131,6 +131,12 @@ public:
return m_publicKeys[m_nextPublicKey++];
}
int HandleSSHKeyAuthentication( git_cred** aOut, const wxString& aUsername );
int HandlePlaintextAuthentication( git_cred** aOut, const wxString& aUsername );
int HandleSSHAgentAuthentication( git_cred** aOut, const wxString& aUsername );
protected:
git_repository* m_repo;
@ -154,10 +160,13 @@ private:
std::vector<wxString> m_publicKeys;
int m_nextPublicKey;
// Create a dummy flag to tell if we have tested ssh agent credentials separately
// from the ssh key credentials
static const unsigned KIGIT_CREDENTIAL_SSH_AGENT = 1 << sizeof( m_testedTypes - 1 );
};
extern "C" int progress_cb( const char* str, int len, void* data );
extern "C" int progress_cb( const char* str, int len, void* data );
extern "C" void clone_progress_cb( const char* str, size_t len, size_t total, void* data );
extern "C" int transfer_progress_cb( const git_transfer_progress* aStats, void* aPayload );
extern "C" int update_cb( const char* aRefname, const git_oid* aFirst, const git_oid* aSecond,