public DisplayPackageViewModel(Package package, User currentUser, string pushedBy)
            : base(package, currentUser)
        {
            Copyright = package.Copyright;

            DownloadCount = package.DownloadCount;
            LastEdited    = package.LastEdited;

            TotalDaysSinceCreated = 0;
            DownloadsPerDay       = 0;

            PushedBy = pushedBy;

            InitializeRepositoryMetadata(package.RepositoryUrl, package.RepositoryType);

            if (PackageHelper.TryPrepareUrlForRendering(package.ProjectUrl, out string projectUrl))
            {
                ProjectUrl = projectUrl;
            }

            EmbeddedLicenseType = package.EmbeddedLicenseType;
            LicenseExpression   = package.LicenseExpression;

            if (PackageHelper.TryPrepareUrlForRendering(package.LicenseUrl, out string licenseUrl))
            {
                LicenseUrl = licenseUrl;

                var licenseNames = package.LicenseNames;
                if (!string.IsNullOrEmpty(licenseNames))
                {
                    LicenseNames = licenseNames.Split(',').Select(l => l.Trim());
                }
            }
        }
        private DisplayLicenseViewModel SetupInternal(
            DisplayLicenseViewModel viewModel,
            Package package,
            IReadOnlyCollection <CompositeLicenseExpressionSegment> licenseExpressionSegments,
            string licenseFileContents,
            User currentUser)
        {
            viewModel.EmbeddedLicenseType = package.EmbeddedLicenseType;
            viewModel.LicenseExpression   = package.LicenseExpression;
            if (PackageHelper.TryPrepareUrlForRendering(package.LicenseUrl, out string licenseUrl))
            {
                viewModel.LicenseUrl = licenseUrl;

                var licenseNames = package.LicenseNames;
                if (!string.IsNullOrEmpty(licenseNames))
                {
                    viewModel.LicenseNames = licenseNames.Split(',').Select(l => l.Trim()).ToList();
                }
            }
            viewModel.LicenseExpressionSegments = licenseExpressionSegments;
            viewModel.LicenseFileContents       = licenseFileContents;

            if (_featureFlagService.IsLicenseMdRenderingEnabled(currentUser) &&
                package.EmbeddedLicenseType == EmbeddedLicenseFileType.Markdown &&
                licenseFileContents != null)
            {
                viewModel.LicenseFileContentsHtml = _markdownService.GetHtmlFromMarkdown(licenseFileContents)?.Content;
            }

            return(viewModel);
        }
Example #3
0
        private DisplayPackageViewModel SetupCommon(
            DisplayPackageViewModel viewModel,
            Package package,
            string pushedBy,
            IReadOnlyDictionary <int, PackageDeprecation> packageKeyToDeprecation)
        {
            viewModel.NuGetVersion = NuGetVersion.Parse(NuGetVersionFormatter.ToFullString(package.Version));
            viewModel.Copyright    = package.Copyright;

            viewModel.DownloadCount = package.DownloadCount;
            viewModel.LastEdited    = package.LastEdited;

            viewModel.TotalDaysSinceCreated = 0;
            viewModel.DownloadsPerDay       = 0;

            viewModel.PushedBy = pushedBy;

            viewModel.InitializeRepositoryMetadata(package.RepositoryUrl, package.RepositoryType);

            if (PackageHelper.TryPrepareUrlForRendering(package.ProjectUrl, out string projectUrl))
            {
                viewModel.ProjectUrl = projectUrl;
            }

            viewModel.EmbeddedLicenseType = package.EmbeddedLicenseType;
            viewModel.LicenseExpression   = package.LicenseExpression;

            if (PackageHelper.TryPrepareUrlForRendering(package.LicenseUrl, out string licenseUrl))
            {
                viewModel.LicenseUrl = licenseUrl;

                var licenseNames = package.LicenseNames;
                if (!string.IsNullOrEmpty(licenseNames))
                {
                    viewModel.LicenseNames = licenseNames.Split(',').Select(l => l.Trim()).ToList();
                }
            }

            if (packageKeyToDeprecation != null && packageKeyToDeprecation.TryGetValue(package.Key, out var deprecation))
            {
                viewModel.DeprecationStatus = deprecation.Status;
            }
            else
            {
                viewModel.DeprecationStatus = PackageDeprecationStatus.NotDeprecated;
            }

            return(viewModel);
        }
        public DisplayLicenseViewModel(Package package, IReadOnlyCollection <CompositeLicenseExpressionSegment> licenseExpressionSegments, string licenseFileContents)
            : base(package)
        {
            EmbeddedLicenseType = package.EmbeddedLicenseType;
            LicenseExpression   = package.LicenseExpression;
            if (PackageHelper.TryPrepareUrlForRendering(package.LicenseUrl, out string licenseUrl))
            {
                LicenseUrl = licenseUrl;

                var licenseNames = package.LicenseNames;
                if (!string.IsNullOrEmpty(licenseNames))
                {
                    LicenseNames = licenseNames.Split(',').Select(l => l.Trim());
                }
            }
            LicenseExpressionSegments = licenseExpressionSegments;
            LicenseFileContents       = licenseFileContents;
        }
Example #5
0
        private DisplayLicenseViewModel SetupInternal(
            DisplayLicenseViewModel viewModel,
            Package package,
            IReadOnlyCollection <CompositeLicenseExpressionSegment> licenseExpressionSegments,
            string licenseFileContents)
        {
            viewModel.EmbeddedLicenseType = package.EmbeddedLicenseType;
            viewModel.LicenseExpression   = package.LicenseExpression;
            if (PackageHelper.TryPrepareUrlForRendering(package.LicenseUrl, out string licenseUrl))
            {
                viewModel.LicenseUrl = licenseUrl;

                var licenseNames = package.LicenseNames;
                if (!string.IsNullOrEmpty(licenseNames))
                {
                    viewModel.LicenseNames = licenseNames.Split(',').Select(l => l.Trim()).ToList();
                }
            }
            viewModel.LicenseExpressionSegments = licenseExpressionSegments;
            viewModel.LicenseFileContents       = licenseFileContents;

            return(viewModel);
        }
Example #6
0
        /// <summary>
        /// Get converted HTML for readme.md string content.
        /// </summary>
        /// <param name="readMeMd">ReadMe.md content.</param>
        /// <returns>HTML content.</returns>
        internal static string GetReadMeHtml(string readMeMd)
        {
            // HTML encode markdown, except for block quotes, to block inline html.
            var encodedMarkdown = EncodedBlockQuotePattern.Replace(HttpUtility.HtmlEncode(readMeMd), "> ");

            var settings = CommonMarkSettings.Default.Clone();

            settings.RenderSoftLineBreaksAsLineBreaks = true;

            // Parse executes CommonMarkConverter's ProcessStage1 and ProcessStage2.
            var document = CommonMarkConverter.Parse(encodedMarkdown, settings);

            foreach (var node in document.AsEnumerable())
            {
                if (node.IsOpening)
                {
                    var block = node.Block;
                    if (block != null)
                    {
                        switch (block.Tag)
                        {
                        // Demote heading tags so they don't overpower expander headings.
                        case BlockTag.AtxHeading:
                        case BlockTag.SetextHeading:
                            var level = (byte)Math.Min(block.Heading.Level + 1, 6);
                            block.Heading = new HeadingData(level);
                            break;

                        // Decode preformatted blocks to prevent double encoding.
                        // Skip BlockTag.BlockQuote, which are partially decoded upfront.
                        case BlockTag.FencedCode:
                        case BlockTag.IndentedCode:
                            if (block.StringContent != null)
                            {
                                var content          = block.StringContent.TakeFromStart(block.StringContent.Length);
                                var unencodedContent = HttpUtility.HtmlDecode(content);
                                block.StringContent.Replace(unencodedContent, 0, unencodedContent.Length);
                            }
                            break;
                        }
                    }

                    var inline = node.Inline;
                    if (inline != null && inline.Tag == InlineTag.Link)
                    {
                        // Allow only http or https links in markdown. Transform link to https for known domains.
                        if (!PackageHelper.TryPrepareUrlForRendering(inline.TargetUrl, out string readyUriString))
                        {
                            inline.TargetUrl = string.Empty;
                        }
                        else
                        {
                            inline.TargetUrl = readyUriString;
                        }
                    }
                }
            }

            // CommonMark.Net does not support link attributes, so manually inject nofollow.
            using (var htmlWriter = new StringWriter())
            {
                CommonMarkConverter.ProcessStage3(document, htmlWriter, settings);

                return(CommonMarkLinkPattern.Replace(htmlWriter.ToString(), "$0" + " rel=\"nofollow\"").Trim());
            }
        }
Example #7
0
        public RenderedMarkdownResult GetHtmlFromMarkdown(string markdownString, int incrementHeadersBy)
        {
            var output = new RenderedMarkdownResult()
            {
                ImagesRewritten = false,
                Content         = ""
            };

            var readmeWithoutBom = markdownString.StartsWith("\ufeff") ? markdownString.Replace("\ufeff", "") : markdownString;

            // HTML encode markdown, except for block quotes, to block inline html.
            var encodedMarkdown = EncodedBlockQuotePattern.Replace(HttpUtility.HtmlEncode(readmeWithoutBom), "> ");

            var settings = CommonMarkSettings.Default.Clone();

            settings.RenderSoftLineBreaksAsLineBreaks = true;

            // Parse executes CommonMarkConverter's ProcessStage1 and ProcessStage2.
            var document = CommonMarkConverter.Parse(encodedMarkdown, settings);

            foreach (var node in document.AsEnumerable())
            {
                if (node.IsOpening)
                {
                    var block = node.Block;
                    if (block != null)
                    {
                        switch (block.Tag)
                        {
                        // Demote heading tags so they don't overpower expander headings.
                        case BlockTag.AtxHeading:
                        case BlockTag.SetextHeading:
                            var level = (byte)Math.Min(block.Heading.Level + incrementHeadersBy, 6);
                            block.Heading = new HeadingData(level);
                            break;

                        // Decode preformatted blocks to prevent double encoding.
                        // Skip BlockTag.BlockQuote, which are partially decoded upfront.
                        case BlockTag.FencedCode:
                        case BlockTag.IndentedCode:
                            if (block.StringContent != null)
                            {
                                var content          = block.StringContent.TakeFromStart(block.StringContent.Length);
                                var unencodedContent = HttpUtility.HtmlDecode(content);
                                block.StringContent.Replace(unencodedContent, 0, unencodedContent.Length);
                            }
                            break;
                        }
                    }

                    var inline = node.Inline;
                    if (inline != null)
                    {
                        if (inline.Tag == InlineTag.Link)
                        {
                            // Allow only http or https links in markdown. Transform link to https for known domains.
                            if (!PackageHelper.TryPrepareUrlForRendering(inline.TargetUrl, out string readyUriString))
                            {
                                inline.TargetUrl = string.Empty;
                            }
                            else
                            {
                                inline.TargetUrl = readyUriString;
                            }
                        }

                        else if (inline.Tag == InlineTag.Image)
                        {
                            if (!PackageHelper.TryPrepareUrlForRendering(inline.TargetUrl, out string readyUriString, rewriteAllHttp: true))
                            {
                                inline.TargetUrl = string.Empty;
                            }
                            else
                            {
                                output.ImagesRewritten = output.ImagesRewritten || (inline.TargetUrl != readyUriString);
                                inline.TargetUrl       = readyUriString;
                            }
                        }
                    }
                }
            }
        private DisplayPackageViewModel SetupCommon(
            DisplayPackageViewModel viewModel,
            Package package,
            string pushedBy,
            IReadOnlyDictionary <int, PackageDeprecation> packageKeyToDeprecation,
            IReadOnlyDictionary <int, IReadOnlyList <PackageVulnerability> > packageKeyToVulnerabilities)
        {
            viewModel.NuGetVersion = NuGetVersion.Parse(NuGetVersionFormatter.ToFullString(package.Version));
            viewModel.Copyright    = package.Copyright;

            viewModel.DownloadCount = package.DownloadCount;
            viewModel.LastEdited    = package.LastEdited;

            viewModel.TotalDaysSinceCreated = 0;
            viewModel.DownloadsPerDay       = 0;

            viewModel.PushedBy = pushedBy;

            viewModel.InitializeRepositoryMetadata(package.RepositoryUrl, package.RepositoryType);

            if (PackageHelper.TryPrepareUrlForRendering(package.ProjectUrl, out string projectUrl))
            {
                viewModel.ProjectUrl = projectUrl;
            }

            var fugetUrl = $"https://www.fuget.org/packages/{package.Id}/{package.NormalizedVersion}";

            if (PackageHelper.TryPrepareUrlForRendering(fugetUrl, out string fugetReadyUrl))
            {
                viewModel.FuGetUrl = fugetReadyUrl;
            }

            viewModel.EmbeddedLicenseType = package.EmbeddedLicenseType;
            viewModel.LicenseExpression   = package.LicenseExpression;

            if (PackageHelper.TryPrepareUrlForRendering(package.LicenseUrl, out string licenseUrl))
            {
                viewModel.LicenseUrl = licenseUrl;

                var licenseNames = package.LicenseNames;
                if (!string.IsNullOrEmpty(licenseNames))
                {
                    viewModel.LicenseNames = licenseNames.Split(',').Select(l => l.Trim()).ToList();
                }
            }

            PackageDeprecation deprecation = null;

            if (packageKeyToDeprecation != null && packageKeyToDeprecation.TryGetValue(package.Key, out deprecation))
            {
                viewModel.DeprecationStatus = deprecation.Status;
            }
            else
            {
                viewModel.DeprecationStatus = PackageDeprecationStatus.NotDeprecated;
            }

            PackageVulnerabilitySeverity?maxVulnerabilitySeverity = null;

            if (packageKeyToVulnerabilities != null &&
                packageKeyToVulnerabilities.TryGetValue(package.Key, out var vulnerabilities) &&
                vulnerabilities != null && vulnerabilities.Any())
            {
                viewModel.Vulnerabilities          = vulnerabilities;
                maxVulnerabilitySeverity           = viewModel.Vulnerabilities.Max(v => v.Severity); // cache for messaging
                viewModel.MaxVulnerabilitySeverity = maxVulnerabilitySeverity.Value;
            }
            else
            {
                viewModel.Vulnerabilities          = null;
                viewModel.MaxVulnerabilitySeverity = default;
            }

            viewModel.PackageWarningIconTitle =
                GetWarningIconTitle(viewModel.Version, deprecation, maxVulnerabilitySeverity);

            return(viewModel);
        }