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);