private static BaseAuthentication CreateAuthentication(OperationArguments operationArguments) { Debug.Assert(operationArguments != null, "The operationArguments is null"); Trace.WriteLine("Program::CreateAuthentication"); var secrets = new SecretStore(SecretsNamespace); BaseAuthentication authority = null; switch (operationArguments.Authority) { case AuthorityType.Auto: Trace.WriteLine(" detecting authority type"); // detect the authority if (BaseVsoAuthentication.GetAuthentication(operationArguments.TargetUri, VsoCredentialScope, secrets, null, out authority) || GithubAuthentication.GetAuthentication(operationArguments.TargetUri, GithubCredentialScope, secrets, out authority)) { // set the authority type based on the returned value if (authority is VsoMsaAuthentication) { operationArguments.Authority = AuthorityType.MicrosoftAccount; goto case AuthorityType.MicrosoftAccount; } else if (authority is VsoAadAuthentication) { operationArguments.Authority = AuthorityType.AzureDirectory; goto case AuthorityType.AzureDirectory; } else if (authority is GithubAuthentication) { operationArguments.Authority = AuthorityType.GitHub; goto case AuthorityType.GitHub; } } operationArguments.Authority = AuthorityType.Basic; goto case AuthorityType.Basic; case AuthorityType.AzureDirectory: Trace.WriteLine(" authority is Azure Directory"); Guid tenantId = Guid.Empty; // return the allocated authority or a generic AAD backed VSO authentication object return(authority ?? new VsoAadAuthentication(Guid.Empty, VsoCredentialScope, secrets)); case AuthorityType.Basic: default: Trace.WriteLine(" authority is basic"); // return a generic username + password authentication object return(authority ?? new BasicAuthentication(secrets)); case AuthorityType.GitHub: Trace.WriteLine(" authority it GitHub"); // return a GitHub authenitcation object return(authority ?? new GithubAuthentication(GithubCredentialScope, secrets)); case AuthorityType.MicrosoftAccount: Trace.WriteLine(" authority is Microsoft Live"); // return the allocated authority or a generic MSA backed VSO authentication object return(authority ?? new VsoMsaAuthentication(VsoCredentialScope, secrets)); } }
private static void Get() { const string AadMsaAuthFailureMessage = "Logon failed, use ctrl+c to cancel basic credential prompt."; const string GitHubAuthFailureMessage = "Logon failed, use ctrl+c to cancel basic credential prompt."; // parse the operations arguments from stdin (this is how git sends commands) // see: https://www.kernel.org/pub/software/scm/git/docs/technical/api-credentials.html // see: https://www.kernel.org/pub/software/scm/git/docs/git-credential.html OperationArguments operationArguments = new OperationArguments(Console.In); Debug.Assert(operationArguments != null, "The operationArguments is null"); Debug.Assert(operationArguments.TargetUri != null, "The operationArgument.TargetUri is null"); LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); Trace.WriteLine("Program::Get"); Trace.WriteLine(" targetUri = " + operationArguments.TargetUri); BaseAuthentication authentication = CreateAuthentication(operationArguments); Credential credentials = null; switch (operationArguments.Authority) { default: case AuthorityType.Basic: if (authentication.GetCredentials(operationArguments.TargetUri, out credentials)) { Trace.WriteLine(" credentials found"); operationArguments.SetCredentials(credentials); } break; case AuthorityType.AzureDirectory: VsoAadAuthentication aadAuth = authentication as VsoAadAuthentication; Task.Run(async() => { // attmempt to get cached creds -> refresh creds -> non-interactive logon -> interactive logon // note that AAD "credentials" are always scoped access tokens if (((operationArguments.Interactivity != Interactivity.Always && aadAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Always && await aadAuth.RefreshCredentials(operationArguments.TargetUri, true) && aadAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Always && await aadAuth.NoninteractiveLogon(operationArguments.TargetUri, true) && aadAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Never && aadAuth.InteractiveLogon(operationArguments.TargetUri, true)) && aadAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { Trace.WriteLine(" credentials found"); operationArguments.SetCredentials(credentials); LogEvent("Azure Directory credentials for " + operationArguments.TargetUri + " successfully retrieved.", EventLogEntryType.SuccessAudit); } else { Console.Error.WriteLine(AadMsaAuthFailureMessage); LogEvent("Failed to retrieve Azure Directory credentials for " + operationArguments.TargetUri + ".", EventLogEntryType.FailureAudit); } }).Wait(); break; case AuthorityType.MicrosoftAccount: VsoMsaAuthentication msaAuth = authentication as VsoMsaAuthentication; Task.Run(async() => { // attmempt to get cached creds -> refresh creds -> interactive logon // note that MSA "credentials" are always scoped access tokens if (((operationArguments.Interactivity != Interactivity.Always && msaAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Always && await msaAuth.RefreshCredentials(operationArguments.TargetUri, true) && msaAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Never && msaAuth.InteractiveLogon(operationArguments.TargetUri, true)) && msaAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { Trace.WriteLine(" credentials found"); operationArguments.SetCredentials(credentials); LogEvent("Microsoft Live credentials for " + operationArguments.TargetUri + " successfully retrieved.", EventLogEntryType.SuccessAudit); } else { Console.Error.WriteLine(AadMsaAuthFailureMessage); LogEvent("Failed to retrieve Microsoft Live credentials for " + operationArguments.TargetUri + ".", EventLogEntryType.FailureAudit); } }).Wait(); break; case AuthorityType.GitHub: GithubAuthentication ghAuth = authentication as GithubAuthentication; Task.Run(async() => { if ((operationArguments.Interactivity != Interactivity.Always && ghAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Never && ghAuth.InteractiveLogon(operationArguments.TargetUri, out credentials) && ghAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { Trace.WriteLine(" credentials found"); operationArguments.SetCredentials(credentials); LogEvent("GitHub credentials for " + operationArguments.TargetUri + " successfully retrieved.", EventLogEntryType.SuccessAudit); } else { Console.Error.WriteLine(GitHubAuthFailureMessage); LogEvent("Failed to retrieve GitHub credentials for " + operationArguments.TargetUri + ".", EventLogEntryType.FailureAudit); } }).Wait(); break; case AuthorityType.Integrated: credentials = new Credential(String.Empty, String.Empty); operationArguments.SetCredentials(credentials); break; } Console.Out.Write(operationArguments); }