mirror of
https://github.com/actions/runner.git
synced 2025-12-11 12:57:05 +00:00
delete un-used code. (#218)
This commit is contained in:
@@ -1,92 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using GitHub.Services.Common.Internal;
|
||||
|
||||
namespace GitHub.Services.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a credential for basic authentication against a Visual Studio Service.
|
||||
/// </summary>
|
||||
public sealed class VssBasicCredential : FederatedCredential
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new <c>VssBasicCredential</c> instance with no token specified.
|
||||
/// </summary>
|
||||
public VssBasicCredential()
|
||||
: this((VssBasicToken)null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <c>VssBasicCredential</c> instance with the specified user name and password.
|
||||
/// </summary>
|
||||
/// <param name="userName">The user name</param>
|
||||
/// <param name="password">The password</param>
|
||||
public VssBasicCredential(
|
||||
string userName,
|
||||
string password)
|
||||
: this(new VssBasicToken(new NetworkCredential(userName, password)))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <c>VssBasicCredential</c> instance with the specified token.
|
||||
/// </summary>
|
||||
/// <param name="initialToken">An optional token which, if present, should be used before obtaining a new token</param>
|
||||
public VssBasicCredential(ICredentials initialToken)
|
||||
: this(new VssBasicToken(initialToken))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <c>VssBasicCredential</c> instance with the specified token.
|
||||
/// </summary>
|
||||
/// <param name="initialToken">An optional token which, if present, should be used before obtaining a new token</param>
|
||||
public VssBasicCredential(VssBasicToken initialToken)
|
||||
: base(initialToken)
|
||||
{
|
||||
}
|
||||
|
||||
public override VssCredentialsType CredentialType
|
||||
{
|
||||
get
|
||||
{
|
||||
return VssCredentialsType.Basic;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsAuthenticationChallenge(IHttpResponse webResponse)
|
||||
{
|
||||
if (webResponse == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (webResponse.StatusCode != HttpStatusCode.Found &&
|
||||
webResponse.StatusCode != HttpStatusCode.Redirect &&
|
||||
webResponse.StatusCode != HttpStatusCode.Unauthorized)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return webResponse.Headers.GetValues(HttpHeaders.WwwAuthenticate).Any(x => x.StartsWith("Basic", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
protected override IssuedTokenProvider OnCreateTokenProvider(
|
||||
Uri serverUrl,
|
||||
IHttpResponse response)
|
||||
{
|
||||
if (serverUrl.Scheme != "https")
|
||||
{
|
||||
String unsafeBasicAuthEnv = Environment.GetEnvironmentVariable("VSS_ALLOW_UNSAFE_BASICAUTH") ?? "false";
|
||||
if (!Boolean.TryParse(unsafeBasicAuthEnv, out Boolean unsafeBasicAuth) || !unsafeBasicAuth)
|
||||
{
|
||||
throw new InvalidOperationException(CommonResources.BasicAuthenticationRequiresSsl());
|
||||
}
|
||||
}
|
||||
|
||||
return new BasicAuthTokenProvider(this, serverUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
|
||||
namespace GitHub.Services.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a token for basic authentication of internet identities.
|
||||
/// </summary>
|
||||
public sealed class VssBasicToken : IssuedToken
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new <c>BasicAuthToken</c> instance with the specified token value.
|
||||
/// </summary>
|
||||
/// <param name="credentials">The credentials which should be used for authentication</param>
|
||||
public VssBasicToken(ICredentials credentials)
|
||||
{
|
||||
m_credentials = credentials;
|
||||
}
|
||||
|
||||
internal ICredentials Credentials
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_credentials;
|
||||
}
|
||||
}
|
||||
|
||||
protected internal override VssCredentialsType CredentialType
|
||||
{
|
||||
get
|
||||
{
|
||||
return VssCredentialsType.Basic;
|
||||
}
|
||||
}
|
||||
|
||||
internal override void ApplyTo(IHttpRequest request)
|
||||
{
|
||||
var basicCredential = m_credentials.GetCredential(request.RequestUri, "Basic");
|
||||
if (basicCredential != null)
|
||||
{
|
||||
request.Headers.SetValue(Internal.HttpHeaders.Authorization, "Basic " + FormatBasicAuthHeader(basicCredential));
|
||||
}
|
||||
}
|
||||
|
||||
private static String FormatBasicAuthHeader(NetworkCredential credential)
|
||||
{
|
||||
String authHeader = String.Empty;
|
||||
if (!String.IsNullOrEmpty(credential.Domain))
|
||||
{
|
||||
authHeader = String.Format(CultureInfo.InvariantCulture, "{0}\\{1}:{2}", credential.Domain, credential.UserName, credential.Password);
|
||||
}
|
||||
else
|
||||
{
|
||||
authHeader = String.Format(CultureInfo.InvariantCulture, "{0}:{1}", credential.UserName, credential.Password);
|
||||
}
|
||||
|
||||
return Convert.ToBase64String(VssHttpRequestSettings.Encoding.GetBytes(authHeader));
|
||||
}
|
||||
|
||||
private readonly ICredentials m_credentials;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
|
||||
namespace GitHub.Services.Common
|
||||
{
|
||||
internal sealed class BasicAuthTokenProvider : IssuedTokenProvider
|
||||
{
|
||||
public BasicAuthTokenProvider(
|
||||
VssBasicCredential credential,
|
||||
Uri serverUrl)
|
||||
: base(credential, serverUrl, serverUrl)
|
||||
{
|
||||
}
|
||||
|
||||
protected override String AuthenticationScheme
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Basic";
|
||||
}
|
||||
}
|
||||
|
||||
public new VssBasicCredential Credential
|
||||
{
|
||||
get
|
||||
{
|
||||
return (VssBasicCredential)base.Credential;
|
||||
}
|
||||
}
|
||||
|
||||
public override Boolean GetTokenIsInteractive
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.CurrentToken == null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,47 +51,7 @@ namespace GitHub.Services.Common
|
||||
/// Initializes a new <c>VssCredentials</c> instance with default credentials.
|
||||
/// </summary>
|
||||
public VssCredentials()
|
||||
: this(true)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <c>VssCredentials</c> instance with default credentials if specified.
|
||||
/// </summary>
|
||||
/// <param name="useDefaultCredentials">True to use default windows credentials; otherwise, false</param>
|
||||
public VssCredentials(bool useDefaultCredentials)
|
||||
: this(new WindowsCredential(useDefaultCredentials))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <c>VssCredentials</c> instance with the specified windows credential.
|
||||
/// </summary>
|
||||
/// <param name="windowsCredential">The windows credential to use for authentication</param>
|
||||
public VssCredentials(WindowsCredential windowsCredential)
|
||||
: this(windowsCredential, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <c>VssCredentials</c> instance with the specified windows credential.
|
||||
/// </summary>
|
||||
/// <param name="windowsCredential">The windows credential to use for authentication</param>
|
||||
/// <param name="promptType">CredentialPromptType.PromptIfNeeded if interactive prompts are allowed, otherwise CredentialProptType.DoNotPrompt</param>
|
||||
public VssCredentials(
|
||||
WindowsCredential windowsCredential,
|
||||
CredentialPromptType promptType)
|
||||
: this(windowsCredential, null, promptType)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <c>VssCredentials</c> instance with the specified issued token credential and
|
||||
/// default windows credential.
|
||||
/// </summary>
|
||||
/// <param name="federatedCredential">The federated credential to use for authentication</param>
|
||||
public VssCredentials(FederatedCredential federatedCredential)
|
||||
: this(new WindowsCredential(), federatedCredential)
|
||||
: this(null)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -99,12 +59,9 @@ namespace GitHub.Services.Common
|
||||
/// Initializes a new <c>VssCredentials</c> instance with the specified windows and issued token
|
||||
/// credential.
|
||||
/// </summary>
|
||||
/// <param name="windowsCredential">The windows credential to use for authentication</param>
|
||||
/// <param name="federatedCredential">The federated credential to use for authentication</param>
|
||||
public VssCredentials(
|
||||
WindowsCredential windowsCredential,
|
||||
FederatedCredential federatedCredential)
|
||||
: this(windowsCredential, federatedCredential, EnvironmentUserInteractive
|
||||
public VssCredentials(FederatedCredential federatedCredential)
|
||||
: this(federatedCredential, EnvironmentUserInteractive
|
||||
? CredentialPromptType.PromptIfNeeded : CredentialPromptType.DoNotPrompt)
|
||||
{
|
||||
}
|
||||
@@ -113,14 +70,12 @@ namespace GitHub.Services.Common
|
||||
/// Initializes a new <c>VssCredentials</c> instance with the specified windows and issued token
|
||||
/// credential.
|
||||
/// </summary>
|
||||
/// <param name="windowsCredential">The windows credential to use for authentication</param>
|
||||
/// <param name="federatedCredential">The federated credential to use for authentication</param>
|
||||
/// <param name="promptType">CredentialPromptType.PromptIfNeeded if interactive prompts are allowed, otherwise CredentialProptType.DoNotPrompt</param>
|
||||
public VssCredentials(
|
||||
WindowsCredential windowsCredential,
|
||||
FederatedCredential federatedCredential,
|
||||
CredentialPromptType promptType)
|
||||
: this(windowsCredential, federatedCredential, promptType, null)
|
||||
: this(federatedCredential, promptType, null)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -128,16 +83,14 @@ namespace GitHub.Services.Common
|
||||
/// Initializes a new <c>VssCredentials</c> instance with the specified windows and issued token
|
||||
/// credential.
|
||||
/// </summary>
|
||||
/// <param name="windowsCredential">The windows credential to use for authentication</param>
|
||||
/// <param name="federatedCredential">The federated credential to use for authentication</param>
|
||||
/// <param name="promptType">CredentialPromptType.PromptIfNeeded if interactive prompts are allowed; otherwise, CredentialProptType.DoNotPrompt</param>
|
||||
/// <param name="scheduler">An optional <c>TaskScheduler</c> to ensure credentials prompting occurs on the UI thread</param>
|
||||
public VssCredentials(
|
||||
WindowsCredential windowsCredential,
|
||||
FederatedCredential federatedCredential,
|
||||
CredentialPromptType promptType,
|
||||
TaskScheduler scheduler)
|
||||
: this(windowsCredential, federatedCredential, promptType, scheduler, null)
|
||||
: this(federatedCredential, promptType, scheduler, null)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -145,13 +98,11 @@ namespace GitHub.Services.Common
|
||||
/// Initializes a new <c>VssCredentials</c> instance with the specified windows and issued token
|
||||
/// credential.
|
||||
/// </summary>
|
||||
/// <param name="windowsCredential">The windows credential to use for authentication</param>
|
||||
/// <param name="federatedCredential">The federated credential to use for authentication</param>
|
||||
/// <param name="promptType">CredentialPromptType.PromptIfNeeded if interactive prompts are allowed; otherwise, CredentialProptType.DoNotPrompt</param>
|
||||
/// <param name="scheduler">An optional <c>TaskScheduler</c> to ensure credentials prompting occurs on the UI thread</param>
|
||||
/// <param name="credentialPrompt">An optional <c>IVssCredentialPrompt</c> to perform prompting for credentials</param>
|
||||
public VssCredentials(
|
||||
WindowsCredential windowsCredential,
|
||||
FederatedCredential federatedCredential,
|
||||
CredentialPromptType promptType,
|
||||
TaskScheduler scheduler,
|
||||
@@ -172,13 +123,6 @@ namespace GitHub.Services.Common
|
||||
scheduler = TaskScheduler.Default;
|
||||
}
|
||||
|
||||
if (windowsCredential != null)
|
||||
{
|
||||
m_windowsCredential = windowsCredential;
|
||||
m_windowsCredential.Scheduler = scheduler;
|
||||
m_windowsCredential.Prompt = credentialPrompt;
|
||||
}
|
||||
|
||||
if (federatedCredential != null)
|
||||
{
|
||||
m_federatedCredential = federatedCredential;
|
||||
@@ -199,16 +143,6 @@ namespace GitHub.Services.Common
|
||||
return new VssCredentials(credential);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implicitly converts a <c>WindowsCredential</c> instance into a <c>VssCredentials</c> instance.
|
||||
/// </summary>
|
||||
/// <param name="credential">The windows credential instance</param>
|
||||
/// <returns>A new <c>VssCredentials</c> instance which wraps the specified credential</returns>
|
||||
public static implicit operator VssCredentials(WindowsCredential credential)
|
||||
{
|
||||
return new VssCredentials(credential);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or not interactive prompts are allowed.
|
||||
/// </summary>
|
||||
@@ -240,17 +174,6 @@ namespace GitHub.Services.Common
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the windows credential to use for NTLM authentication with the server.
|
||||
/// </summary>
|
||||
public WindowsCredential Windows
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_windowsCredential;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A pluggable credential store.
|
||||
/// Simply assign a storage implementation to this property
|
||||
@@ -267,11 +190,6 @@ namespace GitHub.Services.Common
|
||||
{
|
||||
m_credentialStorage = value;
|
||||
|
||||
if (m_windowsCredential != null)
|
||||
{
|
||||
m_windowsCredential.Storage = value;
|
||||
}
|
||||
|
||||
if (m_federatedCredential != null)
|
||||
{
|
||||
m_federatedCredential.Storage = value;
|
||||
@@ -327,20 +245,6 @@ namespace GitHub.Services.Common
|
||||
VssHttpEventSource.Log.IssuedTokenProviderCreated(traceActivity, tokenProvider);
|
||||
}
|
||||
}
|
||||
else if (m_windowsCredential != null && m_windowsCredential.IsAuthenticationChallenge(webResponse))
|
||||
{
|
||||
if (tokenProvider != null)
|
||||
{
|
||||
VssHttpEventSource.Log.IssuedTokenProviderRemoved(traceActivity, tokenProvider);
|
||||
}
|
||||
|
||||
tokenProvider = m_windowsCredential.CreateTokenProvider(serverUrl, webResponse, failedToken);
|
||||
|
||||
if (tokenProvider != null)
|
||||
{
|
||||
VssHttpEventSource.Log.IssuedTokenProviderCreated(traceActivity, tokenProvider);
|
||||
}
|
||||
}
|
||||
|
||||
m_currentProvider = tokenProvider;
|
||||
}
|
||||
@@ -356,7 +260,7 @@ namespace GitHub.Services.Common
|
||||
/// <param name="provider">Stores the active token provider, if one exists</param>
|
||||
/// <returns>True if a token provider was found, false otherwise</returns>
|
||||
public bool TryGetTokenProvider(
|
||||
Uri serverUrl,
|
||||
Uri serverUrl,
|
||||
out IssuedTokenProvider provider)
|
||||
{
|
||||
ArgumentUtility.CheckForNull(serverUrl, "serverUrl");
|
||||
@@ -371,11 +275,6 @@ namespace GitHub.Services.Common
|
||||
m_currentProvider = m_federatedCredential.CreateTokenProvider(serverUrl, null, null);
|
||||
}
|
||||
|
||||
if (m_currentProvider == null && m_windowsCredential != null)
|
||||
{
|
||||
m_currentProvider = m_windowsCredential.CreateTokenProvider(serverUrl, null, null);
|
||||
}
|
||||
|
||||
if (m_currentProvider != null)
|
||||
{
|
||||
VssHttpEventSource.Log.IssuedTokenProviderCreated(VssTraceActivity.Current, m_currentProvider);
|
||||
@@ -401,11 +300,6 @@ namespace GitHub.Services.Common
|
||||
}
|
||||
|
||||
bool isChallenge = false;
|
||||
if (m_windowsCredential != null)
|
||||
{
|
||||
isChallenge = m_windowsCredential.IsAuthenticationChallenge(webResponse);
|
||||
}
|
||||
|
||||
if (!isChallenge && m_federatedCredential != null)
|
||||
{
|
||||
isChallenge = m_federatedCredential.IsAuthenticationChallenge(webResponse);
|
||||
@@ -415,8 +309,8 @@ namespace GitHub.Services.Common
|
||||
}
|
||||
|
||||
internal void SignOut(
|
||||
Uri serverUrl,
|
||||
Uri serviceLocation,
|
||||
Uri serverUrl,
|
||||
Uri serviceLocation,
|
||||
string identityProvider)
|
||||
{
|
||||
// Remove the token in the storage and the current token provider. Note that we don't
|
||||
@@ -450,110 +344,6 @@ namespace GitHub.Services.Common
|
||||
tokenProviderWithSignOut.SignOut(serviceLocation, serverUrl, identityProvider);
|
||||
}
|
||||
|
||||
#if !NETSTANDARD
|
||||
/// <summary>
|
||||
/// Loads stored credentials for the specified server if found. If no credentials are found in the windows
|
||||
/// credential store for the specified server and options then default credentials are returned.
|
||||
/// </summary>
|
||||
/// <param name="serverUrl">The server location</param>
|
||||
/// <param name="requireExactMatch">A value indicating whether or not an exact or partial match of the server is required</param>
|
||||
/// <returns>A credentials object populated with stored credentials for the server if found</returns>
|
||||
public static VssCredentials LoadCachedCredentials(
|
||||
Uri serverUrl,
|
||||
bool requireExactMatch)
|
||||
{
|
||||
return LoadCachedCredentials(null, serverUrl, requireExactMatch);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads stored credentials for the specified server if found. If no credentials are found for the specified server and options then default credentials are returned.
|
||||
/// This overload assumes that the credentials are to be stored under the TFS server's registry root
|
||||
/// </summary>
|
||||
/// <param name="featureRegistryKeyword">An optional application name for isolated credential storage in the registry</param>
|
||||
/// <param name="serverUrl">The server location</param>
|
||||
/// <param name="requireExactMatch">A value indicating whether or not an exact or partial match of the server is required</param>
|
||||
/// <returns>A credentials object populated with stored credentials for the server if found</returns>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static VssCredentials LoadCachedCredentials(
|
||||
string featureRegistryKeyword,
|
||||
Uri serverUrl,
|
||||
bool requireExactMatch)
|
||||
{
|
||||
ArgumentUtility.CheckForNull(serverUrl, "serverUrl");
|
||||
|
||||
bool uriKnownToCachedProvider = false;
|
||||
VssCredentials cred = LoadCachedCredentialsFromRegisteredProviders(serverUrl, out uriKnownToCachedProvider);
|
||||
|
||||
// If one of the registered credential providers had the target URI in its cache but failed to return a valid credential it means
|
||||
// we should have had a cred but something went wrong (user canceled, user failed, auth source unavailable, etc.). In that case
|
||||
// we Do Not want to carry on with the fallback to the VS registry/windows store credential caches. Even if that worked to get a
|
||||
// credential it would put the user in a bad state (having an active, authenticated connection with an unexpected credential type).
|
||||
if (cred == null && !uriKnownToCachedProvider)
|
||||
{
|
||||
WindowsCredential windowsCredential = null;
|
||||
FederatedCredential federatedCredential = null;
|
||||
CredentialsCacheManager credentialsCacheManager = new CredentialsCacheManager();
|
||||
TfsCredentialCacheEntry cacheEntry = credentialsCacheManager.GetCredentials(featureRegistryKeyword, serverUrl, requireExactMatch, null);
|
||||
if (cacheEntry != null)
|
||||
{
|
||||
if (cacheEntry.NonInteractive)
|
||||
{
|
||||
switch (cacheEntry.Type)
|
||||
{
|
||||
case CachedCredentialsType.ServiceIdentity:
|
||||
VssServiceIdentityToken initialToken = null;
|
||||
string initialTokenValue = ReadAuthorizationToken(cacheEntry.Attributes);
|
||||
if (!string.IsNullOrEmpty(initialTokenValue))
|
||||
{
|
||||
initialToken = new VssServiceIdentityToken(initialTokenValue);
|
||||
}
|
||||
|
||||
// Initialize the issued token credential using the stored token if it exists
|
||||
federatedCredential = new VssServiceIdentityCredential(cacheEntry.Credentials.UserName,
|
||||
cacheEntry.Credentials.Password,
|
||||
initialToken);
|
||||
break;
|
||||
|
||||
case CachedCredentialsType.Windows:
|
||||
windowsCredential = new WindowsCredential(cacheEntry.Credentials);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cred = new VssCredentials(windowsCredential ?? new WindowsCredential(true), federatedCredential, CredentialPromptType.DoNotPrompt);
|
||||
}
|
||||
|
||||
return cred ?? new VssCredentials(new WindowsCredential(true), null, CredentialPromptType.DoNotPrompt);
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static VssCredentials LoadCachedCredentialsFromRegisteredProviders(Uri serverUri, out bool knownUri)
|
||||
{
|
||||
LoadRegisteredCachedVssCredentialProviders();
|
||||
bool uriKnownByAnyProvider = false;
|
||||
VssCredentials cred = null;
|
||||
foreach (var pair in m_loadedCachedVssCredentialProviders)
|
||||
{
|
||||
bool uriKnownToProvider = false;
|
||||
cred = pair.Value?.GetCachedCredentials(serverUri, out uriKnownToProvider);
|
||||
if (cred != null || uriKnownToProvider)
|
||||
{
|
||||
uriKnownByAnyProvider |= uriKnownToProvider;
|
||||
break;
|
||||
}
|
||||
}
|
||||
knownUri = uriKnownByAnyProvider;
|
||||
return cred;
|
||||
}
|
||||
|
||||
private static void LoadRegisteredCachedVssCredentialProviders()
|
||||
{
|
||||
CredentialsProviderRegistryHelper.LoadCachedVssCredentialProviders(ref m_loadedCachedVssCredentialProviders);
|
||||
}
|
||||
private static ConcurrentDictionary<string, ICachedVssCredentialProvider> m_loadedCachedVssCredentialProviders = new ConcurrentDictionary<string, ICachedVssCredentialProvider>();
|
||||
#endif
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static void WriteAuthorizationToken(
|
||||
string token,
|
||||
@@ -604,7 +394,6 @@ namespace GitHub.Services.Common
|
||||
private object m_thisLock;
|
||||
private CredentialPromptType m_promptType;
|
||||
private IssuedTokenProvider m_currentProvider;
|
||||
protected WindowsCredential m_windowsCredential;
|
||||
protected FederatedCredential m_federatedCredential;
|
||||
private IVssCredentialStorage m_credentialStorage;
|
||||
}
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace GitHub.Services.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides federated authentication as a service identity with a Visual Studio Service.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public sealed class VssServiceIdentityCredential : FederatedCredential
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new <c>VssServiceIdentityCredential</c> instance with the specified user name and password.
|
||||
/// </summary>
|
||||
/// <param name="userName">The user name</param>
|
||||
/// <param name="password">The password</param>
|
||||
public VssServiceIdentityCredential(
|
||||
string userName,
|
||||
string password)
|
||||
: this(userName, password, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <c>VssServiceIdentityCredential</c> instance with the specified user name and password. The
|
||||
/// provided token, if not null, will be used before attempting authentication with the credentials.
|
||||
/// </summary>
|
||||
/// <param name="userName">The user name</param>
|
||||
/// <param name="password">The password</param>
|
||||
/// <param name="initialToken">An optional token which, if present, should be used before obtaining a new token</param>
|
||||
public VssServiceIdentityCredential(
|
||||
string userName,
|
||||
string password,
|
||||
VssServiceIdentityToken initialToken)
|
||||
: this(userName, password, initialToken, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <c>VssServiceIdentityCredential</c> instance with the specified access token.
|
||||
/// </summary>
|
||||
/// <param name="token">A token which may be used for authorization as the desired service identity</param>
|
||||
public VssServiceIdentityCredential(VssServiceIdentityToken token)
|
||||
: this(null, null, token, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <c>VssServiceIdentityCredential</c> instance with the specified user name and password. The
|
||||
/// provided token, if not null, will be used before attempting authentication with the credentials.
|
||||
/// </summary>
|
||||
/// <param name="userName">The user name</param>
|
||||
/// <param name="password">The password</param>
|
||||
/// <param name="initialToken">An optional token which, if present, should be used before obtaining a new token</param>
|
||||
/// <param name="innerHandler">An optional HttpMessageHandler which if passed will be passed along to the TokenProvider when executing OnCreateTokenProvider </param>
|
||||
public VssServiceIdentityCredential(
|
||||
string userName,
|
||||
string password,
|
||||
VssServiceIdentityToken initialToken,
|
||||
DelegatingHandler innerHandler)
|
||||
: base(initialToken)
|
||||
{
|
||||
m_userName = userName;
|
||||
m_password = password;
|
||||
m_innerHandler = innerHandler;
|
||||
}
|
||||
|
||||
public override VssCredentialsType CredentialType
|
||||
{
|
||||
get
|
||||
{
|
||||
return VssCredentialsType.ServiceIdentity;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user name.
|
||||
/// </summary>
|
||||
public String UserName
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_userName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the password.
|
||||
/// </summary>
|
||||
internal String Password
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_password;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsAuthenticationChallenge(IHttpResponse webResponse)
|
||||
{
|
||||
if (webResponse == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (webResponse.StatusCode == HttpStatusCode.Found ||
|
||||
webResponse.StatusCode == HttpStatusCode.Redirect ||
|
||||
webResponse.StatusCode == HttpStatusCode.Unauthorized)
|
||||
{
|
||||
var authRealm = webResponse.Headers.GetValues(Internal.HttpHeaders.TfsFedAuthRealm).FirstOrDefault();
|
||||
var authIssuer = webResponse.Headers.GetValues(Internal.HttpHeaders.TfsFedAuthIssuer).FirstOrDefault();
|
||||
var wwwAuthenticate = webResponse.Headers.GetValues(Internal.HttpHeaders.WwwAuthenticate);
|
||||
if (!String.IsNullOrEmpty(authIssuer) && !String.IsNullOrEmpty(authRealm))
|
||||
{
|
||||
return webResponse.StatusCode != HttpStatusCode.Unauthorized || wwwAuthenticate.Any(x => x.StartsWith("TFS-Federated", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal override string GetAuthenticationChallenge(IHttpResponse webResponse)
|
||||
{
|
||||
var authRealm = webResponse.Headers.GetValues(Internal.HttpHeaders.TfsFedAuthRealm).FirstOrDefault();
|
||||
var authIssuer = webResponse.Headers.GetValues(Internal.HttpHeaders.TfsFedAuthIssuer).FirstOrDefault();
|
||||
return string.Format(CultureInfo.InvariantCulture, "TFS-Federated realm={0}, issuer={1}", authRealm, authIssuer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a provider for retrieving security tokens for the provided credentials.
|
||||
/// </summary>
|
||||
/// <returns>An issued token provider for the current credential</returns>
|
||||
protected override IssuedTokenProvider OnCreateTokenProvider(
|
||||
Uri serverUrl,
|
||||
IHttpResponse response)
|
||||
{
|
||||
// The response is only null when attempting to determine the most appropriate token provider to
|
||||
// use for the connection. The only way we should do anything here is if we have an initial token
|
||||
// since that means we can present something without making a server call.
|
||||
if (response == null && base.InitialToken == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Uri signInUrl = null;
|
||||
String realm = string.Empty;
|
||||
if (response != null)
|
||||
{
|
||||
realm = response.Headers.GetValues(Internal.HttpHeaders.TfsFedAuthRealm).FirstOrDefault();
|
||||
signInUrl = new Uri(new Uri(response.Headers.GetValues(Internal.HttpHeaders.TfsFedAuthIssuer).FirstOrDefault()).GetLeftPart(UriPartial.Authority));
|
||||
}
|
||||
|
||||
return new VssServiceIdentityTokenProvider(this, serverUrl, signInUrl, realm, m_innerHandler);
|
||||
}
|
||||
|
||||
private readonly String m_userName;
|
||||
private readonly String m_password;
|
||||
|
||||
[NonSerialized]
|
||||
private readonly DelegatingHandler m_innerHandler = null;
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using GitHub.Services.Common.Internal;
|
||||
|
||||
namespace GitHub.Services.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides simple web token used for OAuth authentication.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public sealed class VssServiceIdentityToken : IssuedToken
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new <c>VssServiceIdentityToken</c> instance with the specified token value.
|
||||
/// </summary>
|
||||
/// <param name="token">The token value as a string</param>
|
||||
public VssServiceIdentityToken(string token)
|
||||
{
|
||||
ArgumentUtility.CheckStringForNullOrEmpty(token, "token");
|
||||
|
||||
m_token = token;
|
||||
//.ValidFrom = DateTime.UtcNow;
|
||||
|
||||
// Read out the expiration time for the ValidTo field if we can find it
|
||||
Dictionary<string, string> nameValues;
|
||||
if (TryGetNameValues(token, out nameValues))
|
||||
{
|
||||
string expiresOnValue;
|
||||
if (nameValues.TryGetValue(c_expiresName, out expiresOnValue))
|
||||
{
|
||||
// The time is represented as standard epoch
|
||||
// base.ValidTo = s_epoch.AddSeconds(Convert.ToUInt64(expiresOnValue, CultureInfo.CurrentCulture));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String Token
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_token;
|
||||
}
|
||||
}
|
||||
|
||||
protected internal override VssCredentialsType CredentialType
|
||||
{
|
||||
get
|
||||
{
|
||||
return VssCredentialsType.ServiceIdentity;
|
||||
}
|
||||
}
|
||||
|
||||
internal override void ApplyTo(IHttpRequest request)
|
||||
{
|
||||
request.Headers.SetValue(Internal.HttpHeaders.Authorization, "WRAP access_token=\"" + m_token + "\"");
|
||||
}
|
||||
|
||||
internal static VssServiceIdentityToken ExtractToken(string responseValue)
|
||||
{
|
||||
// Extract the actual token string
|
||||
string token = UriUtility.UrlDecode(responseValue
|
||||
.Split('&')
|
||||
.Single(value => value.StartsWith("wrap_access_token=", StringComparison.OrdinalIgnoreCase))
|
||||
.Split('=')[1], VssHttpRequestSettings.Encoding);
|
||||
|
||||
return new VssServiceIdentityToken(token);
|
||||
}
|
||||
|
||||
internal static bool TryGetNameValues(
|
||||
string token,
|
||||
out Dictionary<string, string> tokenValues)
|
||||
{
|
||||
tokenValues = null;
|
||||
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
tokenValues =
|
||||
token
|
||||
.Split('&')
|
||||
.Aggregate(
|
||||
new Dictionary<string, string>(),
|
||||
(dict, rawNameValue) =>
|
||||
{
|
||||
if (rawNameValue == string.Empty)
|
||||
{
|
||||
return dict;
|
||||
}
|
||||
|
||||
string[] nameValue = rawNameValue.Split('=');
|
||||
|
||||
if (nameValue.Length != 2)
|
||||
{
|
||||
return dict;
|
||||
}
|
||||
|
||||
if (dict.ContainsKey(nameValue[0]) == true)
|
||||
{
|
||||
return dict;
|
||||
}
|
||||
|
||||
dict.Add(UriUtility.UrlDecode(nameValue[0]), UriUtility.UrlDecode(nameValue[1]));
|
||||
return dict;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
private string m_token;
|
||||
private const string c_expiresName = "ExpiresOn";
|
||||
}
|
||||
}
|
||||
@@ -1,201 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.Services.Common.Diagnostics;
|
||||
using GitHub.Services.Common.Internal;
|
||||
|
||||
namespace GitHub.Services.Common
|
||||
{
|
||||
internal sealed class VssServiceIdentityTokenProvider : IssuedTokenProvider
|
||||
{
|
||||
public VssServiceIdentityTokenProvider(
|
||||
VssServiceIdentityCredential credential,
|
||||
Uri serverUrl,
|
||||
Uri signInUrl,
|
||||
string realm,
|
||||
DelegatingHandler innerHandler)
|
||||
: this(credential, serverUrl, signInUrl, realm)
|
||||
{
|
||||
m_innerHandler = innerHandler;
|
||||
}
|
||||
|
||||
public VssServiceIdentityTokenProvider(
|
||||
VssServiceIdentityCredential credential,
|
||||
Uri serverUrl,
|
||||
Uri signInUrl,
|
||||
string realm)
|
||||
: base(credential, serverUrl, signInUrl)
|
||||
{
|
||||
Realm = realm;
|
||||
}
|
||||
|
||||
protected override string AuthenticationParameter
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.Realm) && this.SignInUrl == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "issuer=\"{0}\", realm=\"{1}\"", this.SignInUrl, this.Realm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override String AuthenticationScheme
|
||||
{
|
||||
get
|
||||
{
|
||||
return "TFS-Federated";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the simple web token credential from which this provider was created.
|
||||
/// </summary>
|
||||
public new VssServiceIdentityCredential Credential
|
||||
{
|
||||
get
|
||||
{
|
||||
return (VssServiceIdentityCredential)base.Credential;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not a call to get token will require interactivity.
|
||||
/// </summary>
|
||||
public override Boolean GetTokenIsInteractive
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the realm for the token provider.
|
||||
/// </summary>
|
||||
public String Realm
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
protected internal override bool IsAuthenticationChallenge(IHttpResponse webResponse)
|
||||
{
|
||||
if (!base.IsAuthenticationChallenge(webResponse))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// This means we were proactively constructed without any connection information. In this case
|
||||
// we return false to ensure that a new provider is reconstructed with all appropriate configuration
|
||||
// to retrieve a new token.
|
||||
if (this.SignInUrl == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string authRealm = webResponse.Headers.GetValues(HttpHeaders.TfsFedAuthRealm).FirstOrDefault();
|
||||
string authIssuer = webResponse.Headers.GetValues(HttpHeaders.TfsFedAuthIssuer).FirstOrDefault();
|
||||
Uri signInUrl = new Uri(new Uri(authIssuer).GetLeftPart(UriPartial.Authority), UriKind.Absolute);
|
||||
|
||||
// Make sure that the values match our stored values. This way if the values change we will be thrown
|
||||
// away and a new instance with correct values will be constructed.
|
||||
return this.Realm.Equals(authRealm, StringComparison.OrdinalIgnoreCase) &&
|
||||
Uri.Compare(this.SignInUrl, signInUrl, UriComponents.AbsoluteUri, UriFormat.Unescaped, StringComparison.OrdinalIgnoreCase) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Issues a request to synchronously retrieve a token for the associated credential.
|
||||
/// </summary>
|
||||
/// <param name="failedToken"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
protected override async Task<IssuedToken> OnGetTokenAsync(
|
||||
IssuedToken failedToken,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrEmpty(this.Credential.UserName) ||
|
||||
string.IsNullOrEmpty(this.Credential.Password))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
VssTraceActivity traceActivity = VssTraceActivity.Current;
|
||||
using (HttpClient client = new HttpClient(CreateMessageHandler(), false))
|
||||
{
|
||||
client.BaseAddress = this.SignInUrl;
|
||||
|
||||
KeyValuePair<string, string>[] values = new KeyValuePair<string, string>[]
|
||||
{
|
||||
new KeyValuePair<string, string>("wrap_name", this.Credential.UserName),
|
||||
new KeyValuePair<string, string>("wrap_password", this.Credential.Password),
|
||||
new KeyValuePair<string, string>("wrap_scope", this.Realm),
|
||||
};
|
||||
|
||||
Uri url = new Uri("WRAPv0.9/", UriKind.Relative);
|
||||
FormUrlEncodedContent content = new FormUrlEncodedContent(values);
|
||||
using (HttpResponseMessage response = await client.PostAsync(url, content, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
string responseValue = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
return VssServiceIdentityToken.ExtractToken(responseValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
VssHttpEventSource.Log.AuthenticationError(traceActivity, this, responseValue);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private HttpMessageHandler CreateMessageHandler()
|
||||
{
|
||||
var retryOptions = new VssHttpRetryOptions()
|
||||
{
|
||||
RetryableStatusCodes =
|
||||
{
|
||||
VssNetworkHelper.TooManyRequests,
|
||||
HttpStatusCode.InternalServerError,
|
||||
},
|
||||
};
|
||||
|
||||
HttpMessageHandler innerHandler;
|
||||
|
||||
if (m_innerHandler != null)
|
||||
{
|
||||
if (m_innerHandler.InnerHandler == null)
|
||||
{
|
||||
m_innerHandler.InnerHandler = new HttpClientHandler();
|
||||
}
|
||||
|
||||
innerHandler = m_innerHandler;
|
||||
}
|
||||
else
|
||||
{
|
||||
innerHandler = new HttpClientHandler();
|
||||
}
|
||||
|
||||
// Inherit proxy setting from VssHttpMessageHandler
|
||||
var httpClientHandler = innerHandler as HttpClientHandler;
|
||||
if (httpClientHandler != null && VssHttpMessageHandler.DefaultWebProxy != null)
|
||||
{
|
||||
httpClientHandler.Proxy = VssHttpMessageHandler.DefaultWebProxy;
|
||||
httpClientHandler.UseProxy = true;
|
||||
}
|
||||
|
||||
return new VssHttpRetryMessageHandler(retryOptions, innerHandler);
|
||||
}
|
||||
|
||||
private DelegatingHandler m_innerHandler = null;
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
||||
namespace GitHub.Services.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a credential for windows authentication against a Visual Studio Service.
|
||||
/// </summary>
|
||||
public sealed class WindowsCredential : IssuedTokenCredential
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new <c>WindowsCredential</c> instance using a default user interface provider implementation
|
||||
/// and the default network credentials.
|
||||
/// </summary>
|
||||
public WindowsCredential()
|
||||
: this(true)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <c>WindowsCredential</c> instance using a default user interface provider implementation
|
||||
/// and the default network credentials, if specified.
|
||||
/// </summary>
|
||||
/// <param name="useDefaultCredentials">True if the default credentials should be used; otherwise, false</param>
|
||||
public WindowsCredential(bool useDefaultCredentials)
|
||||
: this(useDefaultCredentials ? CredentialCache.DefaultCredentials : null)
|
||||
{
|
||||
UseDefaultCredentials = useDefaultCredentials;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <c>WindowsCredential</c> instance using a default user interface provider implementation
|
||||
/// and the specified network credentials.
|
||||
/// </summary>
|
||||
/// <param name="credentials">The windows credentials which should be used for authentication</param>
|
||||
public WindowsCredential(ICredentials credentials)
|
||||
: this(null)
|
||||
{
|
||||
m_credentials = credentials;
|
||||
UseDefaultCredentials = credentials == CredentialCache.DefaultCredentials;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <c>WindowsCredential</c> instance using the specified initial token.
|
||||
/// </summary>
|
||||
/// <param name="initialToken">An optional token which, if present, should be used before obtaining a new token</param>
|
||||
public WindowsCredential(WindowsToken initialToken)
|
||||
: base(initialToken)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the credentials associated with this windows credential.
|
||||
/// </summary>
|
||||
public ICredentials Credentials
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_credentials;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_credentials = value;
|
||||
UseDefaultCredentials = Credentials == CredentialCache.DefaultCredentials;
|
||||
}
|
||||
}
|
||||
|
||||
public override VssCredentialsType CredentialType
|
||||
{
|
||||
get
|
||||
{
|
||||
return VssCredentialsType.Windows;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating what value was passed to WindowsCredential(bool useDefaultCredentials) constructor
|
||||
/// </summary>
|
||||
public Boolean UseDefaultCredentials
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public override Boolean IsAuthenticationChallenge(IHttpResponse webResponse)
|
||||
{
|
||||
if (webResponse == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (webResponse.StatusCode == HttpStatusCode.Unauthorized &&
|
||||
webResponse.Headers.GetValues(Internal.HttpHeaders.WwwAuthenticate).Any(x => AuthenticationSchemeValid(x)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (webResponse.StatusCode == HttpStatusCode.ProxyAuthenticationRequired &&
|
||||
webResponse.Headers.GetValues(Internal.HttpHeaders.ProxyAuthenticate).Any(x => AuthenticationSchemeValid(x)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override IssuedTokenProvider OnCreateTokenProvider(
|
||||
Uri serverUrl,
|
||||
IHttpResponse response)
|
||||
{
|
||||
// If we have no idea what kind of credentials we are supposed to be using, don't play a windows token on
|
||||
// the first request.
|
||||
if (response == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (m_credentials != null)
|
||||
{
|
||||
this.InitialToken = new WindowsToken(m_credentials);
|
||||
}
|
||||
|
||||
return new WindowsTokenProvider(this, serverUrl);
|
||||
}
|
||||
|
||||
private static Boolean AuthenticationSchemeValid(String authenticateHeader)
|
||||
{
|
||||
return authenticateHeader.StartsWith("Basic", StringComparison.OrdinalIgnoreCase) ||
|
||||
authenticateHeader.StartsWith("Digest", StringComparison.OrdinalIgnoreCase) ||
|
||||
authenticateHeader.StartsWith("Negotiate", StringComparison.OrdinalIgnoreCase) ||
|
||||
authenticateHeader.StartsWith("Ntlm", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private ICredentials m_credentials;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
|
||||
namespace GitHub.Services.Common
|
||||
{
|
||||
public sealed class WindowsToken : IssuedToken, ICredentials
|
||||
{
|
||||
internal WindowsToken(ICredentials credentials)
|
||||
{
|
||||
this.Credentials = credentials;
|
||||
}
|
||||
|
||||
public ICredentials Credentials
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
protected internal override VssCredentialsType CredentialType
|
||||
{
|
||||
get
|
||||
{
|
||||
return VssCredentialsType.Windows;
|
||||
}
|
||||
}
|
||||
|
||||
internal override void ApplyTo(IHttpRequest request)
|
||||
{
|
||||
// Special-cased by the caller because we implement ICredentials
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
NetworkCredential ICredentials.GetCredential(
|
||||
Uri uri,
|
||||
String authType)
|
||||
{
|
||||
return this.Credentials?.GetCredential(uri, authType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
|
||||
namespace GitHub.Services.Common
|
||||
{
|
||||
internal sealed class WindowsTokenProvider : IssuedTokenProvider
|
||||
{
|
||||
public WindowsTokenProvider(
|
||||
WindowsCredential credential,
|
||||
Uri serverUrl)
|
||||
: base(credential, serverUrl, serverUrl)
|
||||
{
|
||||
}
|
||||
|
||||
protected override String AuthenticationScheme
|
||||
{
|
||||
get
|
||||
{
|
||||
return String.Format(CultureInfo.InvariantCulture, "{0} {1} {2} {3}", AuthenticationSchemes.Negotiate, AuthenticationSchemes.Ntlm, AuthenticationSchemes.Digest, AuthenticationSchemes.Basic);
|
||||
}
|
||||
}
|
||||
|
||||
public new WindowsCredential Credential
|
||||
{
|
||||
get
|
||||
{
|
||||
return (WindowsCredential)base.Credential;
|
||||
}
|
||||
}
|
||||
|
||||
public override Boolean GetTokenIsInteractive
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.CurrentToken == null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,6 @@ using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Sockets;
|
||||
#if !NETSTANDARD
|
||||
using System.Diagnostics.Eventing;
|
||||
#endif
|
||||
|
||||
namespace GitHub.Services.Common.Diagnostics
|
||||
{
|
||||
@@ -838,13 +835,6 @@ namespace GitHub.Services.Common.Diagnostics
|
||||
[NonEvent]
|
||||
private void SetActivityId(VssTraceActivity activity)
|
||||
{
|
||||
#if !NETSTANDARD
|
||||
if (activity != null)
|
||||
{
|
||||
Guid activityId = activity.Id;
|
||||
EventProvider.SetActivityId(ref activityId);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
@@ -876,15 +866,6 @@ namespace GitHub.Services.Common.Diagnostics
|
||||
Action<Int32, String> writeEvent)
|
||||
{
|
||||
writeEvent(param0, message);
|
||||
#if !NETSTANDARD
|
||||
if (EventProvider.GetLastWriteEventError() == EventProvider.WriteEventErrorCode.EventTooBig)
|
||||
{
|
||||
foreach (String messagePart in SplitMessage(message))
|
||||
{
|
||||
writeEvent(param0, messagePart);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
@@ -895,15 +876,6 @@ namespace GitHub.Services.Common.Diagnostics
|
||||
Action<VssCredentialsType, Int32, String> writeEvent)
|
||||
{
|
||||
writeEvent(param0, param1, message);
|
||||
#if !NETSTANDARD
|
||||
if (EventProvider.GetLastWriteEventError() == EventProvider.WriteEventErrorCode.EventTooBig)
|
||||
{
|
||||
foreach (String messagePart in SplitMessage(message))
|
||||
{
|
||||
writeEvent(param0, param1, messagePart);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
@@ -914,23 +886,10 @@ namespace GitHub.Services.Common.Diagnostics
|
||||
Action<VssHttpMethod, String, String> writeEvent)
|
||||
{
|
||||
writeEvent(param0, param1, message);
|
||||
#if !NETSTANDARD
|
||||
if (EventProvider.GetLastWriteEventError() == EventProvider.WriteEventErrorCode.EventTooBig)
|
||||
{
|
||||
foreach (String messagePart in SplitMessage(message))
|
||||
{
|
||||
writeEvent(param0, param1, messagePart);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
#if !NETSTANDARD
|
||||
private unsafe void WriteEvent(
|
||||
#else
|
||||
private new unsafe void WriteEvent(
|
||||
#endif
|
||||
Int32 eventId,
|
||||
Int32 param0,
|
||||
String param1)
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
#if !NETSTANDARD
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
#endif
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace GitHub.Services.Common.Diagnostics
|
||||
@@ -38,22 +35,11 @@ namespace GitHub.Services.Common.Diagnostics
|
||||
/// </summary>
|
||||
public static VssTraceActivity Current
|
||||
{
|
||||
#if !NETSTANDARD
|
||||
get
|
||||
{
|
||||
return CallContext.LogicalGetData(VssTraceActivity.PropertyName) as VssTraceActivity;
|
||||
}
|
||||
private set
|
||||
{
|
||||
CallContext.LogicalSetData(VssTraceActivity.PropertyName, value);
|
||||
}
|
||||
#else
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
set { }
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -8,84 +8,28 @@ namespace GitHub.Services.Common.Internal
|
||||
public static class HttpHeaders
|
||||
{
|
||||
public const String ActivityId = "ActivityId";
|
||||
public const String ETag = "ETag";
|
||||
public const String TfsVersion = "X-TFS-Version";
|
||||
public const String TfsRedirect = "X-TFS-Redirect";
|
||||
public const String TfsException = "X-TFS-Exception";
|
||||
public const String TfsServiceError = "X-TFS-ServiceError";
|
||||
public const String TfsSessionHeader = "X-TFS-Session";
|
||||
public const String TfsSoapException = "X-TFS-SoapException";
|
||||
public const String TfsFedAuthRealm = "X-TFS-FedAuthRealm";
|
||||
public const String TfsFedAuthIssuer = "X-TFS-FedAuthIssuer";
|
||||
public const String TfsFedAuthRedirect = "X-TFS-FedAuthRedirect";
|
||||
public const String VssAuthorizationEndpoint = "X-VSS-AuthorizationEndpoint";
|
||||
public const String VssPageHandlers = "X-VSS-PageHandlers";
|
||||
public const String VssE2EID = "X-VSS-E2EID";
|
||||
public const String VssOrchestrationId = "X-VSS-OrchestrationId";
|
||||
public const String AuditCorrelationId = "X-VSS-Audit-CorrelationId";
|
||||
public const String VssOriginUserAgent = "X-VSS-OriginUserAgent";
|
||||
|
||||
// Internal Headers that we use in our client.
|
||||
public const string TfsInstanceHeader = "X-TFS-Instance";
|
||||
public const string TfsVersionOneHeader = "X-VersionControl-Instance";
|
||||
|
||||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tfs")]
|
||||
public const string TfsImpersonate = "X-TFS-Impersonate";
|
||||
public const string TfsSubjectDescriptorImpersonate = "X-TFS-SubjectDescriptorImpersonate";
|
||||
|
||||
public const string MsContinuationToken = "X-MS-ContinuationToken";
|
||||
public const String VssUserData = "X-VSS-UserData";
|
||||
public const String VssAgentHeader = "X-VSS-Agent";
|
||||
public const String VssAuthenticateError = "X-VSS-AuthenticateError";
|
||||
public const string VssReauthenticationAction = "X-VSS-ReauthenticationAction";
|
||||
public const string RequestedWith = "X-Requested-With";
|
||||
|
||||
public const String VssRateLimitResource = "X-RateLimit-Resource";
|
||||
public const String VssRateLimitDelay = "X-RateLimit-Delay";
|
||||
public const String VssRateLimitLimit = "X-RateLimit-Limit";
|
||||
public const String VssRateLimitRemaining = "X-RateLimit-Remaining";
|
||||
public const String VssRateLimitReset = "X-RateLimit-Reset";
|
||||
public const String RetryAfter = "Retry-After";
|
||||
|
||||
public const String VssGlobalMessage = "X-VSS-GlobalMessage";
|
||||
|
||||
public const String VssRequestRouted = "X-VSS-RequestRouted";
|
||||
public const String VssUseRequestRouting = "X-VSS-UseRequestRouting";
|
||||
|
||||
public const string VssResourceTenant = "X-VSS-ResourceTenant";
|
||||
public const String VssOverridePrompt = "X-VSS-OverridePrompt";
|
||||
|
||||
public const String VssOAuthS2STargetService = "X-VSS-S2STargetService";
|
||||
|
||||
public const String VssHostOfflineError = "X-VSS-HostOfflineError";
|
||||
|
||||
public const string VssForceMsaPassThrough = "X-VSS-ForceMsaPassThrough";
|
||||
public const string VssRequestPriority = "X-VSS-RequestPriority";
|
||||
|
||||
// This header represents set of ';' delimited mappings (usually one) that are considered by DetermineAccessMapping API
|
||||
public const string VssClientAccessMapping = "X-VSS-ClientAccessMapping";
|
||||
|
||||
// This header is used to download artifacts anonymously.
|
||||
// N.B. Some resources secured with download tickets (e.g. TFVC files) are still retrieved with the download
|
||||
// ticket in the query string.
|
||||
public const string VssDownloadTicket = "X-VSS-DownloadTicket";
|
||||
|
||||
public const string IfModifiedSince = "If-Modified-Since";
|
||||
public const string Authorization = "Authorization";
|
||||
public const string Location = "Location";
|
||||
public const string ProxyAuthenticate = "Proxy-Authenticate";
|
||||
public const string WwwAuthenticate = "WWW-Authenticate";
|
||||
|
||||
public const string AfdIncomingRouteKey = "X-FD-RouteKey";
|
||||
public const string AfdOutgoingRouteKey = "X-AS-RouteKey";
|
||||
public const string AfdIncomingEndpointList = "X-FD-RouteKeyApplicationEndpointList";
|
||||
public const string AfdOutgoingEndpointList = "X-AS-RouteKeyApplicationEndpointList";
|
||||
public const string AfdResponseRef = "X-MSEdge-Ref";
|
||||
public const string AfdIncomingClientIp = "X-FD-ClientIP";
|
||||
public const string AfdIncomingSocketIp = "X-FD-SocketIP";
|
||||
public const string AfdIncomingRef = "X-FD-Ref";
|
||||
public const string AfdIncomingEventId = "X-FD-EventId";
|
||||
public const string AfdIncomingEdgeEnvironment = "X-FD-EdgeEnvironment";
|
||||
public const string AfdOutgoingQualityOfResponse = "X-AS-QualityOfResponse";
|
||||
public const string AfdOutgoingClientIp = "X-MSEdge-ClientIP";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,553 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GitHub.Services.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides path normalization/expansion for absolute, relative and UNC-style paths
|
||||
/// and supports paths that contain more than 248 characters.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This utility class can be used in place of the .NET Path and Directory classes
|
||||
/// that throw System.IO.PathTooLongException when paths are longer than 248 characters
|
||||
/// </remarks>
|
||||
public static class LongPathUtility
|
||||
{
|
||||
private static Regex AbsolutePathRegEx = new Regex(@"^([a-zA-Z]:\\|\\\\)", RegexOptions.CultureInvariant | RegexOptions.Compiled);
|
||||
private const int ERROR_FILE_NOT_FOUND = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of directory names under the path specified, and optionally all subdirectories
|
||||
/// </summary>
|
||||
/// <param name="path">The directory to search</param>
|
||||
/// <param name="recursiveSearch">Specifies whether the search operation should include only the currect directory or all subdirectories</param>
|
||||
/// <returns>A list of all subdirectories</returns>
|
||||
public static IEnumerable<string> EnumerateDirectories(string path, bool recursiveSearch)
|
||||
{
|
||||
var directoryPaths = new List<string>();
|
||||
EnumerateDirectoriesInternal(directoryPaths, path, recursiveSearch);
|
||||
return directoryPaths;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of file names under the path specified, and optionally within all subdirectories.
|
||||
/// </summary>
|
||||
/// <param name="path">The directory to search</param>
|
||||
/// <param name="recursiveSearch">Specifies whether the search operation should include only the current directory or all subdirectories</param>
|
||||
/// <returns>
|
||||
/// A list of full file names(including path) contained in the directory specified that match the specified search pattern.</returns>
|
||||
public static IEnumerable<string> EnumerateFiles(string path, bool recursiveSearch)
|
||||
{
|
||||
return EnumerateFiles(path, "*", recursiveSearch);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerable collection of file names that match a search pattern in a specified path,
|
||||
/// and optionally searches subdirectories.
|
||||
/// </summary>
|
||||
/// <param name="path">The directory to search</param>
|
||||
/// <param name="matchPattern">The search string to match against the names of the files</param>
|
||||
/// <param name="recursiveSearch">Specifies whether the search operation should include only the current directory or all subdirectories</param>
|
||||
/// <returns>
|
||||
/// A list of full file names(including path) contained in the directory specified (and subdirectories optionally) that match the specified pattern.
|
||||
/// </returns>
|
||||
public static IEnumerable<string> EnumerateFiles(string path, string matchPattern, bool recursiveSearch)
|
||||
{
|
||||
if (!DirectoryExists(path))
|
||||
{
|
||||
throw new DirectoryNotFoundException($"The path '{path}' is not a valid directory.");
|
||||
}
|
||||
|
||||
var filePaths = new List<string>();
|
||||
EnumerateFilesInternal(filePaths, path, matchPattern, recursiveSearch);
|
||||
return filePaths;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true/false whether the file exists. This method inspects the
|
||||
/// file system attributes and supports files without extensions (ex: DIRS, Sources). This method
|
||||
/// supports file paths that are longer than 260 characters.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The file path to inspect</param>
|
||||
/// <returns>
|
||||
/// True if the file exists or false if not
|
||||
/// </returns>
|
||||
public static bool FileExists(string filePath)
|
||||
{
|
||||
return FileOrDirectoryExists(filePath, isDirectory: false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true/false whether the directory exists. This method inspects the
|
||||
/// file system attributes and supports files without extensions (ex: DIRS, Sources). This method
|
||||
/// supports file paths that are longer than 260 characters.
|
||||
/// </summary>
|
||||
/// <param name="directoryPath">The file path to inspect</param>
|
||||
/// <returns>
|
||||
/// True if the directory exists or false if not
|
||||
/// </returns>
|
||||
public static bool DirectoryExists(string directoryPath)
|
||||
{
|
||||
return FileOrDirectoryExists(directoryPath, isDirectory: true);
|
||||
}
|
||||
|
||||
private static bool FileOrDirectoryExists(string filePath, bool isDirectory)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(filePath))
|
||||
{
|
||||
throw new ArgumentException("A path to the file is required and cannot be null, empty or whitespace", "filePath");
|
||||
}
|
||||
|
||||
bool pathExists = false;
|
||||
|
||||
// File names may or may not include an extension (ex: DIRS, Sources). We have to look at the attributes
|
||||
// on the file system object in order to distinguish a directory from a file
|
||||
var attributes = (FlagsAndAttributes)NativeMethods.GetFileAttributes(filePath);
|
||||
|
||||
if (attributes != FlagsAndAttributes.InvalidFileAttributes)
|
||||
{
|
||||
bool pathIsDirectory = (attributes & FlagsAndAttributes.Directory) == FlagsAndAttributes.Directory;
|
||||
|
||||
if (pathIsDirectory == isDirectory)
|
||||
{
|
||||
pathExists = true;
|
||||
}
|
||||
}
|
||||
|
||||
return pathExists;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the fully expanded/normalized path. This method supports paths that are
|
||||
/// longer than 248 characters.
|
||||
/// </summary>
|
||||
/// <param name="path">The file or directory path</param>
|
||||
/// <returns></returns>
|
||||
public static string GetFullNormalizedPath(string path)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
throw new ArgumentException("A path is required and cannot be null, empty or whitespace", "path");
|
||||
}
|
||||
|
||||
string outPath = path;
|
||||
|
||||
// We need the length of the absolute path in order to prepare a buffer of
|
||||
// the correct size
|
||||
uint bufferSize = NativeMethods.GetFullPathName(path, 0, null, null);
|
||||
int lastWin32Error = Marshal.GetLastWin32Error();
|
||||
|
||||
if (bufferSize > 0)
|
||||
{
|
||||
var absolutePath = new StringBuilder((int)bufferSize);
|
||||
uint length = NativeMethods.GetFullPathName(path, bufferSize, absolutePath, null);
|
||||
lastWin32Error = Marshal.GetLastWin32Error();
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
outPath = absolutePath.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Path resolution failed
|
||||
throw new Win32Exception(
|
||||
lastWin32Error,
|
||||
String.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"Path normalization/expansion failed. The path length was not returned by the Kernel32 subsystem for '{0}'.",
|
||||
path
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Path resolution failed and the path length could not
|
||||
// be determined
|
||||
throw new Win32Exception(
|
||||
lastWin32Error,
|
||||
String.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"Path normalization/expansion failed. A full path was not returned by the Kernel32 subsystem for '{0}'.",
|
||||
path
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return outPath != null ? outPath.TrimEnd('\\') : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified path is an absolute path or not.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to be tested.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the path is absolute; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public static bool IsAbsolutePath(string path)
|
||||
{
|
||||
return LongPathUtility.AbsolutePathRegEx.Match(path).Success;
|
||||
}
|
||||
|
||||
public static string RemoveExtendedLengthPathPrefix(string inPath)
|
||||
{
|
||||
string outPath = inPath;
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(inPath))
|
||||
{
|
||||
if (inPath.StartsWith("\\", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// ex: \\?\UNC\server\share to \\server\share
|
||||
outPath = inPath.Replace(@"\\?\UNC", @"\");
|
||||
|
||||
// ex: \\?\c:\windows to c:\windows
|
||||
outPath = outPath.Replace(@"\\?\", String.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
return outPath;
|
||||
}
|
||||
|
||||
private static string CombinePaths(string pathA, string pathB)
|
||||
{
|
||||
if (pathA == null)
|
||||
{
|
||||
throw new ArgumentNullException("pathA");
|
||||
}
|
||||
|
||||
if (pathB == null)
|
||||
{
|
||||
throw new ArgumentNullException("pathB");
|
||||
}
|
||||
|
||||
// The Path class does not suffer from the 248/260 character limitation
|
||||
// that the File and Directory classes do.
|
||||
return Path.Combine(
|
||||
pathA.TrimEnd('\\'),
|
||||
pathB.TrimStart('\\')
|
||||
);
|
||||
}
|
||||
|
||||
private static string ConvertToExtendedLengthPath(string path)
|
||||
{
|
||||
string extendedLengthPath = GetFullNormalizedPath(path);
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(extendedLengthPath))
|
||||
{
|
||||
//no need to modify- it's already unicode
|
||||
if (!extendedLengthPath.StartsWith(@"\\?", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// ex: \\server\share
|
||||
if (extendedLengthPath.StartsWith(@"\\", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// make it \\?\UNC\server\share
|
||||
extendedLengthPath = String.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
@"\\?\UNC{0}",
|
||||
extendedLengthPath.Substring(1)
|
||||
);
|
||||
}
|
||||
else //not unicode already, and not UNC
|
||||
{
|
||||
extendedLengthPath = String.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
@"\\?\{0}",
|
||||
extendedLengthPath
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return extendedLengthPath;
|
||||
}
|
||||
|
||||
private static IEnumerable<string> EnumerateDirectoriesInPath(string path)
|
||||
{
|
||||
SafeFindHandle handle = null;
|
||||
var findData = new FindData();
|
||||
var childDirectories = new List<string>();
|
||||
|
||||
using (handle = NativeMethods.FindFirstFile(CombinePaths(ConvertToExtendedLengthPath(path), "*"), findData))
|
||||
{
|
||||
if (!handle.IsInvalid)
|
||||
{
|
||||
bool searchComplete = false;
|
||||
|
||||
do
|
||||
{
|
||||
// skip the dot directories
|
||||
if (!findData.fileName.Equals(@".") && !findData.fileName.Equals(@".."))
|
||||
{
|
||||
if ((findData.fileAttributes & (int)FileAttributes.Directory) != 0)
|
||||
{
|
||||
childDirectories.Add(RemoveExtendedLengthPathPrefix(CombinePaths(path, findData.fileName)));
|
||||
}
|
||||
}
|
||||
|
||||
if (NativeMethods.FindNextFile(handle, findData))
|
||||
{
|
||||
if (handle.IsInvalid)
|
||||
{
|
||||
throw new Win32Exception(
|
||||
Marshal.GetLastWin32Error(),
|
||||
String.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"Enumerating subdirectories for path '{0}' failed.",
|
||||
path
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
searchComplete = true;
|
||||
}
|
||||
|
||||
} while (!searchComplete);
|
||||
}
|
||||
}
|
||||
|
||||
return childDirectories;
|
||||
}
|
||||
|
||||
private static IEnumerable<string> EnumerateFilesInPath(string path, string matchPattern)
|
||||
{
|
||||
SafeFindHandle handle = null;
|
||||
var findData = new FindData();
|
||||
var fullFilePaths = new List<string>();
|
||||
|
||||
using (handle = NativeMethods.FindFirstFile(CombinePaths(ConvertToExtendedLengthPath(path), matchPattern), findData))
|
||||
{
|
||||
int lastWin32Error = Marshal.GetLastWin32Error();
|
||||
|
||||
if (handle.IsInvalid)
|
||||
{
|
||||
if (lastWin32Error != ERROR_FILE_NOT_FOUND)
|
||||
{
|
||||
throw new Win32Exception(
|
||||
lastWin32Error,
|
||||
String.Format(CultureInfo.InvariantCulture, "Enumerating files for path '{0}' failed.", path)
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool searchComplete = false;
|
||||
|
||||
do
|
||||
{
|
||||
// skip the dot directories
|
||||
if (!findData.fileName.Equals(@".") && !findData.fileName.Equals(@".."))
|
||||
{
|
||||
if ((findData.fileAttributes & (int)FileAttributes.Directory) == 0)
|
||||
{
|
||||
fullFilePaths.Add(RemoveExtendedLengthPathPrefix(CombinePaths(path, findData.fileName)));
|
||||
}
|
||||
}
|
||||
|
||||
if (NativeMethods.FindNextFile(handle, findData))
|
||||
{
|
||||
lastWin32Error = Marshal.GetLastWin32Error();
|
||||
|
||||
if (handle.IsInvalid)
|
||||
{
|
||||
throw new Win32Exception(
|
||||
lastWin32Error,
|
||||
String.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"Enumerating subdirectories for path '{0}' failed.",
|
||||
path
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
searchComplete = true;
|
||||
}
|
||||
|
||||
} while (!searchComplete);
|
||||
}
|
||||
}
|
||||
|
||||
return fullFilePaths;
|
||||
}
|
||||
|
||||
private static void EnumerateFilesInternal(List<string> filePaths, string path, string matchPattern, bool recursiveSearch)
|
||||
{
|
||||
var fullFilePaths = EnumerateFilesInPath(path, matchPattern);
|
||||
if (fullFilePaths.Any())
|
||||
{
|
||||
lock (filePaths)
|
||||
{
|
||||
filePaths.AddRange(fullFilePaths);
|
||||
}
|
||||
}
|
||||
|
||||
if (recursiveSearch)
|
||||
{
|
||||
var directorySearchPaths = EnumerateDirectoriesInPath(path);
|
||||
if (directorySearchPaths.Any())
|
||||
{
|
||||
Parallel.ForEach(
|
||||
directorySearchPaths,
|
||||
(searchPath) =>
|
||||
{
|
||||
EnumerateFilesInternal(filePaths, searchPath, matchPattern, recursiveSearch);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void EnumerateDirectoriesInternal(List<string> directoryPaths, string path, bool recursiveSearch)
|
||||
{
|
||||
var directorySearchPaths = EnumerateDirectoriesInPath(path);
|
||||
if (directorySearchPaths.Any())
|
||||
{
|
||||
lock (directoryPaths)
|
||||
{
|
||||
directoryPaths.AddRange(directorySearchPaths);
|
||||
}
|
||||
|
||||
if (recursiveSearch)
|
||||
{
|
||||
// This will not ensure that the directory paths are added to the list
|
||||
// in alphabetical order but does provide performance 2 - 4 times better than the
|
||||
// canonical Directory.GetDirectories() method.
|
||||
Parallel.ForEach(
|
||||
directorySearchPaths,
|
||||
(searchPath) =>
|
||||
{
|
||||
EnumerateDirectoriesInternal(directoryPaths, searchPath, recursiveSearch);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Kernel32.dll native interop methods for use with utility file/path parsing
|
||||
/// operations
|
||||
/// </summary>
|
||||
private static class NativeMethods
|
||||
{
|
||||
private const string Kernel32Dll = "kernel32.dll";
|
||||
|
||||
[DllImport(Kernel32Dll, CharSet = CharSet.Unicode, BestFitMapping = false, ThrowOnUnmappableChar = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool FindClose(IntPtr hFindFile);
|
||||
|
||||
[SuppressMessage("Microsoft.Globalization", "CA2101:SpecifyMarshalingForPInvokeStringArguments", MessageId = "FindData.alternateFileName")]
|
||||
[SuppressMessage("Microsoft.Globalization", "CA2101:SpecifyMarshalingForPInvokeStringArguments", MessageId = "FindData.fileName")]
|
||||
[DllImport(Kernel32Dll, CharSet = CharSet.Unicode, BestFitMapping = false, ThrowOnUnmappableChar = true, SetLastError = true)]
|
||||
public static extern SafeFindHandle FindFirstFile(
|
||||
[MarshalAs(UnmanagedType.LPTStr)]
|
||||
string fileName,
|
||||
[In, Out] FindData findFileData
|
||||
);
|
||||
[SuppressMessage("Microsoft.Globalization", "CA2101:SpecifyMarshalingForPInvokeStringArguments", MessageId = "FindData.alternateFileName")]
|
||||
[SuppressMessage("Microsoft.Globalization", "CA2101:SpecifyMarshalingForPInvokeStringArguments", MessageId = "FindData.fileName")]
|
||||
[DllImport(Kernel32Dll, CharSet = CharSet.Unicode, BestFitMapping = false, ThrowOnUnmappableChar = true, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool FindNextFile(SafeFindHandle hFindFile, [In, Out] FindData lpFindFileData);
|
||||
|
||||
[DllImport(Kernel32Dll, CharSet = CharSet.Unicode, BestFitMapping = false, ThrowOnUnmappableChar = true, SetLastError = true)]
|
||||
public static extern int GetFileAttributes(string lpFileName);
|
||||
|
||||
[DllImport(Kernel32Dll, CharSet = CharSet.Unicode, BestFitMapping = false, ThrowOnUnmappableChar = true, SetLastError = true)]
|
||||
public static extern uint GetFullPathName(
|
||||
[MarshalAs(UnmanagedType.LPTStr)]
|
||||
string lpFileName,
|
||||
uint nBufferLength,
|
||||
[Out]
|
||||
StringBuilder lpBuffer,
|
||||
StringBuilder lpFilePart
|
||||
);
|
||||
}
|
||||
|
||||
//for mapping to the WIN32_FIND_DATA native structure
|
||||
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed.")]
|
||||
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed.")]
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
private sealed class FindData
|
||||
{
|
||||
// NOTE:
|
||||
// Although it may seem correct to Marshal the string members of this class as UnmanagedType.LPWStr, they
|
||||
// must explicitly remain UnmanagedType.ByValTStr with the size constraints noted. Otherwise we end up with
|
||||
// COM Interop exceptions while trying to marshal the data across the PInvoke boundaries. We thus require the StyleCop
|
||||
// suppressions on the NativeMethods.FindNextFile() method above.
|
||||
public int fileAttributes;
|
||||
public System.Runtime.InteropServices.ComTypes.FILETIME creationTime;
|
||||
public System.Runtime.InteropServices.ComTypes.FILETIME lastAccessTime;
|
||||
public System.Runtime.InteropServices.ComTypes.FILETIME lastWriteTime;
|
||||
public int nFileSizeHigh;
|
||||
public int nFileSizeLow;
|
||||
public int dwReserved0;
|
||||
public int dwReserved1;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
|
||||
public string fileName;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
|
||||
public string alternateFileName;
|
||||
}
|
||||
|
||||
//A Win32 safe find handle in which a return value of -1 indicates it's invalid
|
||||
private sealed class SafeFindHandle : Microsoft.Win32.SafeHandles.SafeHandleMinusOneIsInvalid
|
||||
{
|
||||
public SafeFindHandle()
|
||||
: base(true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return NativeMethods.FindClose(handle);
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
private enum FlagsAndAttributes : uint
|
||||
{
|
||||
None = 0x00000000,
|
||||
Readonly = 0x00000001,
|
||||
Hidden = 0x00000002,
|
||||
System = 0x00000004,
|
||||
Directory = 0x00000010,
|
||||
Archive = 0x00000020,
|
||||
Device = 0x00000040,
|
||||
Normal = 0x00000080,
|
||||
Temporary = 0x00000100,
|
||||
SparseFile = 0x00000200,
|
||||
ReparsePoint = 0x00000400,
|
||||
Compressed = 0x00000800,
|
||||
Offline = 0x00001000,
|
||||
NotContentIndexed = 0x00002000,
|
||||
Encrypted = 0x00004000,
|
||||
Write_Through = 0x80000000,
|
||||
Overlapped = 0x40000000,
|
||||
NoBuffering = 0x20000000,
|
||||
RandomAccess = 0x10000000,
|
||||
SequentialScan = 0x08000000,
|
||||
DeleteOnClose = 0x04000000,
|
||||
BackupSemantics = 0x02000000,
|
||||
PosixSemantics = 0x01000000,
|
||||
OpenReparsePoint = 0x00200000,
|
||||
OpenNoRecall = 0x00100000,
|
||||
FirstPipeInstance = 0x00080000,
|
||||
|
||||
InvalidFileAttributes = 0xFFFFFFFF // Returned by GetFileAttributes on Non existant path
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,7 +218,6 @@ namespace GitHub.Services.Common
|
||||
}
|
||||
}
|
||||
|
||||
#if NETSTANDARD
|
||||
/// <summary>
|
||||
/// Portable compliant way to get a constructor with specified arguments. This will return a constructor that is public or private as long as the arguments match. NULL will be returned if there is no match.
|
||||
/// Note that it will pick the first one it finds that matches, which is not necesarily the best match.
|
||||
@@ -263,7 +262,6 @@ namespace GitHub.Services.Common
|
||||
}
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
|
||||
private static PropertyInfo GetPublicInstancePropertyInfo(Type type, string name)
|
||||
{
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
// ************************************************************************************************
|
||||
// Microsoft Team Foundation
|
||||
//
|
||||
// Microsoft Confidential
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// File: VssStringComparer.cs
|
||||
// Area: Team Foundation
|
||||
// Classes: VssStringComparer
|
||||
// Contents: The Team Foundation string comparison class provides inner classes
|
||||
// that are used to provide semantic-specific Equals and Compare methods
|
||||
// and a semantic-specific StringComparer instance. New semantics should
|
||||
// be added on an as-needed basis.
|
||||
// ************************************************************************************************
|
||||
using System;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace GitHub.Services.Common
|
||||
|
||||
@@ -13,9 +13,6 @@ namespace GitHub.Services.Common.Internal
|
||||
{
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
#if !NETSTANDARD
|
||||
[CLSCompliant(false)]
|
||||
#endif
|
||||
public static class XmlUtility
|
||||
{
|
||||
internal static FileStream OpenFile(String path, FileShare sharing, Boolean saveFile)
|
||||
|
||||
@@ -5,16 +5,6 @@ using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace GitHub.Services.Common
|
||||
{
|
||||
public static class AdminConstants
|
||||
{
|
||||
/// <summary>
|
||||
/// Each incoming web request is assigned a server process id, this constant defines
|
||||
/// an element within the Context.Items[] to hold that value.
|
||||
/// </summary>
|
||||
public const String ServerProcessID = "serverProcessID";
|
||||
public const String ApplicationName = "ApplicationName";
|
||||
}
|
||||
|
||||
[GenerateSpecificConstants]
|
||||
public static class IdentityConstants
|
||||
{
|
||||
@@ -352,370 +342,6 @@ namespace GitHub.Services.Common
|
||||
public static readonly ISet<string> WhiteListedProperties = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public static class DirectoryRoleConstants
|
||||
{
|
||||
/// Name of the directory role that represents "Company Administrator/Global Admin"
|
||||
public const string CompanyAdministrator = "Company Administrator";
|
||||
}
|
||||
|
||||
// Used with Registration entries
|
||||
[GenerateSpecificConstants]
|
||||
public static class ToolNames
|
||||
{
|
||||
public const string Framework = "Framework";
|
||||
[GenerateConstant]
|
||||
public const string VersionControl = "VersionControl";
|
||||
[GenerateConstant]
|
||||
public const string WorkItemTracking = "WorkItemTracking";
|
||||
[GenerateConstant]
|
||||
public const string RemoteWorkItemTracking = "RemoteWorkItemTracking";
|
||||
public const string CoreServices = "vstfs";
|
||||
public const string Warehouse = "Reports";
|
||||
[GenerateConstant]
|
||||
public const string TeamBuild = "Build";
|
||||
public const string ProxyServer = "ps";
|
||||
public const string TeamFoundation = "vstfs";
|
||||
public const string SharePoint = "Wss";
|
||||
[GenerateConstant]
|
||||
public const string TestManagement = "TestManagement";
|
||||
public const string LabManagement = "LabManagement";
|
||||
public const string ReleaseManagement = "ReleaseManagement";
|
||||
public const string SyncService = "SyncService";
|
||||
public const string TestRig = "TestRig";
|
||||
public const string TSWebAccess = "TSWebAccess";
|
||||
public const string ProjectServer = "ProjectServer";
|
||||
public const string DeploymentRig = "DeploymentRig";
|
||||
public const string TeamProjects = "TeamProjects"; // contains specific project registration entries (project portal, process guidance and doc url)
|
||||
public const string Discussion = "Discussion";
|
||||
[GenerateConstant]
|
||||
public const string Requirements = "Requirements";
|
||||
[GenerateConstant]
|
||||
public const string Hyperlink = "Hyperlink";
|
||||
public const string Classification = "Classification";
|
||||
[GenerateConstant]
|
||||
public const string Legacy = "Legacy";
|
||||
[GenerateConstant]
|
||||
public const string CodeSense = "CodeSense";
|
||||
[GenerateConstant]
|
||||
public const string Git = "Git";
|
||||
[GenerateConstant]
|
||||
public const string CodeReview = "CodeReview";
|
||||
[GenerateConstant]
|
||||
public const string ProjectDownload = "ProjectDownload";
|
||||
public const string DistributedTask = "DistributedTask";
|
||||
[GenerateConstant]
|
||||
public const string Wiki = "Wiki";
|
||||
|
||||
public const string Search = "Search";
|
||||
[GenerateConstant]
|
||||
public const string GitHub = "GitHub";
|
||||
}
|
||||
|
||||
// Artifact types
|
||||
[GenerateSpecificConstants]
|
||||
public static class ArtifactTypeNames
|
||||
{
|
||||
public const string Project = "TeamProject";
|
||||
public const string Node = "Node";
|
||||
public const string Collector = "Collector";
|
||||
public const string TestResult = "TestResult";
|
||||
[GenerateConstant]
|
||||
public const string TcmResult = "TcmResult";
|
||||
[GenerateConstant]
|
||||
public const string TcmResultAttachment = "TcmResultAttachment";
|
||||
[GenerateConstant]
|
||||
public const string TcmTest = "TcmTest";
|
||||
[GenerateConstant]
|
||||
public const string Build = "Build";
|
||||
public const string BuildAgent = "Agent";
|
||||
public const string BuildDefinition = "Definition";
|
||||
public const string BuildController = "Controller";
|
||||
public const string BuildGroup = "Group";
|
||||
public const string BuildRequest = "Request";
|
||||
public const string BuildServiceHost = "ServiceHost";
|
||||
[GenerateConstant]
|
||||
public const string VersionedItem = "VersionedItem";
|
||||
[GenerateConstant]
|
||||
public const string LatestItemVersion = "LatestItemVersion";
|
||||
[GenerateConstant]
|
||||
public const string Changeset = "Changeset";
|
||||
public const string Label = "Label";
|
||||
[GenerateConstant]
|
||||
public const string Shelveset = "Shelveset";
|
||||
public const string ShelvedItem = "ShelvedItem";
|
||||
[GenerateConstant]
|
||||
public const string WorkItem = "WorkItem";
|
||||
public const string Query = "Query";
|
||||
public const string Results = "Results";
|
||||
public const string LabEnvironment = "LabEnvironment";
|
||||
public const string LabTemplate = "LabTemplate";
|
||||
public const string LabSystem = "LabSystem";
|
||||
public const string TeamProjectHostGroup = "TeamProjectHostGroup";
|
||||
public const string TeamProjectLibraryShare = "TeamProjectLibraryShare";
|
||||
public const string TeamProjectCollectionLibraryShare = "TeamProjectCollectionLibraryShare";
|
||||
public const string TeamProjectCollectionHostGroup = "TeamProjectCollectionHostGroup";
|
||||
public const string TestMachine = "TestMachine";
|
||||
[GenerateConstant]
|
||||
public const string Storyboard = "Storyboard";
|
||||
[GenerateConstant]
|
||||
public const string Commit = "Commit";
|
||||
public const string LaunchLatestVersionedItem = "LaunchLatestVersionedItem";
|
||||
[GenerateConstant]
|
||||
public const string CodeReviewId = "CodeReviewId";
|
||||
[GenerateConstant]
|
||||
public const string CodeReviewSdkId = "ReviewId";
|
||||
[GenerateConstant]
|
||||
public const string PullRequestId = "PullRequestId";
|
||||
[GenerateConstant]
|
||||
public const string ProjectDownloadProject = "Project";
|
||||
/// <summary>
|
||||
/// A Git Ref
|
||||
/// </summary>
|
||||
[GenerateConstant]
|
||||
public const string Ref = "Ref";
|
||||
|
||||
public const string TaskAgentPoolMaintenance = "PoolMaintenance";
|
||||
[GenerateConstant]
|
||||
public const string WikiPage = "WikiPage";
|
||||
|
||||
// GitHub
|
||||
[GenerateConstant]
|
||||
public const string PullRequest = "PullRequest";
|
||||
[GenerateConstant]
|
||||
public const string Issue = "Issue";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constant strings used in Notifications
|
||||
/// </summary>
|
||||
public static class NotificationConstants
|
||||
{
|
||||
/// <summary>
|
||||
/// Macro used in subscriptions which will be replaced by the project name when evaluated
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.MyProjectNameMacro in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String MyProjectNameMacro = "@@MyProjectName@@";
|
||||
|
||||
/// <summary>
|
||||
/// Macro used in subscriptions which will be replaced by the subscriber's Display Name when evaluated
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.MyDisplayNameMacro in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String MyDisplayNameMacro = "@@MyDisplayName@@";
|
||||
|
||||
/// <summary>
|
||||
/// Macro used in subscriptions which will be replaced by the subscriber's Unique User Name when evaluated
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.MyUniqueNameMacro in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String MyUniqueNameMacro = "@@MyUniqueName@@";
|
||||
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.SingleQuoteNameMacro in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String SingleQuoteNameMacro = "@@SQBDQ@@"; //SingleQuoteBetweenDoubleQuotes
|
||||
|
||||
[Obsolete]
|
||||
public const String SingleQuoteValue = "\"'\""; //"'"
|
||||
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.DoubleQuoteNameMacro in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String DoubleQuoteNameMacro = "@@DQBSQ@@"; //DoubleQuoteBetweenSingleQuotes
|
||||
|
||||
[Obsolete]
|
||||
public const String DoubleQuoteValue = "'\"'"; //'"'
|
||||
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.SingleQuoteCharMacro in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String SingleQuoteCharMacro = "@@SingleQuote@@";
|
||||
|
||||
[Obsolete]
|
||||
public const String SingleQuoteCharValue = "'";
|
||||
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.DoubleQuoteCharMacro in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String DoubleQuoteCharMacro = "@@DoubleQuote@@";
|
||||
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.DoubleQuoteCharValue in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String DoubleQuoteCharValue = "\"";
|
||||
|
||||
/// <summary>
|
||||
/// Token used in subscription addresses to identify dynamic delivery targets computed from the source event
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.DynamicTargetsToken in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String DynamicTargetsToken = "@@";
|
||||
|
||||
/// <summary>
|
||||
/// TeamFoundationIdentity property name for a user's custom list of Email addresses to receive notifications at
|
||||
/// </summary>
|
||||
public const String CustomNotificationAddressesIdentityProperty = "CustomNotificationAddresses";
|
||||
|
||||
/// <summary>
|
||||
/// TeamFoundationIdentity propery name for a user's confirmed Email address to receive notifications. This is used in Hosted environments only.
|
||||
/// </summary>
|
||||
public const string ConfirmedNotificationAddressIdentityProperty = "ConfirmedNotificationAddress";
|
||||
|
||||
/// <summary>
|
||||
/// The name of the WorkItemChangedEvent
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.LegacyNames.WorkItemChangedEvent in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const string WorkItemChangedEventTypeName = "WorkItemChangedEvent";
|
||||
|
||||
/// <summary>
|
||||
/// The name of the BuildStatusChangedEvent type
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.LegacyNames.BuildStatusChangeEvent in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String BuildStatusChangeEventName = "BuildStatusChangeEvent";
|
||||
|
||||
/// <summary>
|
||||
/// The name of the BuildCompletedEvent type
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.LegacyNames.BuildCompletedEvent in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String BuildCompletedEventName = "BuildCompletedEvent";
|
||||
|
||||
/// <summary>
|
||||
/// The name of the CheckinEvent type
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.LegacyNames.CheckinEvent in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String CheckinEventName = "CheckinEvent";
|
||||
|
||||
/// <summary>
|
||||
/// The name of the CodeReviewChangedEvent type
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.LegacyNames.CodeReviewChangedEvent in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String CodeReviewChangedEventName = "CodeReviewChangedEvent";
|
||||
|
||||
/// <summary>
|
||||
/// The name of the GitPushEvent type
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.LegacyNames.GitPushEvent in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String GitPushEventName = "GitPushEvent";
|
||||
|
||||
/// <summary>
|
||||
/// The name of the GitPullRequestEvent type
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.LegacyNames.GitPullRequestEvent in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String GitPullRequestEventName = "GitPullRequestEvent";
|
||||
|
||||
/// <summary>
|
||||
/// The relative path to the alerts admin web page
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationUrlConstants.AlertsPageRelativePath in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String AlertsPageRelativePath = "{0}#id={1}&showteams={2}";
|
||||
|
||||
/// <summary>
|
||||
/// The alerts page name
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationUrlConstants.AlertsPage in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String AlertsPage = "_Alerts";
|
||||
|
||||
/// <summary>
|
||||
/// The admin alerts page
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationUrlConstants.AlertsAdminPage in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String AlertsAdminPage = "_admin/_Alerts";
|
||||
|
||||
/// <summary>
|
||||
/// Property used to keep track of how many confirmations were sent for this user. Used to limit the number
|
||||
/// of confirmations a single user is allowed to send out for their account.
|
||||
/// The value is updated and monitored by the SendEmailConfirmationJob.
|
||||
/// </summary>
|
||||
public const string EmailConfirmationSendDates = "EmailConfirmationSendDates";
|
||||
|
||||
/// <summary>
|
||||
/// Prefix to denote that identity field value have been processed
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.ProcessedFlagCharacter in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const Char ProcessedFlagCharacter = (Char)7;
|
||||
|
||||
/// <summary>
|
||||
/// Prefix to denote that identity field value have been processed and converted to TFID
|
||||
/// </summary>
|
||||
/// [Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.ProcessedTfIdFlagCharacter in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const Char ProcessedTfIdFlagCharacter = (Char)11;
|
||||
|
||||
/// <summary>
|
||||
/// Prefix to denote that this is the start of displayname value for this identity field
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.DisplayNameFlagCharacter in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const Char DisplayNameFlagCharacter = '|';
|
||||
|
||||
/// <summary>
|
||||
/// Prefix to denote that this is the start of TFID value for this identity field
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.TfIdFlagCharacter in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const Char TfIdFlagCharacter = '%';
|
||||
|
||||
/// <summary>
|
||||
/// Optional Feature flag to enable escaping Regex expressions when creating Notification subscriptions.
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.FeatureFlags.AllowUserRegexInMatchConditionFeatureFlag in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const string AllowUserRegexInMatchConditionFeatureFlag = "VisualStudio.Services.Notifications.AllowUserRegexInMatchCondition";
|
||||
|
||||
/// <summary>
|
||||
/// The MDM scope name for the notification job
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.MDMConstants.MDMNotificationJobScope in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const string MDMNotificationJobScope = "NotificationJob";
|
||||
|
||||
/// <summary>
|
||||
/// Event processing delay KPI name
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.MDMConstants.EventProcessingDelayKPI in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const string EventProcessingDelayKPI = "EventProcessingDelayInMs";
|
||||
|
||||
/// <summary>
|
||||
/// Event processing delay KPI description
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.MDMConstants.EventProcessingDelayKPIDesc in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const string EventProcessingDelayKPIDesc = "Time taken to start processing an event";
|
||||
|
||||
/// <summary>
|
||||
/// The MDM scope name for the delivery job
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.MDMConstants.MDMDeliveryJobscope in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const string MDMDeliveryJobscope = "NotificationDeliveryJob";
|
||||
|
||||
/// <summary>
|
||||
/// Notification delivery delay KPI name
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.MDMConstants.DeliveryDelayKPI in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const string DeliveryDelayKPI = "NotificationDeliveryDelayInMs";
|
||||
|
||||
/// <summary>
|
||||
/// Notification delivery delay with retries KPI name
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.MDMConstants.DeliveryDelayWithRetriesKPI in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const string DeliveryDelayWithRetriesKPI = "NotificationDeliveryDelayWithRetriesInMs";
|
||||
|
||||
/// <summary>
|
||||
/// Total time taken between the event creation till the notification delivery
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.MDMConstants.TotalProcessingTimeKPI in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const string TotalProcessingTimeKPI = "EventProcessingTimeInMs";
|
||||
|
||||
/// <summary>
|
||||
/// Total time taken between the event creation till the notification delivery
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.MDMConstants.TotalProcessingTimeWithRetriesKPI in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const string TotalProcessingTimeWithRetriesKPI = "EventProcessingTimeWithRetriesInMs";
|
||||
|
||||
/// <summary>
|
||||
/// Notification delivery delay KPI description
|
||||
/// </summary>
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.MDMConstants.DeliveryDelayKPIDesc in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const string DeliveryDelayKPIDesc = "Time taken to start deliverying a notification";
|
||||
|
||||
// caching key for our notification bridge interface
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.BridgeKey in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const String BridgeKey = "@NotifBridge";
|
||||
|
||||
// delivery retry count registryKey
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.RetryCountRegistryKey in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const string RetryCountRegistryKey = "NotificationRetryCount";
|
||||
|
||||
// delivery retry count default value
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.RetryCountDefaultValue in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public const Int32 RetryCountDefaultValue = 5;
|
||||
|
||||
// the collection scope Guid
|
||||
[Obsolete("Moved to GitHub.Services.Notifications.Common.NotificationFrameworkConstants.CollectionScope in assembly MS.VS.Services.Notifications.WebApi")]
|
||||
public static Guid CollectionScope = new Guid("00000000-0000-636f-6c6c-656374696f6e");
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public class LocationSecurityConstants
|
||||
{
|
||||
@@ -732,16 +358,6 @@ namespace GitHub.Services.Common
|
||||
public const Int32 AllPermissions = Read | Write;
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public class SecuritySecurityConstants
|
||||
{
|
||||
public static readonly Guid NamespaceId = new Guid("9A82C708-BFBE-4F31-984C-E860C2196781");
|
||||
public const char Separator = '/';
|
||||
public const String RootToken = "";
|
||||
|
||||
public const int Read = 1;
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public class GraphSecurityConstants
|
||||
{
|
||||
@@ -753,158 +369,6 @@ namespace GitHub.Services.Common
|
||||
public const int ReadByPersonalIdentifier = 2;
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static class TeamProjectSecurityConstants
|
||||
{
|
||||
public static readonly Guid NamespaceId = new Guid("52D39943-CB85-4d7f-8FA8-C6BAAC873819");
|
||||
|
||||
// Existed in Orcas
|
||||
public static readonly Int32 GenericRead = 1;
|
||||
public static readonly Int32 GenericWrite = 2;
|
||||
public static readonly Int32 Delete = 4;
|
||||
public static readonly Int32 PublishTestResults = 8;
|
||||
public static readonly Int32 AdministerBuild = 16;
|
||||
public static readonly Int32 StartBuild = 32;
|
||||
public static readonly Int32 EditBuildStatus = 64;
|
||||
public static readonly Int32 UpdateBuild = 128;
|
||||
public static readonly Int32 DeleteTestResults = 256;
|
||||
public static readonly Int32 ViewTestResults = 512;
|
||||
|
||||
// Dev10 Beta1
|
||||
public static readonly Int32 ManageTestEnvironments = 2048;
|
||||
|
||||
// Dev10 Beta2
|
||||
public static readonly Int32 ManageTestConfigurations = 4096;
|
||||
|
||||
// Dev14 Update 2 / VSO (M91)
|
||||
public static readonly Int32 WorkItemDelete = 8192;
|
||||
|
||||
// Dev14 Update 2 / VSO (M92)
|
||||
public static readonly Int32 WorkItemMove = 16384;
|
||||
|
||||
// Dev14 Update 2 / VSO (M94)
|
||||
public static readonly Int32 WorkItemPermanentlyDelete = 32768;
|
||||
|
||||
// Dev15 / VSO (M99)
|
||||
public static readonly Int32 Rename = 65536;
|
||||
|
||||
/// <summary>
|
||||
/// The permission required for setting project properties.
|
||||
/// Introduced in Dev15 Update 2 / VSO (M116).
|
||||
/// </summary>
|
||||
public static readonly Int32 ManageProperties = 131072;
|
||||
|
||||
/// <summary>
|
||||
/// The permission required for setting system project properties.
|
||||
/// Introduced in Dev15 Update 2 / VSO (M116).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This permission was excluded from AllPermissions to avoid being unintentionally granted.
|
||||
/// </remarks>
|
||||
public static readonly Int32 ManageSystemProperties = 262144;
|
||||
|
||||
/// <summary>
|
||||
/// The permission required for bypassing the project property cache.
|
||||
/// Introduced in Dev16 / VSO (M118).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This permission was excluded from AllPermissions to avoid being unintentionally granted.
|
||||
/// </remarks>
|
||||
public static readonly Int32 BypassPropertyCache = 524288;
|
||||
|
||||
/// <summary>
|
||||
/// The permission required for bypassing the rules while updating work items.
|
||||
/// Introduced in Dev16 / VSO (M126).
|
||||
/// </summary>
|
||||
public static readonly Int32 BypassRules= 1048576;
|
||||
|
||||
/// <summary>
|
||||
/// The permission required for suppressing notifications for work item updates.
|
||||
/// Introduced in Dev16 / VSO (M126).
|
||||
/// </summary>
|
||||
public static readonly Int32 SuppressNotifications= 2097152;
|
||||
|
||||
/// <summary>
|
||||
/// The permission required for updating project visibility.
|
||||
/// Introduced in Dev16 / VSO (M131).
|
||||
/// </summary>
|
||||
public static readonly Int32 UpdateVisibility = 4194304;
|
||||
|
||||
/// <summary>
|
||||
/// The permission required for changing the process of the team project
|
||||
/// Introduced in Dev17 / VSO (M136).
|
||||
/// </summary>
|
||||
public static readonly Int32 ChangeProjectsProcess = 8388608;
|
||||
|
||||
/// <summary>
|
||||
/// The permission required for granting access to backlog management. For stakeholder, this would disabled for private project and enabled for public project.
|
||||
/// Introduced in Dev17 / VSO (M137).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This permission was excluded from AllPermissions to avoid being unintentionally granted.
|
||||
/// </remarks>
|
||||
public static readonly Int32 AgileToolsBacklogManagement = 16777216;
|
||||
|
||||
/// <summary>
|
||||
/// The permission required for granting access to backlog management. For stakeholder, this is always disabled.
|
||||
/// Introduced in Dev17 / VSO (M150).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This permission was excluded from AllPermissions to avoid being unintentionally granted.
|
||||
/// </remarks>
|
||||
public static readonly Int32 AgileToolsPlans = 33554432;
|
||||
|
||||
public static readonly Int32 AllPermissions =
|
||||
GenericRead |
|
||||
GenericWrite |
|
||||
Delete |
|
||||
PublishTestResults |
|
||||
AdministerBuild |
|
||||
StartBuild |
|
||||
EditBuildStatus |
|
||||
UpdateBuild |
|
||||
DeleteTestResults |
|
||||
ViewTestResults |
|
||||
ManageTestEnvironments |
|
||||
ManageTestConfigurations |
|
||||
WorkItemDelete |
|
||||
WorkItemMove |
|
||||
WorkItemPermanentlyDelete |
|
||||
Rename |
|
||||
ManageProperties |
|
||||
BypassRules |
|
||||
SuppressNotifications |
|
||||
UpdateVisibility |
|
||||
ChangeProjectsProcess;
|
||||
|
||||
public const String ProjectTokenPrefix = "$PROJECT:";
|
||||
|
||||
public static String GetToken(String projectUri)
|
||||
{
|
||||
if (String.IsNullOrEmpty(projectUri) || !projectUri.StartsWith(ProjectTokenPrefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (projectUri == null)
|
||||
{
|
||||
projectUri = String.Empty;
|
||||
}
|
||||
|
||||
return ProjectTokenPrefix + projectUri + ":";
|
||||
}
|
||||
|
||||
return projectUri + ":";
|
||||
}
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static class ContentValidationSecurityConstants
|
||||
{
|
||||
public static readonly Guid NamespaceId = new Guid("B1982126-CB90-4479-BDFD-CBF193241CB8");
|
||||
public static readonly string ViolationsToken = "Violations";
|
||||
|
||||
public const int Read = 1;
|
||||
public const int Write = 2;
|
||||
}
|
||||
|
||||
public enum WinHttpErrorCode
|
||||
{
|
||||
WINHTTP_ERROR_BASE = 12000,
|
||||
|
||||
@@ -124,9 +124,6 @@ namespace GitHub.Services.Common
|
||||
LogException = (bool)info.GetValue("m_logException", typeof(bool));
|
||||
ReportException = (bool)info.GetValue("m_reportException", typeof(bool));
|
||||
ErrorCode = (int)info.GetValue("m_errorCode", typeof(int));
|
||||
#if !NETSTANDARD
|
||||
LogLevel = (EventLogEntryType)info.GetValue("m_logLevel", typeof(EventLogEntryType));
|
||||
#endif
|
||||
EventId = (int)info.GetValue("m_eventId", typeof(int));
|
||||
}
|
||||
|
||||
@@ -137,9 +134,6 @@ namespace GitHub.Services.Common
|
||||
info.AddValue("m_logException", LogException);
|
||||
info.AddValue("m_reportException", ReportException);
|
||||
info.AddValue("m_errorCode", ErrorCode);
|
||||
#if !NETSTANDARD
|
||||
info.AddValue("m_logLevel", LogLevel);
|
||||
#endif
|
||||
info.AddValue("m_eventId", EventId);
|
||||
}
|
||||
|
||||
@@ -157,22 +151,6 @@ namespace GitHub.Services.Common
|
||||
}
|
||||
}
|
||||
|
||||
#if !NETSTANDARD
|
||||
/// <summary>The event log entry type to use when logging the exception</summary>
|
||||
/// <value>One of the event log entry types: </value>
|
||||
public EventLogEntryType LogLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_logLevel;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_logLevel = value;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>A user-defined error code.</summary>
|
||||
public int ErrorCode
|
||||
{
|
||||
@@ -279,10 +257,6 @@ namespace GitHub.Services.Common
|
||||
private bool m_reportException;
|
||||
private int m_errorCode;
|
||||
|
||||
#if !NETSTANDARD
|
||||
private EventLogEntryType m_logLevel = EventLogEntryType.Warning;
|
||||
#endif
|
||||
|
||||
private int m_eventId = DefaultExceptionEventId;
|
||||
|
||||
//From EventLog.cs in Framework.
|
||||
|
||||
@@ -33,13 +33,7 @@ namespace GitHub.Services.Common
|
||||
public VssHttpMessageHandler(
|
||||
VssCredentials credentials,
|
||||
VssHttpRequestSettings settings)
|
||||
: this(credentials, settings,
|
||||
#if !NETSTANDARD
|
||||
new WebRequestHandler()
|
||||
#else
|
||||
new HttpClientHandler()
|
||||
#endif
|
||||
)
|
||||
: this(credentials, settings, new HttpClientHandler())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -76,13 +70,7 @@ namespace GitHub.Services.Common
|
||||
m_transportHandler = transportHandler;
|
||||
}
|
||||
|
||||
#if NETSTANDARD
|
||||
//.Net Core does not recognize CredentialCache.DefaultCredentials if we wrap them with CredentialWrapper
|
||||
bool isDefaultCredentials = credentials != null && credentials.Windows != null && credentials.Windows.UseDefaultCredentials;
|
||||
ApplySettings(m_transportHandler, isDefaultCredentials ? CredentialCache.DefaultCredentials : m_credentialWrapper, this.Settings);
|
||||
#else
|
||||
ApplySettings(m_transportHandler, m_credentialWrapper, this.Settings);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -139,35 +127,6 @@ namespace GitHub.Services.Common
|
||||
var traceInfo = VssHttpMessageHandlerTraceInfo.GetTraceInfo(request);
|
||||
traceInfo?.TraceHandlerStartTime();
|
||||
|
||||
#if !NETSTANDARD
|
||||
// This action is deferred from ApplySettings because we want don't want to do it if we aren't
|
||||
// talking to an HTTPS endpoint.
|
||||
if (!m_appliedClientCertificatesToTransportHandler &&
|
||||
request.RequestUri.Scheme == "https")
|
||||
{
|
||||
WebRequestHandler webRequestHandler = m_transportHandler as WebRequestHandler;
|
||||
if (webRequestHandler != null &&
|
||||
this.Settings.ClientCertificateManager != null &&
|
||||
this.Settings.ClientCertificateManager.ClientCertificates != null &&
|
||||
this.Settings.ClientCertificateManager.ClientCertificates.Count > 0)
|
||||
{
|
||||
webRequestHandler.ClientCertificates.AddRange(this.Settings.ClientCertificateManager.ClientCertificates);
|
||||
}
|
||||
m_appliedClientCertificatesToTransportHandler = true;
|
||||
}
|
||||
|
||||
if (!m_appliedServerCertificateValidationCallbackToTransportHandler &&
|
||||
request.RequestUri.Scheme == "https")
|
||||
{
|
||||
WebRequestHandler webRequestHandler = m_transportHandler as WebRequestHandler;
|
||||
if (webRequestHandler != null &&
|
||||
this.Settings.ServerCertificateValidationCallback != null)
|
||||
{
|
||||
webRequestHandler.ServerCertificateValidationCallback = this.Settings.ServerCertificateValidationCallback;
|
||||
}
|
||||
m_appliedServerCertificateValidationCallbackToTransportHandler = true;
|
||||
}
|
||||
#else
|
||||
if (!m_appliedClientCertificatesToTransportHandler &&
|
||||
request.RequestUri.Scheme == "https")
|
||||
{
|
||||
@@ -201,7 +160,6 @@ namespace GitHub.Services.Common
|
||||
{
|
||||
request.Version = HttpVersion.Version11;
|
||||
}
|
||||
#endif
|
||||
|
||||
IssuedToken token = null;
|
||||
IssuedTokenProvider provider;
|
||||
@@ -540,16 +498,11 @@ namespace GitHub.Services.Common
|
||||
}
|
||||
}
|
||||
|
||||
private static IWebProxy s_defaultWebProxy =
|
||||
#if !NETSTANDARD
|
||||
WebRequest.DefaultWebProxy;
|
||||
#else
|
||||
// setting this to WebRequest.DefaultWebProxy in NETSTANDARD is causing a System.PlatformNotSupportedException
|
||||
//.in System.Net.SystemWebProxy.IsBypassed. Comment in IsBypassed method indicates ".NET Core and .NET Native
|
||||
// code will handle this exception and call into WinInet/WinHttp as appropriate to use the system proxy."
|
||||
// This needs to be investigated further.
|
||||
null;
|
||||
#endif
|
||||
// setting this to WebRequest.DefaultWebProxy in NETSTANDARD is causing a System.PlatformNotSupportedException
|
||||
//.in System.Net.SystemWebProxy.IsBypassed. Comment in IsBypassed method indicates ".NET Core and .NET Native
|
||||
// code will handle this exception and call into WinInet/WinHttp as appropriate to use the system proxy."
|
||||
// This needs to be investigated further.
|
||||
private static IWebProxy s_defaultWebProxy = null;
|
||||
|
||||
/// <summary>
|
||||
/// Allows you to set a proxy to be used by all VssHttpMessageHandler requests without affecting the global WebRequest.DefaultWebProxy. If not set it returns the WebRequest.DefaultWebProxy.
|
||||
@@ -585,13 +538,9 @@ namespace GitHub.Services.Common
|
||||
private bool m_appliedServerCertificateValidationCallbackToTransportHandler;
|
||||
private readonly HttpMessageHandler m_transportHandler;
|
||||
|
||||
#if NETSTANDARD
|
||||
//.Net Core does not attempt NTLM schema on Linux, unless ICredentials is a CredentialCache instance
|
||||
//This workaround may not be needed after this corefx fix is consumed: https://github.com/dotnet/corefx/pull/7923
|
||||
private sealed class CredentialWrapper : CredentialCache, ICredentials
|
||||
#else
|
||||
private sealed class CredentialWrapper : ICredentials
|
||||
#endif
|
||||
{
|
||||
public ICredentials InnerCredentials
|
||||
{
|
||||
|
||||
@@ -44,9 +44,7 @@ namespace GitHub.Services.Common
|
||||
this.SuppressFedAuthRedirects = true;
|
||||
this.ClientCertificateManager = null;
|
||||
this.ServerCertificateValidationCallback = null;
|
||||
#if NETSTANDARD
|
||||
this.UseHttp11 = false;
|
||||
#endif
|
||||
|
||||
// If different, we'll also add CurrentCulture to the request headers,
|
||||
// but UICulture was added first, so it gets first preference
|
||||
@@ -99,9 +97,7 @@ namespace GitHub.Services.Common
|
||||
this.ClientCertificateManager = copy.ClientCertificateManager;
|
||||
this.ServerCertificateValidationCallback = copy.ServerCertificateValidationCallback;
|
||||
this.MaxRetryRequest = copy.MaxRetryRequest;
|
||||
#if NETSTANDARD
|
||||
this.UseHttp11 = copy.UseHttp11;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -144,7 +140,6 @@ namespace GitHub.Services.Common
|
||||
set;
|
||||
}
|
||||
|
||||
#if NETSTANDARD
|
||||
/// <summary>
|
||||
/// The .NET Core 2.1 runtime switched its HTTP default from HTTP 1.1 to HTTP 2.
|
||||
/// This causes problems with some versions of the Curl handler on Linux.
|
||||
@@ -156,7 +151,6 @@ namespace GitHub.Services.Common
|
||||
get;
|
||||
set;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum size allowed for response content buffering.
|
||||
@@ -266,15 +260,6 @@ namespace GitHub.Services.Common
|
||||
set;
|
||||
}
|
||||
|
||||
#if !NETSTANDARD
|
||||
/// <summary>
|
||||
/// Optional implementation used to validate server certificate validation
|
||||
/// </summary>
|
||||
public RemoteCertificateValidationCallback ServerCertificateValidationCallback
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
#else
|
||||
/// <summary>
|
||||
/// Optional implementation used to validate server certificate validation
|
||||
/// </summary>
|
||||
@@ -283,7 +268,6 @@ namespace GitHub.Services.Common
|
||||
get;
|
||||
set;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Number of times to retry a request that has an ambient failure
|
||||
@@ -359,13 +343,11 @@ namespace GitHub.Services.Common
|
||||
request.Headers.Add(Internal.HttpHeaders.VssAgentHeader, this.AgentId);
|
||||
}
|
||||
|
||||
#if NETSTANDARD
|
||||
// Content is being sent as chunked by default in dotnet5.4, which differs than the .net 4.5 behaviour.
|
||||
if (request.Content != null && !request.Content.Headers.ContentLength.HasValue && !request.Headers.TransferEncodingChunked.HasValue)
|
||||
{
|
||||
request.Content.Headers.ContentLength = request.Content.ReadAsByteArrayAsync().Result.Length;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -216,21 +216,13 @@ namespace GitHub.Services.Common
|
||||
}
|
||||
}
|
||||
}
|
||||
#if !NETSTANDARD
|
||||
else if (ex is System.Data.Services.Client.DataServiceRequestException ||
|
||||
ex is System.Data.Services.Client.DataServiceClientException)
|
||||
{
|
||||
// WCF exceptions
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HttpStatusCode which represents a throttling error.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Gets the HttpStatusCode which represents a throttling error.
|
||||
/// </summary>
|
||||
public const HttpStatusCode TooManyRequests = (HttpStatusCode)429;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,30 +10,14 @@ namespace GitHub.Services.Common
|
||||
// See Toolsets\Version\Version.props for more details.
|
||||
public const String MajorVersion = "16";
|
||||
public const String MinorVersion = "0";
|
||||
public const String BuildVersion = "65000";
|
||||
public const String PatchVersion = "0";
|
||||
public const String ProductVersion = MajorVersion + "." + MinorVersion;
|
||||
|
||||
// Assembly version (i.e. strong name)
|
||||
public const String AssemblyMajorVersion = "16";
|
||||
public const String AssemblyMinorVersion = "0";
|
||||
public const String AssemblyBuildVersion = "0";
|
||||
public const String AssemblyPatchVersion = "0";
|
||||
public const String AssemblyVersion = AssemblyMajorVersion + "." + AssemblyMinorVersion + "." + AssemblyBuildVersion + "." + AssemblyPatchVersion;
|
||||
|
||||
// File version
|
||||
public const String FileMajorVersion = "16";
|
||||
public const String FileMinorVersion = "255";
|
||||
public const String FileBuildVersion = "65000";
|
||||
public const String FilePatchVersion = "0";
|
||||
public const String FileVersion = FileMajorVersion + "." + FileMinorVersion + "." + FileBuildVersion + "." + FilePatchVersion;
|
||||
|
||||
// Derived versions
|
||||
public const String TfsMajorVersion = "8";
|
||||
public const String TfsMinorVersion = "0";
|
||||
public const String TfsProductVersion = TfsMajorVersion + "." + TfsMinorVersion;
|
||||
|
||||
// On-premises TFS install folder
|
||||
public const String TfsInstallDirectory = "Azure DevOps Server 2019";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user