1
0
Форкнуть 0

authentication: Add base class to all types.

All non-static classes now inherit from the base type `Base` which will enable service-provider like functionality.
This commit is contained in:
J Wyman ∞ 2018-03-05 17:42:10 -05:00
Родитель f68181beae
Коммит 602a623f09
25 изменённых файлов: 194 добавлений и 123 удалений

Просмотреть файл

@ -14,7 +14,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
public void VerifyBitbucketOrgIsIdentified()
{
var targetUri = new TargetUri("https://bitbucket.org");
var bbAuth = Authentication.GetAuthentication(targetUri, new MockCredentialStore(), null, null);
var bbAuth = Authentication.GetAuthentication(RuntimeContext.Default, targetUri, new MockCredentialStore(), null, null);
Assert.NotNull(bbAuth);
}
@ -23,7 +23,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
public void VerifyNonBitbucketOrgIsIgnored()
{
var targetUri = new TargetUri("https://example.com");
var bbAuth = Authentication.GetAuthentication(targetUri, new MockCredentialStore(), null, null);
var bbAuth = Authentication.GetAuthentication(RuntimeContext.Default, targetUri, new MockCredentialStore(), null, null);
Assert.Null(bbAuth);
}
@ -34,7 +34,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
var targetUri = new TargetUri("https://example.com");
var credentialStore = new MockCredentialStore();
var credentials = new Credential("a", "b");
var bbAuth = new Authentication(credentialStore, null, null);
var bbAuth = new Authentication(RuntimeContext.Default, credentialStore, null, null);
try
{
@ -67,7 +67,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
{
var credentialStore = new MockCredentialStore();
var credentials = new Credential("a", "b");
var bbAuth = new Authentication(credentialStore, null, null);
var bbAuth = new Authentication(RuntimeContext.Default, credentialStore, null, null);
await bbAuth.SetCredentials(null, credentials);
}).Wait();
@ -91,7 +91,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
{
var targetUri = new TargetUri("https://example.com");
var credentialStore = new MockCredentialStore();
var bbAuth = new Authentication(credentialStore, null, null);
var bbAuth = new Authentication(RuntimeContext.Default, credentialStore, null, null);
await bbAuth.SetCredentials(targetUri, null);
}).Wait();
@ -116,7 +116,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
var targetUri = new TargetUri("https://example.com");
var credentialStore = new MockCredentialStore();
var credentials = new Credential("a", new string('x', 2047 + 1));
var bbAuth = new Authentication(credentialStore, null, null);
var bbAuth = new Authentication(RuntimeContext.Default, credentialStore, null, null);
await bbAuth.SetCredentials(targetUri, credentials);
}).Wait();
@ -141,7 +141,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
var targetUri = new TargetUri("https://example.com");
var credentialStore = new MockCredentialStore();
var credentials = new Credential(new string('x', 2047 + 1), "b");
var bbAuth = new Authentication(credentialStore, null, null);
var bbAuth = new Authentication(RuntimeContext.Default, credentialStore, null, null);
await bbAuth.SetCredentials(targetUri, credentials);
}).Wait();
@ -164,7 +164,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
Task.Run(async () =>
{
var credentialStore = new MockCredentialStore();
var bbAuth = new Authentication(credentialStore, null, null);
var bbAuth = new Authentication(RuntimeContext.Default, credentialStore, null, null);
await bbAuth.DeleteCredentials(null);
@ -190,7 +190,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
// Add a stored basic authentication credential to delete.
credentialStore.Credentials.Add("https://example.com/", new Credential("john", "squire"));
var bbAuth = new Authentication(credentialStore, null, null);
var bbAuth = new Authentication(RuntimeContext.Default, credentialStore, null, null);
var targetUri = new TargetUri("https://example.com/");
bbAuth.DeleteCredentials(targetUri);
@ -222,7 +222,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
credentialStore.Credentials.Add("https://example.com/", new Credential("john", "a1b2c3"));
credentialStore.Credentials.Add("https://example.com/refresh_token", new Credential("john", "d4e5f6"));
var bbAuth = new Authentication(credentialStore, null, null);
var bbAuth = new Authentication(RuntimeContext.Default, credentialStore, null, null);
var targetUri = new TargetUri("https://example.com/");
bbAuth.DeleteCredentials(targetUri);
@ -256,7 +256,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
// per user credentials
credentialStore.Credentials.Add("https://john@example.com/", new Credential("john", "squire"));
var bbAuth = new Authentication(credentialStore, null, null);
var bbAuth = new Authentication(RuntimeContext.Default, credentialStore, null, null);
var targetUri = new TargetUri("https://john@example.com/");
bbAuth.DeleteCredentials(targetUri);
@ -300,7 +300,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
// per user credentials
credentialStore.Credentials.Add("https://john@example.com/", new Credential("john", "squire"));
var bbAuth = new Authentication(credentialStore, null, null);
var bbAuth = new Authentication(RuntimeContext.Default, credentialStore, null, null);
var targetUri = new TargetUri("https://john@example.com/");
bbAuth.DeleteCredentials(targetUri);
@ -335,7 +335,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
public void VerifyGetPerUserTargetUriInsertsMissingUsernameToActualUri()
{
var credentialStore = new MockCredentialStore();
var bbAuth = new Authentication(credentialStore, null, null);
var bbAuth = new Authentication(RuntimeContext.Default, credentialStore, null, null);
var targetUri = new TargetUri("https://example.com");
var username = "johnsquire";
@ -360,7 +360,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
public void VerifyGetPerUserTargetUriFormatsEmailUsernames()
{
var credentialStore = new MockCredentialStore();
var bbAuth = new Authentication(credentialStore, null, null);
var bbAuth = new Authentication(RuntimeContext.Default, credentialStore, null, null);
var targetUri = new TargetUri("https://example.com");
var username = "johnsquire@stoneroses.com";
@ -384,7 +384,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
public void VerifyGetPerUserTargetUriDoesNotDuplicateUsernameOnActualUri()
{
var credentialStore = new MockCredentialStore();
var bbAuth = new Authentication(credentialStore, null, null);
var bbAuth = new Authentication(RuntimeContext.Default, credentialStore, null, null);
var targetUri = new TargetUri("https://johnsquire@example.com");
var username = "johnsquire";

Просмотреть файл

@ -16,7 +16,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
public async Task BitbucketAuthDeleteCredentialsTest()
{
var targetUri = new TargetUri("http://localhost");
var bitbucketAuth = GetBitbucketAuthentication("Bitbucket-delete");
var bitbucketAuth = GetBitbucketAuthentication(RuntimeContext.Default, "Bitbucket-delete");
await bitbucketAuth.PersonalAccessTokenStore.WriteCredentials(targetUri, new Credential("username", "password"));
@ -32,7 +32,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
public async Task BitbucketAuthGetCredentialsTest()
{
var targetUri = new TargetUri("http://localhost");
var bitbucketAuth = GetBitbucketAuthentication("Bitbucket-get");
var bitbucketAuth = GetBitbucketAuthentication(RuntimeContext.Default, "Bitbucket-get");
Credential credentials = null;
@ -51,7 +51,7 @@ namespace Atlassian.Bitbucket.Authentication.Test
public async Task BitbucketAuthSetCredentialsTest()
{
var targetUri = new TargetUri("http://localhost");
var bitbucketAuth = GetBitbucketAuthentication("Bitbucket-set");
var bitbucketAuth = GetBitbucketAuthentication(RuntimeContext.Default, "Bitbucket-set");
Credential credentials = null;
@ -79,11 +79,11 @@ namespace Atlassian.Bitbucket.Authentication.Test
Assert.NotNull(credentials = await bitbucketAuth.GetCredentials(targetUri));
}
private Authentication GetBitbucketAuthentication(string @namespace)
private Authentication GetBitbucketAuthentication(RuntimeContext context, string @namespace)
{
ICredentialStore credentialStore = new SecretCache(@namespace);
ICredentialStore credentialStore = new SecretCache(context, @namespace);
return new Authentication(credentialStore, null, null);
return new Authentication(context, credentialStore, null, null);
}
}
}

Просмотреть файл

@ -39,6 +39,7 @@ namespace Atlassian.Bitbucket.Authentication
public class Authentication : BaseAuthentication, IAuthentication
{
public const string BitbucketBaseUrlHost = "bitbucket.org";
private const string RefreshTokenSuffix = "/refresh_token";
/// <summary>
/// Default constructor
@ -50,7 +51,12 @@ namespace Atlassian.Bitbucket.Authentication
/// <param name="acquireAuthenticationOAuthCallback">
/// what to call to prompt the user to run the OAuth process
/// </param>
public Authentication(ICredentialStore personalAccessTokenStore, AcquireCredentialsDelegate acquireCredentialsCallback, AcquireAuthenticationOAuthDelegate acquireAuthenticationOAuthCallback)
public Authentication(
RuntimeContext context,
ICredentialStore personalAccessTokenStore,
AcquireCredentialsDelegate acquireCredentialsCallback,
AcquireAuthenticationOAuthDelegate acquireAuthenticationOAuthCallback)
: base(context)
{
if (personalAccessTokenStore == null)
throw new ArgumentNullException(nameof(personalAccessTokenStore), $"The parameter `{nameof(personalAccessTokenStore)}` is null or invalid.");
@ -77,8 +83,6 @@ namespace Atlassian.Bitbucket.Authentication
internal AuthenticationResultDelegate AuthenticationResultCallback { get; set; }
private const string refreshTokenSuffix = "/refresh_token";
/// <summary>
/// Deletes a `<see cref="Credential"/>` from the storage used by the authentication object.
/// </summary>
@ -139,7 +143,7 @@ namespace Atlassian.Bitbucket.Authentication
/// <returns></returns>
private static TargetUri GetRefreshTokenTargetUri(TargetUri targetUri)
{
var uri = new Uri(targetUri.QueryUri, refreshTokenSuffix);
var uri = new Uri(targetUri.QueryUri, RefreshTokenSuffix);
return new TargetUri(uri);
}
@ -280,7 +284,12 @@ namespace Atlassian.Bitbucket.Authentication
/// Returns a `<see cref="BaseAuthentication"/>` instance if the `<paramref name="targetUri"/>` represents Bitbucket; otherwise `<see langword=""="null"/>`.
/// </summary>
/// <param name="targetUri"></param>
public static BaseAuthentication GetAuthentication(TargetUri targetUri, ICredentialStore personalAccessTokenStore, AcquireCredentialsDelegate acquireCredentialsCallback, AcquireAuthenticationOAuthDelegate acquireAuthenticationOAuthCallback)
public static BaseAuthentication GetAuthentication(
RuntimeContext context,
TargetUri targetUri,
ICredentialStore personalAccessTokenStore,
AcquireCredentialsDelegate acquireCredentialsCallback,
AcquireAuthenticationOAuthDelegate acquireAuthenticationOAuthCallback)
{
BaseAuthentication authentication = null;
@ -291,7 +300,7 @@ namespace Atlassian.Bitbucket.Authentication
if (targetUri.QueryUri.DnsSafeHost.EndsWith(BitbucketBaseUrlHost, StringComparison.OrdinalIgnoreCase))
{
authentication = new Authentication(personalAccessTokenStore, acquireCredentialsCallback, acquireAuthenticationOAuthCallback);
authentication = new Authentication(context, personalAccessTokenStore, acquireCredentialsCallback, acquireAuthenticationOAuthCallback);
Trace.WriteLine("authentication for Bitbucket created");
}
else

Просмотреть файл

@ -47,8 +47,13 @@ namespace Microsoft.Alm.Cli
private static readonly Regex AskPasswordRegex = new Regex(@"(\S+)'s\s+password:\s*", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
private static readonly Regex AskAuthenticityRegex = new Regex(@"^\s*The authenticity of host '([^']+)' can't be established.\s+RSA key fingerprint is ([^\s:]+:[^\.]+).", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
internal Program()
internal Program(Microsoft.Alm.Authentication.RuntimeContext context)
{
if (context is null)
throw new ArgumentNullException(nameof(context));
_context = context;
Title = AssemblyTitle;
}
@ -320,7 +325,7 @@ namespace Microsoft.Alm.Cli
[STAThread]
private static void Main(string[] args)
{
Program program = new Program();
Program program = new Program(RuntimeContext.Default);
program.Run(args);
}

Просмотреть файл

@ -37,8 +37,8 @@ namespace Microsoft.Alm.CredentialHelper.Test
{
const string Namespace = "test";
var credentialCache = new SecretCache(Namespace);
var basicAuthentication = new BasicAuthentication(credentialCache);
var credentialCache = new SecretCache(RuntimeContext.Default, Namespace);
var basicAuthentication = new BasicAuthentication(RuntimeContext.Default, credentialCache);
var targetUri = new Uri("https://username@domain.not");
var credentials = new Credential("real", "pass");

Просмотреть файл

@ -26,6 +26,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Alm.Authentication;
using Moq;
using Xunit;
@ -38,7 +39,7 @@ namespace Microsoft.Alm.Cli.Test
[Fact]
public async Task LoadOperationArgumentsTest()
{
var program = new Program
var program = new Program(RuntimeContext.Default)
{
_dieException = (Program caller, Exception e, string path, int line, string name) => Assert.False(true, $"Error: {e.ToString()}"),
_dieMessage = (Program caller, string m, string path, int line, string name) => Assert.False(true, $"Error: {m}"),
@ -160,7 +161,7 @@ namespace Microsoft.Alm.Cli.Test
bool? yesno;
KeyType key = (KeyType)keyValue;
var program = new Program
var program = new Program(RuntimeContext.Default)
{
_dieException = (Program caller, Exception e, string path, int line, string name) => Assert.False(true, $"Error: {e.ToString()}"),
_dieMessage = (Program caller, string m, string path, int line, string name) => Assert.False(true, $"Error: {m}"),
@ -254,7 +255,7 @@ namespace Microsoft.Alm.Cli.Test
{
KeyType key = (KeyType)keyValue;
var program = new Program
var program = new Program(RuntimeContext.Default)
{
_dieException = (Program caller, Exception e, string path, int line, string name) => Assert.False(true, $"Error: {e.ToString()}"),
_dieMessage = (Program caller, string m, string path, int line, string name) => Assert.False(true, $"Error: {m}"),

Просмотреть файл

@ -74,8 +74,13 @@ namespace Microsoft.Alm.Cli
CommandVersion
};
internal Program()
internal Program(RuntimeContext context)
{
if (context is null)
throw new ArgumentNullException(nameof(context));
_context = context;
Title = AssemblyTitle;
}
@ -443,7 +448,7 @@ namespace Microsoft.Alm.Cli
[STAThread]
private static void Main(string[] args)
{
var program = new Program();
var program = new Program(RuntimeContext.Default);
program.Run(args);
}

Просмотреть файл

@ -29,7 +29,6 @@ using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Alm.Authentication;
using Microsoft.Alm.Authentication.Git;
using Bitbucket = Atlassian.Bitbucket.Authentication;
using Git = Microsoft.Alm.Authentication.Git;
using Github = GitHub.Authentication;
@ -81,17 +80,20 @@ namespace Microsoft.Alm.Cli
Git.Trace.WriteLine($"detecting authority type for '{operationArguments.TargetUri}'.");
// Detect the authority.
authority = await BaseVstsAuthentication.GetAuthentication(operationArguments.TargetUri,
authority = await BaseVstsAuthentication.GetAuthentication(program.Context,
operationArguments.TargetUri,
Program.VstsCredentialScope,
new SecretStore(secretsNamespace, BaseVstsAuthentication.UriNameConversion))
?? Github.Authentication.GetAuthentication(operationArguments.TargetUri,
new SecretStore(program.Context, secretsNamespace, BaseVstsAuthentication.UriNameConversion))
?? Github.Authentication.GetAuthentication(program.Context,
operationArguments.TargetUri,
Program.GitHubCredentialScope,
new SecretStore(secretsNamespace, Secret.UriToName),
new SecretStore(program.Context, secretsNamespace, Secret.UriToName),
githubCredentialCallback,
githubAuthcodeCallback,
null)
?? Bitbucket.Authentication.GetAuthentication(operationArguments.TargetUri,
new SecretStore(secretsNamespace, Secret.UriToIdentityUrl),
?? Bitbucket.Authentication.GetAuthentication(program.Context,
operationArguments.TargetUri,
new SecretStore(program.Context, secretsNamespace, Secret.UriToIdentityUrl),
bitbucketCredentialCallback,
bitbucketOauthCallback);
@ -135,9 +137,10 @@ namespace Microsoft.Alm.Cli
}
// Return the allocated authority or a generic AAD backed VSTS authentication object.
return authority ?? new VstsAadAuthentication(tenantId,
return authority ?? new VstsAadAuthentication(program.Context,
tenantId,
operationArguments.VstsTokenScope,
new SecretStore(secretsNamespace, VstsAadAuthentication.UriNameConversion));
new SecretStore(program.Context, secretsNamespace, VstsAadAuthentication.UriNameConversion));
case AuthorityType.Basic:
// Enforce basic authentication only.
@ -148,9 +151,10 @@ namespace Microsoft.Alm.Cli
Git.Trace.WriteLine($"authority for '{operationArguments.TargetUri}' is GitHub.");
// Return a GitHub authentication object.
return authority ?? new Github.Authentication(operationArguments.TargetUri,
return authority ?? new Github.Authentication(program.Context,
operationArguments.TargetUri,
Program.GitHubCredentialScope,
new SecretStore(secretsNamespace, Secret.UriToName),
new SecretStore(program.Context, secretsNamespace, Secret.UriToName),
githubCredentialCallback,
githubAuthcodeCallback,
null);
@ -159,7 +163,8 @@ namespace Microsoft.Alm.Cli
Git.Trace.WriteLine($"authority for '{operationArguments.TargetUri}' is Bitbucket");
// Return a Bitbucket authentication object.
return authority ?? new Bitbucket.Authentication(new SecretStore(secretsNamespace, Secret.UriToIdentityUrl),
return authority ?? new Bitbucket.Authentication(program.Context,
new SecretStore(program.Context, secretsNamespace, Secret.UriToIdentityUrl),
bitbucketCredentialCallback,
bitbucketOauthCallback);
@ -167,8 +172,9 @@ namespace Microsoft.Alm.Cli
Git.Trace.WriteLine($"authority for '{operationArguments.TargetUri}' is Microsoft Live.");
// Return the allocated authority or a generic MSA backed VSTS authentication object.
return authority ?? new VstsMsaAuthentication(operationArguments.VstsTokenScope,
new SecretStore(secretsNamespace, VstsMsaAuthentication.UriNameConversion));
return authority ?? new VstsMsaAuthentication(program.Context,
operationArguments.VstsTokenScope,
new SecretStore(program.Context, secretsNamespace, VstsMsaAuthentication.UriNameConversion));
case AuthorityType.Ntlm:
// Enforce NTLM authentication only.
@ -179,7 +185,8 @@ namespace Microsoft.Alm.Cli
Git.Trace.WriteLine($"authority for '{operationArguments.TargetUri}' is basic with NTLM={basicNtlmSupport}.");
// Return a generic username + password authentication object.
return authority ?? new BasicAuthentication(new SecretStore(secretsNamespace, Secret.UriToIdentityUrl),
return authority ?? new BasicAuthentication(program.Context,
new SecretStore(program.Context, secretsNamespace, Secret.UriToIdentityUrl),
basicNtlmSupport,
basicCredentialCallback,
null);
@ -267,7 +274,7 @@ namespace Microsoft.Alm.Cli
Git.Trace.WriteLine("trace logging enabled.");
string gitConfigPath;
if (Where.GitLocalConfig(out gitConfigPath))
if (Git.Where.GitLocalConfig(out gitConfigPath))
{
Git.Trace.WriteLine($"git local config found at '{gitConfigPath}'.");
@ -278,7 +285,7 @@ namespace Microsoft.Alm.Cli
program.EnableTraceLogging(operationArguments, gitDirPath);
}
}
else if (Where.GitGlobalConfig(out gitConfigPath))
else if (Git.Where.GitGlobalConfig(out gitConfigPath))
{
Git.Trace.WriteLine($"git global config found at '{gitConfigPath}'.");
@ -522,7 +529,7 @@ namespace Microsoft.Alm.Cli
// Check the git-config http.proxy setting just-in-case.
else
{
Configuration.Entry entry;
Git.Configuration.Entry entry;
if (operationArguments.GitConfiguration.TryGetEntry("http", operationArguments.QueryUri, "proxy", out entry)
&& !string.IsNullOrWhiteSpace(entry.Value))
{
@ -834,7 +841,7 @@ namespace Microsoft.Alm.Cli
var config = operationArguments.GitConfiguration;
// Look for an entry in the git config.
Configuration.Entry entry;
Git.Configuration.Entry entry;
if (!string.IsNullOrWhiteSpace(configKey)
&& config.TryGetEntry(Program.ConfigPrefix, operationArguments.QueryUri, configKey, out entry))
{
@ -897,10 +904,10 @@ namespace Microsoft.Alm.Cli
return true;
}
Configuration config = operationArguments.GitConfiguration;
Git.Configuration config = operationArguments.GitConfiguration;
// Look for an entry in the git config.
Configuration.Entry entry;
Git.Configuration.Entry entry;
if (!string.IsNullOrWhiteSpace(configKey)
&& config.TryGetEntry(Program.ConfigPrefix, operationArguments.QueryUri, configKey, out entry)
&& !string.IsNullOrWhiteSpace(entry.Value))

Просмотреть файл

@ -156,6 +156,7 @@ namespace Microsoft.Alm.Cli
}
private string _executablePath;
private readonly RuntimeContext _context;
private string _location;
private string _name;
private Stream _stdErrStream;
@ -276,6 +277,9 @@ namespace Microsoft.Alm.Cli
}
}
internal RuntimeContext Context
=> _context;
internal TextWriter Error
{
get

Просмотреть файл

@ -18,6 +18,7 @@ namespace GitHub.Authentication.Test
var credentialStore = new InMemoryCredentialStore();
var authentication = new Authentication(
RuntimeContext.Default,
new Uri(writeUriString),
TokenScope.Gist,
credentialStore,
@ -37,6 +38,7 @@ namespace GitHub.Authentication.Test
var credentialStore = new InMemoryCredentialStore();
var authentication = new Authentication(
RuntimeContext.Default,
new Uri("https://github.com/"),
TokenScope.Gist,
credentialStore,

Просмотреть файл

@ -50,12 +50,14 @@ namespace GitHub.Authentication
/// A secure secret store for any personal access tokens acquired.
/// </param>
public Authentication(
RuntimeContext context,
TargetUri targetUri,
TokenScope tokenScope,
ICredentialStore personalAccessTokenStore,
AcquireCredentialsDelegate acquireCredentialsCallback,
AcquireAuthenticationCodeDelegate acquireAuthenticationCodeCallback,
AuthenticationResultDelegate authenticationResultCallback)
: base(context)
{
TokenScope = tokenScope
?? throw new ArgumentNullException("tokenScope", "The parameter `tokenScope` is null or invalid.");
@ -76,9 +78,13 @@ namespace GitHub.Authentication
public readonly TokenScope TokenScope;
internal IAuthority Authority { get; set; }
internal ICredentialStore PersonalAccessTokenStore { get; set; }
internal AcquireCredentialsDelegate AcquireCredentialsCallback { get; set; }
internal AcquireAuthenticationCodeDelegate AcquireAuthenticationCodeCallback { get; set; }
internal AuthenticationResultDelegate AuthenticationResultCallback { get; set; }
/// <summary>
@ -114,6 +120,7 @@ namespace GitHub.Authentication
/// <param name="authentication">(out) The authentication object if successful.</param>
/// <returns>True if success; otherwise false.</returns>
public static BaseAuthentication GetAuthentication(
RuntimeContext context,
TargetUri targetUri,
TokenScope tokenScope,
ICredentialStore personalAccessTokenStore,
@ -130,7 +137,13 @@ namespace GitHub.Authentication
if (targetUri.DnsSafeHost.EndsWith(GitHubBaseUrlHost, StringComparison.OrdinalIgnoreCase))
{
var normalizedTargetUri = NormalizeUri(targetUri);
authentication = new Authentication(normalizedTargetUri, tokenScope, personalAccessTokenStore, acquireCredentialsCallback, acquireAuthenticationCodeCallback, authenticationResultCallback);
authentication = new Authentication(context,
normalizedTargetUri,
tokenScope,
personalAccessTokenStore,
acquireCredentialsCallback,
acquireAuthenticationCodeCallback,
authenticationResultCallback);
Git.Trace.WriteLine($"created GitHub authentication for '{normalizedTargetUri}'.");
}
else

Просмотреть файл

@ -15,7 +15,7 @@ namespace Microsoft.Alm.Authentication.Test
public async Task BasicAuthDeleteCredentialsTest()
{
TargetUri targetUri = new TargetUri("http://localhost");
BasicAuthentication basicAuth = GetBasicAuthentication("basic-delete");
BasicAuthentication basicAuth = GetBasicAuthentication(RuntimeContext.Default, "basic-delete");
await basicAuth.CredentialStore.WriteCredentials(targetUri, new Credential("username", "password"));
@ -28,7 +28,7 @@ namespace Microsoft.Alm.Authentication.Test
public async Task BasicAuthGetCredentialsTest()
{
TargetUri targetUri = new TargetUri("http://localhost");
BasicAuthentication basicAuth = GetBasicAuthentication("basic-get");
BasicAuthentication basicAuth = GetBasicAuthentication(RuntimeContext.Default, "basic-get");
Credential credentials = null;
@ -45,7 +45,7 @@ namespace Microsoft.Alm.Authentication.Test
public async Task BasicAuthSetCredentialsTest()
{
TargetUri targetUri = new TargetUri("http://localhost");
BasicAuthentication basicAuth = GetBasicAuthentication("basic-set");
BasicAuthentication basicAuth = GetBasicAuthentication(RuntimeContext.Default, "basic-set");
Credential credentials = null;
@ -70,11 +70,11 @@ namespace Microsoft.Alm.Authentication.Test
Assert.NotNull(credentials = await basicAuth.GetCredentials(targetUri));
}
private BasicAuthentication GetBasicAuthentication(string @namespace)
private BasicAuthentication GetBasicAuthentication(RuntimeContext context, string @namespace)
{
ICredentialStore credentialStore = new SecretCache(@namespace);
ICredentialStore credentialStore = new SecretCache(context, @namespace);
return new BasicAuthentication(credentialStore, NtlmSupport.Auto, null, null);
return new BasicAuthentication(context, credentialStore, NtlmSupport.Auto, null, null);
}
}
}

Просмотреть файл

@ -47,8 +47,8 @@ namespace Microsoft.Alm.Authentication.Test
var uri = new TargetUri(url);
var writeCreds = new Credential(username, password);
var credentialStore = useCache
? new SecretCache("test", Secret.UriToName) as ICredentialStore
: new SecretStore("test", null, null, Secret.UriToName) as ICredentialStore;
? new SecretCache(RuntimeContext.Default, "test", Secret.UriToName) as ICredentialStore
: new SecretStore(RuntimeContext.Default, "test", null, null, Secret.UriToName) as ICredentialStore;
Credential readCreds = null;
await credentialStore.WriteCredentials(uri, writeCreds);

Просмотреть файл

@ -35,8 +35,8 @@ namespace Microsoft.Alm.Authentication.Test
public async Task Token_WriteDelete(bool useCache, string secretName, string url, string token)
{
var tokenStore = useCache
? new SecretCache(secretName) as ITokenStore
: new SecretStore(secretName) as ITokenStore;
? new SecretCache(RuntimeContext.Default, secretName) as ITokenStore
: new SecretStore(RuntimeContext.Default, secretName) as ITokenStore;
var uri = new TargetUri(url);
var writeToken = new Token(token, TokenType.Test);

Просмотреть файл

@ -30,8 +30,12 @@ namespace Microsoft.Alm.Authentication
/// <summary>
/// Base authentication mechanisms for setting, retrieving, and deleting stored credentials.
/// </summary>
public abstract class BaseAuthentication : IAuthentication
public abstract class BaseAuthentication : Base, IAuthentication
{
protected BaseAuthentication(RuntimeContext context)
: base(context)
{ }
/// <summary>
/// Deletes a `<see cref="Credential"/>` from the storage used by the authentication object.
/// </summary>

Просмотреть файл

@ -31,10 +31,14 @@ using System.Text;
namespace Microsoft.Alm.Authentication
{
public abstract class BaseSecureStore
public abstract class BaseSecureStore: Base
{
public static readonly char[] IllegalCharacters = new[] { ':', ';', '\\', '?', '@', '=', '&', '%', '$' };
protected BaseSecureStore(RuntimeContext context)
: base(context)
{ }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
protected bool Delete(string targetName)
{

Просмотреть файл

@ -49,10 +49,12 @@ namespace Microsoft.Alm.Authentication
/// <param name="acquireCredentialsCallback">(optional) delegate for acquiring credentials.</param>
/// <param name="acquireResultCallback">Optional delegate for notification of acquisition results.</param>
public BasicAuthentication(
RuntimeContext context,
ICredentialStore credentialStore,
NtlmSupport ntlmSupport,
AcquireCredentialsDelegate acquireCredentialsCallback,
AcquireResultDelegate acquireResultCallback)
: base(context)
{
if (credentialStore == null)
throw new ArgumentNullException(nameof(credentialStore));
@ -63,10 +65,16 @@ namespace Microsoft.Alm.Authentication
_ntlmSupport = ntlmSupport;
}
public BasicAuthentication(ICredentialStore credentialStore)
: this(credentialStore, NtlmSupport.Auto, null, null)
public BasicAuthentication(RuntimeContext context, ICredentialStore credentialStore)
: this(context, credentialStore, NtlmSupport.Auto, null, null)
{ }
private readonly AcquireCredentialsDelegate _acquireCredentials;
private readonly AcquireResultDelegate _acquireResult;
private readonly ICredentialStore _credentialStore;
private AuthenticationHeaderValue[] _httpAuthenticateOptions;
private NtlmSupport _ntlmSupport;
/// <summary>
/// Gets the underlying credential store for this instance of `<see cref="BasicAuthentication"/>`.
/// </summary>
@ -83,12 +91,6 @@ namespace Microsoft.Alm.Authentication
get { return _ntlmSupport; }
}
private readonly AcquireCredentialsDelegate _acquireCredentials;
private readonly AcquireResultDelegate _acquireResult;
private readonly ICredentialStore _credentialStore;
private AuthenticationHeaderValue[] _httpAuthenticateOptions;
private NtlmSupport _ntlmSupport;
/// <summary>
/// Acquires credentials via the registered callbacks.
/// <para/>

Просмотреть файл

@ -71,7 +71,7 @@ namespace Microsoft.Alm.Authentication
/// </summary>
/// <param name="obj">The object to compare.</param>
/// <returns><see langword="true"/> if equal; <see langword="false"/> otherwise.</returns>
public override bool Equals(Object obj)
public override bool Equals(object obj)
{
return this == obj as Credential;
}
@ -90,7 +90,7 @@ namespace Microsoft.Alm.Authentication
/// Gets a hash code based on the contents of the <see cref="Credential"/>.
/// </summary>
/// <returns>32-bit hash code.</returns>
public override Int32 GetHashCode()
public override int GetHashCode()
{
unchecked
{

Просмотреть файл

@ -29,13 +29,13 @@ using System.Threading.Tasks;
namespace Microsoft.Alm.Authentication
{
public sealed class SecretCache : ICredentialStore, ITokenStore
public sealed class SecretCache : Base, ICredentialStore, ITokenStore
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly StringComparer KeyComparer = StringComparer.OrdinalIgnoreCase;
public SecretCache(string @namespace, Secret.UriNameConversionDelegate getTargetName)
: this()
public SecretCache(RuntimeContext context, string @namespace, Secret.UriNameConversionDelegate getTargetName)
: this(context)
{
if (string.IsNullOrWhiteSpace(@namespace))
throw new ArgumentNullException(@namespace);
@ -44,12 +44,12 @@ namespace Microsoft.Alm.Authentication
_getTargetName = getTargetName ?? Secret.UriToName;
}
public SecretCache(string @namespace)
: this(@namespace, null)
public SecretCache(RuntimeContext context, string @namespace)
: this(context, @namespace, null)
{ }
internal SecretCache(ICredentialStore credentialStore)
: this()
internal SecretCache(RuntimeContext context, ICredentialStore credentialStore)
: this(context)
{
if (credentialStore == null)
throw new ArgumentNullException(nameof(credentialStore));
@ -58,7 +58,8 @@ namespace Microsoft.Alm.Authentication
_getTargetName = credentialStore.UriNameConversion;
}
private SecretCache()
private SecretCache(RuntimeContext context)
: base(context)
{
_cache = new Dictionary<string, Secret>(KeyComparer);
}

Просмотреть файл

@ -47,7 +47,13 @@ namespace Microsoft.Alm.Authentication
/// <param name="getTargetName">
/// Delegate used to transform a `<see cref="TargetUri"/>` into a store lookup key.
/// </param>
public SecretStore(string @namespace, ICredentialStore credentialCache, ITokenStore tokenCache, Secret.UriNameConversionDelegate getTargetName)
public SecretStore(
RuntimeContext context,
string @namespace,
ICredentialStore credentialCache,
ITokenStore tokenCache,
Secret.UriNameConversionDelegate getTargetName)
: base(context)
{
if (string.IsNullOrWhiteSpace(@namespace))
throw new ArgumentNullException(nameof(@namespace));
@ -57,16 +63,16 @@ namespace Microsoft.Alm.Authentication
_getTargetName = getTargetName ?? Secret.UriToName;
_namespace = @namespace;
_credentialCache = credentialCache ?? new SecretCache(@namespace, _getTargetName);
_tokenCache = tokenCache ?? new SecretCache(@namespace, _getTargetName);
_credentialCache = credentialCache ?? new SecretCache(context, @namespace, _getTargetName);
_tokenCache = tokenCache ?? new SecretCache(context, @namespace, _getTargetName);
}
public SecretStore(string @namespace, Secret.UriNameConversionDelegate getTargetName)
: this(@namespace, null, null, getTargetName)
public SecretStore(RuntimeContext context, string @namespace, Secret.UriNameConversionDelegate getTargetName)
: this(context, @namespace, null, null, getTargetName)
{ }
public SecretStore(string @namespace)
: this(@namespace, null, null, null)
public SecretStore(RuntimeContext context, string @namespace)
: this(context, @namespace, null, null, null)
{ }
public string Namespace

Просмотреть файл

@ -13,7 +13,7 @@ namespace Microsoft.Alm.Authentication.Test
public async Task VstsAadDeleteCredentialsTest()
{
TargetUri targetUri = DefaultTargetUri;
VstsAadAuthentication aadAuthentication = GetVstsAadAuthentication("aad-delete");
VstsAadAuthentication aadAuthentication = GetVstsAadAuthentication(RuntimeContext.Default, "aad-delete");
if (aadAuthentication.VstsAuthority is AuthorityFake fake)
{
@ -33,7 +33,7 @@ namespace Microsoft.Alm.Authentication.Test
public async Task VstsAadGetCredentialsTest()
{
TargetUri targetUri = DefaultTargetUri;
VstsAadAuthentication aadAuthentication = GetVstsAadAuthentication("aad-get");
VstsAadAuthentication aadAuthentication = GetVstsAadAuthentication(RuntimeContext.Default, "aad-get");
Assert.Null(await aadAuthentication.GetCredentials(targetUri));
@ -46,7 +46,7 @@ namespace Microsoft.Alm.Authentication.Test
public async Task VstsAadInteractiveLogonTest()
{
TargetUri targetUri = DefaultTargetUri;
VstsAadAuthentication aadAuthentication = GetVstsAadAuthentication("aad-logon");
VstsAadAuthentication aadAuthentication = GetVstsAadAuthentication(RuntimeContext.Default, "aad-logon");
Assert.Null(await aadAuthentication.PersonalAccessTokenStore.ReadCredentials(targetUri));
@ -59,7 +59,7 @@ namespace Microsoft.Alm.Authentication.Test
public async Task VstsAadNoninteractiveLogonTest()
{
TargetUri targetUri = DefaultTargetUri;
VstsAadAuthentication aadAuthentication = GetVstsAadAuthentication("aad-noninteractive");
VstsAadAuthentication aadAuthentication = GetVstsAadAuthentication(RuntimeContext.Default, "aad-noninteractive");
Assert.NotNull(await aadAuthentication.NoninteractiveLogon(targetUri, new PersonalAccessTokenOptions { RequireCompactToken = false }));
@ -70,7 +70,7 @@ namespace Microsoft.Alm.Authentication.Test
public async Task VstsAadSetCredentialsTest()
{
TargetUri targetUri = DefaultTargetUri;
VstsAadAuthentication aadAuthentication = GetVstsAadAuthentication("aad-set");
VstsAadAuthentication aadAuthentication = GetVstsAadAuthentication(RuntimeContext.Default, "aad-set");
Credential credentials = DefaultCredentials;
await aadAuthentication.SetCredentials(targetUri, credentials);
@ -82,7 +82,7 @@ namespace Microsoft.Alm.Authentication.Test
[Fact]
public async Task VstsAadValidateCredentialsTest()
{
VstsAadAuthentication aadAuthentication = GetVstsAadAuthentication("aad-validate");
VstsAadAuthentication aadAuthentication = GetVstsAadAuthentication(RuntimeContext.Default, "aad-validate");
Credential credentials = null;
Assert.False(await aadAuthentication.ValidateCredentials(DefaultTargetUri, credentials), "Credential validation unexpectedly failed.");
@ -92,14 +92,14 @@ namespace Microsoft.Alm.Authentication.Test
Assert.True(await aadAuthentication.ValidateCredentials(DefaultTargetUri, credentials), "Credential validation unexpectedly failed.");
}
private static VstsAadAuthentication GetVstsAadAuthentication(string @namespace)
private static VstsAadAuthentication GetVstsAadAuthentication(RuntimeContext context, string @namespace)
{
string expectedQueryParameters = null;
ICredentialStore tokenStore1 = new SecretCache(@namespace + 1, Secret.UriToIdentityUrl);
ITokenStore tokenStore2 = new SecretCache(@namespace + 2, Secret.UriToIdentityUrl);
ICredentialStore tokenStore1 = new SecretCache(context, @namespace + 1, Secret.UriToIdentityUrl);
ITokenStore tokenStore2 = new SecretCache(context, @namespace + 2, Secret.UriToIdentityUrl);
IVstsAuthority vstsAuthority = new AuthorityFake(expectedQueryParameters);
return new VstsAadAuthentication(tokenStore1, tokenStore2, vstsAuthority);
return new VstsAadAuthentication(context, tokenStore1, tokenStore2, vstsAuthority);
}
}
}

Просмотреть файл

@ -13,7 +13,7 @@ namespace Microsoft.Alm.Authentication.Test
public async Task VstsMsaDeleteCredentialsTest()
{
TargetUri targetUri = DefaultTargetUri;
VstsMsaAuthentication msaAuthority = GetVstsMsaAuthentication("msa-delete");
VstsMsaAuthentication msaAuthority = GetVstsMsaAuthentication(RuntimeContext.Default, "msa-delete");
if (msaAuthority.VstsAuthority is AuthorityFake fake)
{
@ -33,7 +33,7 @@ namespace Microsoft.Alm.Authentication.Test
public async Task VstsMsaGetCredentialsTest()
{
TargetUri targetUri = DefaultTargetUri;
VstsMsaAuthentication msaAuthority = GetVstsMsaAuthentication("msa-get");
VstsMsaAuthentication msaAuthority = GetVstsMsaAuthentication(RuntimeContext.Default, "msa-get");
Assert.Null(await msaAuthority.GetCredentials(targetUri));
@ -46,7 +46,7 @@ namespace Microsoft.Alm.Authentication.Test
public async Task VstsMsaInteractiveLogonTest()
{
TargetUri targetUri = DefaultTargetUri;
VstsMsaAuthentication msaAuthority = GetVstsMsaAuthentication("msa-logon");
VstsMsaAuthentication msaAuthority = GetVstsMsaAuthentication(RuntimeContext.Default, "msa-logon");
Assert.Null(await msaAuthority.PersonalAccessTokenStore.ReadCredentials(targetUri));
@ -59,7 +59,7 @@ namespace Microsoft.Alm.Authentication.Test
public async Task VstsMsaSetCredentialsTest()
{
TargetUri targetUri = DefaultTargetUri;
VstsMsaAuthentication msaAuthority = GetVstsMsaAuthentication("msa-set");
VstsMsaAuthentication msaAuthority = GetVstsMsaAuthentication(RuntimeContext.Default, "msa-set");
await msaAuthority.SetCredentials(targetUri, DefaultCredentials);
@ -69,7 +69,7 @@ namespace Microsoft.Alm.Authentication.Test
[Fact]
public async Task VstsMsaValidateCredentialsTest()
{
VstsMsaAuthentication msaAuthority = GetVstsMsaAuthentication("msa-validate");
VstsMsaAuthentication msaAuthority = GetVstsMsaAuthentication(RuntimeContext.Default, "msa-validate");
Credential credentials = null;
Assert.False( await msaAuthority.ValidateCredentials(DefaultTargetUri, credentials), "Credential validation unexpectedly failed.");
@ -79,12 +79,12 @@ namespace Microsoft.Alm.Authentication.Test
Assert.True(await msaAuthority.ValidateCredentials(DefaultTargetUri, credentials), "Credential validation unexpectedly failed.");
}
private static VstsMsaAuthentication GetVstsMsaAuthentication(string @namespace)
private static VstsMsaAuthentication GetVstsMsaAuthentication(RuntimeContext context, string @namespace)
{
ICredentialStore tokenStore1 = new SecretCache(@namespace + 1, Secret.UriToIdentityUrl);
ITokenStore tokenStore2 = new SecretCache( @namespace + 2, Secret.UriToIdentityUrl);
ICredentialStore tokenStore1 = new SecretCache(context, @namespace + 1, Secret.UriToIdentityUrl);
ITokenStore tokenStore2 = new SecretCache(context, @namespace + 2, Secret.UriToIdentityUrl);
IVstsAuthority liveAuthority = new AuthorityFake(VstsMsaAuthentication.QueryParameters);
return new VstsMsaAuthentication(tokenStore1, tokenStore2, liveAuthority);
return new VstsMsaAuthentication(context, tokenStore1, tokenStore2, liveAuthority);
}
}
}

Просмотреть файл

@ -45,7 +45,8 @@ namespace Microsoft.Alm.Authentication
protected const string AdalRefreshPrefix = "ada";
protected BaseVstsAuthentication(VstsTokenScope tokenScope, ICredentialStore personalAccessTokenStore)
protected BaseVstsAuthentication(RuntimeContext context, VstsTokenScope tokenScope, ICredentialStore personalAccessTokenStore)
: base(context)
{
if (tokenScope is null)
throw new ArgumentNullException(nameof(tokenScope));
@ -60,10 +61,11 @@ namespace Microsoft.Alm.Authentication
}
internal BaseVstsAuthentication(
RuntimeContext context,
ICredentialStore personalAccessTokenStore,
ITokenStore vstsIdeTokenCache,
IVstsAuthority vstsAuthority)
: this(VstsTokenScope.ProfileRead, personalAccessTokenStore)
: this(context, VstsTokenScope.ProfileRead, personalAccessTokenStore)
{
if (vstsIdeTokenCache is null)
throw new ArgumentNullException(nameof(vstsIdeTokenCache));
@ -255,6 +257,7 @@ namespace Microsoft.Alm.Authentication
/// <param name="scope">The scope of the access being requested.</param>
/// <param name="personalAccessTokenStore">Storage container for personal access token secrets.</param>
public static async Task<BaseAuthentication> GetAuthentication(
RuntimeContext context,
TargetUri targetUri,
VstsTokenScope scope,
ICredentialStore personalAccessTokenStore)
@ -279,12 +282,12 @@ namespace Microsoft.Alm.Authentication
if (tenantId == Guid.Empty)
{
Git.Trace.WriteLine("MSA authority detected.");
authentication = new VstsMsaAuthentication(scope, personalAccessTokenStore);
authentication = new VstsMsaAuthentication(context, scope, personalAccessTokenStore);
}
else
{
Git.Trace.WriteLine($"AAD authority for tenant '{tenantId}' detected.");
authentication = new VstsAadAuthentication(tenantId, scope, personalAccessTokenStore);
authentication = new VstsAadAuthentication(context, tenantId, scope, personalAccessTokenStore);
(authentication as VstsAadAuthentication).TenantId = tenantId;
}

Просмотреть файл

@ -46,10 +46,11 @@ namespace Microsoft.Alm.Authentication
/// <param name="personalAccessTokenStore">The secure secret store for storing any personal access tokens acquired.</param>
/// <param name="adaRefreshTokenStore">The secure secret store for storing any Azure tokens acquired.</param>
public VstsAadAuthentication(
RuntimeContext context,
Guid tenantId,
VstsTokenScope tokenScope,
ICredentialStore personalAccessTokenStore)
: base(tokenScope, personalAccessTokenStore)
: base(context, tokenScope, personalAccessTokenStore)
{
if (tenantId == Guid.Empty)
{
@ -67,10 +68,12 @@ namespace Microsoft.Alm.Authentication
/// Test constructor which allows for using fake credential stores.
/// </summary>
internal VstsAadAuthentication(
RuntimeContext context,
ICredentialStore personalAccessTokenStore,
ITokenStore vstsIdeTokenCache,
IVstsAuthority vstsAuthority)
: base(personalAccessTokenStore,
: base(context,
personalAccessTokenStore,
vstsIdeTokenCache,
vstsAuthority)
{ }

Просмотреть файл

@ -35,8 +35,8 @@ namespace Microsoft.Alm.Authentication
public const string DefaultAuthorityHost = AzureAuthority.AuthorityHostUrlBase + "/live.com";
internal const string QueryParameters = "domain_hint=live.com&display=popup&site_id=501454&nux=1";
public VstsMsaAuthentication(VstsTokenScope tokenScope, ICredentialStore personalAccessTokenStore)
: base(tokenScope, personalAccessTokenStore)
public VstsMsaAuthentication(RuntimeContext context, VstsTokenScope tokenScope, ICredentialStore personalAccessTokenStore)
: base(context, tokenScope, personalAccessTokenStore)
{
VstsAuthority = new VstsAzureAuthority(DefaultAuthorityHost);
}
@ -49,10 +49,12 @@ namespace Microsoft.Alm.Authentication
/// <param name="vstsIdeTokenCache"></param>
/// <param name="liveAuthority"></param>
internal VstsMsaAuthentication(
RuntimeContext context,
ICredentialStore personalAccessTokenStore,
ITokenStore vstsIdeTokenCache,
IVstsAuthority liveAuthority)
: base(personalAccessTokenStore,
: base(context,
personalAccessTokenStore,
vstsIdeTokenCache,
liveAuthority)
{ }