public ListPackageVersionViewModel(DisplayPackageViewModel package, DisplayPackageViewModel currentPackageVersion, bool moderationRole, Markdown markdownGenerator, bool displayVersion) { Package = package; CurrentPackageVersion = currentPackageVersion; ModerationRole = moderationRole; MarkdownGenerator = markdownGenerator; DisplayVersion = displayVersion; }
public virtual ActionResult DisplayPackage(string id, string version) { var package = _packageSvc.FindPackageByIdAndVersion(id, version); if (package == null) { return(PackageNotFound(id, version)); } var model = new DisplayPackageViewModel(package); return(View(model)); }
public DisplayPackageViewModel Setup( DisplayPackageViewModel viewModel, Package package, IReadOnlyCollection <Package> allVersions, User currentUser, IReadOnlyDictionary <int, PackageDeprecation> packageKeyToDeprecation, RenderedReadMeResult readmeResult) { _listPackageItemViewModelFactory.Setup(viewModel, package, currentUser); SetupCommon(viewModel, package, pushedBy: null, packageKeyToDeprecation: packageKeyToDeprecation); return(SetupInternal(viewModel, package, allVersions, currentUser, packageKeyToDeprecation, readmeResult)); }
/// <summary> /// Get the converted HTML from the stored ReadMe markdown. /// </summary> /// <param name="package">Package entity associated with the ReadMe.</param> /// <param name="model">Display package view model to populate.</param> /// <param name="isPending">Whether to retrieve the pending ReadMe.</param> /// <returns>Pending or active ReadMe converted to HTML.</returns> public async Task GetReadMeHtmlAsync(Package package, DisplayPackageViewModel model, bool isPending = false) { var readMeMd = await GetReadMeMdAsync(package, isPending); if (!string.IsNullOrWhiteSpace(readMeMd)) { var readMeMdClamped = string.Join(Environment.NewLine, readMeMd.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Take(ReadMeClampedLineCount)); model.ReadMeHtml = GetReadMeHtml(readMeMd).Trim(); model.ReadMeHtmlClamped = GetReadMeHtml(readMeMdClamped).Trim(); } }
public virtual ActionResult DisplayPackage(string id, string version) { var package = _packageService.FindPackageByIdAndVersion(id, version); if (package == null) { return(HttpNotFound()); } var model = new DisplayPackageViewModel(package); ViewBag.FacebookAppID = _config.FacebookAppId; return(View(model)); }
public virtual ActionResult DisplayPackage(string id, string version) { var package = packageSvc.FindPackageByIdAndVersion(id, version); if (package == null) { return(PackageNotFound(id, version)); } var scanResults = packageSvc.GetPackageScanResults(id, package.Version); var model = new DisplayPackageViewModel(package, scanResults); return(View("~/Views/Packages/DisplayPackage.cshtml", model)); }
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 DisplayPackageViewModel Create( Package package, User currentUser, PackageDeprecation deprecation, string readmeHtml) { var viewModel = new DisplayPackageViewModel(); return(Setup( viewModel, package, currentUser, deprecation, readmeHtml)); }
public DisplayPackageViewModel Create( Package package, User currentUser, PackageDeprecation deprecation, RenderedReadMeResult readmeResult) { var viewModel = new DisplayPackageViewModel(); return(Setup( viewModel, package, currentUser, deprecation, readmeResult)); }
public DisplayPackageViewModel Setup( DisplayPackageViewModel viewModel, Package package, IReadOnlyCollection <Package> allVersions, User currentUser, IReadOnlyDictionary <int, PackageDeprecation> packageKeyToDeprecation, IReadOnlyDictionary <int, IReadOnlyList <PackageVulnerability> > packageKeyToVulnerabilities, IReadOnlyList <PackageRename> packageRenames, RenderedMarkdownResult readmeResult) { _listPackageItemViewModelFactory.Setup(viewModel, package, currentUser); SetupCommon(viewModel, package, pushedBy: null, packageKeyToDeprecation: packageKeyToDeprecation, packageKeyToVulnerabilities: packageKeyToVulnerabilities); return(SetupInternal(viewModel, package, allVersions, currentUser, packageKeyToDeprecation, packageKeyToVulnerabilities, packageRenames, readmeResult)); }
private ActionResult GetPackageOwnerActionFormResult(string id, string version) { var package = _packageService.FindPackageByIdAndVersion(id, version); if (package == null) { return(HttpNotFound()); } if (!package.IsOwner(HttpContext.User)) { return(new HttpStatusCodeResult(401, "Unauthorized")); } var model = new DisplayPackageViewModel(package); return(View(model)); }
public DisplayPackageViewModel Create( Package package, IReadOnlyCollection <Package> allVersions, User currentUser, IReadOnlyDictionary <int, PackageDeprecation> packageKeyToDeprecation, RenderedReadMeResult readmeResult) { var viewModel = new DisplayPackageViewModel(); return(Setup( viewModel, package, allVersions, currentUser, packageKeyToDeprecation, readmeResult)); }
private ActionResult GetPackageOwnerActionFormResult(string id, string version) { var package = packageSvc.FindPackageByIdAndVersion(id, version); if (package == null) { return(PackageNotFound(id, version)); } if (!UserHasPackageChangePermissions(HttpContext.User, package)) { return(new HttpStatusCodeResult(401, "Unauthorized")); } var model = new DisplayPackageViewModel(package, null); return(View(model)); }
public virtual ActionResult DisplayPackage(string id, string version) { var package = packageSvc.FindPackageByIdAndVersion(id, version); if (package == null) { return(PackageNotFound(id, version)); } var scanResults = packageSvc.GetPackageScanResults(id, package.Version); package.Files = packageSvc.GetPackageFiles(package).ToList(); package.Description = FindAndCorrectInvalidMarkdownHeaders(package.Description); package.ReleaseNotes = FindAndCorrectInvalidMarkdownHeaders(package.ReleaseNotes); var model = new DisplayPackageViewModel(package, scanResults); return(View("~/Views/Packages/DisplayPackage.cshtml", model)); }
public DisplayPackageViewModel Create( Package package, IReadOnlyCollection <Package> allVersions, User currentUser, IReadOnlyDictionary <int, PackageDeprecation> packageKeyToDeprecation, IReadOnlyDictionary <int, IReadOnlyList <PackageVulnerability> > packageKeyToVulnerabilities, IReadOnlyList <PackageRename> packageRenames, RenderedMarkdownResult readmeResult) { var viewModel = new DisplayPackageViewModel(); return(Setup( viewModel, package, allVersions, currentUser, packageKeyToDeprecation, packageKeyToVulnerabilities, packageRenames, readmeResult)); }
public static string GetCakeInstallPackageCommand(this DisplayPackageViewModel model) { var scheme = model.IsDotnetToolPackageType ? "dotnet" : "nuget"; var reference = $"{scheme}:?package={model.Id}&version={model.Version}"; if (model.Prerelease) { reference += "&prerelease"; } if (model.IsDotnetToolPackageType) { return($"#tool {reference}"); } if (IsCakeAddin(model)) { return($"#addin {reference}"); } if (IsCakeModule(model)) { return($"#module {reference}"); } if (IsCakeRecipe(model)) { return($"#load {reference}"); } return(string.Join(Environment.NewLine, $"// Install {model.Id} as a Cake Addin", $"#addin {reference}", "", $"// Install {model.Id} as a Cake Tool", $"#tool {reference}" )); }
public virtual ActionResult DisplayPackage(string id, string version) { string normalized = SemanticVersionExtensions.Normalize(version); if (!String.Equals(version, normalized)) { // Permanent redirect to the normalized one (to avoid multiple URLs for the same content) return(RedirectToActionPermanent("DisplayPackage", new { id = id, version = normalized })); } var package = _packageService.FindPackageByIdAndVersion(id, version); if (package == null) { return(HttpNotFound()); } var model = new DisplayPackageViewModel(package); if (package.IsOwner(User)) { // Tell logged-in package owners not to cache the package page, so they won't be confused about the state of pending edits. Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetNoStore(); Response.Cache.SetMaxAge(TimeSpan.Zero); Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); var pendingMetadata = _editPackageService.GetPendingMetadata(package); if (pendingMetadata != null) { model.SetPendingMetadata(pendingMetadata); } } ViewBag.FacebookAppID = _config.FacebookAppId; return(View(model)); }
public virtual ActionResult DisplayPackage(string id, string version) { var package = _packageService.FindPackageByIdAndVersion(id, version); if (package == null) { return HttpNotFound(); } var model = new DisplayPackageViewModel(package); if (package.IsOwner(HttpContext.User)) { // Tell logged-in package owners not to cache the package page, so they won't be confused about the state of pending edits. Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetNoStore(); Response.Cache.SetMaxAge(TimeSpan.Zero); Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); var pendingMetadata = _editPackageService.GetPendingMetadata(package); if (pendingMetadata != null) { model.SetPendingMetadata(pendingMetadata); } } ViewBag.FacebookAppID = _config.FacebookAppId; return View(model); }
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); }
public virtual ActionResult DisplayPackage(string id, string version, FormCollection form) { if (!ModelState.IsValid) return DisplayPackage(id, version); var package = packageSvc.FindPackageByIdAndVersion(id, version); if (package == null) return PackageNotFound(id, version); var model = new DisplayPackageViewModel(package); if (!ModelState.IsValid) return View("~/Views/Packages/DisplayPackage.cshtml", model); var status = PackageStatusType.Unknown; try { status = (PackageStatusType)Enum.Parse(typeof(PackageStatusType), form["Status"]); } catch (Exception ex) { // Log but swallow the exception ErrorSignal.FromCurrentContext().Raise(ex); } //reviewers cannot change the current status if (User.IsReviewer()) status = package.Status; if (package.Status != PackageStatusType.Unknown && status == PackageStatusType.Unknown) { ModelState.AddModelError(String.Empty, "A package cannot be moved into unknown status."); return View("~/Views/Packages/DisplayPackage.cshtml", model); } if (package.Status == PackageStatusType.Unknown && status == PackageStatusType.Submitted) { ModelState.AddModelError(String.Empty, "A package cannot be moved from unknown to submitted status."); return View("~/Views/Packages/DisplayPackage.cshtml", model); } if (User.IsReviewer() && status != PackageStatusType.Submitted) { ModelState.AddModelError(String.Empty, "A reviewer can only comment/submit in submitted status."); return View("~/Views/Packages/DisplayPackage.cshtml", model); } var comments = form["ReviewComments"]; bool sendEmail = form["SendEmail"] != null; bool trustedPackage = form["IsTrusted"] == "true,false"; var moderator = userSvc.FindByUsername(HttpContext.User.Identity.Name); packageSvc.ChangePackageStatus(package, status, comments, moderator, sendEmail); packageSvc.ChangeTrustedStatus(package, trustedPackage, moderator); //grab updated package package = packageSvc.FindPackageByIdAndVersion(id, version); model = new DisplayPackageViewModel(package); TempData["Message"] = "Changes to package status have been saved."; return View("~/Views/Packages/DisplayPackage.cshtml", model); }
private ActionResult GetPackageOwnerActionFormResult(string id, string version) { var package = packageSvc.FindPackageByIdAndVersion(id, version); if (package == null) return PackageNotFound(id, version); if (!UserHasPackageChangePermissions(HttpContext.User, package)) return new HttpStatusCodeResult(401, "Unauthorized"); var model = new DisplayPackageViewModel(package); return View(model); }
public virtual ActionResult DisplayPackage(string id, string version, FormCollection form) { if (!ModelState.IsValid) { return DisplayPackage(id, version); } var package = packageSvc.FindPackageByIdAndVersion(id, version); if (package == null) { return PackageNotFound(id, version); } var model = new DisplayPackageViewModel(package); if (!ModelState.IsValid) { return View(model); } var status = PackageStatusType.Unknown; try { status = (PackageStatusType) Enum.Parse(typeof (PackageStatusType), form["Status"]); } catch (Exception ex) { // Log but swallow the exception Elmah.ErrorSignal.FromCurrentContext().Raise(ex); } if (package.Status != PackageStatusType.Unknown && status == PackageStatusType.Unknown) { ModelState.AddModelError(String.Empty, "A package cannot be moved into unknown status."); return View(model); } if (package.Status == PackageStatusType.Unknown && status == PackageStatusType.Submitted) { ModelState.AddModelError(String.Empty, "A package cannot be moved from unknown to submitted status."); return View(model); } var comments = form["ReviewComments"]; bool sendEmail = form["SendEmail"] != null; packageSvc.ChangePackageStatus(package, status, comments, userSvc.FindByUsername(HttpContext.User.Identity.Name), sendEmail); //grab updated package package = packageSvc.FindPackageByIdAndVersion(id, version); model = new DisplayPackageViewModel(package); TempData["Message"] = "Changes to package status have been saved."; return View(model); }
public virtual ActionResult DisplayPackage(string id, string version, FormCollection form) { if (!ModelState.IsValid) return DisplayPackage(id, version); var currentUser = userSvc.FindByUsername(GetIdentity().Name); var package = packageSvc.FindPackageByIdAndVersion(id, version, allowPrerelease: true, useCache: false); if (package == null) return PackageNotFound(id, version); var model = new DisplayPackageViewModel(package); var packageRegistration = package.PackageRegistration; var isMaintainer = packageRegistration.Owners.AnySafe(x => x.Key == currentUser.Key); var isModerationRole = User.IsInAnyModerationRole() && !isMaintainer; var isModerator = User.IsModerator() && !isMaintainer; if (packageRegistration != null && !isMaintainer && !isModerationRole) { ModelState.AddModelError(String.Empty, String.Format(CultureInfo.CurrentCulture, Strings.ApiKeyNotAuthorized, "maintain")); return View("~/Views/Packages/DisplayPackage.cshtml", model); } if (!ModelState.IsValid) return View("~/Views/Packages/DisplayPackage.cshtml", model); var status = PackageStatusType.Unknown; if (isMaintainer) { status = package.Status; } else { try { status = (PackageStatusType)Enum.Parse(typeof(PackageStatusType), form["Status"]); } catch (Exception ex) { // Log but swallow the exception ErrorSignal.FromCurrentContext().Raise(ex); } } // maintainers and reviewers cannot change the current status if (User.IsReviewer() || isMaintainer) status = package.Status; if (package.Status != PackageStatusType.Unknown && status == PackageStatusType.Unknown) { ModelState.AddModelError(String.Empty, "A package cannot be moved into unknown status."); return View("~/Views/Packages/DisplayPackage.cshtml", model); } if (package.Status == PackageStatusType.Unknown && status == PackageStatusType.Submitted) { ModelState.AddModelError(String.Empty, "A package cannot be moved from unknown to submitted status."); return View("~/Views/Packages/DisplayPackage.cshtml", model); } if (User.IsReviewer() && status != PackageStatusType.Submitted) { ModelState.AddModelError(String.Empty, "A reviewer can only comment/submit in submitted status."); return View("~/Views/Packages/DisplayPackage.cshtml", model); } var comments = form["ReviewComments"]; var newComments = form["NewReviewComments"]; bool sendEmail = form["SendEmail"] != null; bool trustedPackage = form["IsTrusted"] == "true,false"; bool maintainerReject = form["MaintainerReject"] == "true"; bool rerunTests = form["RerunTests"] == "true"; if (maintainerReject && string.IsNullOrWhiteSpace(newComments)) { ModelState.AddModelError(String.Empty, "In order to reject a package version, you must provide comments indicating why it is being rejected."); return View("~/Views/Packages/DisplayPackage.cshtml", model); } if (isMaintainer && string.IsNullOrWhiteSpace(newComments)) { ModelState.AddModelError(String.Empty, "You need to provide comments."); return View("~/Views/Packages/DisplayPackage.cshtml", model); } if (isMaintainer && maintainerReject) { status = PackageStatusType.Rejected; } if (rerunTests) { packageSvc.ResetPackageTestStatus(package); } // could be null if no moderation has happened yet var moderator = isModerationRole ? currentUser : package.ReviewedBy; packageSvc.ChangePackageStatus(package, status, comments, newComments, currentUser, moderator, sendEmail, isModerationRole ? PackageSubmittedStatusType.Waiting : PackageSubmittedStatusType.Responded); if (isModerator) { packageSvc.ChangeTrustedStatus(package, trustedPackage, moderator); } //grab updated package package = packageSvc.FindPackageByIdAndVersion(id, version, allowPrerelease: true, useCache: false); model = new DisplayPackageViewModel(package); TempData["Message"] = "Changes to package status have been saved."; return View("~/Views/Packages/DisplayPackage.cshtml", model); }
public virtual ActionResult DisplayPackage(string id, string version, FormCollection form) { if (!ModelState.IsValid) return DisplayPackage(id, version); var currentUser = userSvc.FindByUsername(GetIdentity().Name); var package = packageSvc.FindPackageByIdAndVersion(id, version, allowPrerelease: true, useCache: false); if (package == null) return PackageNotFound(id, version); var model = new DisplayPackageViewModel(package); var packageRegistration = package.PackageRegistration; var isMaintainer = packageRegistration.Owners.AnySafe(x => x.Key == currentUser.Key); var isModerationRole = User.IsInAnyModerationRole() && !isMaintainer; var isModerator = User.IsModerator() && !isMaintainer; if (packageRegistration != null && !isMaintainer && !isModerationRole) { ModelState.AddModelError(String.Empty, String.Format(CultureInfo.CurrentCulture, Strings.ApiKeyNotAuthorized, "maintain")); return View("~/Views/Packages/DisplayPackage.cshtml", model); } if (!ModelState.IsValid) return View("~/Views/Packages/DisplayPackage.cshtml", model); var status = PackageStatusType.Unknown; if (isMaintainer) { status = package.Status; } else { try { status = (PackageStatusType)Enum.Parse(typeof(PackageStatusType), form["Status"]); } catch (Exception ex) { // Log but swallow the exception ErrorSignal.FromCurrentContext().Raise(ex); } } // maintainers and reviewers cannot change the current status if (User.IsReviewer() || isMaintainer) status = package.Status; if (package.Status != PackageStatusType.Unknown && status == PackageStatusType.Unknown) { ModelState.AddModelError(String.Empty, "A package cannot be moved into unknown status."); return View("~/Views/Packages/DisplayPackage.cshtml", model); } if (package.Status == PackageStatusType.Unknown && status == PackageStatusType.Submitted) { ModelState.AddModelError(String.Empty, "A package cannot be moved from unknown to submitted status."); return View("~/Views/Packages/DisplayPackage.cshtml", model); } if (User.IsReviewer() && status != PackageStatusType.Submitted) { ModelState.AddModelError(String.Empty, "A reviewer can only comment/submit in submitted status."); return View("~/Views/Packages/DisplayPackage.cshtml", model); } var reviewedPlusOneHour = package.ReviewedDate.GetValueOrDefault().AddHours(1); if (!User.IsAdmin() && package.Status != status && reviewedPlusOneHour < DateTime.UtcNow && (package.Status == PackageStatusType.Approved || package.Status == PackageStatusType.Exempted || package.Status == PackageStatusType.Rejected ) ) { ModelState.AddModelError(String.Empty, "Only an admin can move a package from approved/exempt/rejected after one hour of status change. Please reach out on Gitter or use contact site admins link in the left side bar."); return View("~/Views/Packages/DisplayPackage.cshtml", model); } var comments = form["ReviewComments"]; var newComments = form["NewReviewComments"]; bool sendMaintainerEmail = form["SendEmail"] == "true"; bool trustedPackage = form["IsTrusted"] == "true,false"; bool maintainerReject = form["MaintainerReject"] == "true"; bool changeSubmittedStatus = form["ChangeSubmittedStatus"] == "true"; //if (comments != package.ReviewComments) //{ // ModelState.AddModelError(String.Empty, "New comments have been added, please reload."); // return View("~/Views/Packages/DisplayPackage.cshtml", model); //} if (maintainerReject && string.IsNullOrWhiteSpace(newComments)) { ModelState.AddModelError(String.Empty, "In order to reject a package version, you must provide comments indicating why it is being rejected."); return View("~/Views/Packages/DisplayPackage.cshtml", model); } if (isMaintainer && string.IsNullOrWhiteSpace(newComments)) { ModelState.AddModelError(String.Empty, "You need to provide comments."); return View("~/Views/Packages/DisplayPackage.cshtml", model); } if (isMaintainer && maintainerReject) { status = PackageStatusType.Rejected; } bool exemptVerfication = form["IsExemptedFromVerification"] == "true,false"; var exemptVerficationReason = form["ExemptedFromVerificationReason"]; if (exemptVerfication && string.IsNullOrWhiteSpace(exemptVerficationReason)) { ModelState.AddModelError(String.Empty, "In order to exempt a package from automated testing, a reason should be specified."); return View("~/Views/Packages/DisplayPackage.cshtml", model); } if (isModerationRole) { packageSvc.ExemptPackageFromTesting(package, exemptVerfication, exemptVerficationReason, currentUser); } bool rerunTests = form["RerunTests"] == "true"; if (rerunTests) { packageSvc.ResetPackageTestStatus(package); if (!string.IsNullOrWhiteSpace(newComments)) newComments += "{0}".format_with(Environment.NewLine); newComments += "Auto Verification Change - Verification tests have been set to rerun."; } // could be null if no moderation has happened yet var moderator = isModerationRole ? currentUser : package.ReviewedBy; packageSvc.ChangePackageStatus(package, status, package.ReviewComments, newComments, currentUser, moderator, sendMaintainerEmail, isModerationRole ? changeSubmittedStatus ? PackageSubmittedStatusType.Waiting : package.SubmittedStatus : PackageSubmittedStatusType.Responded, assignReviewer: true ); if (isModerator) { packageSvc.ChangeTrustedStatus(package, trustedPackage, moderator); } //grab updated package package = packageSvc.FindPackageByIdAndVersion(id, version, allowPrerelease: true, useCache: false); model = new DisplayPackageViewModel(package); TempData["Message"] = "Changes to package status have been saved."; return View("~/Views/Packages/DisplayPackage.cshtml", model); }
private ActionResult GetPackageOwnerActionFormResult(string id, string version) { var package = _packageService.FindPackageByIdAndVersion(id, version); if (package == null) { return HttpNotFound(); } if (!package.IsOwner(HttpContext.User)) { return new HttpStatusCodeResult(401, "Unauthorized"); } var model = new DisplayPackageViewModel(package); return View(model); }
public virtual async Task<ActionResult> DisplayPackage(string id, string version) { string normalized = SemanticVersionExtensions.Normalize(version); if (!string.Equals(version, normalized)) { // Permanent redirect to the normalized one (to avoid multiple URLs for the same content) return RedirectToActionPermanent("DisplayPackage", new { id = id, version = normalized }); } var package = _packageService.FindPackageByIdAndVersion(id, version); if (package == null) { return HttpNotFound(); } var model = new DisplayPackageViewModel(package); if (package.IsOwner(User)) { // Tell logged-in package owners not to cache the package page, // so they won't be confused about the state of pending edits. Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetNoStore(); Response.Cache.SetMaxAge(TimeSpan.Zero); Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); var pendingMetadata = _editPackageService.GetPendingMetadata(package); if (pendingMetadata != null) { model.SetPendingMetadata(pendingMetadata); } } if (_searchService.ContainsAllVersions) { var isIndexedCacheKey = string.Format("IsIndexed_{0}_{1}", package.PackageRegistration.Id, package.Version); var isIndexed = HttpContext.Cache.Get(isIndexedCacheKey) as bool?; if (!isIndexed.HasValue) { var searchFilter = SearchAdaptor.GetSearchFilter( "id:\"" + package.PackageRegistration.Id + "\" AND version:\"" + package.Version + "\"", 1, null, SearchFilter.ODataSearchContext); var results = await _searchService.Search(searchFilter); isIndexed = results.Hits > 0; var expiration = Cache.NoAbsoluteExpiration; if (!isIndexed.Value) { expiration = DateTime.UtcNow.Add(TimeSpan.FromSeconds(30)); } HttpContext.Cache.Add(isIndexedCacheKey, isIndexed, null, expiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, null); } model.IsIndexed = isIndexed; } ViewBag.FacebookAppID = _config.FacebookAppId; return View(model); }
public static bool IsCakeExtension(this DisplayPackageViewModel model) { return(IsCakeAddin(model) || IsCakeModule(model) || IsCakeRecipe(model)); }
public virtual ActionResult DisplayPackage(string id, string version, FormCollection form) { if (!ModelState.IsValid) { return(DisplayPackage(id, version)); } var package = packageSvc.FindPackageByIdAndVersion(id, version); if (package == null) { return(PackageNotFound(id, version)); } var model = new DisplayPackageViewModel(package); if (!ModelState.IsValid) { return(View("~/Views/Packages/DisplayPackage.cshtml", model)); } var status = PackageStatusType.Unknown; try { status = (PackageStatusType)Enum.Parse(typeof(PackageStatusType), form["Status"]); } catch (Exception ex) { // Log but swallow the exception ErrorSignal.FromCurrentContext().Raise(ex); } //reviewers cannot change the current status if (User.IsReviewer()) { status = package.Status; } if (package.Status != PackageStatusType.Unknown && status == PackageStatusType.Unknown) { ModelState.AddModelError(String.Empty, "A package cannot be moved into unknown status."); return(View("~/Views/Packages/DisplayPackage.cshtml", model)); } if (package.Status == PackageStatusType.Unknown && status == PackageStatusType.Submitted) { ModelState.AddModelError(String.Empty, "A package cannot be moved from unknown to submitted status."); return(View("~/Views/Packages/DisplayPackage.cshtml", model)); } if (User.IsReviewer() && status != PackageStatusType.Submitted) { ModelState.AddModelError(String.Empty, "A reviewer can only comment/submit in submitted status."); return(View("~/Views/Packages/DisplayPackage.cshtml", model)); } var comments = form["ReviewComments"]; bool sendEmail = form["SendEmail"] != null; bool trustedPackage = form["IsTrusted"] == "true,false"; var moderator = userSvc.FindByUsername(HttpContext.User.Identity.Name); packageSvc.ChangePackageStatus(package, status, comments, moderator, sendEmail); packageSvc.ChangeTrustedStatus(package, trustedPackage, moderator); //grab updated package package = packageSvc.FindPackageByIdAndVersion(id, version); model = new DisplayPackageViewModel(package); TempData["Message"] = "Changes to package status have been saved."; return(View("~/Views/Packages/DisplayPackage.cshtml", model)); }
public virtual ActionResult DisplayPackage(string id, string version) { var package = _packageService.FindPackageByIdAndVersion(id, version); if (package == null) { return HttpNotFound(); } var model = new DisplayPackageViewModel(package); ViewBag.FacebookAppID = _config.FacebookAppId; return View(model); }
private DisplayPackageViewModel SetupInternal( DisplayPackageViewModel viewModel, Package package, User currentUser, PackageDeprecation deprecation, string readMeHtml) { viewModel.HasSemVer2Version = viewModel.NuGetVersion.IsSemVer2; viewModel.HasSemVer2Dependency = package.Dependencies.ToList() .Where(pd => !string.IsNullOrEmpty(pd.VersionSpec)) .Select(pd => VersionRange.Parse(pd.VersionSpec)) .Any(p => (p.HasUpperBound && p.MaxVersion.IsSemVer2) || (p.HasLowerBound && p.MinVersion.IsSemVer2)); viewModel.Dependencies = new DependencySetsViewModel(package.Dependencies); var packageHistory = package .PackageRegistration .Packages .OrderByDescending(p => new NuGetVersion(p.Version)) .ToList(); var pushedByCache = new Dictionary <User, string>(); viewModel.PackageVersions = packageHistory .Select( p => { var vm = new DisplayPackageViewModel(); _listPackageItemViewModelFactory.Setup(vm, p, currentUser); return(SetupCommon(vm, p, GetPushedBy(p, currentUser, pushedByCache))); }) .ToList(); viewModel.PushedBy = GetPushedBy(package, currentUser, pushedByCache); viewModel.PackageFileSize = package.PackageFileSize; viewModel.LatestSymbolsPackage = package.LatestSymbolPackage(); viewModel.LatestAvailableSymbolsPackage = viewModel.LatestSymbolsPackage != null && viewModel.LatestSymbolsPackage.StatusKey == PackageStatus.Available ? viewModel.LatestSymbolsPackage : package.LatestAvailableSymbolPackage(); if (packageHistory.Any()) { // calculate the number of days since the package registration was created // round to the nearest integer, with a min value of 1 // divide the total download count by this number viewModel.TotalDaysSinceCreated = Convert.ToInt32(Math.Max(1, Math.Round((DateTime.UtcNow - packageHistory.Min(p => p.Created)).TotalDays))); viewModel.DownloadsPerDay = viewModel.TotalDownloadCount / viewModel.TotalDaysSinceCreated; // for the package viewModel.DownloadsPerDayLabel = viewModel.DownloadsPerDay < 1 ? "<1" : viewModel.DownloadsPerDay.ToNuGetNumberString(); viewModel.IsDotnetToolPackageType = package.PackageTypes.Any(e => e.Name.Equals("DotnetTool", StringComparison.OrdinalIgnoreCase)); } if (deprecation != null) { viewModel.AlternatePackageId = deprecation.AlternatePackageRegistration?.Id; var alternatePackage = deprecation.AlternatePackage; if (alternatePackage != null) { // A deprecation should not have both an alternate package registration and an alternate package. // In case a deprecation does have both, we will hide the alternate package registration's ID in this model. viewModel.AlternatePackageId = alternatePackage?.Id; viewModel.AlternatePackageVersion = alternatePackage?.Version; } viewModel.CustomMessage = deprecation.CustomMessage; } viewModel.ReadMeHtml = readMeHtml; viewModel.HasEmbeddedIcon = package.HasEmbeddedIcon; return(viewModel); }
public virtual ActionResult DisplayPackage(string id, string version) { string normalized = SemanticVersionExtensions.Normalize(version); if (!String.Equals(version, normalized)) { // Permanent redirect to the normalized one (to avoid multiple URLs for the same content) return RedirectToActionPermanent("DisplayPackage", new { id = id, version = normalized }); } var package = _packageService.FindPackageByIdAndVersion(id, version); if (package == null) { return HttpNotFound(); } var model = new DisplayPackageViewModel(package); if (package.IsOwner(GetUser())) { // Tell logged-in package owners not to cache the package page, so they won't be confused about the state of pending edits. Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetNoStore(); Response.Cache.SetMaxAge(TimeSpan.Zero); Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); var pendingMetadata = _editPackageService.GetPendingMetadata(package); if (pendingMetadata != null) { model.SetPendingMetadata(pendingMetadata); } } ViewBag.FacebookAppID = _config.FacebookAppId; return View(model); }
public virtual async Task <ActionResult> DisplayPackage(string id, string version) { string normalized = NuGetVersionNormalizer.Normalize(version); if (!string.Equals(version, normalized)) { // Permanent redirect to the normalized one (to avoid multiple URLs for the same content) return(RedirectToActionPermanent("DisplayPackage", new { id = id, version = normalized })); } var package = _packageService.FindPackageByIdAndVersion(id, version); if (package == null) { return(HttpNotFound()); } var packageHistory = package.PackageRegistration.Packages.ToList() .OrderByDescending(p => new NuGetVersion(p.Version)); var model = new DisplayPackageViewModel(package, packageHistory); if (package.IsOwner(User)) { // Tell logged-in package owners not to cache the package page, // so they won't be confused about the state of pending edits. Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetNoStore(); Response.Cache.SetMaxAge(TimeSpan.Zero); Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); var pendingMetadata = _editPackageService.GetPendingMetadata(package); if (pendingMetadata != null) { model.SetPendingMetadata(pendingMetadata); } } var externalSearchService = _searchService as ExternalSearchService; if (_searchService.ContainsAllVersions && externalSearchService != null) { var isIndexedCacheKey = $"IsIndexed_{package.PackageRegistration.Id}_{package.Version}"; var isIndexed = HttpContext.Cache.Get(isIndexedCacheKey) as bool?; if (!isIndexed.HasValue) { var searchFilter = SearchAdaptor.GetSearchFilter( "id:\"" + package.PackageRegistration.Id + "\" AND version:\"" + package.Version + "\"", 1, null, SearchFilter.ODataSearchContext); var results = await externalSearchService.RawSearch(searchFilter); isIndexed = results.Hits > 0; var expiration = Cache.NoAbsoluteExpiration; if (!isIndexed.Value) { expiration = DateTime.UtcNow.Add(TimeSpan.FromSeconds(30)); } HttpContext.Cache.Add(isIndexedCacheKey, isIndexed, null, expiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, null); } model.IsIndexed = isIndexed; } ViewBag.FacebookAppID = _config.FacebookAppId; return(View(model)); }
public virtual ActionResult DisplayPackage(string id, string version, FormCollection form) { if (!ModelState.IsValid) { return(DisplayPackage(id, version)); } var currentUser = userSvc.FindByUsername(GetIdentity().Name); var package = packageSvc.FindPackageByIdAndVersion(id, version, allowPrerelease: true, useCache: false); if (package == null) { return(PackageNotFound(id, version)); } var scanResults = packageSvc.GetPackageScanResults(id, version, useCache: false); package.Files = packageSvc.GetPackageFiles(package, useCache: false).ToList(); package.Description = FindAndCorrectInvalidMarkdownHeaders(package.Description); package.ReleaseNotes = FindAndCorrectInvalidMarkdownHeaders(package.ReleaseNotes); var model = new DisplayPackageViewModel(package, scanResults); if (currentUser.IsBanned) { TempData["Message"] = "Changes to package status have been saved."; return(View("~/Views/Packages/DisplayPackage.cshtml", model)); } var packageRegistration = package.PackageRegistration; var isMaintainer = packageRegistration.Owners.AnySafe(x => x.Key == currentUser.Key); var isModerationRole = User.IsInAnyModerationRole() && !isMaintainer; var isModerator = User.IsModerator() && !isMaintainer; if (packageRegistration != null && !isMaintainer && !isModerationRole) { ModelState.AddModelError(String.Empty, String.Format(CultureInfo.CurrentCulture, Strings.ApiKeyNotAuthorized, "maintain")); return(View("~/Views/Packages/DisplayPackage.cshtml", model)); } if (!ModelState.IsValid) { return(View("~/Views/Packages/DisplayPackage.cshtml", model)); } var status = PackageStatusType.Unknown; if (isMaintainer) { status = package.Status; } else { try { status = (PackageStatusType)Enum.Parse(typeof(PackageStatusType), form["Status"].clean_html()); } catch (Exception ex) { // Log but swallow the exception ErrorSignal.FromCurrentContext().Raise(ex); } } // maintainers and reviewers cannot change the current status if (User.IsReviewer() || isMaintainer) { status = package.Status; } if (package.Status != PackageStatusType.Unknown && status == PackageStatusType.Unknown) { ModelState.AddModelError(String.Empty, "A package cannot be moved into unknown status."); return(View("~/Views/Packages/DisplayPackage.cshtml", model)); } if (package.Status == PackageStatusType.Unknown && status == PackageStatusType.Submitted) { ModelState.AddModelError(String.Empty, "A package cannot be moved from unknown to submitted status."); return(View("~/Views/Packages/DisplayPackage.cshtml", model)); } if (User.IsReviewer() && status != PackageStatusType.Submitted) { ModelState.AddModelError(String.Empty, "A reviewer can only comment/submit in submitted status."); return(View("~/Views/Packages/DisplayPackage.cshtml", model)); } var reviewedPlusOneHour = package.ReviewedDate.GetValueOrDefault().AddHours(1); if (!User.IsAdmin() && package.Status != status && reviewedPlusOneHour < DateTime.UtcNow && (package.Status == PackageStatusType.Approved || package.Status == PackageStatusType.Exempted || package.Status == PackageStatusType.Rejected ) ) { ModelState.AddModelError(String.Empty, "Only an admin can move a package from approved/exempt/rejected after one hour of status change. Please reach out on Gitter or use contact site admins link in the left side bar."); return(View("~/Views/Packages/DisplayPackage.cshtml", model)); } var newComments = form["NewReviewComments"].clean_html(); bool sendMaintainerEmail = form["SendEmail"].clean_html() == "true"; bool trustedPackage = form["IsTrusted"].clean_html() == "true,false"; bool maintainerReject = form["MaintainerReject"].clean_html() == "true"; bool changeSubmittedStatus = form["ChangeSubmittedStatus"].clean_html() == "true"; //if (comments != package.ReviewComments) //{ // ModelState.AddModelError(String.Empty, "New comments have been added, please reload."); // return View("~/Views/Packages/DisplayPackage.cshtml", model); //} if (maintainerReject && string.IsNullOrWhiteSpace(newComments)) { ModelState.AddModelError(String.Empty, "In order to reject a package version, you must provide comments indicating why it is being rejected."); return(View("~/Views/Packages/DisplayPackage.cshtml", model)); } if (isMaintainer && string.IsNullOrWhiteSpace(newComments)) { ModelState.AddModelError(String.Empty, "You need to provide comments."); return(View("~/Views/Packages/DisplayPackage.cshtml", model)); } if (isMaintainer && maintainerReject) { status = PackageStatusType.Rejected; } bool exemptVerfication = form["IsExemptedFromVerification"].clean_html() == "true,false"; var exemptVerficationReason = form["ExemptedFromVerificationReason"].clean_html(); if (exemptVerfication && string.IsNullOrWhiteSpace(exemptVerficationReason)) { ModelState.AddModelError(String.Empty, "In order to exempt a package from automated testing, a reason should be specified."); return(View("~/Views/Packages/DisplayPackage.cshtml", model)); } if (isModerationRole) { packageSvc.ExemptPackageFromTesting(package, exemptVerfication, exemptVerficationReason, currentUser); } bool rerunTests = form["RerunTests"].clean_html() == "true"; if (rerunTests) { packageSvc.ResetPackageTestStatus(package); if (!string.IsNullOrWhiteSpace(newComments)) { newComments += "{0}".format_with(Environment.NewLine); } newComments += "Auto Verification Change - Verification tests have been set to rerun."; } bool rerunValidation = form["RerunValidation"].clean_html() == "true"; if (rerunValidation) { packageSvc.ResetPackageValidationStatus(package); if (!string.IsNullOrWhiteSpace(newComments)) { newComments += "{0}".format_with(Environment.NewLine); } newComments += "Auto Validation Change - Validation tests have been set to rerun."; } bool rerunVirusScanner = form["RerunVirusScanner"].clean_html() == "true"; if (rerunVirusScanner) { package.PackageScanStatus = PackageScanStatusType.Unknown; packageSvc.SaveMinorPackageChanges(package); if (!string.IsNullOrWhiteSpace(newComments)) { newComments += "{0}".format_with(Environment.NewLine); } newComments += "Virus Scanner has ben set to rerun"; } bool rerunPackageCacher = form["RerunPackageCacher"].clean_html() == "true"; if (rerunPackageCacher) { package.DownloadCacheStatus = PackageDownloadCacheStatusType.Unknown; packageSvc.SaveMinorPackageChanges(package); if (!string.IsNullOrWhiteSpace(newComments)) { newComments += "{0}".format_with(Environment.NewLine); } newComments += "Package Cacher (CDN Download Cache) has ben set to rerun"; } bool exemptPackageFromValidation = form["ExemptPackageFromValidation"].clean_html() == "true"; if (exemptPackageFromValidation) { packageSvc.ExemptPackageFromValidation(package); if (!string.IsNullOrWhiteSpace(newComments)) { newComments += "{0}".format_with(Environment.NewLine); } newComments += "Auto Validation Change - Validation tests have been exempted."; } // could be null if no moderation has happened yet var moderator = isModerationRole ? currentUser : package.ReviewedBy; packageSvc.ChangePackageStatus(package, status, package.ReviewComments, newComments, currentUser, moderator, sendMaintainerEmail, isModerationRole ? changeSubmittedStatus ? PackageSubmittedStatusType.Waiting : package.SubmittedStatus : PackageSubmittedStatusType.Responded, assignReviewer: true ); if (isModerator) { packageSvc.ChangeTrustedStatus(package, trustedPackage, moderator); } //grab updated package package = packageSvc.FindPackageByIdAndVersion(id, version, allowPrerelease: true, useCache: false); scanResults = packageSvc.GetPackageScanResults(id, version, useCache: false); package.Files = packageSvc.GetPackageFiles(package, useCache: false).ToList(); model = new DisplayPackageViewModel(package, scanResults); TempData["Message"] = "Changes to package status have been saved."; return(View("~/Views/Packages/DisplayPackage.cshtml", model)); }
public virtual ActionResult DisplayPackage(string id, string version) { var package = packageSvc.FindPackageByIdAndVersion(id, version); if (package == null) return PackageNotFound(id, version); var model = new DisplayPackageViewModel(package); return View("~/Views/Packages/DisplayPackage.cshtml", model); }
public virtual ActionResult DisplayPackage(string id, string version) { var package = _packageSvc.FindPackageByIdAndVersion(id, version); if (package == null) { return PackageNotFound(id, version); } var model = new DisplayPackageViewModel(package); return View(model); }
private DisplayPackageViewModel SetupInternal( DisplayPackageViewModel viewModel, Package package, IReadOnlyCollection <Package> allVersions, User currentUser, IReadOnlyDictionary <int, PackageDeprecation> packageKeyToDeprecation, IReadOnlyList <PackageRename> packageRenames, RenderedReadMeResult readmeResult) { var dependencies = package.Dependencies.ToList(); viewModel.Dependencies = new DependencySetsViewModel(dependencies); var packageHistory = allVersions .OrderByDescending(p => new NuGetVersion(p.Version)) .ToList(); var pushedByCache = new Dictionary <User, string>(); viewModel.PackageVersions = packageHistory .Select( p => { var vm = new DisplayPackageViewModel(); _listPackageItemViewModelFactory.Setup(vm, p, currentUser); return(SetupCommon(vm, p, GetPushedBy(p, currentUser, pushedByCache), packageKeyToDeprecation)); }) .ToList(); viewModel.PushedBy = GetPushedBy(package, currentUser, pushedByCache); viewModel.PackageFileSize = package.PackageFileSize; viewModel.LatestSymbolsPackage = package.LatestSymbolPackage(); viewModel.LatestAvailableSymbolsPackage = viewModel.LatestSymbolsPackage != null && viewModel.LatestSymbolsPackage.StatusKey == PackageStatus.Available ? viewModel.LatestSymbolsPackage : package.LatestAvailableSymbolPackage(); if (packageHistory.Any()) { // calculate the number of days since the package registration was created // round to the nearest integer, with a min value of 1 // divide the total download count by this number viewModel.TotalDaysSinceCreated = Convert.ToInt32(Math.Max(1, Math.Round((DateTime.UtcNow - packageHistory.Min(p => p.Created)).TotalDays))); viewModel.DownloadsPerDay = viewModel.TotalDownloadCount / viewModel.TotalDaysSinceCreated; // for the package viewModel.DownloadsPerDayLabel = viewModel.DownloadsPerDay < 1 ? "<1" : viewModel.DownloadsPerDay.ToNuGetNumberString(); // Lazily load the package types from the database. viewModel.IsDotnetToolPackageType = package.PackageTypes.Any(e => e.Name.Equals("DotnetTool", StringComparison.OrdinalIgnoreCase)); viewModel.IsDotnetNewTemplatePackageType = package.PackageTypes.Any(e => e.Name.Equals("Template", StringComparison.OrdinalIgnoreCase)); } if (packageKeyToDeprecation != null && packageKeyToDeprecation.TryGetValue(package.Key, out var deprecation)) { viewModel.AlternatePackageId = deprecation.AlternatePackageRegistration?.Id; var alternatePackage = deprecation.AlternatePackage; if (alternatePackage != null) { // A deprecation should not have both an alternate package registration and an alternate package. // In case a deprecation does have both, we will hide the alternate package registration's ID in this model. viewModel.AlternatePackageId = alternatePackage?.Id; viewModel.AlternatePackageVersion = alternatePackage?.Version; } viewModel.CustomMessage = deprecation.CustomMessage; } if (packageRenames != null && packageRenames.Count != 0) { viewModel.PackageRenames = packageRenames; if (package.PackageRegistration?.RenamedMessage != null) { viewModel.RenamedMessage = package.PackageRegistration.RenamedMessage; } } viewModel.ReadMeHtml = readmeResult?.Content; viewModel.ReadMeImagesRewritten = readmeResult != null ? readmeResult.ImagesRewritten : false; viewModel.HasEmbeddedIcon = package.HasEmbeddedIcon; return(viewModel); }