Пример #1
0
        static DotNetSdkTestBase()
        {
            s_dotnetExeName = "dotnet" + (Path.DirectorySeparatorChar == '/' ? "" : ".exe");
            s_buildInfo     = typeof(DotNetSdkTestBase).Assembly.GetCustomAttribute <BuildInfoAttribute>();

            var minSdkVersion = SemanticVersion.Parse(s_buildInfo.SdkVersion);
Пример #2
0
        public async Task <IPackageInfo> GetPackageInfoAsync(string packageId, string version, IPackageQueryConfiguration queryConfiguration, CancellationToken cancellationToken)
        {
            if (packageId == null)
            {
                return(null);
            }

            string        packageDisplayMetadataUriTemplateIdentifier = "PackageDisplayMetadataUriTemplate/3.0.0-rc";
            List <string> packageQuickInfoAddresses = await DiscoverEndpointsAsync(_feed, packageDisplayMetadataUriTemplateIdentifier, cancellationToken).ConfigureAwait(false);

            if (packageQuickInfoAddresses == null || packageQuickInfoAddresses.Count == 0)
            {
                return(null);
            }

            string packageQuickInfoAddress = packageQuickInfoAddresses[0];

            string  location = packageQuickInfoAddress.Replace("{id-lower}", packageId.ToLowerInvariant());
            JObject responseJson;

            try
            {
                responseJson = await _webRequestFactory.GetJsonAsync(location, cancellationToken).ConfigureAwait(false) as JObject;
            }
            catch
            {
                return(null);
            }

            if (responseJson != null && responseJson.TryGetValue("items", out JToken topLevelItemsParseItem))
            {
                JArray  topLevelItemsArray      = topLevelItemsParseItem as JArray;
                JObject packageResultsContainer = topLevelItemsArray?.FirstOrDefault() as JObject;
                JToken  packageResultsItemsParseItem;

                if (packageResultsContainer != null && packageResultsContainer.TryGetValue("items", out packageResultsItemsParseItem))
                {
                    JArray packageResultsItems = packageResultsItemsParseItem as JArray;

                    if (packageResultsItemsParseItem == null)
                    {
                        return(null);
                    }

                    string          id, title, authors, summary, description, licenseUrl, projectUrl, iconUrl, tags;
                    SemanticVersion bestSemanticVersion = null;
                    PackageInfo     packageInfo         = null;

                    foreach (JToken element in packageResultsItems)
                    {
                        JObject packageContainer = element as JObject;
                        JToken  catalogEntryParseItem;

                        if (packageContainer != null && packageContainer.TryGetValue("catalogEntry", out catalogEntryParseItem))
                        {
                            JObject catalogEntry = catalogEntryParseItem as JObject;

                            if (catalogEntry != null)
                            {
                                string ver = catalogEntry["version"]?.ToString();

                                if (ver == null)
                                {
                                    continue;
                                }

                                SemanticVersion currentVersion = SemanticVersion.Parse(ver);

                                if (version != null)
                                {
                                    if (string.Equals(version, catalogEntry["version"]?.ToString(), StringComparison.OrdinalIgnoreCase))
                                    {
                                        id          = catalogEntry["id"]?.ToString();
                                        title       = catalogEntry ["title"]?.ToString();
                                        authors     = catalogEntry["authors"]?.ToString();
                                        summary     = catalogEntry ["summary"]?.ToString();
                                        description = catalogEntry["description"]?.ToString();
                                        projectUrl  = catalogEntry["projectUrl"]?.ToString();
                                        licenseUrl  = catalogEntry["licenseUrl"]?.ToString();
                                        iconUrl     = catalogEntry["iconUrl"]?.ToString();
                                        tags        = catalogEntry ["tags"]?.ToString();
                                        packageInfo = new PackageInfo(id, version, title, authors, summary, description, licenseUrl, projectUrl, iconUrl, tags, _kind);
                                        return(packageInfo);
                                    }
                                }
                                else
                                {
                                    if (currentVersion.CompareTo(bestSemanticVersion) > 0)
                                    {
                                        id                  = catalogEntry["id"]?.ToString();
                                        title               = catalogEntry["title"]?.ToString();
                                        authors             = catalogEntry["authors"]?.ToString();
                                        summary             = catalogEntry["summary"]?.ToString();
                                        description         = catalogEntry["description"]?.ToString();
                                        projectUrl          = catalogEntry["projectUrl"]?.ToString();
                                        licenseUrl          = catalogEntry["licenseUrl"]?.ToString();
                                        iconUrl             = catalogEntry["iconUrl"]?.ToString();
                                        tags                = catalogEntry["tags"]?.ToString();
                                        packageInfo         = new PackageInfo(id, version, title, authors, summary, description, licenseUrl, projectUrl, iconUrl, tags, _kind);
                                        bestSemanticVersion = currentVersion;
                                    }
                                }
                            }
                        }
                    }

                    return(packageInfo);
                }
            }

            return(null);
        }
Пример #3
0
        // private methods
        private bool CanRunOn(ICluster cluster, BsonDocument requirement)
        {
            foreach (var item in requirement)
            {
                switch (item.Name)
                {
                case "authEnabled":
                case "auth":
                {
                    return(IsAuthenticated() == item.Value.ToBoolean());
                }

                case "minServerVersion":
                {
                    var actualVersion    = CoreTestConfiguration.ServerVersion;
                    var minServerVersion = SemanticVersion.Parse(item.Value.AsString);
                    if (SemanticVersionCompareToAsReleased(actualVersion, minServerVersion) < 0)
                    {
                        return(false);
                    }
                }
                break;

                case "maxServerVersion":
                {
                    var actualVersion    = CoreTestConfiguration.ServerVersion;
                    var maxServerVersion = SemanticVersion.Parse(item.Value.AsString);
                    if (SemanticVersionCompareToAsReleased(actualVersion, maxServerVersion) > 0)
                    {
                        return(false);
                    }
                }
                break;

                case "serverParameters":
                {
                    var serverParameters = CoreTestConfiguration.GetServerParameters();
                    foreach (var parameter in item.Value.AsBsonDocument)
                    {
                        if (serverParameters[parameter.Name] != parameter.Value)
                        {
                            return(false);
                        }
                    }
                }
                break;

                case "topologies":
                case "topology":
                {
                    var actualClusterType = CoreTestConfiguration.Cluster.Description.Type;
                    var runOnClusterTypes = item.Value.AsBsonArray.Select(topology => MapTopologyToClusterType(topology.AsString)).ToList();
                    if (!runOnClusterTypes.Contains(actualClusterType))
                    {
                        return(false);
                    }
                }
                break;

                case "serverless":
                    return(false);    // TODO: not implemented yet

                default:
                    throw new FormatException($"Unrecognized requirement field: '{item.Name}'");
                }
            }

            return(true);
        }
Пример #4
0
        /* Checks for updates and returns release informations when there is newer one.
         * Returns null if there is no newer release.
         * If Prerelease argument is true, it will return also Pre-release, otherwise Pre-releases are ignored.
         * An existing last checked release will be discarded.
         * Throws UpdaterException if error occurs.
         */
        public static Release CheckForUpdates(bool Prerelease = true)
        {
            if (Latest != null)
            {
                if (Latest.IsDownloading)
                {
                    throw new UpdaterException(L10n.Message("Download already in progress"));
                }

                // If release was installed, report no update.
                if (Latest.IsInstalled)
                {
                    return(null);
                }

                Dispose();
            }

            if (IsNewerProductInstalled())
            {
                // Newer product is installed, there is no update.
                IsChecked = true;

                return(null);
            }

            var webClient = new UpdaterWebClient();

            webClient.Encoding = Encoding.UTF8;

            try
            {
                string json     = webClient.DownloadString(GitAPILatestReleaseURL);
                JArray releases = JArray.Parse(json);
                if (releases.Count < 1)
                {
                    throw new UpdaterException(L10n.Message("No release found"));
                }

                var current = GetCurrentVersion(); // Current version (tag).

                // Iterate thru avialable releases.
                foreach (JObject release in (JArray)releases)
                {
                    // Drafts are not returned by API, but just in case...
                    bool draft = release["draft"].Value <bool>();
                    if (draft)
                    {
                        continue;        // Ignore drafts.
                    }
                    // Check if there are assets attached.
                    JArray assets = (JArray)release["assets"];
                    if (assets.Count < 1)
                    {
                        continue;                   // No assets, ignore it.
                    }
                    // Compare release tag with our version (tag).
                    string tag     = release["tag_name"].Value <string>();
                    var    version = SemanticVersion.Parse(tag);
                    if (version.CompareTo(current) <= 0)
                    {
                        // Same or older version.
                        IsChecked = true;

                        return(null);
                    }

                    // Check if it is pre-release and we want to update to it.
                    bool prerelease = release["prerelease"].Value <bool>();
                    if (prerelease && !Prerelease)
                    {
                        continue;                            // Found unwanted pre-release, ignore it.
                    }
                    // Find release package.
                    string  fileName = null;
                    JObject pkgAsset = null;
                    foreach (JObject asset in assets)
                    {
                        // Check if asset upload completed.
                        if (asset["state"].Value <string>() != "uploaded")
                        {
                            continue;
                        }

                        string content_type = asset["content_type"].Value <string>();
                        if (content_type != PackageContentType)
                        {
                            continue;                                     // Not a package, ignore it.
                        }
                        fileName = asset["name"].Value <string>();
                        Match m = RePackage.Match(fileName);
                        if (m.Success)
                        {
                            // Found release package.
                            pkgAsset = asset;
                            break;
                        }
                    }
                    if (pkgAsset == null)
                    {
                        continue;                   // No package found.
                    }
                    // This is newer release.
                    IsChecked = true;
                    Latest    = new Release
                    {
                        Name         = release["name"].Value <string>(),
                        Description  = release["body"].Value <string>(),
                        IsPrerelease = prerelease,
                        // A release is an update, if file name starts with our PackageName.
                        IsUpdate        = fileName.StartsWith(GetPackageName(Properties.Version.ProductName) + "-"),
                        PackageFileName = fileName,
                        Version         = tag,
                        URI             = new Uri(pkgAsset["browser_download_url"].Value <string>())
                    };

                    // We are done, exit loop.
                    break;
                }
            }
            catch (WebException e)
            {
                if (e.Status == WebExceptionStatus.ProtocolError)
                {
                    throw new UpdaterException("HTTP " + ((int)((HttpWebResponse)e.Response).StatusCode) + " " + ((HttpWebResponse)e.Response).StatusDescription);
                }
                else
                {
                    throw new UpdaterException(e.Message, e);
                }
            }
            catch (Exception e)
            {
                throw new UpdaterException(e.Message, e);
            }

            return(Latest);
        }
Пример #5
0
        private void LogHintPathRewriteMessage(IPackage package, string includeName, string includeVersion)
        {
            var message = string.Format("Attempting to update hintpaths for \"{0}\" {1}using package \"{2}\" version \"{3}\"",
                                        includeName,
                                        string.IsNullOrEmpty(includeVersion) ? "" : "version \"" + includeVersion + "\" ",
                                        package.Id,
                                        package.Version);

            if (package.Id.Equals(includeName, StringComparison.OrdinalIgnoreCase))
            {
                if (!string.IsNullOrEmpty(includeVersion) && package.Version.Version != SemanticVersion.Parse(includeVersion).Version)
                {
                    _console.WriteWarning(message);
                }
                else
                {
                    _console.WriteLine(message);
                }
            }
            else
            {
                _console.WriteWarning(message);
            }
        }
Пример #6
0
        /// <summary>
        /// <para>
        /// Verifies the <b>$sdk-catalog.json/</b> SDK catalog file by downloading
        /// the binaries and verifying their SHA512 hashes.
        /// </para>
        /// <note>
        /// This program assumes that it's running within the GitHub repository.
        /// </note>
        /// </summary>
        /// <param name="args">Ignored</param>
        /// <returns>The tracking <see cref="Task"/>.</returns>
        public static async Task Main(string[] args)
        {
            var catalogPath = Path.GetFullPath(Path.Combine(Assembly.GetExecutingAssembly().Location, "..", "..", "..", "..", "..", "RaspberryDebugger", "sdk-catalog.json"));
            var catalog     = (SdkCatalog)null;
            var ok          = true;

            Console.WriteLine($"reading: {catalogPath}");

            try
            {
                catalog = NeonHelper.JsonDeserialize <SdkCatalog>(File.ReadAllText(catalogPath));
            }
            catch (Exception e)
            {
                Console.WriteLine(NeonHelper.ExceptionError(e));
                Environment.Exit(1);
            }

            Console.WriteLine();
            Console.WriteLine($"[{catalog.Items.Count}] catalog items");

            // Verify that all of the links are unique.

            var sdkLinkToItem = new Dictionary <string, SdkCatalogItem>();

            foreach (var item in catalog.Items)
            {
                if (sdkLinkToItem.TryGetValue(item.Link, out var existingItem))
                {
                    ok = false;
                    Console.WriteLine($"SDK [{existingItem.Name}/{existingItem.Architecture}] and [{item.Name}/{item.Architecture}] have the same link: [{item.Link}]");
                    continue;
                }

                sdkLinkToItem.Add(item.Link, item);
            }

            // Verify that all SDK names are unique for a given architecture.

            var sdkNameArchectureToItem = new Dictionary <string, SdkCatalogItem>();

            foreach (var item in catalog.Items)
            {
                if (sdkLinkToItem.TryGetValue($"{item.Name}/{item.Architecture}", out var existingItem))
                {
                    ok = false;
                    Console.WriteLine($"SDK [{existingItem.Name}/{existingItem.Architecture}] is listed multiple times.");
                    continue;
                }

                if (!item.Link.Contains(item.Name))
                {
                    ok = false;
                    Console.WriteLine($"*** ERROR: Link does not include the SDK name: {item.Name}");
                    continue;
                }

                if (item.Architecture == SdkArchitecture.ARM32)
                {
                    if (item.Link.Contains("arm64"))
                    {
                        ok = false;
                        Console.WriteLine($"*** ERROR: ARM32 SDK link references a 64-bit SDK.");
                        continue;
                    }
                }
                else
                {
                    if (!item.Link.Contains("arm64"))
                    {
                        ok = false;
                        Console.WriteLine($"*** ERROR: ARM64 SDK link references a 32-bit SDK.");
                        continue;
                    }
                }

                sdkLinkToItem.Add($"{item.Name}/{item.Architecture}", item);
            }

            // Verify the links and SHA256 hashes.  We're going to do this check in reverse
            // order by .NET version name to verify newer entries first because those will
            // be most likely to be incorrect.

            using (var client = new HttpClient())
            {
                foreach (var item in catalog.Items
                         .OrderByDescending(item => SemanticVersion.Parse(item.Version))
                         .ThenBy(item => item.Name)
                         .ThenBy(item => item.Architecture))
                {
                    Console.WriteLine();
                    Console.WriteLine("----------------------------------------");
                    Console.WriteLine();
                    Console.WriteLine($"SDK:    {item.Name}/{item.Architecture} (v{item.Version})");
                    Console.WriteLine($"Link:   {item.Link}");

                    // I've seen some transient issues with downloading SDKs from Microsoft: 404 & 503
                    // We're going to retry up to 5 times.

                    var binary = (byte[])null;

                    for (int i = 0; i < 5; i++)
                    {
                        try
                        {
                            binary = await client.GetByteArraySafeAsync(item.Link);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(NeonHelper.ExceptionError(e));
                        }
                    }

                    if (binary == null)
                    {
                        ok = false;
                    }

                    var expectedSha512 = item.SHA512.ToLowerInvariant();
                    var actualSha512   = CryptoHelper.ComputeSHA512String(binary).ToLowerInvariant();

                    if (actualSha512 == expectedSha512)
                    {
                        Console.WriteLine("SHA512: Hashes match");
                    }
                    else
                    {
                        ok = false;

                        Console.WriteLine();
                        Console.WriteLine($"*** ERROR: SHA512 hashes don't match!");
                        Console.WriteLine($"Expected: {expectedSha512}");
                        Console.WriteLine($"Actual:   {actualSha512}");
                    }
                }
            }

            Console.WriteLine();
            Console.WriteLine("----------------------------------------");
            Console.WriteLine();

            if (ok)
            {
                Console.WriteLine("Catalog is OK");
                Environment.Exit(1);
            }
            else
            {
                Console.WriteLine("*** ERROR: One or more catalog items have issues");
                Environment.Exit(0);
            }
        }
Пример #7
0
        public void NullDependencyVersionsAreParsed()
        {
            var lockFileData = @"{
  ""locked"": false,
  ""version"": 1,
  ""targets"": {
        "".NETFramework,Version=v4.5"": {
            ""SomeProject/1.0.0"": {
                ""type"": ""project"",
                ""framework"": "".NETFramework,Version=v4.5""
            },
            ""WindowsAzure.ServiceBus/2.6.7"": {
                ""dependencies"": {
                    ""Microsoft.WindowsAzure.ConfigurationManager"": null
                },
                ""frameworkAssemblies"": [
                  ""System.ServiceModel"",
                  ""System.Xml"",
                  ""System.Runtime.Serialization""
                ],
                ""compile"": {
                  ""lib/net40-full/Microsoft.ServiceBus.dll"": {}
                },
                ""runtime"": {
                  ""lib/net40-full/Microsoft.ServiceBus.dll"": {}
                }
            }
        }
  },
  ""libraries"": {
    ""WindowsAzure.ServiceBus/2.6.7"": {
      ""sha512"": ""AhQ4nya0Pu0tGev/Geqt5+yBTI+ov66ginMHCm+HqmXezTIOSfBu7HOI5RuvmiQqM99AeTuASD6gMz+zWueHNQ=="",
      ""files"": [
        ""WindowsAzure.ServiceBus.2.6.7.nupkg"",
        ""WindowsAzure.ServiceBus.2.6.7.nupkg.sha512"",
        ""WindowsAzure.ServiceBus.nuspec"",
        ""content/app.config.install.xdt"",
        ""content/web.config.install.xdt"",
        ""lib/net40-full/Microsoft.ServiceBus.dll"",
        ""lib/net40-full/Microsoft.ServiceBus.xml""
      ]
    }
  },
  ""projectFileDependencyGroups"": {
    """": [
      ""SomeProject "",
      ""WindowsAzure.ServiceBus >= 2.6.7""
    ],
    "".NETFramework,Version=v4.5"": []
  }
}";

            var reader = new LockFileReader();

            var stream   = new MemoryStream(Encoding.UTF8.GetBytes(lockFileData));
            var lockFile = reader.Read(stream);

            Assert.False(lockFile.Islocked);
            Assert.Equal(1, lockFile.Targets.Count);
            var library1 = lockFile.Targets[0].Libraries[0];

            Assert.Equal("SomeProject", library1.Name);
            Assert.Equal("project", library1.Type);
            Assert.Equal(new FrameworkName(".NETFramework,Version=v4.5"), library1.TargetFramework);
            Assert.Equal(SemanticVersion.Parse("1.0.0"), library1.Version);
            var library2 = lockFile.Targets[0].Libraries[1];

            Assert.Equal("WindowsAzure.ServiceBus", library2.Name);
            Assert.Null(library2.Type);
            Assert.Equal(SemanticVersion.Parse("2.6.7"), library2.Version);
            Assert.Equal(1, library2.Dependencies.Count);
            var dependency = library2.Dependencies[0];

            Assert.Equal(dependency.Id, "Microsoft.WindowsAzure.ConfigurationManager");
            Assert.Null(dependency.VersionSpec);
        }
        private static async Task <ImmutableArray <AvailableVersion> > GetAvailableVersionsFromNuGet(
            HttpClient httpClient,
            ILogger logger,
            CancellationToken cancellationToken)
        {
            try
            {
                var url = new Uri("https://dist.nuget.org/index.json");

                string json;
                using (var request = new HttpRequestMessage(HttpMethod.Get, url))
                {
                    using HttpResponseMessage response = await httpClient.SendAsync(request, cancellationToken).ConfigureAwait(false);

                    if (!response.IsSuccessStatusCode)
                    {
                        logger.Warning(
                            "Could not get available nuget.exe versions, http status code was not successful {StatusCode}",
                            response.StatusCode);

                        return(ImmutableArray <AvailableVersion> .Empty);
                    }

                    json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                }

                var sample = new
                {
                    artifacts =
                        new[]
                    {
                        new
                        {
                            name        = "",
                            displayName = "",
                            versions    = new[]
                            {
                                new { displayName = "", version = "", url = "", releasedate = "" }
                            }
                        }
                    }
                };

                var deserializedAnonymousType = JsonConvert.DeserializeAnonymousType(json, sample);

                var availableVersions = deserializedAnonymousType?.artifacts
                                        .SingleOrDefault(artifact =>
                                                         artifact.name.Equals("win-x86-commandline", StringComparison.OrdinalIgnoreCase))
                                        ?.versions
                                        .Where(version => version.displayName.Equals("nuget.exe", StringComparison.OrdinalIgnoreCase))
                                        .Select(version => new AvailableVersion(new Uri(version.url, UriKind.Absolute),
                                                                                SemanticVersion.Parse(version.version)))
                                        .Where(availableVersion => !availableVersion.SemanticVersion.IsPrerelease)
                                        .OrderByDescending(availableVersion => availableVersion.SemanticVersion)
                                        .ToImmutableArray();

                if (availableVersions?.Length > 0)
                {
                    logger.Debug("Found available NuGet versions [{Count}]\r\n{AvailableVersions}",
                                 availableVersions.Value.Length,
                                 availableVersions);
                }

                return(availableVersions ?? ImmutableArray <AvailableVersion> .Empty);
            }
            catch (Exception ex)
            {
                logger.Warning(ex, "Could not get available NuGet versions");
                return(ImmutableArray <AvailableVersion> .Empty);
            }
        }
Пример #9
0
        private static void PopulateDependencies(
            IList <LibraryDependency> results,
            JObject settings,
            string propertyName,
            bool isGacOrFrameworkReference)
        {
            var dependencies = settings[propertyName] as JObject;

            if (dependencies != null)
            {
                foreach (var dependency in dependencies)
                {
                    if (String.IsNullOrEmpty(dependency.Key))
                    {
                        throw new InvalidDataException("Unable to resolve dependency ''.");
                    }

                    // Support
                    // "dependencies" : {
                    //    "Name" : "1.0"
                    // }

                    var    dependencyValue        = dependency.Value;
                    string dependencyVersionValue = null;
                    var    dependencyTypeValue    = LibraryDependencyType.Default;
                    if (dependencyValue.Type == JTokenType.String)
                    {
                        dependencyVersionValue = dependencyValue.Value <string>();
                    }
                    else
                    {
                        if (dependencyValue.Type == JTokenType.Object)
                        {
                            var dependencyVersionToken = dependencyValue["version"];
                            if (dependencyVersionToken != null && dependencyVersionToken.Type == JTokenType.String)
                            {
                                dependencyVersionValue = dependencyVersionToken.Value <string>();
                            }
                        }

                        IEnumerable <string> strings;
                        if (TryGetStringEnumerable(dependencyValue["type"], out strings))
                        {
                            dependencyTypeValue = LibraryDependencyType.Parse(strings);
                        }
                    }

                    SemanticVersion dependencyVersion = null;
                    if (!String.IsNullOrEmpty(dependencyVersionValue))
                    {
                        dependencyVersion = SemanticVersion.Parse(dependencyVersionValue);
                    }

                    results.Add(new LibraryDependency(
                                    name: dependency.Key,
                                    version: dependencyVersion,
                                    isGacOrFrameworkReference: isGacOrFrameworkReference,
                                    type: dependencyTypeValue
                                    ));
                }
            }
        }
Пример #10
0
        private void ProduceVersionCompletionSet()
        {
            List <Microsoft.VisualStudio.Language.Intellisense.Completion> completions = new List <Microsoft.VisualStudio.Language.Intellisense.Completion>();
            Dictionary <string, FeedKind> iconMap = new Dictionary <string, FeedKind>();

            foreach (Tuple <string, FeedKind> info in _versionSearchJob.Results)
            {
                if (!iconMap.TryGetValue(info.Item1, out FeedKind existing) || existing != FeedKind.Local)
                {
                    iconMap[info.Item1] = info.Item2;
                }
            }

            foreach (KeyValuePair <string, FeedKind> entry in iconMap.OrderByDescending(x => SemanticVersion.Parse(x.Key)))
            {
                ImageMoniker moniker = KnownMonikers.NuGet;

                switch (entry.Value)
                {
                case FeedKind.Local:
                    moniker = KnownMonikers.FolderClosed;
                    break;
                    //TODO: Add different icons for MyGet/network/etc
                }

                completions.Add(new VersionCompletion(entry.Key, entry.Key, null, moniker, entry.Key));
            }

            _currentCompletionSet.AccessibleCompletions.Clear();
            _currentCompletionSet.AccessibleCompletions.AddRange(completions);
        }
        private async Task ExportModulesInternalAsync(ZipArchive zipArchive, PlatformExportManifest manifest, Action <ExportImportProgressInfo> progressCallback, ICancellationToken cancellationToken)
        {
            var progressInfo = new ExportImportProgressInfo();

            foreach (var module in manifest.Modules)
            {
                var moduleDescriptor = InnerGetModulesWithInterface(typeof(IImportSupport)).FirstOrDefault(x => x.Id == module.Id);
                if (moduleDescriptor != null)
                {
                    //Create part for module
                    var moduleZipEntryName = module.Id + ".json";
                    var zipEntry           = zipArchive.CreateEntry(moduleZipEntryName, CompressionLevel.Optimal);

                    void ModuleProgressCallback(ExportImportProgressInfo x)
                    {
                        progressInfo.Description = $"{ module.Id }: { x.Description }";
                        progressInfo.Errors      = x.Errors;
                        progressCallback(progressInfo);
                    }

                    progressInfo.Description = $"{module.Id}: exporting...";
                    progressCallback(progressInfo);
                    if (moduleDescriptor.ModuleInstance is IExportSupport exporter)
                    {
                        try
                        {
                            //TODO: Add JsonConverter which will be materialized concrete ExportImport option type
                            //ToDo: Added check ExportImportOptions for modules (DefaultIfEmpty)
                            var options = manifest.Options
                                          .DefaultIfEmpty(new ExportImportOptions {
                                HandleBinaryData = manifest.HandleBinaryData, ModuleIdentity = new ModuleIdentity(module.Id, SemanticVersion.Parse(module.Version))
                            })
                                          .FirstOrDefault(x => x.ModuleIdentity.Id == moduleDescriptor.Identity.Id);
                            await exporter.ExportAsync(zipEntry.Open(), options, ModuleProgressCallback, cancellationToken);
                        }
                        catch (Exception ex)
                        {
                            progressInfo.Errors.Add($"{ module.Id}: {ex}");
                            progressCallback(progressInfo);
                        }
                    }
                    module.PartUri = moduleZipEntryName;
                }
            }
        }
Пример #12
0
 public void Parse_ShouldNotParseNullVersion()
 {
     Assert.ThrowsException <ArgumentNullException>(() => SemanticVersion.Parse(null));
 }
Пример #13
0
 [DataRow("1.0.0+é")]       // Invalid character
 public void TryParse_ShouldNotParseVersion(string version)
 {
     Assert.IsFalse(SemanticVersion.TryParse(version, out _));
     Assert.ThrowsException <ArgumentException>(() => SemanticVersion.Parse(version));
 }
Пример #14
0
        public void ToString(string version)
        {
            var semanticVersion = SemanticVersion.Parse(version);

            Assert.AreEqual(version, semanticVersion.ToString());
        }
Пример #15
0
        public void TestSetAssemblyInfo()
        {
            File.Copy("Packages/SetAsmInfoTest.dll", "SetAsmInfoTest.dll", true);
            var fileName = $"SetAsmInfoTest.dll";

            // Check if version is null
            Assert.IsNull(ReadAssemblyVersionStep.GetVersion(fileName), "Assembly version is not null as expected.");

            // Check if version has been new version inserted
            SetAsmInfo.SetAsmInfo.SetInfo(fileName, Version.Parse("1.2.3.4"), Version.Parse("2.3.4.5"), SemanticVersion.Parse("2.3.4-test"));
            Assert.IsTrue(ReadAssemblyVersionStep.GetVersion(fileName)?.Equals(SemanticVersion.Parse("2.3.4-test")), "Assembly version was not inserted correctly.");

            // Check if version has been updated.
            SetAsmInfo.SetAsmInfo.SetInfo(fileName, Version.Parse("1.2.3.4"), Version.Parse("2.3.4.5"), SemanticVersion.Parse("3.4.5-test"));
            Assert.IsTrue(ReadAssemblyVersionStep.GetVersion(fileName)?.Equals(SemanticVersion.Parse("3.4.5-test")), "Assembly version was not updated correctly.");
        }
Пример #16
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();
            // This custom provider allows able to use just [Authorize] instead of having to define [Authorize(AuthenticationSchemes = "Bearer")] above every API controller
            // without this Bearer authorization will not work
            services.AddSingleton <IAuthenticationSchemeProvider, CustomAuthenticationSchemeProvider>();

            services.Configure <PlatformOptions>(Configuration.GetSection("VirtoCommerce"));
            services.Configure <HangfireOptions>(Configuration.GetSection("VirtoCommerce:Jobs"));

            PlatformVersion.CurrentVersion = SemanticVersion.Parse(Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.Application.ApplicationVersion);

            services.AddPlatformServices(Configuration);
            services.AddSecurityServices();

            var mvcBuilder = services.AddMvc(mvcOptions =>
            {
                // NOTE: combining multiple Authorize attributes when using a custom IAuthorizationPolicyProvider
                //       with ASP.NET Core MVC 2.1 causes an ArgumentNullException when calling an action.
                //       For more information, please see https://github.com/aspnet/Mvc/issues/7809
                //
                // Currently this issue affects following controllers:
                // - VirtoCommerce.Platform.Web.Controllers.Api.DynamicPropertiesController
                // - VirtoCommerce.SitemapsModule.Web.Controllers.Api.SitemapsModuleApiController
                // - probably some other controllers in modules not ported to VC Platform 3.x yet...
                //
                // This issue is fixed in ASP.NET Core MVC 2.2. The following line is a workaround for 2.1.
                // TODO: remove the following workaround after migrating to ASP.NET Core MVC 2.2
                mvcOptions.AllowCombiningAuthorizeFilters = false;

                //Disable 204 response for null result. https://github.com/aspnet/AspNetCore/issues/8847
                var noContentFormatter = mvcOptions.OutputFormatters.OfType <HttpNoContentOutputFormatter>().FirstOrDefault();
                if (noContentFormatter != null)
                {
                    noContentFormatter.TreatNullValueAsNoContent = false;
                }
            }
                                             )
                             .AddJsonOptions(options =>
            {
                //Next line needs to represent custom derived types in the resulting swagger doc definitions. Because default SwaggerProvider used global JSON serialization settings
                //we should register this converter globally.
                options.SerializerSettings.ContractResolver = new PolymorphJsonContractResolver();
                //Next line allow to use polymorph types as parameters in API controller methods
                options.SerializerSettings.Converters.Add(new PolymorphJsonConverter());
                options.SerializerSettings.Converters.Add(new ModuleIdentityJsonConverter());
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                options.SerializerSettings.DateTimeZoneHandling  = DateTimeZoneHandling.Utc;
                options.SerializerSettings.NullValueHandling     = NullValueHandling.Ignore;
                options.SerializerSettings.Converters.Add(new StringEnumConverter());
                options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.None;
                options.SerializerSettings.Formatting = Formatting.None;

                options.SerializerSettings.Error += (sender, args) =>
                {
                    // Expose any JSON serialization exception as HTTP error
                    throw new JsonException(args.ErrorContext.Error.Message);
                };
                options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
                options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
            }
                                             )
                             .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            services.AddDbContext <SecurityDbContext>(options =>
            {
                options.UseSqlServer(Configuration.GetConnectionString("VirtoCommerce"));
                // Register the entity sets needed by OpenIddict.
                // Note: use the generic overload if you need
                // to replace the default OpenIddict entities.
                options.UseOpenIddict();
            });

            services.Configure <CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded    = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddAuthentication().AddCookie();
            services.AddSecurityServices(options =>
            {
                options.NonEditableUsers = new[] { "admin" };
            });

            services.AddIdentity <ApplicationUser, Role>(options => options.Stores.MaxLengthForKeys = 128)
            .AddEntityFrameworkStores <SecurityDbContext>()
            .AddDefaultTokenProviders();

            // Configure Identity to use the same JWT claims as OpenIddict instead
            // of the legacy WS-Federation claims it uses by default (ClaimTypes),
            // which saves you from doing the mapping in your authorization controller.
            services.Configure <IdentityOptions>(options =>
            {
                options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Subject;
                options.ClaimsIdentity.UserIdClaimType   = OpenIdConnectConstants.Claims.Name;
                options.ClaimsIdentity.RoleClaimType     = OpenIdConnectConstants.Claims.Role;
            });
            var azureAdSection = Configuration.GetSection("AzureAd");


            if (azureAdSection.GetChildren().Any())
            {
                var options = new AzureAdOptions();
                azureAdSection.Bind(options);

                if (options.Enabled)
                {
                    //TODO: Need to check how this influence to OpennIddict Reference tokens activated by this line below  AddValidation(options => options.UseReferenceTokens());
                    var auth = services.AddAuthentication().AddOAuthValidation();
                    auth.AddOpenIdConnect(options.AuthenticationType, options.AuthenticationCaption,
                                          openIdConnectOptions =>
                    {
                        openIdConnectOptions.ClientId             = options.ApplicationId;
                        openIdConnectOptions.Authority            = $"{options.AzureAdInstance}{options.TenantId}";
                        openIdConnectOptions.UseTokenLifetime     = true;
                        openIdConnectOptions.RequireHttpsMetadata = false;
                        openIdConnectOptions.SignInScheme         = IdentityConstants.ExternalScheme;
                    });
                }
            }
            services.Configure <Core.Security.AuthorizationOptions>(Configuration.GetSection("Authorization"));
            var authorizationOptions = Configuration.GetSection("Authorization").Get <Core.Security.AuthorizationOptions>();

            // Register the OpenIddict services.
            // Note: use the generic overload if you need
            // to replace the default OpenIddict entities.
            services.AddOpenIddict()
            .AddCore(options =>
            {
                options.UseEntityFrameworkCore()
                .UseDbContext <SecurityDbContext>();
            }).AddServer(options =>
            {
                // Register the ASP.NET Core MVC binder used by OpenIddict.
                // Note: if you don't call this method, you won't be able to
                // bind OpenIdConnectRequest or OpenIdConnectResponse parameters.
                options.UseMvc();

                // Enable the authorization, logout, token and userinfo endpoints.
                options.EnableTokenEndpoint("/connect/token")
                .EnableUserinfoEndpoint("/api/security/userinfo");

                // Note: the Mvc.Client sample only uses the code flow and the password flow, but you
                // can enable the other flows if you need to support implicit or client credentials.
                options.AllowPasswordFlow()
                .AllowRefreshTokenFlow();

                options.SetRefreshTokenLifetime(authorizationOptions.RefreshTokenLifeTime);
                options.SetAccessTokenLifetime(authorizationOptions.AccessTokenLifeTime);

                options.AcceptAnonymousClients();

                // Configure Openiddict to issues new refresh token for each token refresh request.
                options.UseRollingTokens();

                // Make the "client_id" parameter mandatory when sending a token request.
                //options.RequireClientIdentification();

                // When request caching is enabled, authorization and logout requests
                // are stored in the distributed cache by OpenIddict and the user agent
                // is redirected to the same page with a single parameter (request_id).
                // This allows flowing large OpenID Connect requests even when using
                // an external authentication provider like Google, Facebook or Twitter.
                options.EnableRequestCaching();

                options.UseReferenceTokens();
                options.DisableScopeValidation();

                // During development, you can disable the HTTPS requirement.
                if (HostingEnvironment.IsDevelopment())
                {
                    options.DisableHttpsRequirement();
                }

                // Note: to use JWT access tokens instead of the default
                // encrypted format, the following lines are required:
                //
                //options.UseJsonWebTokens();
                //TODO: Replace to X.509 certificate
                //options.AddEphemeralSigningKey();
            }).AddValidation(options => options.UseReferenceTokens());

            services.Configure <IdentityOptions>(Configuration.GetSection("IdentityOptions"));

            //always  return 401 instead of 302 for unauthorized  requests
            services.ConfigureApplicationCookie(options =>
            {
                options.Events.OnRedirectToLogin = context =>
                {
                    context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    return(Task.CompletedTask);
                };
                options.Events.OnRedirectToAccessDenied = context =>
                {
                    context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    return(Task.CompletedTask);
                };
            });

            services.AddAuthorization();
            // register the AuthorizationPolicyProvider which dynamically registers authorization policies for each permission defined in module manifest
            services.AddSingleton <IAuthorizationPolicyProvider, PermissionAuthorizationPolicyProvider>();
            //Platform authorization handler for policies based on permissions
            services.AddSingleton <IAuthorizationHandler, PermissionAuthorizationHandler>();
            // Default password validation service implementation
            services.AddScoped <IPasswordCheckService, PasswordCheckService>();

            var modulesDiscoveryPath = Path.GetFullPath("Modules");

            services.AddModules(mvcBuilder, options =>
            {
                options.DiscoveryPath = modulesDiscoveryPath;
                options.ProbingPath   = "App_Data/Modules";
            });

            services.Configure <ExternalModuleCatalogOptions>(Configuration.GetSection("ExternalModules"));
            services.AddExternalModules();

            // Add memory cache services
            services.AddMemoryCache();

            // Register the Swagger generator
            services.AddSwagger();

            //Add SignalR for push notifications
            services.AddSignalR();

            var assetsProvider = Configuration.GetSection("Assets:Provider").Value;

            if (assetsProvider.EqualsInvariant(AzureBlobProvider.ProviderName))
            {
                services.Configure <AzureBlobOptions>(Configuration.GetSection("Assets:AzureBlobStorage"));
                services.AddAzureBlobProvider();
            }
            else
            {
                services.Configure <FileSystemBlobOptions>(Configuration.GetSection("Assets:FileSystem"));
                services.AddFileSystemBlobProvider(options =>
                {
                    options.RootPath = HostingEnvironment.MapPath(options.RootPath);
                });
            }

            var hangfireOptions = new HangfireOptions();

            Configuration.GetSection("VirtoCommerce:Hangfire").Bind(hangfireOptions);
            if (hangfireOptions.JobStorageType == HangfireJobStorageType.SqlServer)
            {
                services.AddHangfire(config => config.UseSqlServerStorage(Configuration.GetConnectionString("VirtoCommerce")));
            }
            else
            {
                services.AddHangfire(config => config.UseMemoryStorage());
            }

            var mvcJsonOptions = services.BuildServiceProvider().GetService <IOptions <MvcJsonOptions> >();

            JobHelper.SetSerializerSettings(mvcJsonOptions.Value.SerializerSettings);
        }
Пример #17
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();
            // This custom provider allows able to use just [Authorize] instead of having to define [Authorize(AuthenticationSchemes = "Bearer")] above every API controller
            // without this Bearer authorization will not work
            services.AddSingleton <IAuthenticationSchemeProvider, CustomAuthenticationSchemeProvider>();

            services.AddRedis(Configuration);

            services.AddSignalR().AddPushNotifications(Configuration);

            services.AddOptions <PlatformOptions>().Bind(Configuration.GetSection("VirtoCommerce")).ValidateDataAnnotations();
            services.AddOptions <TranslationOptions>().Configure(options =>
            {
                options.PlatformTranslationFolderPath = WebHostEnvironment.MapPath(options.PlatformTranslationFolderPath);
            });
            //Get platform version from GetExecutingAssembly
            PlatformVersion.CurrentVersion = SemanticVersion.Parse(FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion);

            services.AddPlatformServices(Configuration);
            services.AddSecurityServices();
            services.AddSingleton <LicenseProvider>();

            // The following line enables Application Insights telemetry collection.
            services.AddApplicationInsightsTelemetry();
            services.AddApplicationInsightsTelemetryProcessor <IgnoreSignalRTelemetryProcessor>();

            var mvcBuilder = services.AddMvc(mvcOptions =>
            {
                //Disable 204 response for null result. https://github.com/aspnet/AspNetCore/issues/8847
                var noContentFormatter = mvcOptions.OutputFormatters.OfType <HttpNoContentOutputFormatter>().FirstOrDefault();
                if (noContentFormatter != null)
                {
                    noContentFormatter.TreatNullValueAsNoContent = false;
                }
            }
                                             )
                             .AddNewtonsoftJson(options =>
            {
                //Next line needs to represent custom derived types in the resulting swagger doc definitions. Because default SwaggerProvider used global JSON serialization settings
                //we should register this converter globally.
                options.SerializerSettings.ContractResolver = new PolymorphJsonContractResolver();
                //Next line allow to use polymorph types as parameters in API controller methods
                options.SerializerSettings.Converters.Add(new StringEnumConverter());
                options.SerializerSettings.Converters.Add(new PolymorphJsonConverter());
                options.SerializerSettings.Converters.Add(new ModuleIdentityJsonConverter());
                options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.None;
                options.SerializerSettings.ReferenceLoopHandling      = ReferenceLoopHandling.Ignore;
                options.SerializerSettings.DateTimeZoneHandling       = DateTimeZoneHandling.Utc;
                options.SerializerSettings.NullValueHandling          = NullValueHandling.Ignore;

                options.SerializerSettings.Formatting = Formatting.None;

                options.SerializerSettings.Error += (sender, args) =>
                {
                    // Expose any JSON serialization exception as HTTP error
                    throw new JsonException(args.ErrorContext.Error.Message);
                };
            }
                                                );

            services.AddSingleton(js =>
            {
                var serv = js.GetService <IOptions <MvcNewtonsoftJsonOptions> >();
                return(JsonSerializer.Create(serv.Value.SerializerSettings));
            });

            services.AddDbContext <SecurityDbContext>(options =>
            {
                options.UseSqlServer(Configuration.GetConnectionString("VirtoCommerce"));
                // Register the entity sets needed by OpenIddict.
                // Note: use the generic overload if you need
                // to replace the default OpenIddict entities.
                options.UseOpenIddict();
            });

            // Enable synchronous IO if using Kestrel:
            services.Configure <KestrelServerOptions>(options =>
            {
                options.AllowSynchronousIO = true;
            });

            // Enable synchronous IO if using IIS:
            services.Configure <IISServerOptions>(options =>
            {
                options.AllowSynchronousIO = true;
            });

            services.Configure <CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded    = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            var authBuilder = services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                              //Add the second ApiKey auth schema to handle api_key in query string
                              .AddScheme <ApiKeyAuthenticationOptions, ApiKeyAuthenticationHandler>(ApiKeyAuthenticationOptions.DefaultScheme, options => { })
                              .AddCookie();


            services.AddSecurityServices(options =>
            {
            });

            services.AddIdentity <ApplicationUser, Role>(options => options.Stores.MaxLengthForKeys = 128)
            .AddEntityFrameworkStores <SecurityDbContext>()
            .AddDefaultTokenProviders();

            // Configure Identity to use the same JWT claims as OpenIddict instead
            // of the legacy WS-Federation claims it uses by default (ClaimTypes),
            // which saves you from doing the mapping in your authorization controller.
            services.Configure <IdentityOptions>(options =>
            {
                options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Subject;
                options.ClaimsIdentity.UserIdClaimType   = OpenIdConnectConstants.Claims.Name;
                options.ClaimsIdentity.RoleClaimType     = OpenIdConnectConstants.Claims.Role;
            });

            // Support commonly used forwarded headers
            // X-Forwarded-For - Holds Client IP (optionally port number) across proxies and ends up in HttpContext.Connection.RemoteIpAddress
            // X-Forwarded-Proto - Holds original scheme (HTTP or HTTPS) even if call traversed proxies and changed and ends up in HttpContext.Request.Scheme
            services.Configure <ForwardedHeadersOptions>(options =>
            {
                options.KnownProxies.Clear();
                options.ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedProto | Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedFor;
            });

            //Create backup of token handler before default claim maps are cleared
            var defaultTokenHandler = new JwtSecurityTokenHandler();

            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
            JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();
            authBuilder.AddJwtBearer(options =>
            {
                options.Authority = Configuration["Auth:Authority"];
                options.Audience  = Configuration["Auth:Audience"];

                if (WebHostEnvironment.IsDevelopment())
                {
                    options.RequireHttpsMetadata = false;
                }

                options.IncludeErrorDetails = true;

                X509SecurityKey publicKey = null;
                if (!Configuration["Auth:PublicCertPath"].IsNullOrEmpty())
                {
                    var publicCert = new X509Certificate2(Configuration["Auth:PublicCertPath"]);
                    publicKey      = new X509SecurityKey(publicCert);
                }

                options.TokenValidationParameters = new TokenValidationParameters()
                {
                    NameClaimType            = OpenIdConnectConstants.Claims.Subject,
                    RoleClaimType            = OpenIdConnectConstants.Claims.Role,
                    ValidateIssuer           = !string.IsNullOrEmpty(options.Authority),
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey         = publicKey
                };
            });

            var azureAdSection = Configuration.GetSection("AzureAd");

            if (azureAdSection.GetChildren().Any())
            {
                var options = new AzureAdOptions();
                azureAdSection.Bind(options);

                if (options.Enabled)
                {
                    //TODO: Need to check how this influence to OpennIddict Reference tokens activated by this line below  AddValidation(options => options.UseReferenceTokens());
                    authBuilder.AddOpenIdConnect(options.AuthenticationType, options.AuthenticationCaption,
                                                 openIdConnectOptions =>
                    {
                        openIdConnectOptions.ClientId               = options.ApplicationId;
                        openIdConnectOptions.Authority              = $"{options.AzureAdInstance}{options.TenantId}";
                        openIdConnectOptions.UseTokenLifetime       = true;
                        openIdConnectOptions.RequireHttpsMetadata   = false;
                        openIdConnectOptions.SignInScheme           = IdentityConstants.ExternalScheme;
                        openIdConnectOptions.SecurityTokenValidator = defaultTokenHandler;
                    });
                }
            }

            services.AddOptions <Core.Security.AuthorizationOptions>().Bind(Configuration.GetSection("Authorization")).ValidateDataAnnotations();
            var authorizationOptions = Configuration.GetSection("Authorization").Get <Core.Security.AuthorizationOptions>();
            var platformOptions      = Configuration.GetSection("VirtoCommerce").Get <PlatformOptions>();

            // Register the OpenIddict services.
            // Note: use the generic overload if you need
            // to replace the default OpenIddict entities.
            services.AddOpenIddict()
            .AddCore(options =>
            {
                options.UseEntityFrameworkCore()
                .UseDbContext <SecurityDbContext>();
            }).AddServer(options =>
            {
                // Register the ASP.NET Core MVC binder used by OpenIddict.
                // Note: if you don't call this method, you won't be able to
                // bind OpenIdConnectRequest or OpenIdConnectResponse parameters.
                options.UseMvc();

                // Enable the authorization, logout, token and userinfo endpoints.
                options.EnableTokenEndpoint("/connect/token")
                .EnableUserinfoEndpoint("/api/security/userinfo");

                // Note: the Mvc.Client sample only uses the code flow and the password flow, but you
                // can enable the other flows if you need to support implicit or client credentials.
                options.AllowPasswordFlow()
                .AllowRefreshTokenFlow()
                .AllowClientCredentialsFlow();

                options.SetRefreshTokenLifetime(authorizationOptions?.RefreshTokenLifeTime);
                options.SetAccessTokenLifetime(authorizationOptions?.AccessTokenLifeTime);

                options.AcceptAnonymousClients();

                // Configure Openiddict to issues new refresh token for each token refresh request.
                options.UseRollingTokens();

                // Make the "client_id" parameter mandatory when sending a token request.
                //options.RequireClientIdentification();

                // When request caching is enabled, authorization and logout requests
                // are stored in the distributed cache by OpenIddict and the user agent
                // is redirected to the same page with a single parameter (request_id).
                // This allows flowing large OpenID Connect requests even when using
                // an external authentication provider like Google, Facebook or Twitter.
                options.EnableRequestCaching();

                options.DisableScopeValidation();

                // During development or when you explicitly run the platform in production mode without https, need to disable the HTTPS requirement.
                if (WebHostEnvironment.IsDevelopment() || platformOptions.AllowInsecureHttp || !Configuration.IsHttpsServerUrlSet())
                {
                    options.DisableHttpsRequirement();
                }

                // Note: to use JWT access tokens instead of the default
                // encrypted format, the following lines are required:
                options.UseJsonWebTokens();

                var bytes = File.ReadAllBytes(Configuration["Auth:PrivateKeyPath"]);
                X509Certificate2 privateKey;
                if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    // https://github.com/dotnet/corefx/blob/release/2.2/Documentation/architecture/cross-platform-cryptography.md
                    // macOS cannot load certificate private keys without a keychain object, which requires writing to disk. Keychains are created automatically for PFX loading, and are deleted when no longer in use. Since the X509KeyStorageFlags.EphemeralKeySet option means that the private key should not be written to disk, asserting that flag on macOS results in a PlatformNotSupportedException.
                    privateKey = new X509Certificate2(bytes, Configuration["Auth:PrivateKeyPassword"], X509KeyStorageFlags.MachineKeySet);
                }
                else
                {
                    privateKey = new X509Certificate2(bytes, Configuration["Auth:PrivateKeyPassword"], X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.EphemeralKeySet);
                }
                options.AddSigningCertificate(privateKey);
            });

            services.Configure <IdentityOptions>(Configuration.GetSection("IdentityOptions"));

            //always  return 401 instead of 302 for unauthorized  requests
            services.ConfigureApplicationCookie(options =>
            {
                options.Events.OnRedirectToLogin = context =>
                {
                    context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    return(Task.CompletedTask);
                };
                options.Events.OnRedirectToAccessDenied = context =>
                {
                    context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    return(Task.CompletedTask);
                };
            });

            services.AddAuthorization(options =>
            {
                //We need this policy because it is a single way to implicitly use the two schema (JwtBearer and ApiKey)  authentication for resource based authorization.
                var mutipleSchemaAuthPolicy = new AuthorizationPolicyBuilder().AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme, ApiKeyAuthenticationOptions.DefaultScheme)
                                              .RequireAuthenticatedUser()
                                              .Build();
                //The good article is described the meaning DefaultPolicy and FallbackPolicy
                //https://scottsauber.com/2020/01/20/globally-require-authenticated-users-by-default-using-fallback-policies-in-asp-net-core/
                options.DefaultPolicy = mutipleSchemaAuthPolicy;
            });
            // register the AuthorizationPolicyProvider which dynamically registers authorization policies for each permission defined in module manifest
            services.AddSingleton <IAuthorizationPolicyProvider, PermissionAuthorizationPolicyProvider>();
            //Platform authorization handler for policies based on permissions
            services.AddSingleton <IAuthorizationHandler, DefaultPermissionAuthorizationHandler>();
            // Default password validation service implementation
            services.AddScoped <IPasswordCheckService, PasswordCheckService>();

            services.AddOptions <LocalStorageModuleCatalogOptions>().Bind(Configuration.GetSection("VirtoCommerce"))
            .PostConfigure(options =>
            {
                options.DiscoveryPath = Path.GetFullPath(options.DiscoveryPath ?? "Modules");
            })
            .ValidateDataAnnotations();
            services.AddModules(mvcBuilder);

            services.AddOptions <ExternalModuleCatalogOptions>().Bind(Configuration.GetSection("ExternalModules")).ValidateDataAnnotations();
            services.AddExternalModules();

            //Assets
            var assetsProvider = Configuration.GetSection("Assets:Provider").Value;

            if (assetsProvider.EqualsInvariant(AzureBlobProvider.ProviderName))
            {
                services.AddOptions <AzureBlobOptions>().Bind(Configuration.GetSection("Assets:AzureBlobStorage")).ValidateDataAnnotations();
                services.AddAzureBlobProvider();
            }
            else
            {
                services.AddOptions <FileSystemBlobOptions>().Bind(Configuration.GetSection("Assets:FileSystem"))
                .PostConfigure(options =>
                {
                    options.RootPath = WebHostEnvironment.MapPath(options.RootPath);
                }).ValidateDataAnnotations();

                services.AddFileSystemBlobProvider();
            }

            //HangFire
            services.AddHangfire(Configuration);

            // Register the Swagger generator
            services.AddSwagger();
        }
Пример #18
0
        protected override async Task Export(Dictionary <string, string> paramDictionary)
        {
            if (string.IsNullOrWhiteSpace(paramDictionary["Project"]))
            {
                throw new CommandException("Please specify the project name using the parameter: --project=XYZ");
            }
            if (string.IsNullOrWhiteSpace(paramDictionary["ReleaseVersion"]))
            {
                throw new CommandException("Please specify the release, or range of releases using the parameter: --releaseVersion=1.0.0 for a single release, or --releaseVersion=1.0.0-1.0.3 for a range of releases");
            }
            var projectName    = paramDictionary["Project"];
            var releaseVersion = paramDictionary["ReleaseVersion"];

            Log.Debug("Finding project: {Project:l}", projectName);
            var project = await Repository.Projects.FindByName(projectName).ConfigureAwait(false);

            if (project == null)
            {
                throw new CouldNotFindException("a project named", projectName);
            }

            SemanticVersion minVersionToExport;
            SemanticVersion maxVersionToExport;

            // I don't think -> works on the command line unless it is quoted --releaseVersion="1.0.0->1.0.1"
            if (releaseVersion.IndexOf("->", StringComparison.Ordinal) > 0)
            {
                var releaseVersions = releaseVersion.Split(new[] { "->" }, StringSplitOptions.RemoveEmptyEntries);
                if (releaseVersions.Count() > 2)
                {
                    throw new CommandException("Incorrect format for exporting multiple releases, please specify the release versions as --releaseVersion=1.0.0-1.0.3");
                }
                minVersionToExport = SemanticVersion.Parse(releaseVersions[0]);
                maxVersionToExport = SemanticVersion.Parse(releaseVersions[1]);
            }
            else if (releaseVersion.IndexOf("-", StringComparison.Ordinal) > 0)
            {
                var releaseVersions = releaseVersion.Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
                if (releaseVersions.Count() > 2)
                {
                    throw new CommandException("Incorrect format for exporting multiple releases, please specify the release versions as --releaseVersion=1.0.0-1.0.3");
                }

                minVersionToExport = SemanticVersion.Parse(releaseVersions[0]);
                if (!SemanticVersion.TryParse(releaseVersions[1], out maxVersionToExport))
                {
                    minVersionToExport = SemanticVersion.Parse(releaseVersion);
                    maxVersionToExport = minVersionToExport;
                }
            }
            else
            {
                minVersionToExport = SemanticVersion.Parse(releaseVersion);
                maxVersionToExport = minVersionToExport;
            }

            Log.Debug("Finding releases for project...");
            var releasesToExport = new List <ReleaseResource>();
            var releases         = await Repository.Projects.GetReleases(project).ConfigureAwait(false);

            await releases.Paginate(Repository, page =>
            {
                foreach (var release in page.Items)
                {
                    var version = SemanticVersion.Parse(release.Version);
                    if (minVersionToExport <= version && version <= maxVersionToExport)
                    {
                        Log.Debug("Found release {Version:l}", version);
                        releasesToExport.Add(release);

                        if (minVersionToExport == maxVersionToExport)
                        {
                            break;
                        }
                    }
                }

                // Stop paging if the range is a single version, or if there is only a single release worth exporting after this page
                return((minVersionToExport != maxVersionToExport) || releasesToExport.Count != 1);
            })
            .ConfigureAwait(false);

            var metadata = new ExportMetadata
            {
                ExportedAt     = DateTime.Now,
                OctopusVersion = (await Repository.LoadRootDocument().ConfigureAwait(false)).Version,
                Type           = typeof(ReleaseExporter).GetAttributeValue((ExporterAttribute ea) => ea.Name),
                ContainerType  = typeof(ReleaseExporter).GetAttributeValue((ExporterAttribute ea) => ea.EntityType)
            };

            FileSystemExporter.Export(FilePath, metadata, releasesToExport);
        }
Пример #19
0
        /// <summary>
        /// Updates an existing Rock package to the given version and returns true if successful.
        /// </summary>
        /// <returns>true if the update was successful; false if errors were encountered</returns>
        protected bool UpdateRockPackage(string version)
        {
            IEnumerable <string> errors = Enumerable.Empty <string>();

            try
            {
                var update    = NuGetService.SourceRepository.FindPackage(_rockPackageId, (version != null) ? SemanticVersion.Parse(version) : null, false, false);
                var installed = NuGetService.GetInstalledPackage(_rockPackageId);

                if (installed == null)
                {
                    errors = NuGetService.InstallPackage(update);
                }
                else
                {
                    errors = NuGetService.UpdatePackage(update);
                }
                nbSuccess.Text  = System.Web.HttpUtility.HtmlEncode(update.ReleaseNotes).ConvertCrLfToHtmlBr();
                nbSuccess.Text += "<p><b>NOTE:</b> Any database changes will take effect at the next page load.</p>";
            }
            catch (InvalidOperationException ex)
            {
                errors = errors.Concat(new[] { string.Format("There is a problem installing v{0}: {1}", version, ex.Message) });
            }

            if (errors != null && errors.Count() > 0)
            {
                nbErrors.Visible = true;
                nbErrors.Text    = errors.Aggregate(new StringBuilder("<ul>"), (sb, s) => sb.AppendFormat("<li>{0}</li>", s)).Append("</ul>").ToString();
                return(false);
            }
            else
            {
                nbSuccess.Visible          = true;
                rptPackageVersions.Visible = false;
                return(true);
            }
        }
Пример #20
0
        public SemanticVersion GetVersion(string workingDirectory = null)
        {
            var shellResult = PlatformSupport.ExecuteShellCommand(Path.Combine(workingDirectory, _dotnetPath), "--version");

            return(SemanticVersion.Parse(shellResult.Output));
        }
Пример #21
0
 private void UpdatePackage(string id, string version)
 {
     _packages.Update(id, SemanticVersion.Parse(version));
 }
Пример #22
0
        public void RunTestDefinition(IEnumerable <BsonDocument> data, string databaseName, string collectionName, BsonDocument definition, bool async)
        {
            definition = (BsonDocument)DeepCopy(definition); // protect against side effects when the same definition is run twice (async=false/true)

            BsonValue bsonValue;

            if (definition.TryGetValue("ignore_if_server_version_greater_than", out bsonValue))
            {
                var serverVersion    = GetServerVersion();
                var maxServerVersion = SemanticVersion.Parse(bsonValue.AsString);
                if (serverVersion > maxServerVersion)
                {
                    throw new SkipTestException($"Test ignored because server version {serverVersion} is greater than max server version {maxServerVersion}.");
                }
            }
            if (definition.TryGetValue("ignore_if_server_version_less_than", out bsonValue))
            {
                var serverVersion    = GetServerVersion();
                var minServerVersion = SemanticVersion.Parse(bsonValue.AsString);
                if (serverVersion < minServerVersion)
                {
                    throw new SkipTestException($"Test ignored because server version {serverVersion} is less than min server version {minServerVersion}.");
                }
            }

            var database = __client
                           .GetDatabase(databaseName);
            var collection = database
                             .GetCollection <BsonDocument>(collectionName);

            database.DropCollection(collection.CollectionNamespace.CollectionName);
            collection.InsertMany(data);

            __capturedEvents.Clear();
            try
            {
                ExecuteOperation(database, collection, (BsonDocument)definition["operation"], async);
            }
            catch (NotImplementedException)
            {
                throw;
            }
            catch (Exception)
            {
                // catch everything...
            }

            long?operationId = null;

            foreach (BsonDocument expected in (BsonArray)definition["expectations"])
            {
                if (!__capturedEvents.Any() && !SpinWait.SpinUntil(__capturedEvents.Any, TimeSpan.FromSeconds(5)))
                {
                    Assert.True(false, "Expected an event, but no events were captured.");
                }

                if (expected.Contains("command_started_event"))
                {
                    var actual = (CommandStartedEvent)__capturedEvents.Next();
                    if (!operationId.HasValue)
                    {
                        operationId = actual.OperationId;
                    }
                    actual.OperationId.Should().Be(operationId);
                    VerifyCommandStartedEvent(actual, (BsonDocument)expected["command_started_event"], databaseName, collectionName);
                }
                else if (expected.Contains("command_succeeded_event"))
                {
                    var actual = (CommandSucceededEvent)__capturedEvents.Next();
                    actual.OperationId.Should().Be(operationId);
                    VerifyCommandSucceededEvent(actual, (BsonDocument)expected["command_succeeded_event"], databaseName, collectionName);
                }
                else if (expected.Contains("command_failed_event"))
                {
                    var actual = (CommandFailedEvent)__capturedEvents.Next();
                    actual.OperationId.Should().Be(operationId);
                    VerifyCommandFailedEvent(actual, (BsonDocument)expected["command_failed_event"], databaseName, collectionName);
                }
                else
                {
                    Assert.True(false, "Unknown event type.");
                }
            }
        }
Пример #23
0
 // Returns current version.
 private static SemanticVersion GetCurrentVersion()
 {
     return(SemanticVersion.Parse(Properties.Version.ProductVersion));
 }
Пример #24
0
        RootResource LoadRootDocumentInner()
        {
            var       watch     = Stopwatch.StartNew();
            Exception lastError = null;

            // 60 second limit using Stopwatch alone makes debugging impossible.
            var retries = 3;

            RootResource rootDocument;

            while (true)
            {
                if (retries <= 0 && TimeSpan.FromMilliseconds(watch.ElapsedMilliseconds) > TimeSpan.FromSeconds(60))
                {
                    if (lastError == null)
                    {
                        throw new Exception("Unable to connect to the Octopus Deploy server.");
                    }

                    throw new Exception("Unable to connect to the Octopus Deploy server. See the inner exception for details.", lastError);
                }

                try
                {
                    rootDocument = Client.Get <RootResource>("~/api");
                    break;
                }
                catch (WebException ex)
                {
                    Thread.Sleep(1000);
                    lastError = ex;
                }
                catch (OctopusServerException ex)
                {
                    if (ex.HttpStatusCode != 503)
                    {
                        // 503 means the service is starting, so give it some time to start
                        throw;
                    }

                    Thread.Sleep(500);
                    lastError = ex;
                }
                retries--;
            }

            if (string.IsNullOrWhiteSpace(rootDocument.ApiVersion))
            {
                throw new UnsupportedApiVersionException("This Octopus Deploy server uses an older API specification than this tool can handle. Please check for updates to the Octo tool.");
            }

            var min     = SemanticVersion.Parse(ApiConstants.SupportedApiSchemaVersionMin);
            var max     = SemanticVersion.Parse(ApiConstants.SupportedApiSchemaVersionMax);
            var current = SemanticVersion.Parse(rootDocument.ApiVersion);

            if (current < min || current > max)
            {
                throw new UnsupportedApiVersionException(string.Format("This Octopus Deploy server uses a newer API specification ({0}) than this tool can handle ({1} to {2}). Please check for updates to this tool.", rootDocument.ApiVersion, ApiConstants.SupportedApiSchemaVersionMin, ApiConstants.SupportedApiSchemaVersionMax));
            }

            return(rootDocument);
        }
Пример #25
0
        protected override async Task Execute()
        {
            if (ChannelNames.Any() && !Repository.SupportsChannels())
            {
                throw new CommandException("Your Octopus server does not support channels, which was introduced in Octopus 3.2. Please upgrade your Octopus server, or remove the --channel arguments.");
            }
            if (string.IsNullOrWhiteSpace(ProjectName))
            {
                throw new CommandException("Please specify a project name using the parameter: --project=XYZ");
            }
            if (string.IsNullOrWhiteSpace(MinVersion))
            {
                throw new CommandException("Please specify a minimum version number using the parameter: --minversion=X.Y.Z");
            }
            if (string.IsNullOrWhiteSpace(MaxVersion))
            {
                throw new CommandException("Please specify a maximum version number using the parameter: --maxversion=X.Y.Z");
            }

            var min = SemanticVersion.Parse(MinVersion);
            var max = SemanticVersion.Parse(MaxVersion);

            var project = await GetProject().ConfigureAwait(false);

            var channelsTask = GetChannelIds(project);
            var releases     = await Repository.Projects.GetReleases(project).ConfigureAwait(false);

            var channels = await channelsTask.ConfigureAwait(false);

            Log.Debug("Finding releases for project...");
            var toDelete = new List <string>();
            await releases.Paginate(Repository, page =>
            {
                foreach (var release in page.Items)
                {
                    if (channels.Any() && !channels.Contains(release.ChannelId))
                    {
                        continue;
                    }

                    var version = SemanticVersion.Parse(release.Version);
                    if (min > version || version > max)
                    {
                        continue;
                    }

                    if (WhatIf)
                    {
                        Log.Information("[Whatif] Version {Version:l} would have been deleted", version);
                    }
                    else
                    {
                        toDelete.Add(release.Link("Self"));
                        Log.Information("Deleting version {Version:l}", version);
                    }
                }

                // We need to consider all releases
                return(true);
            })
            .ConfigureAwait(false);

            // Don't do anything else for WhatIf
            if (WhatIf)
            {
                return;
            }

            foreach (var release in toDelete)
            {
                await Repository.Client.Delete(release).ConfigureAwait(false);
            }
        }
Пример #26
0
        public void CreatePackageVersioningIlAsm()
        {
            var tmpFile = Path.GetTempFileName();

            File.Delete(tmpFile);
            tmpFile += ".dll";

            File.Copy("OpenTap.dll", tmpFile, true);

            OpenTap.Package.SetAsmInfo.SetAsmInfo.SetInfo(tmpFile, new Version("1.2.3"), new Version("4.5.6"), SemanticVersion.Parse("0.1.2"), SetAsmInfo.UpdateMethod.ILDasm);

            var asm = Assembly.LoadFrom(tmpFile);

            Assert.AreEqual(1, asm.GetName().Version.Major, "Wrong major");
            Assert.AreEqual(2, asm.GetName().Version.Minor, "Wrong minor");
            Assert.AreEqual(3, asm.GetName().Version.Build, "Wrong build");

            Assert.AreEqual("4.5.6", asm.GetCustomAttribute <AssemblyFileVersionAttribute>().Version, "File version");
            Assert.AreEqual("0.1.2", asm.GetCustomAttribute <AssemblyInformationalVersionAttribute>().InformationalVersion, "Informational version");

            Assert.AreEqual("4.5.6", FileVersionInfo.GetVersionInfo(tmpFile).FileVersion, "GetVersionInfo().FileVersion");
            Assert.AreEqual("0.1.2", FileVersionInfo.GetVersionInfo(tmpFile).ProductVersion, "GetVersionInfo().ProductVersion");
            Assert.AreEqual("0.1.2", FileSystemHelper.GetAssemblyVersion(tmpFile), "FileSystemHelper.GetAssemblyVersion");
        }
Пример #27
0
 public RequireServer VersionLessThanOrEqualTo(string version)
 {
     return(VersionLessThanOrEqualTo(SemanticVersion.Parse(version)));
 }
Пример #28
0
        public void CreatePackageDepReuse()
        {
            if (Directory.Exists("Packages2"))
            {
                Directory.Delete("Packages2", true);
            }

            Directory.Move("Packages", "Packages2");
            File.Copy("Packages2/DependencyTest.dll", "DependencyTest.dll", true);

            try
            {
                Directory.CreateDirectory("Packages");

                {
                    PackageDef def = new PackageDef()
                    {
                        Name = "pkg1", Version = SemanticVersion.Parse("1.2")
                    };
                    def.AddFile("OpenTap.dll");
                    Directory.CreateDirectory("Packages/pkg1");
                    using (var f = File.OpenWrite("Packages/pkg1/package.xml")) def.SaveTo(f);
                }

                {
                    PackageDef def = new PackageDef()
                    {
                        Name = "gui", Version = SemanticVersion.Parse("1.2")
                    };
                    def.AddFile("Keysight.OpenTap.Wpf.dll");
                    Directory.CreateDirectory("Packages/gui");
                    using (var f = File.OpenWrite("Packages/gui/package.xml")) def.SaveTo(f);
                }

                {
                    PackageDef def = new PackageDef()
                    {
                        Name = "rv", Version = SemanticVersion.Parse("1.2")
                    };
                    def.AddFile("Keysight.OpenTap.Wpf.dll");
                    Directory.CreateDirectory("Packages/rv");
                    using (var f = File.OpenWrite("Packages/rv/package.xml")) def.SaveTo(f);
                }

                {
                    PackageDef def = new PackageDef();
                    def.Name     = "test";
                    def.InfoLink = "a";
                    def.Date     = DateTime.Today;

                    def.Dependencies.Add(new PackageDependency("rv", VersionSpecifier.Parse("1.2")));

                    def.AddFile("DependencyTest.dll");
                    def.Files[0].DependentAssemblies.AddRange(PluginManager.GetSearcher().Assemblies.First(f => f.Name == "DependencyTest").References);

                    var searcher = new PluginSearcher();
                    searcher.Search(Directory.GetCurrentDirectory());
                    List <AssemblyData> assemblies = searcher.Assemblies.ToList();
                    def.findDependencies(new List <string>(), assemblies);

                    //Assert.AreEqual(3, def.Dependencies.Count);
                    Assert.IsTrue(def.Dependencies.Any(d => d.Name == "rv"));
                    Assert.IsTrue(def.Dependencies.Any(d => d.Name == "pkg1"));
                }

                {
                    PackageDef def = new PackageDef();
                    def.Name     = "test";
                    def.InfoLink = "a";
                    def.Date     = DateTime.Today;

                    def.Dependencies.Add(new PackageDependency("gui", VersionSpecifier.Parse("1.2")));

                    def.AddFile("DependencyTest.dll");
                    def.Files[0].DependentAssemblies.AddRange(PluginManager.GetSearcher().Assemblies.First(f => f.Name == "DependencyTest").References);

                    var searcher = new PluginSearcher();
                    searcher.Search(Directory.GetCurrentDirectory());
                    List <AssemblyData> assemblies = searcher.Assemblies.ToList();
                    def.findDependencies(new List <string>(), assemblies);

                    //Assert.AreEqual(2, def.Dependencies.Count);
                    Assert.IsTrue(def.Dependencies.Any(d => d.Name == "gui"));
                    Assert.IsTrue(def.Dependencies.Any(d => d.Name == "pkg1"));
                }
            }
            finally
            {
                if (Directory.Exists("Packages"))
                {
                    Directory.Delete("Packages", true);
                }
                Directory.Move("Packages2", "Packages");
            }
        }
 public void VersionSorting()
 {
     SemanticVersion.Parse("1.0.0", null).ShouldBeGreaterThan(SemanticVersion.Parse("1.0.0-beta", null));
     SemanticVersion.Parse("1.0.0-beta.2", null).ShouldBeGreaterThan(SemanticVersion.Parse("1.0.0-beta.1", null));
     SemanticVersion.Parse("1.0.0-beta.1", null).ShouldBeLessThan(SemanticVersion.Parse("1.0.0-beta.2", null));
 }
Пример #30
0
        public async Task TestGetSnapsReleasesAsync()
        {
            var snapAppsReleases = new SnapAppsReleases();
            var genesisSnapApp   = _baseFixturePackaging.BuildSnapApp();
            var update1SnapApp   = _baseFixturePackaging.Bump(genesisSnapApp);
            var update2SnapApp   = _baseFixturePackaging.Bump(update1SnapApp);

            using var rootDirectory = new DisposableDirectory(_baseFixturePackaging.WorkingDirectory, _snapFilesystem);
            using var nugetPackageSourcesDirectory = _snapFilesystem.WithDisposableTempDirectory(_baseFixturePackaging.WorkingDirectory);
            using var genesisReleaseBuilder        =
                      _baseFixturePackaging.WithSnapReleaseBuilder(rootDirectory, snapAppsReleases, genesisSnapApp, _releaseBuilderContext);
            using var update1ReleaseBuilder =
                      _baseFixturePackaging.WithSnapReleaseBuilder(rootDirectory, snapAppsReleases, update1SnapApp, _releaseBuilderContext);
            using var update2ReleaseBuilder =
                      _baseFixturePackaging.WithSnapReleaseBuilder(rootDirectory, snapAppsReleases, update2SnapApp, _releaseBuilderContext);
            var nugetPackageSources = genesisSnapApp.BuildNugetSources(nugetPackageSourcesDirectory.WorkingDirectory);

            genesisReleaseBuilder
            .AddNuspecItem(_baseFixturePackaging.BuildSnapExecutable(genesisSnapApp))
            .AddSnapDll();

            update1ReleaseBuilder
            .AddNuspecItem(_baseFixturePackaging.BuildSnapExecutable(update1SnapApp))
            .AddSnapDll();

            update2ReleaseBuilder
            .AddNuspecItem(_baseFixturePackaging.BuildSnapExecutable(update2SnapApp))
            .AddSnapDll();

            using (await _baseFixturePackaging.BuildPackageAsync(genesisReleaseBuilder))
                using (await _baseFixturePackaging.BuildPackageAsync(update1ReleaseBuilder))
                {
                    using var update2PackageContext = await _baseFixturePackaging.BuildPackageAsync(update2ReleaseBuilder);

                    using var releasesNupkgMemoryStream = _snapPack.BuildReleasesPackage(genesisSnapApp, snapAppsReleases);
                    var expectedVersion = SemanticVersion.Parse("1.0.0");

                    var expectedPackageIdentity = new PackageIdentity(
                        update2PackageContext.FullPackageSnapRelease.BuildNugetReleasesUpstreamId(),
                        expectedVersion.ToNuGetVersion());

                    using (var releasesPackageArchiveReader = new PackageArchiveReader(releasesNupkgMemoryStream, true))
                    {
                        Assert.Equal(expectedPackageIdentity, releasesPackageArchiveReader.GetIdentity());
                    }

                    releasesNupkgMemoryStream.Seek(0, SeekOrigin.Begin);

                    _baseFixtureNuget.SetupReleases(_nugetServiceMock, releasesNupkgMemoryStream, nugetPackageSources, genesisSnapApp);

                    var(snapAppsReleasesAfter, packageSourceAfter, releasesMemoryStream) = await _snapPackageManager.GetSnapsReleasesAsync(genesisSnapApp);

                    using (releasesMemoryStream)
                    {
                        Assert.NotNull(releasesMemoryStream);
                        Assert.Equal(0, releasesMemoryStream.Position);
                        Assert.True(releasesMemoryStream.Length > 0);

                        Assert.NotNull(snapAppsReleasesAfter);
                        Assert.NotNull(packageSourceAfter);
                        Assert.Equal(expectedVersion, snapAppsReleases.Version);
                        Assert.Equal(expectedVersion, snapAppsReleasesAfter.Version);

                        var snapAppReleases = snapAppsReleasesAfter.GetReleases(genesisSnapApp);
                        Assert.Equal(3, snapAppReleases.Count());
                    }
                }
        }