Esempio n. 1
0
        public virtual ActionResult SubmitPackageValidationResults(string apiKey, string id, string version, bool success, string validationComments)
        {
            Guid parsedApiKey;

            if (!Guid.TryParse(apiKey, out parsedApiKey))
            {
                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, Strings.InvalidApiKey));
            }

            var testReporterUser = userSvc.FindByApiKey(parsedApiKey);

            if (testReporterUser == null)
            {
                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, String.Format(CultureInfo.CurrentCulture, Strings.ApiKeyNotAuthorized, "submitvalidationresults")));
            }
            // Only the package operations user can submit test results
            if (testReporterUser.Key != settings.PackageOperationsUserKey)
            {
                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, String.Format(CultureInfo.CurrentCulture, Strings.ApiKeyNotAuthorized, "submitvalidationresults")));
            }

            if (String.IsNullOrEmpty(id) || String.IsNullOrEmpty(version))
            {
                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.NotFound, string.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version)));
            }

            if (string.IsNullOrWhiteSpace(validationComments))
            {
                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "Submitting validation results requires 'validationComments' and 'success'."));
            }

            var package = packageSvc.FindPackageByIdAndVersion(id, version, allowPrerelease: true, useCache: false);

            if (package == null)
            {
                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.NotFound, string.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version)));
            }

            package.PackageValidationResultDate   = DateTime.UtcNow;
            package.PackageValidationResultStatus = PackageAutomatedReviewResultStatusType.Failing;

            var message = "{0} has failed automated validation.".format_with(package.PackageRegistration.Id);

            if (success)
            {
                package.PackageValidationResultStatus = PackageAutomatedReviewResultStatusType.Passing;
                message = "{0} has passed automated validation. It may have or may still fail other checks like testing (verification).".format_with(package.PackageRegistration.Id);
            }

            message += "{0}{1}".format_with(Environment.NewLine, validationComments);

            packageSvc.UpdateSubmittedStatusAfterAutomatedReviews(package);

            packageSvc.ChangePackageStatus(package, package.Status, package.ReviewComments, message, testReporterUser, testReporterUser, sendMaintainerEmail: true, submittedStatus: success ? package.SubmittedStatus : PackageSubmittedStatusType.Waiting, assignReviewer: false);

            return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Accepted, "Package validation results have been updated."));
        }
Esempio n. 2
0
        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, 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));
        }