Skip to content

Commit dff2b6a

Browse files
committed
implement SshKeyFromMemory
fixes libgit2gh-796 libgit2 already supports it.
1 parent 33873e5 commit dff2b6a

File tree

5 files changed

+82
-5
lines changed

5 files changed

+82
-5
lines changed

ext/rugged/rugged_cred.c

+42-5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ extern VALUE rb_mRugged;
1111
VALUE rb_mRuggedCred;
1212
VALUE rb_cRuggedCredUserPassword;
1313
VALUE rb_cRuggedCredSshKey;
14+
VALUE rb_cRuggedCredSshKeyFromMemory;
1415
VALUE rb_cRuggedCredSshKeyFromAgent;
1516
VALUE rb_cRuggedCredDefault;
1617

@@ -55,6 +56,31 @@ static void rugged_cred_extract_ssh_key(git_cred **cred, VALUE rb_credential)
5556
);
5657
}
5758

59+
static void rugged_cred_extract_ssh_key_from_memory(git_cred **cred, VALUE rb_credential)
60+
{
61+
VALUE rb_username = rb_iv_get(rb_credential, "@username");
62+
VALUE rb_publickey = rb_iv_get(rb_credential, "@publickey");
63+
VALUE rb_privatekey = rb_iv_get(rb_credential, "@privatekey");
64+
VALUE rb_passphrase = rb_iv_get(rb_credential, "@passphrase");
65+
66+
Check_Type(rb_username, T_STRING);
67+
Check_Type(rb_privatekey, T_STRING);
68+
69+
if (!NIL_P(rb_publickey))
70+
Check_Type(rb_publickey, T_STRING);
71+
if (!NIL_P(rb_passphrase))
72+
Check_Type(rb_passphrase, T_STRING);
73+
74+
rugged_exception_check(
75+
git_cred_ssh_key_memory_new(cred,
76+
StringValueCStr(rb_username),
77+
NIL_P(rb_publickey) ? NULL : StringValueCStr(rb_publickey),
78+
StringValueCStr(rb_privatekey),
79+
NIL_P(rb_passphrase) ? NULL : StringValueCStr(rb_passphrase)
80+
)
81+
);
82+
}
83+
5884
static void rugged_credential_extract_ssh_key_from_agent(git_cred **cred, VALUE rb_credential)
5985
{
6086
VALUE rb_username = rb_iv_get(rb_credential, "@username");
@@ -101,6 +127,16 @@ void rugged_cred_extract(git_cred **cred, int allowed_types, VALUE rb_credential
101127
rb_raise(rb_eArgError, "Invalid credential type");
102128

103129
rugged_cred_extract_ssh_key(cred, rb_credential);
130+
} else if (rb_obj_is_kind_of(rb_credential, rb_cRuggedCredSshKeyFromMemory)) {
131+
if (allowed_types & GIT_CREDTYPE_USERNAME) {
132+
rugged_cred_extract_username(cred, rb_credential);
133+
return;
134+
}
135+
136+
if (!(allowed_types & GIT_CREDTYPE_SSH_KEY))
137+
rb_raise(rb_eArgError, "Invalid credential type");
138+
139+
rugged_cred_extract_ssh_key_from_memory(cred, rb_credential);
104140
} else if (rb_obj_is_kind_of(rb_credential, rb_cRuggedCredSshKeyFromAgent)) {
105141
if (allowed_types & GIT_CREDTYPE_USERNAME) {
106142
rugged_cred_extract_username(cred, rb_credential);
@@ -122,10 +158,11 @@ void rugged_cred_extract(git_cred **cred, int allowed_types, VALUE rb_credential
122158

123159
void Init_rugged_cred(void)
124160
{
125-
rb_mRuggedCred = rb_define_module_under(rb_mRugged, "Credentials");
161+
rb_mRuggedCred = rb_define_module_under(rb_mRugged, "Credentials");
126162

127-
rb_cRuggedCredUserPassword = rb_define_class_under(rb_mRuggedCred, "UserPassword", rb_cObject);
128-
rb_cRuggedCredSshKey = rb_define_class_under(rb_mRuggedCred, "SshKey", rb_cObject);
129-
rb_cRuggedCredSshKeyFromAgent = rb_define_class_under(rb_mRuggedCred, "SshKeyFromAgent", rb_cObject);
130-
rb_cRuggedCredDefault = rb_define_class_under(rb_mRuggedCred, "Default", rb_cObject);
163+
rb_cRuggedCredUserPassword = rb_define_class_under(rb_mRuggedCred, "UserPassword", rb_cObject);
164+
rb_cRuggedCredSshKey = rb_define_class_under(rb_mRuggedCred, "SshKey", rb_cObject);
165+
rb_cRuggedCredSshKeyFromMemory = rb_define_class_under(rb_mRuggedCred, "SshKeyFromMemory", rb_cObject);
166+
rb_cRuggedCredSshKeyFromAgent = rb_define_class_under(rb_mRuggedCred, "SshKeyFromAgent", rb_cObject);
167+
rb_cRuggedCredDefault = rb_define_class_under(rb_mRuggedCred, "Default", rb_cObject);
131168
}

lib/rugged/credentials.rb

+13
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def call(url, username_from_url, allowed_types)
1717
end
1818

1919
# A ssh key credential object that can optionally be passphrase-protected
20+
# publickey and privatekey are filenames that will be opened to load the key
2021
class SshKey
2122
def initialize(options)
2223
@username, @publickey, @privatekey, @passphrase = options[:username], options[:publickey], options[:privatekey], options[:passphrase]
@@ -27,6 +28,18 @@ def call(url, username_from_url, allowed_types)
2728
end
2829
end
2930

31+
# A ssh key credential object that can optionally be passphrase-protected
32+
# publickey and privatekey are string that are the actual contents of the key
33+
class SshKeyFromMemory
34+
def initialize(options)
35+
@username, @publickey, @privatekey, @passphrase = options[:username], options[:publickey], options[:privatekey], options[:passphrase]
36+
end
37+
38+
def call(*)
39+
self
40+
end
41+
end
42+
3043
class SshKeyFromAgent
3144
def initialize(options)
3245
@username = options[:username]

test/online/clone_test.rb

+10
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ def test_clone_over_ssh_with_credentials
2222
end
2323
end
2424

25+
def test_clone_over_ssh_with_credentials
26+
Dir.mktmpdir do |dir|
27+
repo = Rugged::Repository.clone_at(ENV['GITTEST_REMOTE_SSH_URL'], dir, {
28+
credentials: ssh_key_credential_from_memory
29+
})
30+
31+
assert_instance_of Rugged::Repository, repo
32+
end
33+
end
34+
2535
def test_clone_over_ssh_with_credentials_from_agent
2636
Dir.mktmpdir do |dir|
2737
repo = Rugged::Repository.clone_at(ENV['GITTEST_REMOTE_SSH_URL'], dir, {

test/online/fetch_test.rb

+8
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ def test_fetch_over_ssh_with_credentials
8181
})
8282
end
8383

84+
def test_fetch_over_ssh_with_credentials_from_memory
85+
@repo.remotes.create("origin", ENV['GITTEST_REMOTE_SSH_URL'])
86+
87+
@repo.fetch("origin", {
88+
credentials: ssh_key_credential_from_memory
89+
})
90+
end
91+
8492
def test_fetch_over_ssh_with_credentials_from_agent
8593
@repo.remotes.create("origin", ENV['GITTEST_REMOTE_SSH_URL'])
8694

test/test_helper.rb

+9
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,15 @@ def ssh_key_credential
162162
})
163163
end
164164

165+
def ssh_key_credential_from_memory
166+
Rugged::Credentials::SshKeyFromMemory.new({
167+
username: ENV["GITTEST_REMOTE_SSH_USER"],
168+
publickey: File.read(ENV["GITTEST_REMOTE_SSH_PUBKEY"]),
169+
privatekey: File.read(ENV["GITTEST_REMOTE_SSH_KEY"]),
170+
passphrase: ENV["GITTEST_REMOTE_SSH_PASSPHASE"],
171+
})
172+
end
173+
165174
def ssh_key_credential_from_agent
166175
Rugged::Credentials::SshKeyFromAgent.new({
167176
username: ENV["GITTEST_REMOTE_SSH_USER"]

0 commit comments

Comments
 (0)