Example #1
0
        public bool TryReadSecureData(string key, out string name, out byte[] data)
        {
            string path = string.Empty;

            if (!TryReadNext(nameof(TryReadSecureData), ref path, out CapturedStorageQuery query))
            {
                throw new ReplayNotFoundException("Unable to dequeue next operation", path);
            }
            if (!(query.Input is string input))
            {
                throw new ReplayInputTypeException(typeof(string), query.Input?.GetType());
            }
            if (!(query.Output is CapturedStorageQuery.SecureDataOutput output))
            {
                throw new ReplayOutputTypeException(typeof(CapturedStorageQuery.SecureDataOutput), query.Output?.GetType());
            }

            // Validate inputs are as expected
            if (!OrdinalIgnoreCase.Equals(key, input))
            {
                throw new ReplayInputException($"Unexpected `{nameof(key)}` value. Expected \"{input}\" vs actual \"{key}\".");
            }

            data = output.Data;
            name = output.Name;

            return(output.Result);
        }
Example #2
0
        public Stream FileOpen(string path, FileMode mode, FileAccess access, FileShare share)
        {
            if (!TryReadNext(nameof(FileOpen), ref path, out CapturedStorageQuery query))
            {
                throw new ReplayNotFoundException($"Unable to dequeue next operation for \"{path}\"", path);
            }
            if (!(query.Input is CapturedStorageQuery.OpenInput input))
            {
                throw new ReplayInputTypeException(typeof(CapturedStorageQuery.OpenInput), query.Input?.GetType());
            }
            if (!(query.Output is CapturedStorageQuery.OpenOutput output))
            {
                throw new ReplayOutputTypeException(typeof(byte[]), query.Output?.GetType());
            }

            // Validate inputs are as expected
            if (!OrdinalIgnoreCase.Equals(input.Path, path))
            {
                throw new ReplayInputException($"Unexpected `{nameof(path)}` value. Expected \"{input.Path}\" vs actual \"{path}\".");
            }
            if (input.Mode != (int)mode)
            {
                throw new ReplayInputException($"Unexpected `{nameof(mode)}` value. Expected \"{input.Mode}\" vs actual \"{mode}\".");
            }
            if (input.Access != (int)access)
            {
                throw new ReplayInputException($"Unexpected `{nameof(access)}` value. Expected \"{input.Access}\" vs actual \"{access}\".");
            }
            if (input.Share != (int)share)
            {
                throw new ReplayInputException($"Unexpected `{nameof(share)}` value. Expected \"{input.Share}\" vs actual \"{share}\".");
            }

            return(new ReplayStream((FileAccess)output.Access, output.Data));;
        }
Example #3
0
        public bool TryWriteSecureData(string key, string name, byte[] data)
        {
            string path = string.Empty;

            if (!TryReadNext(nameof(TryWriteSecureData), ref path, out CapturedStorageQuery query))
            {
                throw new ReplayNotFoundException("Unable to dequeue next operation", path);
            }
            if (!(query.Input is CapturedStorageQuery.SecureDataInput input))
            {
                throw new ReplayInputTypeException(typeof(CapturedStorageQuery.SecureDataInput), query.Input?.GetType());
            }
            if (!(query.Output is bool output))
            {
                throw new ReplayOutputTypeException(typeof(bool), query.Output?.GetType());
            }

            // Validate inputs are as expected
            if (!OrdinalIgnoreCase.Equals(key, input.Key))
            {
                throw new ReplayInputException($"Unexpected `{nameof(key)}` value. Expected \"{input.Key}\" vs actual \"{key}\".");
            }
            if (!OrdinalIgnoreCase.Equals(name, input.Name))
            {
                throw new ReplayInputException($"Unexpected `{nameof(name)}` value. Expected \"{input.Name}\" vs actual \"{name}\".");
            }
            if ((data == null && input.Data != null) ||
                (data != null && input.Data == null) ||
                data.Length != input.Data.Length)
            {
                throw new ReplayInputException($"Unexpected `{nameof(data)}` value. Expected \"{input.Data?.Length}\" vs actual \"{data?.Length}\".");
            }

            return(output);
        }
Example #4
0
        private Tuple <Warp, Warp> GetCellarToFarmHouseWarps(FarmHouse farmHouse)
        {
            GameLocation cellar = Game1.getLocationFromName(farmHouse.GetCellarName());

            // Get warp points. If these aren't available an exception is thrown.
            Point p1 = new Point(3, 1);
            Point p2 = new Point(4, 1);

            try {
                // ATTENTION: There are multiple variants of the string "FarmHouse"
                // in the code and the map that differ by case.
                Warp warp1 = cellar.warps.First(warp => {
                    return(OrdinalIgnoreCase.Equals(warp.TargetName, "FarmHouse") &&
                           warp.X == p1.X &&
                           warp.Y == p1.Y);
                });

                Warp warp2 = cellar.warps.First(warp => {
                    return(OrdinalIgnoreCase.Equals(warp.TargetName, "FarmHouse") &&
                           warp.X == p2.X &&
                           warp.Y == p2.Y);
                });

                return(Tuple.Create(warp1, warp2));
            }
            catch {
                throw new Exception($"The cellar map doesn't have the required warp points at {p1} and {p2}.");
            }
        }
Example #5
0
 internal static bool IsVstsUrl(TargetUri targetUri)
 {
     return((OrdinalIgnoreCase.Equals(targetUri.Scheme, Uri.UriSchemeHttp) ||
             OrdinalIgnoreCase.Equals(targetUri.Scheme, Uri.UriSchemeHttps)) &&
            (targetUri.DnsSafeHost.EndsWith(VstsBaseUrlHost, StringComparison.OrdinalIgnoreCase) ||
             targetUri.DnsSafeHost.EndsWith(AzureBaseUrlHost, StringComparison.OrdinalIgnoreCase)));
 }
Example #6
0
        public void FileCopy(string sourcePath, string targetPath, bool overwrite)
        {
            if (!TryReadNext(nameof(FileCopy), ref sourcePath, out CapturedStorageQuery query))
            {
                throw new ReplayNotFoundException($"Unable to dequeue next operation for \"{sourcePath}\"", sourcePath);
            }
            if (!(query.Input is CapturedStorageQuery.CopyInput input))
            {
                throw new ReplayInputTypeException(typeof(CapturedStorageQuery.WriteAllBytesInput), query.Input?.GetType());
            }

            // Validate that inputs are identical
            if (!OrdinalIgnoreCase.Equals(sourcePath, input.SourcePath))
            {
                throw new ReplayInputException($"Unexpected `{nameof(sourcePath)}`: expected \"{input.SourcePath}\" vs actual \"{sourcePath}\".");
            }
            if (!OrdinalIgnoreCase.Equals(targetPath, input.TargetPath))
            {
                throw new ReplayInputException($"Unexpected `{nameof(targetPath)}`: expected \"{input.TargetPath}\" vs actual \"{targetPath}\".");
            }
            if (overwrite != input.Overwrite)
            {
                throw new ReplayInputException($"Unexpected `{nameof(overwrite)}`: expected \"{input.Overwrite}\" vs actual \"{overwrite}\".");
            }
        }
Example #7
0
        public IEnumerable <SecureData> EnumerateSecureData(string prefix)
        {
            string path = string.Empty;

            if (!TryReadNext(nameof(EnumerateSecureData), ref path, out CapturedStorageQuery query))
            {
                throw new ReplayNotFoundException("Unable to dequeue next operation", path);
            }
            if (!(query.Input is string input))
            {
                throw new ReplayInputTypeException(typeof(string), query.Input?.GetType());
            }
            if (!(query.Output is CapturedStorageQuery.SecureDataOutput[] output))
            {
                throw new ReplayOutputTypeException(typeof(CapturedStorageQuery.SecureDataOutput[]), query.Output?.GetType());
            }

            // Validate inputs are identical
            if (!OrdinalIgnoreCase.Equals(input, prefix))
            {
                throw new ReplayInputException($"Unexpected `{nameof(prefix)}`: expected \"{input}\" vs actual \"{prefix}\".");
            }

            var result = new List <SecureData>(output.Length);

            foreach (var item in output)
            {
                result.Add(new SecureData(item.Key, item.Name, item.Data));
            }

            return(result);
        }
Example #8
0
        public override bool Equals(string x, string y)
        {
            if (ReferenceEquals(x, y))
            {
                return(true);
            }
            if (x is null || y is null)
            {
                return(false);
            }

            Split(x, out string xSection, out string xScope, out string xProperty);
            Split(y, out string ySection, out string yScope, out string yProperty);

            // Section and property names are not case sensitive, but the inner 'scope' IS case sensitive!
            return(OrdinalIgnoreCase.Equals(xSection, ySection) &&
                   OrdinalIgnoreCase.Equals(xProperty, yProperty) &&
                   Ordinal.Equals(xScope, yScope));
        }
Example #9
0
        public void FileWriteAllText(string path, string contents, Encoding encoding)
        {
            if (!TryReadNext(nameof(FileWriteAllBytes), ref path, out CapturedStorageQuery query))
            {
                throw new ReplayNotFoundException($"Unable to dequeue next operation for \"{path}\"", path);
            }
            if (!(query.Input is CapturedStorageQuery.WriteAllTextInput input))
            {
                throw new ReplayInputTypeException(typeof(CapturedStorageQuery.WriteAllBytesInput), query.Input?.GetType());
            }

            // Validate that inputs are identical
            if (!OrdinalIgnoreCase.Equals(path, input.Path))
            {
                throw new ReplayInputException($"Unexpected `{nameof(path)}` value. Expected \"{input.Path}\" vs actual \"{path}\".");
            }
            if (!Ordinal.Equals(contents, input.Contents))
            {
                throw new ReplayInputException($"Unexpected `{nameof(contents)}` value. Expected \"{input.Contents}\" vs actual \"{contents}\".");
            }
        }
        private async Task <string> GetContentAsString(HttpContent content)
        {
            if (content is null)
            {
                throw new ArgumentNullException(nameof(content));
            }

            string asString = null;

            if (content.Headers.ContentType?.MediaType != null &&
                (content.Headers.ContentType.MediaType.StartsWith("text/", StringComparison.OrdinalIgnoreCase) ||
                 content.Headers.ContentType.MediaType.EndsWith("/json", StringComparison.OrdinalIgnoreCase)))
            {
                if (content.Headers.ContentEncoding.Any(e => OrdinalIgnoreCase.Equals("gzip", e)))
                {
                    using (var stream = await content.ReadAsStreamAsync())
                        using (var inflate = new GZipStream(stream, CompressionMode.Decompress))
                            using (var reader = new StreamReader(inflate, Encoding.UTF8))
                            {
                                asString = reader.ReadToEnd();
                            }
                }
                else if (content.Headers.ContentEncoding.Any(e => OrdinalIgnoreCase.Equals("deflate", e)))
                {
                    using (var stream = await content.ReadAsStreamAsync())
                        using (var inflate = new DeflateStream(stream, CompressionMode.Decompress))
                            using (var reader = new StreamReader(inflate, Encoding.UTF8))
                            {
                                asString = reader.ReadToEnd();
                            }
                }
                else
                {
                    asString = await content.ReadAsStringAsync();
                }
            }

            return(asString);
        }
Example #11
0
        public string RegistryReadString(RegistryHive registryHive, RegistryView registryView, string registryPath, string keyName)
        {
            string path = CapturedStorageQuery.RegistryReadInput.CreateStoragePath(registryHive,
                                                                                   registryView,
                                                                                   registryPath,
                                                                                   keyName);

            if (!TryReadNext(nameof(RegistryReadString), ref path, out CapturedStorageQuery query))
            {
                throw new ReplayNotFoundException($"Unable to dequeue next operation for \"{path}\"", path);
            }
            if (!(query.Input is CapturedStorageQuery.RegistryReadInput input))
            {
                throw new ReplayInputTypeException(typeof(CapturedStorageQuery.RegistryReadInput), query.Input?.GetType());
            }

            string output = query.Output as string;

            // Validated inputs are as expected
            if (input.Hive != (int)registryHive)
            {
                throw new ReplayInputException($"Unexpected `{nameof(registryHive)}` value. Expected \"{(RegistryHive)input.Hive}\" vs actual \"{registryHive}\".");
            }
            if (input.View != (int)registryView)
            {
                throw new ReplayInputException($"Unexpected `{nameof(registryView)}` value. Expected \"{(RegistryView)input.View}\" vs actual \"{registryView}\".");
            }
            if (!OrdinalIgnoreCase.Equals(input.Path, registryPath))
            {
                throw new ReplayInputException($"Unexpected `{nameof(registryPath)}` value. Expected \"{input.Path}\" vs actual \"{registryPath}\".");
            }
            if (!OrdinalIgnoreCase.Equals(input.Name, keyName))
            {
                throw new ReplayInputException($"Unexpected `{nameof(keyName)}` value. Expected \"{input.Name}\" vs actual \"{keyName}\".");
            }

            return(output);
        }
Example #12
0
        protected UnitTestBase(IUnitTestTrace output, string projectDirectory, [CallerFilePath] string filePath = "")
            : base(RuntimeContext.Create())
        {
            if (output is null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            if (string.IsNullOrWhiteSpace(filePath))
            {
                filePath = Invariant($"{nameof(UnitTestBase)}.cs");
            }

            TestMode = ProjectTestMode;

            _filePath         = filePath;
            _iteration        = -1;
            _projectDirectory = projectDirectory ?? Directory.GetParent(filePath).FullName;
            _tempDirectory    = Path.GetTempPath();
            _testInstanceName = Guid.NewGuid().ToString("N");

            while (_projectDirectory != null &&
                   !Directory.EnumerateFiles(_projectDirectory)
                   .Any(x => OrdinalIgnoreCase.Equals(Path.GetExtension(x), ".csproj")))
            {
                _projectDirectory = Path.GetDirectoryName(_projectDirectory);
            }

            _solutionDirectory = FindSolutionDirectory(_projectDirectory);

            Context.Trace = new UnitTestTrace(Context.Trace, output);

            _output = output;

            _output.WriteLine($"Starting {GetType().FullName}.");
        }
        public static bool GetTypeFromFriendlyName(string name, out TokenType type)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            type = TokenType.Unknown;

            foreach (var value in Enum.GetValues(typeof(TokenType)))
            {
                type = (TokenType)value;

                if (GetFriendlyNameFromType(type, out string typename))
                {
                    if (OrdinalIgnoreCase.Equals(name, typename))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Example #14
0
        public void FileWriteAllBytes(string path, byte[] data)
        {
            if (!TryReadNext(nameof(FileWriteAllBytes), ref path, out CapturedStorageQuery query))
            {
                throw new ReplayNotFoundException($"Unable to dequeue next operation for \"{path}\"", path);
            }
            if (!(query.Input is CapturedStorageQuery.WriteAllBytesInput input))
            {
                throw new ReplayInputTypeException(typeof(CapturedStorageQuery.WriteAllBytesInput), query.Input?.GetType());
            }

            // Validate that inputs are identical
            if (!OrdinalIgnoreCase.Equals(path, input.Path))
            {
                throw new ReplayInputException($"Unexpected `{nameof(path)}` value. Expected \"{input.Path}\" vs actual \"{path}\".");
            }

            if ((data == null && input.Data != null) ||
                (data != null && input.Data == null) ||
                data.Length != input.Data.Length)
            {
                throw new ReplayInputException($"Contents of `{nameof(data)}` do not match the expected value.");
            }
        }
Example #15
0
 /// <summary>
 /// Determines whether the current instance equals the specified object.
 /// </summary>
 /// <param name="other">The other object to compare against.</param>
 /// <returns>True if the objects are equal; otherwise, false.</returns>
 public bool Equals(SqlIdentifier other)
 {
     return(OrdinalIgnoreCase.Equals(SchemaName, other.SchemaName) &&
            OrdinalIgnoreCase.Equals(ObjectName, other.ObjectName));
 }
        public static async Task <Guid?> DetectAuthority(RuntimeContext context, TargetUri targetUri)
        {
            const int    GuidStringLength         = 36;
            const string XvssResourceTenantHeader = "X-VSS-ResourceTenant";

            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (targetUri is null)
            {
                throw new ArgumentNullException(nameof(targetUri));
            }

            // Assume Azure DevOps using Azure "common tenant" (empty GUID).
            var tenantId = Guid.Empty;

            // Compose the request Uri, by default it is the target Uri.
            var requestUri = targetUri;

            // Override the request Uri, when actual Uri exists, with actual Uri.
            if (targetUri.ActualUri != null)
            {
                requestUri = targetUri.CreateWith(queryUri: targetUri.ActualUri);
            }

            // If the protocol (aka scheme) being used isn't HTTP based, there's no point in
            // querying the server, so skip that work.
            if (OrdinalIgnoreCase.Equals(requestUri.Scheme, Uri.UriSchemeHttp) ||
                OrdinalIgnoreCase.Equals(requestUri.Scheme, Uri.UriSchemeHttps))
            {
                var requestUrl = GetTargetUrl(requestUri, false);

                // Read the cache from disk.
                var cache = await DeserializeTenantCache(context);

                // Check the cache for an existing value.
                if (cache.TryGetValue(requestUrl, out tenantId))
                {
                    context.Trace.WriteLine($"'{requestUrl}' is Azure DevOps, tenant resource is {{{tenantId.ToString("N")}}}.");

                    return(tenantId);
                }

                var options = new NetworkRequestOptions(false)
                {
                    Flags   = NetworkRequestOptionFlags.UseProxy,
                    Timeout = TimeSpan.FromMilliseconds(Global.RequestTimeout),
                };

                try
                {
                    // Query the host use the response headers to determine if the host is Azure DevOps or not.
                    using (var response = await context.Network.HttpHeadAsync(requestUri, options))
                    {
                        if (response.Headers != null)
                        {
                            // If the "X-VSS-ResourceTenant" was returned, then it is Azure DevOps and we'll need it's value.
                            if (response.Headers.TryGetValues(XvssResourceTenantHeader, out IEnumerable <string> values))
                            {
                                context.Trace.WriteLine($"detected '{requestUrl}' as Azure DevOps from GET response.");

                                // The "Www-Authenticate" is a more reliable header, because it indicates the
                                // authentication scheme that should be used to access the requested entity.
                                if (response.Headers.WwwAuthenticate != null)
                                {
                                    foreach (var header in response.Headers.WwwAuthenticate)
                                    {
                                        const string AuthorizationUriPrefix = "authorization_uri=";

                                        var value = header.Parameter;

                                        if (value.Length >= AuthorizationUriPrefix.Length + AuthorityHostUrlBase.Length + GuidStringLength)
                                        {
                                            // The header parameter will look something like "authorization_uri=https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47"
                                            // and all we want is the portion after the '=' and before the last '/'.
                                            int index1 = value.IndexOf('=', AuthorizationUriPrefix.Length - 1);
                                            int index2 = value.LastIndexOf('/');

                                            // Parse the header value if the necessary characters exist...
                                            if (index1 > 0 && index2 > index1)
                                            {
                                                var authorityUrl = value.Substring(index1 + 1, index2 - index1 - 1);
                                                var guidString   = value.Substring(index2 + 1, GuidStringLength);

                                                // If the authority URL is as expected, attempt to parse the tenant resource identity.
                                                if (OrdinalIgnoreCase.Equals(authorityUrl, AuthorityHostUrlBase) &&
                                                    Guid.TryParse(guidString, out tenantId))
                                                {
                                                    // Update the cache.
                                                    cache[requestUrl] = tenantId;

                                                    // Write the cache to disk.
                                                    await SerializeTenantCache(context, cache);

                                                    // Since we found a value, break the loop (likely a loop of one item anyways).
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    // Since there wasn't a "Www-Authenticate" header returned
                                    // iterate through the values, taking the first non-zero value.
                                    foreach (string value in values)
                                    {
                                        // Try to find a value for the resource-tenant identity.
                                        // Given that some projects will return multiple tenant identities,
                                        if (!string.IsNullOrWhiteSpace(value) &&
                                            Guid.TryParse(value, out tenantId))
                                        {
                                            // Update the cache.
                                            cache[requestUrl] = tenantId;

                                            // Write the cache to disk.
                                            await SerializeTenantCache(context, cache);

                                            // Break the loop if a non-zero value has been detected.
                                            if (tenantId != Guid.Empty)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                }

                                context.Trace.WriteLine($"tenant resource for '{requestUrl}' is {{{tenantId.ToString("N")}}}.");

                                // Return the tenant identity to the caller because this is Azure DevOps.
                                return(tenantId);
                            }
                        }
                        else
                        {
                            context.Trace.WriteLine($"unable to get response from '{requestUri}' [{(int)response.StatusCode} {response.StatusCode}].");
                        }
                    }
                }
                catch (HttpRequestException exception)
                {
                    context.Trace.WriteLine($"unable to get response from '{requestUri}', an error occurred before the server could respond.");
                    context.Trace.WriteException(exception);
                }
            }
            else
            {
                context.Trace.WriteLine($"detected non-http(s) based protocol: '{requestUri.Scheme}'.");
            }

            if (OrdinalIgnoreCase.Equals(VstsBaseUrlHost, requestUri.Host))
            {
                return(Guid.Empty);
            }

            // Fallback to basic authentication.
            return(null);
        }
Example #17
0
        public bool GitLocalConfig(string startingDirectory, out string path)
        {
            const string GitFolderName       = ".git";
            const string LocalConfigFileName = "config";

            if (!string.IsNullOrWhiteSpace(startingDirectory))
            {
                string directory = startingDirectory;
                string result    = null;

                if (Storage.DirectoryExists(directory))
                {
                    string hasOdb(string dir)
                    {
                        if (dir == null || !Storage.DirectoryExists(dir))
                        {
                            return(null);
                        }

                        foreach (var entryPath in Storage.EnumerateFileSystemEntries(dir))
                        {
                            if (entryPath is null)
                            {
                                continue;
                            }

                            string file = Storage.GetFileName(entryPath);

                            if (OrdinalIgnoreCase.Equals(file, GitFolderName) &&
                                Storage.DirectoryExists(entryPath))
                            {
                                return(entryPath);
                            }

                            if (OrdinalIgnoreCase.Equals(file, LocalConfigFileName) &&
                                Storage.FileExists(entryPath))
                            {
                                return(entryPath);
                            }
                        }

                        return(null);
                    }

                    while (directory != null &&
                           Storage.DirectoryExists(directory))
                    {
                        if ((result = hasOdb(directory)) != null)
                        {
                            break;
                        }

                        directory = Storage.GetParent(directory);
                    }

                    if (result != null)
                    {
                        result = Storage.GetFullPath(result);

                        if (Storage.DirectoryExists(result))
                        {
                            var localPath = Path.Combine(result, LocalConfigFileName);
                            if (Storage.FileExists(localPath))
                            {
                                path = localPath;
                                return(true);
                            }
                        }
                        else if (Storage.FileExists(result) &&
                                 OrdinalIgnoreCase.Equals(Storage.GetFileName(result), LocalConfigFileName))
                        {
                            path = result;
                            return(true);
                        }
                        else
                        {
                            // parse the file like gitdir: ../.git/modules/libgit2sharp
                            string content = null;

                            using (var stream = Storage.FileOpen(result, FileMode.Open, FileAccess.Read, FileShare.Read))
                                using (var reader = new StreamReader(stream))
                                {
                                    content = reader.ReadToEnd();
                                }

                            Match match;
                            if ((match = Regex.Match(content, @"gitdir\s*:\s*([^\r\n]+)", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase)).Success &&
                                match.Groups.Count > 1)
                            {
                                content = match.Groups[1].Value;
                                content = content.Replace('/', '\\');

                                string localPath = null;

                                if (Path.IsPathRooted(content))
                                {
                                    localPath = content;
                                }
                                else
                                {
                                    localPath = Storage.GetParent(result);
                                    localPath = Path.Combine(localPath, content);
                                }

                                if (Storage.DirectoryExists(localPath))
                                {
                                    localPath = Path.Combine(localPath, LocalConfigFileName);
                                    if (Storage.FileExists(localPath))
                                    {
                                        path = localPath;
                                        return(true);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            path = null;
            return(false);
        }
Example #18
0
        public static async Task <Guid?> DetectAuthority(RuntimeContext context, TargetUri targetUri)
        {
            const string VstsResourceTenantHeader = "X-VSS-ResourceTenant";

            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (targetUri is null)
            {
                throw new ArgumentNullException(nameof(targetUri));
            }

            var tenantId = Guid.Empty;

            if (IsVstsUrl(targetUri))
            {
                var tenantUrl = GetTargetUrl(targetUri, false);

                context.Trace.WriteLine($"'{targetUri}' is a member '{tenantUrl}', checking AAD vs MSA.");

                if (OrdinalIgnoreCase.Equals(targetUri.Scheme, Uri.UriSchemeHttp) ||
                    OrdinalIgnoreCase.Equals(targetUri.Scheme, Uri.UriSchemeHttps))
                {
                    // Read the cache from disk.
                    var cache = await DeserializeTenantCache(context);

                    // Check the cache for an existing value.
                    if (cache.TryGetValue(tenantUrl, out tenantId))
                    {
                        return(tenantId);
                    }

                    var options = new NetworkRequestOptions(false)
                    {
                        Flags   = NetworkRequestOptionFlags.UseProxy,
                        Timeout = TimeSpan.FromMilliseconds(Global.RequestTimeout),
                    };

                    try
                    {
                        var tenantUri = targetUri.CreateWith(tenantUrl);

                        using (var response = await context.Network.HttpHeadAsync(tenantUri, options))
                        {
                            if (response.Headers != null && response.Headers.TryGetValues(VstsResourceTenantHeader, out IEnumerable <string> values))
                            {
                                foreach (string value in values)
                                {
                                    // Try to find a non-empty value for the resource-tenant identity
                                    if (!string.IsNullOrWhiteSpace(value) &&
                                        Guid.TryParse(value, out tenantId) &&
                                        tenantId != Guid.Empty)
                                    {
                                        // Update the cache.
                                        cache[tenantUrl] = tenantId;

                                        // Write the cache to disk.
                                        await SerializeTenantCache(context, cache);

                                        // Success, notify the caller
                                        return(tenantId);
                                    }
                                }

                                // Since we did not find a better identity, fallback to the default (Guid.Empty).
                                return(tenantId);
                            }
                            else
                            {
                                context.Trace.WriteLine($"unable to get response from '{targetUri}' [{(int)response.StatusCode} {response.StatusCode}].");
                            }
                        }
                    }
                    catch (HttpRequestException exception)
                    {
                        context.Trace.WriteLine($"unable to get response from '{targetUri}', an error occurred before the server could respond.");
                        context.Trace.WriteException(exception);
                    }
                }
                else
                {
                    context.Trace.WriteLine($"detected non-http(s) based protocol: '{targetUri.Scheme}'.");
                }
            }

            if (StringComparer.OrdinalIgnoreCase.Equals(VstsBaseUrlHost, targetUri.Host))
            {
                return(Guid.Empty);
            }

            // Fallback to basic authentication.
            return(null);
        }
Example #19
0
 /// <inheritdoc />
 public override bool Equals(string x, string y)
 {
     return(OrdinalIgnoreCase.Equals(x, y));
 }
        public async Task SetContent(HttpContent content)
        {
            if (content is null)
            {
                throw new ArgumentNullException(nameof(content));
            }

            if (content.Headers.ContentType.MediaType != null &&
                (content.Headers.ContentType.MediaType.StartsWith("text/", StringComparison.OrdinalIgnoreCase) ||
                 content.Headers.ContentType.MediaType.EndsWith("/json", StringComparison.OrdinalIgnoreCase)))
            {
                string asString = null;

                if (content.Headers.ContentEncoding.Any(e => OrdinalIgnoreCase.Equals(AcceptEncodingGzip, e)))
                {
                    using (var stream = await content.ReadAsStreamAsync())
                        using (var inflate = new GZipStream(stream, CompressionMode.Decompress))
                            using (var reader = new StreamReader(inflate, Encoding.UTF8))
                            {
                                asString = reader.ReadToEnd();
                            }
                }
                else if (content.Headers.ContentEncoding.Any(e => OrdinalIgnoreCase.Equals(AcceptEncodingDeflate, e)))
                {
                    using (var stream = await content.ReadAsStreamAsync())
                        using (var inflate = new DeflateStream(stream, CompressionMode.Decompress))
                            using (var reader = new StreamReader(inflate, Encoding.UTF8))
                            {
                                asString = reader.ReadToEnd();
                            }
                }
                else
                {
                    asString = await content.ReadAsStringAsync();
                }

                lock (_syncpoint)
                {
                    _mediaType = content.Headers.ContentType.MediaType;
                    _string    = asString;
                }
            }
            else
            {
                byte[] asBytes = null;

                if (content.Headers.ContentEncoding.Any(e => OrdinalIgnoreCase.Equals(AcceptEncodingGzip, e)))
                {
                    using (var stream = await content.ReadAsStreamAsync())
                        using (var inflate = new GZipStream(stream, CompressionMode.Decompress))
                            using (var memory = new MemoryStream())
                            {
                                inflate.CopyTo(memory);

                                asBytes = memory.ToArray();
                            }
                }
                else if (content.Headers.ContentEncoding.Any(e => OrdinalIgnoreCase.Equals(AcceptEncodingDeflate, e)))
                {
                    using (var stream = await content.ReadAsStreamAsync())
                        using (var inflate = new DeflateStream(stream, CompressionMode.Decompress))
                            using (var memory = new MemoryStream())
                            {
                                inflate.CopyTo(memory);

                                asBytes = memory.ToArray();
                            }
                }
                else
                {
                    asBytes = await content.ReadAsByteArrayAsync();
                }

                lock (_syncpoint)
                {
                    _mediaType = content.Headers.ContentType.MediaType;
                    _byteArray = asBytes;
                }
            }
        }
Example #21
0
        internal bool GetCapturedData(ICapturedDataFilter filter, out CapturedSettingsData capturedData)
        {
            if (filter is null)
            {
                throw new ArgumentNullException(nameof(filter));
            }

            lock (_syncpoint)
            {
                _captured.EnvironmentVariables = new List <CapturedSettingsEnvironmentVariables>(3);

                // Ensure the special GCM_DEBUG environment variable is set.
                if (!_variables[EnvironmentVariableTarget.Process].ContainsKey("GCM_DEBUG"))
                {
                    _variables[EnvironmentVariableTarget.Process].Add("GCM_DEBUG", null);
                }

                foreach (var target in _variables.Keys)
                {
                    var variables = new CapturedSettingsEnvironmentVariables
                    {
                        Target = (int)target,
                        Values = new List <CapturedSettingsEnvironmentVariable>(),
                    };

                    foreach (var kvp in _variables[target])
                    {
                        if (kvp.Key is null)
                        {
                            continue;
                        }

                        if (OrdinalIgnoreCase.Equals("PATH", kvp.Key))
                        {
                            var items = kvp.Value?.Split(';');
                            var keeps = new List <string>(items.Length);

                            for (int i = 0; i < items.Length; i += 1)
                            {
                                foreach (var legal in AllowedCapturedPathValues)
                                {
                                    if (legal.IsMatch(items[i]))
                                    {
                                        keeps.Add(items[i]);
                                        break;
                                    }
                                }
                            }

                            if (keeps.Count > 0)
                            {
                                var name     = kvp.Key;
                                var variable = string.Join(";", keeps);

                                var entry = new CapturedSettingsEnvironmentVariable
                                {
                                    Name     = name,
                                    Variable = variable,
                                };

                                variables.Values.Add(entry);
                            }
                        }
                        else if (AllowedCapturedVariables.TryGetValue(kvp.Key, out string variable))
                        {
                            var name = kvp.Key;

                            var entry = new CapturedSettingsEnvironmentVariable
                            {
                                Name     = name,
                                Variable = variable,
                            };

                            variables.Values.Add(entry);
                        }
                        else
                        {
                            var name = kvp.Key;
                            variable = kvp.Value;

                            foreach (var allowed in AllowedCapturedVariableNames)
                            {
                                if (allowed.IsMatch(name))
                                {
                                    variable = filter.ApplyFilter(variable);

                                    var entry = new CapturedSettingsEnvironmentVariable
                                    {
                                        Name     = name,
                                        Variable = variable,
                                    };

                                    variables.Values.Add(entry);

                                    break;
                                }
                            }
                        }
                    }

                    _captured.EnvironmentVariables.Add(variables);
                }

                _captured.ExpandVariables = new List <CapturedSettingsExpandVariable>();

                foreach (var kvp in _expandedVariables)
                {
                    if (kvp.Key is null)
                    {
                        continue;
                    }

                    var expanded = kvp.Value;
                    var original = kvp.Key;

                    expanded = filter.ApplyFilter(expanded);
                    original = filter.ApplyFilter(original);

                    var query = new CapturedSettingsExpandVariable
                    {
                        Expanded = expanded,
                        Original = original,
                    };

                    _captured.ExpandVariables.Add(query);
                }

                _captured.SpecialFolders = new List <CapturedSettingsSpecialFolder>();

                foreach (var kvp in _specialFolders)
                {
                    if (kvp.Value is null)
                    {
                        continue;
                    }

                    var path = kvp.Value;

                    path = filter.ApplyFilter(path);

                    var folder = new CapturedSettingsSpecialFolder
                    {
                        SpecialFolder = (int)kvp.Key,
                        Path          = path,
                    };

                    _captured.SpecialFolders.Add(folder);
                }

                _captured.CurrentDirectory = filter.ApplyFilter(_captured.CurrentDirectory);

                capturedData = _captured;
                return(true);
            }
        }
        private void Run(string[] args)
        {
            try
            {
                EnableDebugTrace();

                if (args.Length == 0 ||
                    OrdinalIgnoreCase.Equals(args[0], "--help") ||
                    OrdinalIgnoreCase.Equals(args[0], "-h") ||
                    args[0].Contains('?'))
                {
                    PrintHelpMessage();
                    return;
                }

                // Enable tracing if "GCM_TRACE" has been enabled in the environment.
                DetectTraceEnvironmentKey(EnvironConfigTraceKey);

                PrintArgs(args);

                // List of `arg` => method associations (case-insensitive).
                var actions = new Dictionary <string, Action>(OrdinalIgnoreCase)
                {
                    { CommandApprove, Store },
                    { CommandClear, Clear },
                    { CommandConfig, Config },
                    { CommandDelete, Delete },
                    { CommandDeploy, Deploy },
                    { CommandErase, Erase },
                    { CommandFill, Get },
                    { CommandGet, Get },
                    { CommandInstall, Deploy },
                    { CommandReject, Erase },
                    { CommandRemove, Remove },
                    { CommandStore, Store },
                    { CommandUninstall, Remove },
                    { CommandVersion, PrintVersion },
                };

                // Invoke action specified by arg0.
                if (actions.ContainsKey(args[0]))
                {
                    actions[args[0]]();
                }
            }
            catch (AggregateException exception)
            {
                // Print out more useful information when an `AggregateException` is encountered.
                exception = exception.Flatten();

                // Find the first inner exception which isn't an `AggregateException` with fall-back
                // to the canonical `.InnerException`.
                Exception innerException = exception.InnerExceptions.FirstOrDefault(e => !(e is AggregateException))
                                           ?? exception.InnerException;

                Die(innerException);
            }
            catch (Exception exception)
            {
                Die(exception);
            }
        }
Example #23
0
        public async Task Upload(string payload, string basePath, IEnumerable <string> filePaths)
        {
            if (payload is null)
            {
                throw new ArgumentNullException(nameof(payload));
            }
            if (filePaths is null)
            {
                throw new ArgumentNullException(nameof(filePaths));
            }

            if (!PayloadId.TryParse(payload, out var payloadId))
            {
                throw new ArgumentException($"Invalid Payload ID received: {{{payload}}}.", nameof(payload));
            }

            var queue          = new Queue <string>(filePaths);
            var completedFiles = new List <PayloadFileDetails>();

            basePath = EnsureBasePathEndsWithSlash(basePath);

            await Policy.Handle <Exception>()
            .WaitAndRetryAsync(3,
                               retryAttempt
                               => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
                               (exception, retryCount, context)
                               => _logger.Log(LogLevel.Error, "Exception while uploading file(s) to {{{0}}}: {exception}.", payload, exception))
            .ExecuteAsync(async() =>
            {
                var list = new List <(uint mode, string name, Stream stream)>();
                var temp = new List <string>();

                try
                {
                    while (queue.Count > 0)
                    {
                        var filePath = queue.Dequeue();
                        temp.Add(filePath);
                        var filename = filePath.Replace(basePath, "");
                        if (System.Linq.Enumerable.Any(completedFiles, (PayloadFileDetails pfd) => OrdinalIgnoreCase.Equals(filename, pfd.Name)))
                        {
                            continue;
                        }
                        try
                        {
                            var stream = _fileSystem.File.OpenRead(filePath);
                            list.Add((0, filename, stream));
                            _logger.Log(LogLevel.Debug, "Ready to upload file \"{0}\" to PayloadId {1}.", filename, payloadId);
                        }
                        catch (System.Exception ex)
                        {
                            _logger.Log(LogLevel.Error, "Failed to open/read file {0}: {1}", filename, ex);
                            throw;
                        }
                    }

                    try
                    {
                        var uploadedFiles = await _payloadsClient.UploadTo(payloadId, list);

                        completedFiles.AddRange(uploadedFiles);
                        _logger.Log(LogLevel.Information, "{0} files uploaded to PayloadId {1}", completedFiles.Count, payloadId);
                    }
                    catch (PayloadUploadFailedException ex)
                    {
                        completedFiles.AddRange(ex.CompletedFiles);
                        temp.ForEach(file => queue.Enqueue(file));

                        if (completedFiles.Count != filePaths.Count())
                        {
                            throw;
                        }
                        _logger.Log(LogLevel.Information, "{0} files uploaded to PayloadId {1}", completedFiles.Count, payloadId);
                    }
                    catch
                    {
                        temp.ForEach(file => queue.Enqueue(file));
                        throw;
                    }
                }
                finally
                {
                    for (var i = 0; i < list.Count; i += 1)
                    {
                        try
                        {
                            list[i].stream?.Dispose();
                        }
                        catch (Exception exception)
                        {
                            _logger.Log(LogLevel.Error, exception, $"Failed to dispose \"{list[i].name}\" stream.");
                        }
                    }
                }
            }).ConfigureAwait(false);
        }