Коммит
30c208e92a
|
@ -13,7 +13,7 @@ namespace Bitbucket.Authentication.Test
|
|||
public class AuthorityTest
|
||||
{
|
||||
[Fact]
|
||||
public async void VerifyAcquireTokenAcceptsValidAuthenticationResultTypes()
|
||||
public void VerifyAcquireTokenAcceptsValidAuthenticationResultTypes()
|
||||
{
|
||||
var context = RuntimeContext.Default;
|
||||
var authority = new Authority(context);
|
||||
|
|
|
@ -92,7 +92,7 @@ namespace Microsoft.Alm.Authentication.Git
|
|||
return false;
|
||||
}
|
||||
|
||||
internal IEnumerable<Win32.ProcessEntry32> EnumerateParentProcesses()
|
||||
internal static IEnumerable<Win32.ProcessEntry32> EnumerateParentProcesses()
|
||||
{
|
||||
var processTable = new Dictionary<uint, uint>();
|
||||
var processEntries = new Dictionary<uint, Win32.ProcessEntry32>();
|
||||
|
|
|
@ -209,127 +209,145 @@ namespace Microsoft.Alm.Authentication.Git
|
|||
const string GitSubkeyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Git_is1";
|
||||
const string GitValueName = "InstallLocation";
|
||||
|
||||
installations = null;
|
||||
|
||||
var programFiles32Path = string.Empty;
|
||||
var programFiles64Path = string.Empty;
|
||||
var appDataRoamingPath = string.Empty;
|
||||
var appDataLocalPath = string.Empty;
|
||||
var programDataPath = string.Empty;
|
||||
var reg32HklmPath = string.Empty;
|
||||
var reg64HklmPath = string.Empty;
|
||||
var reg32HkcuPath = string.Empty;
|
||||
var reg64HkcuPath = string.Empty;
|
||||
var shellPathValue = string.Empty;
|
||||
|
||||
using (var reg32HklmKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
|
||||
using (var reg32HkcuKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry32))
|
||||
using (var reg32HklmSubKey = reg32HklmKey?.OpenSubKey(GitSubkeyName))
|
||||
using (var reg32HkcuSubKey = reg32HkcuKey?.OpenSubKey(GitSubkeyName))
|
||||
void ScanApplicationData(IList<Installation> output)
|
||||
{
|
||||
reg32HklmPath = reg32HklmSubKey?.GetValue(GitValueName, reg32HklmPath) as string;
|
||||
reg32HkcuPath = reg32HkcuSubKey?.GetValue(GitValueName, reg32HkcuPath) as string;
|
||||
}
|
||||
var appDataRoamingPath = string.Empty;
|
||||
|
||||
if ((programFiles32Path = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)) != null)
|
||||
{
|
||||
programFiles32Path = Path.Combine(programFiles32Path, GitAppName);
|
||||
}
|
||||
|
||||
if (Environment.Is64BitOperatingSystem)
|
||||
{
|
||||
using (var reg64HklmKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
|
||||
using (var reg64HkcuKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64))
|
||||
using (var reg64HklmSubKey = reg64HklmKey?.OpenSubKey(GitSubkeyName))
|
||||
using (var reg64HkcuSubKey = reg64HkcuKey?.OpenSubKey(GitSubkeyName))
|
||||
if ((appDataRoamingPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) != null)
|
||||
{
|
||||
reg64HklmPath = reg64HklmSubKey?.GetValue(GitValueName, reg64HklmPath) as string;
|
||||
reg64HkcuPath = reg64HkcuSubKey?.GetValue(GitValueName, reg64HkcuPath) as string;
|
||||
appDataRoamingPath = Path.Combine(appDataRoamingPath, GitAppName);
|
||||
|
||||
output.Add(new Installation(Context, appDataRoamingPath, KnownDistribution.GitForWindows64v2));
|
||||
output.Add(new Installation(Context, appDataRoamingPath, KnownDistribution.GitForWindows32v2));
|
||||
output.Add(new Installation(Context, appDataRoamingPath, KnownDistribution.GitForWindows32v1));
|
||||
}
|
||||
|
||||
if ((programFiles64Path = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)) != null)
|
||||
var appDataLocalPath = string.Empty;
|
||||
|
||||
if ((appDataLocalPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)) != null)
|
||||
{
|
||||
programFiles64Path = Path.Combine(programFiles64Path, GitAppName);
|
||||
appDataLocalPath = Path.Combine(appDataLocalPath, GitAppName);
|
||||
|
||||
output.Add(new Installation(Context, appDataLocalPath, KnownDistribution.GitForWindows64v2));
|
||||
output.Add(new Installation(Context, appDataLocalPath, KnownDistribution.GitForWindows32v2));
|
||||
output.Add(new Installation(Context, appDataLocalPath, KnownDistribution.GitForWindows32v1));
|
||||
}
|
||||
|
||||
var programDataPath = string.Empty;
|
||||
|
||||
if ((programDataPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)) != null)
|
||||
{
|
||||
programDataPath = Path.Combine(programDataPath, GitAppName);
|
||||
|
||||
output.Add(new Installation(Context, programDataPath, KnownDistribution.GitForWindows64v2));
|
||||
output.Add(new Installation(Context, programDataPath, KnownDistribution.GitForWindows32v2));
|
||||
output.Add(new Installation(Context, programDataPath, KnownDistribution.GitForWindows32v1));
|
||||
}
|
||||
}
|
||||
|
||||
if ((appDataRoamingPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) != null)
|
||||
void ScanProgramFiles(IList<Installation> output)
|
||||
{
|
||||
appDataRoamingPath = Path.Combine(appDataRoamingPath, GitAppName);
|
||||
}
|
||||
var programFiles32Path = string.Empty;
|
||||
|
||||
if ((appDataLocalPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)) != null)
|
||||
{
|
||||
appDataLocalPath = Path.Combine(appDataLocalPath, GitAppName);
|
||||
}
|
||||
|
||||
if ((programDataPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)) != null)
|
||||
{
|
||||
programDataPath = Path.Combine(programDataPath, GitAppName);
|
||||
}
|
||||
|
||||
List<Installation> candidates = new List<Installation>();
|
||||
// Add candidate locations in order of preference.
|
||||
if (FindApp(GitAppName, out shellPathValue))
|
||||
{
|
||||
// `Where.App` returns the path to the executable, truncate to the installation root
|
||||
if (shellPathValue.EndsWith(Installation.AllVersionCmdPath, StringComparison.OrdinalIgnoreCase))
|
||||
if ((programFiles32Path = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)) != null)
|
||||
{
|
||||
shellPathValue = shellPathValue.Substring(0, shellPathValue.Length - Installation.AllVersionCmdPath.Length);
|
||||
programFiles32Path = Path.Combine(programFiles32Path, GitAppName);
|
||||
|
||||
output.Add(new Installation(Context, programFiles32Path, KnownDistribution.GitForWindows32v2));
|
||||
output.Add(new Installation(Context, programFiles32Path, KnownDistribution.GitForWindows32v1));
|
||||
}
|
||||
|
||||
candidates.Add(new Installation(Context, shellPathValue, KnownDistribution.GitForWindows64v2));
|
||||
candidates.Add(new Installation(Context, shellPathValue, KnownDistribution.GitForWindows32v2));
|
||||
candidates.Add(new Installation(Context, shellPathValue, KnownDistribution.GitForWindows32v1));
|
||||
if (Environment.Is64BitOperatingSystem)
|
||||
{
|
||||
var programFiles64Path = string.Empty;
|
||||
|
||||
if ((programFiles64Path = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)) != null)
|
||||
{
|
||||
programFiles64Path = Path.Combine(programFiles64Path, GitAppName);
|
||||
|
||||
output.Add(new Installation(Context, programFiles64Path, KnownDistribution.GitForWindows64v2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(reg64HklmPath))
|
||||
void ScanRegistry(IList<Installation> output)
|
||||
{
|
||||
candidates.Add(new Installation(Context, reg64HklmPath, KnownDistribution.GitForWindows64v2));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(programFiles64Path))
|
||||
{
|
||||
candidates.Add(new Installation(Context, programFiles64Path, KnownDistribution.GitForWindows64v2));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(reg64HkcuPath))
|
||||
{
|
||||
candidates.Add(new Installation(Context, reg64HkcuPath, KnownDistribution.GitForWindows64v2));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(reg32HklmPath))
|
||||
{
|
||||
candidates.Add(new Installation(Context, reg32HklmPath, KnownDistribution.GitForWindows32v2));
|
||||
candidates.Add(new Installation(Context, reg32HklmPath, KnownDistribution.GitForWindows32v1));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(programFiles32Path))
|
||||
{
|
||||
candidates.Add(new Installation(Context, programFiles32Path, KnownDistribution.GitForWindows32v2));
|
||||
candidates.Add(new Installation(Context, programFiles32Path, KnownDistribution.GitForWindows32v1));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(reg32HkcuPath))
|
||||
{
|
||||
candidates.Add(new Installation(Context, reg32HkcuPath, KnownDistribution.GitForWindows32v2));
|
||||
candidates.Add(new Installation(Context, reg32HkcuPath, KnownDistribution.GitForWindows32v1));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(programDataPath))
|
||||
{
|
||||
candidates.Add(new Installation(Context, programDataPath, KnownDistribution.GitForWindows64v2));
|
||||
candidates.Add(new Installation(Context, programDataPath, KnownDistribution.GitForWindows32v2));
|
||||
candidates.Add(new Installation(Context, programDataPath, KnownDistribution.GitForWindows32v1));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(appDataLocalPath))
|
||||
{
|
||||
candidates.Add(new Installation(Context, appDataLocalPath, KnownDistribution.GitForWindows64v2));
|
||||
candidates.Add(new Installation(Context, appDataLocalPath, KnownDistribution.GitForWindows32v2));
|
||||
candidates.Add(new Installation(Context, appDataLocalPath, KnownDistribution.GitForWindows32v1));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(appDataRoamingPath))
|
||||
{
|
||||
candidates.Add(new Installation(Context, appDataRoamingPath, KnownDistribution.GitForWindows64v2));
|
||||
candidates.Add(new Installation(Context, appDataRoamingPath, KnownDistribution.GitForWindows32v2));
|
||||
candidates.Add(new Installation(Context, appDataRoamingPath, KnownDistribution.GitForWindows32v1));
|
||||
var reg32HklmPath = string.Empty;
|
||||
var reg32HkcuPath = string.Empty;
|
||||
|
||||
using (var reg32HklmKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
|
||||
using (var reg32HkcuKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry32))
|
||||
using (var reg32HklmSubKey = reg32HklmKey?.OpenSubKey(GitSubkeyName))
|
||||
using (var reg32HkcuSubKey = reg32HkcuKey?.OpenSubKey(GitSubkeyName))
|
||||
{
|
||||
reg32HklmPath = reg32HklmSubKey?.GetValue(GitValueName, reg32HklmPath) as string;
|
||||
reg32HkcuPath = reg32HkcuSubKey?.GetValue(GitValueName, reg32HkcuPath) as string;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(reg32HklmPath))
|
||||
{
|
||||
output.Add(new Installation(Context, reg32HklmPath, KnownDistribution.GitForWindows32v2));
|
||||
output.Add(new Installation(Context, reg32HklmPath, KnownDistribution.GitForWindows32v1));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(reg32HkcuPath))
|
||||
{
|
||||
output.Add(new Installation(Context, reg32HkcuPath, KnownDistribution.GitForWindows32v2));
|
||||
output.Add(new Installation(Context, reg32HkcuPath, KnownDistribution.GitForWindows32v1));
|
||||
}
|
||||
|
||||
if (Environment.Is64BitOperatingSystem)
|
||||
{
|
||||
var reg64HklmPath = string.Empty;
|
||||
var reg64HkcuPath = string.Empty;
|
||||
|
||||
using (var reg64HklmKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
|
||||
using (var reg64HkcuKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64))
|
||||
using (var reg64HklmSubKey = reg64HklmKey?.OpenSubKey(GitSubkeyName))
|
||||
using (var reg64HkcuSubKey = reg64HkcuKey?.OpenSubKey(GitSubkeyName))
|
||||
{
|
||||
reg64HklmPath = reg64HklmSubKey?.GetValue(GitValueName, reg64HklmPath) as string;
|
||||
reg64HkcuPath = reg64HkcuSubKey?.GetValue(GitValueName, reg64HkcuPath) as string;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(reg64HklmPath))
|
||||
{
|
||||
output.Add(new Installation(Context, reg64HklmPath, KnownDistribution.GitForWindows64v2));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(reg64HkcuPath))
|
||||
{
|
||||
output.Add(new Installation(Context, reg64HkcuPath, KnownDistribution.GitForWindows64v2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<Installation> pathSet = new HashSet<Installation>();
|
||||
void ScanShellPath(IList<Installation> output)
|
||||
{
|
||||
var shellPathValue = string.Empty;
|
||||
|
||||
if (FindApp(GitAppName, out shellPathValue))
|
||||
{
|
||||
// `Where.App` returns the path to the executable, truncate to the installation root
|
||||
if (shellPathValue.EndsWith(Installation.AllVersionCmdPath, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
shellPathValue = shellPathValue.Substring(0, shellPathValue.Length - Installation.AllVersionCmdPath.Length);
|
||||
}
|
||||
|
||||
output.Add(new Installation(Context, shellPathValue, KnownDistribution.GitForWindows64v2));
|
||||
output.Add(new Installation(Context, shellPathValue, KnownDistribution.GitForWindows32v2));
|
||||
output.Add(new Installation(Context, shellPathValue, KnownDistribution.GitForWindows32v1));
|
||||
}
|
||||
}
|
||||
|
||||
var candidates = new List<Installation>();
|
||||
|
||||
ScanShellPath(candidates);
|
||||
ScanRegistry(candidates);
|
||||
ScanProgramFiles(candidates);
|
||||
ScanApplicationData(candidates);
|
||||
|
||||
var pathSet = new HashSet<Installation>();
|
||||
foreach (var candidate in candidates)
|
||||
{
|
||||
if (candidate.IsValid())
|
||||
|
|
|
@ -230,6 +230,7 @@ namespace Microsoft.Alm.Authentication
|
|||
/// The new URL used for all queries if not `<see langword="null"/>`; otherwise is unchanged from `<seealso cref="ActualUri"/>`.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentException">When all arguments are `<see langword="null"/>`.</exception>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
|
||||
public TargetUri CreateWith(string queryUrl = null, string proxyUrl = null, string actualUrl = null)
|
||||
{
|
||||
if (queryUrl is null && proxyUrl is null && actualUrl is null)
|
||||
|
@ -255,6 +256,7 @@ namespace Microsoft.Alm.Authentication
|
|||
/// The new `<seealso cref="Uri"/>` used for all queries if not `<see langword="null"/>`; otherwise is unchanged from `<seealso cref="ActualUri"/>`.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentException">When all arguments are `<see langword="null"/>`.</exception>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
|
||||
public TargetUri CreateWith(Uri queryUri = null, Uri proxyUri = null, Uri actualUri = null)
|
||||
{
|
||||
if (queryUri is null && proxyUri is null && actualUri is null)
|
||||
|
|
|
@ -90,7 +90,7 @@ namespace VisualStudioTeamServices.Authentication
|
|||
/// </summary>
|
||||
public string AuthorityHostUrl { get; protected set; }
|
||||
|
||||
public async Task<Token> GeneratePersonalAccessToken(TargetUri targetUri, Token authorization, TokenScope tokenScope, bool requireCompactToken, TimeSpan? tokenDuration = null)
|
||||
public async Task<Token> GeneratePersonalAccessToken(TargetUri targetUri, Token authorization, TokenScope tokenScope, bool requireCompactToken, TimeSpan? tokenDuration)
|
||||
{
|
||||
if (targetUri is null)
|
||||
throw new ArgumentNullException(nameof(targetUri));
|
||||
|
@ -143,6 +143,9 @@ namespace VisualStudioTeamServices.Authentication
|
|||
return null;
|
||||
}
|
||||
|
||||
public Task<Token> GeneratePersonalAccessToken(TargetUri targetUri, Token authorization, TokenScope tokenScope, bool requireCompactToken)
|
||||
=> GeneratePersonalAccessToken(targetUri, authorization, tokenScope, requireCompactToken, null);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the properly formatted URL for the Azure authority given a tenant identity.
|
||||
/// </summary>
|
||||
|
|
|
@ -45,7 +45,18 @@ namespace VisualStudioTeamServices.Authentication
|
|||
/// <para/>
|
||||
/// The authority granting the token decides the actual lifetime of any token granted, regardless of the duration requested.
|
||||
/// </param>
|
||||
Task<Token> GeneratePersonalAccessToken(TargetUri targetUri, Token accessToken, TokenScope tokenScope, bool requireCompactToken, TimeSpan? tokenDuration = null);
|
||||
Task<Token> GeneratePersonalAccessToken(TargetUri targetUri, Token accessToken, TokenScope tokenScope, bool requireCompactToken, TimeSpan? tokenDuration);
|
||||
|
||||
/// <summary>
|
||||
/// Generates a personal access token for use with Visual Studio Team Services.
|
||||
/// <para/>
|
||||
/// Returns the acquired `<seealso cref="Token"/>` if successful; otherwise `<see langword="null"/>`;
|
||||
/// </summary>
|
||||
/// <param name="targetUri">The uniform resource indicator of the resource access tokens are being requested for.</param>
|
||||
/// <param name="accessToken">Access token granted by the identity authority (Azure).</param>
|
||||
/// <param name="tokenScope">The requested access scopes to be granted to the token.</param>
|
||||
/// <param name="requireCompactToken">`<see langword="true"/>` if requesting a compact format token; otherwise `<see langword="false"/>`.</param>
|
||||
Task<Token> GeneratePersonalAccessToken(TargetUri targetUri, Token accessToken, TokenScope tokenScope, bool requireCompactToken);
|
||||
|
||||
/// <summary>
|
||||
/// Acquires a `<seealso cref="Token"/>` from the authority via an interactive user logon prompt.
|
||||
|
@ -57,7 +68,7 @@ namespace VisualStudioTeamServices.Authentication
|
|||
/// <param name="resource">Identifier of the target resource that is the recipient of the requested token.</param>
|
||||
/// <param name="redirectUri">Address to return to upon receiving a response from the authority.</param>
|
||||
/// <param name="queryParameters">optional value, appended as-is to the query string in the HTTP authentication request to the authority.</param>
|
||||
Task<Token> InteractiveAcquireToken(TargetUri targetUri, string clientId, string resource, Uri redirectUri, string queryParameters = null);
|
||||
Task<Token> InteractiveAcquireToken(TargetUri targetUri, string clientId, string resource, Uri redirectUri, string queryParameters);
|
||||
|
||||
/// <summary>
|
||||
/// Acquires a `<see cref="Token"/>` from the authority via an non-interactive user logon.
|
||||
|
|
|
@ -62,6 +62,18 @@ namespace VisualStudioTeamServices.Authentication.Test
|
|||
return await Task.FromResult(new Token("personal-access-token", TokenType.Personal));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a personal access token for use with Visual Studio Team Services.
|
||||
/// <para/>
|
||||
/// Returns the acquired token if successful; otherwise <see langword="null"/>;
|
||||
/// </summary>
|
||||
/// <param name="targetUri">The uniform resource indicator of the resource access tokens are being requested for.</param>
|
||||
/// <param name="accessToken">Access token granted by the identity authority (Azure).</param>
|
||||
/// <param name="tokenScope">The requested access scopes to be granted to the token.</param>
|
||||
/// <param name="requireCompactToken">`<see langword="true"/>` if requesting a compact format token; otherwise `<see langword="false"/>`.</param>
|
||||
public Task<Token> GeneratePersonalAccessToken(TargetUri targetUri, Token accessToken, TokenScope tokenScope, bool requireCompactToken)
|
||||
=> GeneratePersonalAccessToken(targetUri, accessToken, tokenScope, requireCompactToken, null);
|
||||
|
||||
/// <summary>
|
||||
/// Acquires a <see cref="Token"/> from the authority via an interactive user logon prompt.
|
||||
/// <para/>
|
||||
|
@ -72,7 +84,7 @@ namespace VisualStudioTeamServices.Authentication.Test
|
|||
/// <param name="resource">Identifier of the target resource that is the recipient of the requested token.</param>
|
||||
/// <param name="redirectUri">Address to return to upon receiving a response from the authority.</param>
|
||||
/// <param name="queryParameters">optional value, appended as-is to the query string in the HTTP authentication request to the authority.</param>
|
||||
public async Task<Token> InteractiveAcquireToken(TargetUri targetUri, string clientId, string resource, Uri redirectUri, string queryParameters = null)
|
||||
public async Task<Token> InteractiveAcquireToken(TargetUri targetUri, string clientId, string resource, Uri redirectUri, string queryParameters)
|
||||
{
|
||||
Assert.Equal(ExpectedQueryParameters, queryParameters);
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
<Rule Id="CA2201" Action="None" />
|
||||
<Rule Id="CA2202" Action="None" />
|
||||
<Rule Id="CA2204" Action="None" />
|
||||
<Rule Id="CA2205" Action="None" />
|
||||
<Rule Id="CA2208" Action="None" />
|
||||
<Rule Id="CA2210" Action="None" />
|
||||
<Rule Id="CA2225" Action="None" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче