From 753ffce0c80591cc3ea65ef53b0d920ab3a5584f Mon Sep 17 00:00:00 2001 From: Twarit Waikar Date: Sun, 10 Oct 2021 07:29:07 +0530 Subject: [PATCH] Add support for sending SSH credentials for auth SSH support is however incomplete as of now because SSH support is currently in getting turned OFF in libgit2 as we do not link to libssh2 yet --- godot-git-plugin/src/git_api.cpp | 44 +++++++++++------------------ godot-git-plugin/src/git_api.h | 13 +++++---- godot-git-plugin/src/git_common.cpp | 30 ++++++++++++++------ godot-git-plugin/src/git_common.h | 8 ++++++ 4 files changed, 52 insertions(+), 43 deletions(-) diff --git a/godot-git-plugin/src/git_api.cpp b/godot-git-plugin/src/git_api.cpp index 9f133e5..918701a 100644 --- a/godot-git-plugin/src/git_api.cpp +++ b/godot-git-plugin/src/git_api.cpp @@ -40,6 +40,7 @@ void GitAPI::_register_methods() { register_method("_pull", &GitAPI::_pull); register_method("_push", &GitAPI::_push); register_method("_get_line_diff", &GitAPI::_get_line_diff); + register_method("_set_credentials", &GitAPI::_set_credentials); } bool GitAPI::check_errors(int error, String message, String function, String file, int line) { @@ -61,6 +62,14 @@ bool GitAPI::check_errors(int error, String message, String function, String fil return true; } +void GitAPI::_set_credentials(const String username, const String password, const String ssh_public_key_path, const String ssh_private_key_path, const String ssh_passphrase) { + creds.username = username; + creds.password = password; + creds.ssh_public_key_path = ssh_public_key_path; + creds.ssh_private_key_path = ssh_private_key_path; + creds.ssh_passphrase = ssh_passphrase; +} + void GitAPI::_discard_file(const String file_path) { git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; @@ -376,7 +385,7 @@ void GitAPI::_create_branch(const String branch_name) { void GitAPI::_create_remote(const String remote_name, const String remote_url) { git_remote_ptr remote; GIT2_PTR("Could not create remote", - git_remote_create, remote, repo.get(), CString(remote_name).data, CString(remote_url).data); + git_remote_create_with_opts, remote, CString(remote_url).data, &opts); } Array GitAPI::_get_line_diff(String file_path, String text) { @@ -479,7 +488,7 @@ Array GitAPI::_get_previous_commits(const int64_t max_commits) { return commits; } -void GitAPI::_fetch(String remote, String username, String password) { +void GitAPI::_fetch(String remote) { Godot::print("GitAPI: Performing fetch from " + remote); @@ -487,20 +496,12 @@ void GitAPI::_fetch(String remote, String username, String password) { GIT2_PTR("Could not lookup remote \"" + remote + "\"", git_remote_lookup, remote_object, repo.get(), CString(remote).data); - CString c_username(username); - CString c_password(username); - - String payload[2] = { - username, - password - }; - git_remote_callbacks remote_cbs = GIT_REMOTE_CALLBACKS_INIT; remote_cbs.credentials = &credentials_cb; remote_cbs.update_tips = &update_cb; remote_cbs.sideband_progress = &progress_cb; remote_cbs.transfer_progress = &transfer_progress_cb; - remote_cbs.payload = payload; + remote_cbs.payload = &creds; remote_cbs.push_transfer_progress = &push_transfer_progress_cb; remote_cbs.push_update_reference = &push_update_reference_cb; @@ -515,24 +516,19 @@ void GitAPI::_fetch(String remote, String username, String password) { Godot::print("GitAPI: Fetch ended"); } -void GitAPI::_pull(String remote, String username, String password) { +void GitAPI::_pull(String remote) { Godot::print("GitAPI: Performing pull from " + remote); git_remote_ptr remote_object; GIT2_PTR("Could not lookup remote \"" + remote + "\"", git_remote_lookup, remote_object, repo.get(), CString(remote).data); - String payload[2] = { - username, - password - }; - git_remote_callbacks remote_cbs = GIT_REMOTE_CALLBACKS_INIT; remote_cbs.credentials = &credentials_cb; remote_cbs.update_tips = &update_cb; remote_cbs.sideband_progress = &progress_cb; remote_cbs.transfer_progress = &transfer_progress_cb; - remote_cbs.payload = payload; + remote_cbs.payload = &creds; remote_cbs.push_transfer_progress = &push_transfer_progress_cb; remote_cbs.push_update_reference = &push_update_reference_cb; @@ -631,27 +627,19 @@ void GitAPI::_pull(String remote, String username, String password) { Godot::print("GitAPI: Pull ended"); } -void GitAPI::_push(const String remote, const String username, const String password, const bool force) { +void GitAPI::_push(const String remote, const bool force) { Godot::print("GitAPI: Performing push to " + remote); git_remote_ptr remote_object; GIT2_PTR("Could not lookup remote \"" + remote + "\"", git_remote_lookup, remote_object, repo.get(), CString(remote).data); - CString c_username(username); - CString c_password(username); - - String payload[2] = { - username, - password - }; - git_remote_callbacks remote_cbs = GIT_REMOTE_CALLBACKS_INIT; remote_cbs.credentials = &credentials_cb; remote_cbs.update_tips = &update_cb; remote_cbs.sideband_progress = &progress_cb; remote_cbs.transfer_progress = &transfer_progress_cb; - remote_cbs.payload = payload; + remote_cbs.payload = &creds; remote_cbs.push_transfer_progress = &push_transfer_progress_cb; remote_cbs.push_update_reference = &push_update_reference_cb; diff --git a/godot-git-plugin/src/git_api.h b/godot-git-plugin/src/git_api.h index 24d46e6..a43e8cb 100644 --- a/godot-git-plugin/src/git_api.h +++ b/godot-git-plugin/src/git_api.h @@ -75,18 +75,18 @@ using git_tree_ptr = unique_ptr_deleter; class GitAPI : public EditorVCSInterface { GODOT_CLASS(GitAPI, EditorVCSInterface) - git_repository_ptr repo; - + Credentials creds; bool has_merge = false; + git_repository_ptr repo; git_oid pull_merge_oid = {}; - + // Endpoints bool _checkout_branch(const String branch_name); void _commit(const String msg); void _create_branch(const String branch_name); void _create_remote(const String remote_name, const String remote_url); void _discard_file(const String file_path); - void _fetch(const String remote, const String username, const String password); + void _fetch(const String remote); Array _get_branch_list(); String _get_current_branch_name(); Array _get_diff(const String identifier, const int64_t area); @@ -96,8 +96,9 @@ class GitAPI : public EditorVCSInterface { Array _get_remotes(); String _get_vcs_name(); bool _initialize(const String project_path); - void _pull(const String remote, const String username, const String password); - void _push(const String remote, const String username, const String password, const bool force); + void _pull(const String remote); + void _push(const String remote, const bool force); + void _set_credentials(const String username, const String password, const String ssh_public_key_path, const String ssh_private_key_path, const String ssh_passphrase); bool _shut_down(); void _stage_file(const String file_path); void _unstage_file(const String file_path); diff --git a/godot-git-plugin/src/git_common.cpp b/godot-git-plugin/src/git_common.cpp index 7cc197f..3fdf033 100644 --- a/godot-git-plugin/src/git_common.cpp +++ b/godot-git-plugin/src/git_common.cpp @@ -1,6 +1,9 @@ -#include #include +#include + +#include + extern "C" int progress_cb(const char *str, int len, void *data) { (void)data; godot::String progress_str; @@ -72,16 +75,25 @@ extern "C" int push_update_reference_cb(const char *refname, const char *status, } extern "C" int credentials_cb(git_cred **out, const char *url, const char *username_from_url, unsigned int allowed_types, void *payload) { - godot::String* creds = (godot::String *)payload; - - godot::String& username = creds[0]; - godot::String& password = creds[1]; - - if (username.empty() || password.empty()) { - return GIT_EUSER; + Credentials* creds = (Credentials *)payload; + + if (allowed_types & GIT_CREDENTIAL_USERPASS_PLAINTEXT) { + return git_cred_userpass_plaintext_new(out, godot::CString(creds->username).data, godot::CString(creds->password).data); } - return git_cred_userpass_plaintext_new(out, godot::CString(username).data, godot::CString(password).data); + if (allowed_types & GIT_CREDENTIAL_SSH_KEY) { + return git_credential_ssh_key_new(out, + godot::CString(creds->username).data, + godot::CString(creds->ssh_public_key_path).data, + godot::CString(creds->ssh_private_key_path).data, + godot::CString(creds->ssh_passphrase).data); + } + + if (allowed_types & GIT_CREDENTIAL_USERNAME) { + return git_credential_username_new(out, godot::CString(creds->username).data); + } + + return GIT_PASSTHROUGH; } extern "C" int diff_hunk_cb(const git_diff_delta *delta, const git_diff_hunk *range, void *payload){ diff --git a/godot-git-plugin/src/git_common.h b/godot-git-plugin/src/git_common.h index 668c678..42969af 100644 --- a/godot-git-plugin/src/git_common.h +++ b/godot-git-plugin/src/git_common.h @@ -7,6 +7,14 @@ #include +struct Credentials { + godot::String username; + godot::String password; + godot::String ssh_public_key_path; + godot::String ssh_private_key_path; + godot::String ssh_passphrase; +}; + extern "C" int progress_cb(const char *str, int len, void *data); extern "C" int update_cb(const char *refname, const git_oid *a, const git_oid *b, void *data); extern "C" int transfer_progress_cb(const git_indexer_progress *stats, void *payload);