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
This commit is contained in:
Twarit Waikar
2021-10-10 07:29:07 +05:30
parent 055c9c387a
commit 753ffce0c8
4 changed files with 52 additions and 43 deletions

View File

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

View File

@@ -75,18 +75,18 @@ using git_tree_ptr = unique_ptr_deleter<git_tree, git_tree_free>;
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);

View File

@@ -1,6 +1,9 @@
#include <git_api.h>
#include <git_common.h>
#include <Directory.hpp>
#include <git_api.h>
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){

View File

@@ -7,6 +7,14 @@
#include <git2.h>
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);