Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2sharp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Straub <bs@github.com>2013-01-09 03:11:59 +0400
committerBen Straub <bs@github.com>2013-01-16 19:30:59 +0400
commit20a6b51fca0083a66b6f892d038f1d8b2d593ce9 (patch)
tree1f35e2433ad048094546bb568fde1acc8eca4e9a
parent95a50c31370c43aba6ee66b8705df45810dac0e8 (diff)
Provide access to basic username/password auth for clone
-rw-r--r--LibGit2Sharp.Tests/CloneFixture.cs25
-rw-r--r--LibGit2Sharp.Tests/RemoteFixture.cs22
-rw-r--r--LibGit2Sharp.Tests/TestHelpers/Constants.cs5
-rw-r--r--LibGit2Sharp/Core/GitCloneOptions.cs2
-rw-r--r--LibGit2Sharp/Core/NativeMethods.cs23
-rw-r--r--LibGit2Sharp/Core/Proxy.cs5
-rw-r--r--LibGit2Sharp/Credentials.cs18
-rw-r--r--LibGit2Sharp/LibGit2Sharp.csproj1
-rw-r--r--LibGit2Sharp/Remote.cs16
-rw-r--r--LibGit2Sharp/Repository.cs33
10 files changed, 138 insertions, 12 deletions
diff --git a/LibGit2Sharp.Tests/CloneFixture.cs b/LibGit2Sharp.Tests/CloneFixture.cs
index 05d27521..864ea97e 100644
--- a/LibGit2Sharp.Tests/CloneFixture.cs
+++ b/LibGit2Sharp.Tests/CloneFixture.cs
@@ -110,5 +110,30 @@ namespace LibGit2Sharp.Tests
Assert.True(checkoutWasCalled);
}
}
+
+ [SkippableFact]
+ public void CanCloneWithCredentials()
+ {
+ InconclusiveIf(() => string.IsNullOrEmpty(Constants.PrivateRepoUrl),
+ "Populate Constants.PrivateRepo* to run this test");
+
+ var scd = BuildSelfCleaningDirectory();
+ using (Repository repo = Repository.Clone(
+ Constants.PrivateRepoUrl, scd.RootedDirectoryPath,
+ credentials: new Credentials
+ {
+ Username = Constants.PrivateRepoUsername,
+ Password = Constants.PrivateRepoPassword
+ }))
+ {
+ string dir = repo.Info.Path;
+ Assert.True(Path.IsPathRooted(dir));
+ Assert.True(Directory.Exists(dir));
+
+ Assert.NotNull(repo.Info.WorkingDirectory);
+ Assert.Equal(Path.Combine(scd.RootedDirectoryPath, ".git" + Path.DirectorySeparatorChar), repo.Info.Path);
+ Assert.False(repo.Info.IsBare);
+ }
+ }
}
}
diff --git a/LibGit2Sharp.Tests/RemoteFixture.cs b/LibGit2Sharp.Tests/RemoteFixture.cs
index 2fc2bfad..c2831bcf 100644
--- a/LibGit2Sharp.Tests/RemoteFixture.cs
+++ b/LibGit2Sharp.Tests/RemoteFixture.cs
@@ -110,6 +110,28 @@ namespace LibGit2Sharp.Tests
}
}
+ [SkippableFact]
+ public void CanFetchIntoAnEmptyRepositoryWithCredentials()
+ {
+ InconclusiveIf(() => string.IsNullOrEmpty(Constants.PrivateRepoUrl),
+ "Populate Constants.PrivateRepo* to run this test");
+
+ string remoteName = "testRemote";
+
+ var scd = BuildSelfCleaningDirectory();
+ using (var repo = Repository.Init(scd.RootedDirectoryPath))
+ {
+ Remote remote = repo.Remotes.Add(remoteName, Constants.PrivateRepoUrl);
+
+ // Perform the actual fetch
+ remote.Fetch(credentials: new Credentials
+ {
+ Username = Constants.PrivateRepoUsername,
+ Password = Constants.PrivateRepoPassword
+ });
+ }
+ }
+
[Theory]
[InlineData("http://github.com/libgit2/TestGitRepository")]
[InlineData("https://github.com/libgit2/TestGitRepository")]
diff --git a/LibGit2Sharp.Tests/TestHelpers/Constants.cs b/LibGit2Sharp.Tests/TestHelpers/Constants.cs
index 79ed9580..212c29e1 100644
--- a/LibGit2Sharp.Tests/TestHelpers/Constants.cs
+++ b/LibGit2Sharp.Tests/TestHelpers/Constants.cs
@@ -7,5 +7,10 @@ namespace LibGit2Sharp.Tests.TestHelpers
public const string TemporaryReposPath = "TestRepos";
public const string UnknownSha = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
public static readonly Signature Signature = new Signature("A. U. Thor", "thor@valhalla.asgard.com", new DateTimeOffset(2011, 06, 16, 10, 58, 27, TimeSpan.FromHours(2)));
+
+ // Populate these to turn on live credential tests
+ public const string PrivateRepoUrl = "";
+ public const string PrivateRepoUsername = "";
+ public const string PrivateRepoPassword = "";
}
}
diff --git a/LibGit2Sharp/Core/GitCloneOptions.cs b/LibGit2Sharp/Core/GitCloneOptions.cs
index c6efd1a9..4b6c6832 100644
--- a/LibGit2Sharp/Core/GitCloneOptions.cs
+++ b/LibGit2Sharp/Core/GitCloneOptions.cs
@@ -18,7 +18,7 @@ namespace LibGit2Sharp.Core
public IntPtr FetchSpec;
public IntPtr PushSpec;
- public IntPtr CredAcquireCallback;
+ public NativeMethods.git_cred_acquire_cb CredAcquireCallback;
public IntPtr CredAcquirePayload;
public IntPtr Transport;
diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs
index 07a4bce3..491cc47f 100644
--- a/LibGit2Sharp/Core/NativeMethods.cs
+++ b/LibGit2Sharp/Core/NativeMethods.cs
@@ -300,6 +300,23 @@ namespace LibGit2Sharp.Core
config_foreach_callback callback,
IntPtr payload);
+ // Ordinarily we would decorate the `url` parameter with the Utf8Marshaler like we do everywhere
+ // else, but apparently doing a native->managed callback with the 64-bit version of CLR 2.0 can
+ // sometimes vomit when using a custom IMarshaler. So yeah, don't do that. If you need the url,
+ // call Utf8Marshaler.FromNative manually. See the discussion here:
+ // http://social.msdn.microsoft.com/Forums/en-US/netfx64bit/thread/1eb746c6-d695-4632-8a9e-16c4fa98d481
+ internal delegate int git_cred_acquire_cb(
+ out IntPtr cred,
+ IntPtr url,
+ uint allowed_types,
+ IntPtr payload);
+
+ [DllImport(libgit2)]
+ internal static extern int git_cred_userpass_plaintext_new(
+ out IntPtr cred,
+ [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Utf8Marshaler))] string username,
+ [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (Utf8Marshaler))] string password);
+
[DllImport(libgit2)]
internal static extern void git_diff_list_free(IntPtr diff);
@@ -630,6 +647,12 @@ namespace LibGit2Sharp.Core
internal static extern int git_remote_save(RemoteSafeHandle remote);
[DllImport(libgit2)]
+ internal static extern void git_remote_set_cred_acquire_cb(
+ RemoteSafeHandle remote,
+ git_cred_acquire_cb cred_acquire_cb,
+ IntPtr payload);
+
+ [DllImport(libgit2)]
internal static extern int git_repository_odb(out ObjectDatabaseSafeHandle odb, RepositorySafeHandle repo);
[DllImport(libgit2)]
diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs
index 97973dda..7115fdde 100644
--- a/LibGit2Sharp/Core/Proxy.cs
+++ b/LibGit2Sharp/Core/Proxy.cs
@@ -1253,6 +1253,11 @@ namespace LibGit2Sharp.Core
}
}
+ public static void git_remote_set_cred_acquire_cb(RemoteSafeHandle remote, NativeMethods.git_cred_acquire_cb cred_acquire_cb, IntPtr payload)
+ {
+ NativeMethods.git_remote_set_cred_acquire_cb(remote, cred_acquire_cb, payload);
+ }
+
public static void git_remote_update_tips(RemoteSafeHandle remote)
{
using (ThreadAffinity())
diff --git a/LibGit2Sharp/Credentials.cs b/LibGit2Sharp/Credentials.cs
new file mode 100644
index 00000000..f03a5cfa
--- /dev/null
+++ b/LibGit2Sharp/Credentials.cs
@@ -0,0 +1,18 @@
+namespace LibGit2Sharp
+{
+ /// <summary>
+ /// Class that holds credentials for remote repository access.
+ /// </summary>
+ public class Credentials
+ {
+ /// <summary>
+ /// Username for username/password authentication (as in HTTP basic auth).
+ /// </summary>
+ public string Username { get; set; }
+
+ /// <summary>
+ /// Password for username/password authentication (as in HTTP basic auth).
+ /// </summary>
+ public string Password { get; set; }
+ }
+}
diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj
index 7664ce89..0fef0a45 100644
--- a/LibGit2Sharp/LibGit2Sharp.csproj
+++ b/LibGit2Sharp/LibGit2Sharp.csproj
@@ -84,6 +84,7 @@
<Compile Include="Core\LazyGroup.cs" />
<Compile Include="Core\Handles\GitConfigEntryHandle.cs" />
<Compile Include="Core\Proxy.cs" />
+ <Compile Include="Credentials.cs" />
<Compile Include="DiffOptions.cs" />
<Compile Include="DiffTargets.cs" />
<Compile Include="Handlers.cs" />
diff --git a/LibGit2Sharp/Remote.cs b/LibGit2Sharp/Remote.cs
index 13316590..25ef6fd7 100644
--- a/LibGit2Sharp/Remote.cs
+++ b/LibGit2Sharp/Remote.cs
@@ -60,12 +60,14 @@ namespace LibGit2Sharp
/// <param name="onUpdateTips">UpdateTips callback. Corresponds to libgit2 update_tips callback.</param>
/// <param name="onTransferProgress">Callback method that transfer progress will be reported through.
/// Reports the client's state regarding the received and processed (bytes, objects) from the server.</param>
+ /// <param name="credentials">Credentials to use for username/password authentication.</param>
public virtual void Fetch(
TagFetchMode tagFetchMode = TagFetchMode.Auto,
ProgressHandler onProgress = null,
CompletionHandler onCompletion = null,
UpdateTipsHandler onUpdateTips = null,
- TransferProgressHandler onTransferProgress = null)
+ TransferProgressHandler onTransferProgress = null,
+ Credentials credentials = null)
{
using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, this.Name, true))
{
@@ -74,6 +76,18 @@ namespace LibGit2Sharp
Proxy.git_remote_set_autotag(remoteHandle, tagFetchMode);
+ // Username/password auth
+ if (credentials != null)
+ {
+ Proxy.git_remote_set_cred_acquire_cb(
+ remoteHandle,
+ (out IntPtr cred, IntPtr url, uint types, IntPtr payload) =>
+ NativeMethods.git_cred_userpass_plaintext_new(out cred,
+ credentials.Username,
+ credentials.Password),
+ IntPtr.Zero);
+ }
+
// It is OK to pass the reference to the GitCallbacks directly here because libgit2 makes a copy of
// the data in the git_remote_callbacks structure. If, in the future, libgit2 changes its implementation
// to store a reference to the git_remote_callbacks structure this would introduce a subtle bug
diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs
index 40acadb5..3b9fa492 100644
--- a/LibGit2Sharp/Repository.cs
+++ b/LibGit2Sharp/Repository.cs
@@ -440,24 +440,37 @@ namespace LibGit2Sharp
/// <param name="onTransferProgress">Handler for network transfer and indexing progress information</param>
/// <param name="onCheckoutProgress">Handler for checkout progress information</param>
/// <param name="options">Overrides to the way a repository is opened.</param>
+ /// <param name="credentials">Credentials to use for user/pass authentication</param>
/// <returns></returns>
public static Repository Clone(string sourceUrl, string workdirPath,
bool bare = false,
bool checkout = true,
TransferProgressHandler onTransferProgress = null,
CheckoutProgressHandler onCheckoutProgress = null,
- RepositoryOptions options = null)
+ RepositoryOptions options = null,
+ Credentials credentials = null)
{
var cloneOpts = new GitCloneOptions
- {
- Bare = bare ? 1 : 0,
- TransferProgressCallback = TransferCallbacks.GenerateCallback(onTransferProgress),
- };
- cloneOpts.CheckoutOpts.version = 1;
- cloneOpts.CheckoutOpts.progress_cb = CheckoutCallbacks.GenerateCheckoutCallbacks(onCheckoutProgress);
- cloneOpts.CheckoutOpts.checkout_strategy = checkout
- ? CheckoutStrategy.GIT_CHECKOUT_SAFE_CREATE
- : CheckoutStrategy.GIT_CHECKOUT_NONE;
+ {
+ Bare = bare ? 1 : 0,
+ TransferProgressCallback = TransferCallbacks.GenerateCallback(onTransferProgress),
+ CheckoutOpts =
+ {
+ version = 1,
+ progress_cb =
+ CheckoutCallbacks.GenerateCheckoutCallbacks(onCheckoutProgress),
+ checkout_strategy = checkout
+ ? CheckoutStrategy.GIT_CHECKOUT_SAFE_CREATE
+ : CheckoutStrategy.GIT_CHECKOUT_NONE
+ },
+ };
+
+ if (credentials != null)
+ {
+ cloneOpts.CredAcquireCallback =
+ (out IntPtr cred, IntPtr url, uint types, IntPtr payload) =>
+ NativeMethods.git_cred_userpass_plaintext_new(out cred, credentials.Username, credentials.Password);
+ }
using(Proxy.git_clone(sourceUrl, workdirPath, cloneOpts)) {}
return new Repository(workdirPath, options);