public async Task CreatePackageWillSavePackageFileToFileStorage() { // Arrange var guid = Guid.NewGuid().ToString(); var fakeUser = new User(); var userService = new Mock<IUserService>(); userService.Setup(x => x.FindByApiKey(It.IsAny<Guid>())).Returns(fakeUser); var packageRegistration = new PackageRegistration(); packageRegistration.Owners.Add(fakeUser); var packageService = new Mock<IPackageService>(); packageService.Setup(p => p.FindPackageRegistrationById(It.IsAny<string>())).Returns(packageRegistration); var packageFileService = new Mock<IPackageFileService>(); packageFileService.Setup(p => p.SavePackageFileAsync(It.IsAny<Package>(), It.IsAny<Stream>())).Returns(Task.FromResult(0)).Verifiable(); var nuGetPackage = new Mock<INupkg>(); nuGetPackage.Setup(x => x.Metadata.Id).Returns("theId"); nuGetPackage.Setup(x => x.Metadata.Version).Returns(new SemanticVersion("1.0.42")); var controller = CreateController( fileService: packageFileService, userService: userService, packageService: packageService, packageFromInputStream: nuGetPackage); // Act await controller.CreatePackagePut(guid); // Assert packageFileService.Verify(); }
public void WillReturnConflictIfAPackageWithTheIdAndSemanticVersionAlreadyExists() { var version = new SemanticVersion("1.0.42"); var nuGetPackage = new Mock<IPackage>(); nuGetPackage.Setup(x => x.Id).Returns("theId"); nuGetPackage.Setup(x => x.Version).Returns(version); var user = new User(); var packageRegistration = new PackageRegistration { Packages = new List<Package> { new Package { Version = version.ToString() } }, Owners = new List<User> { user } }; var packageSvc = new Mock<IPackageService>(); packageSvc.Setup(x => x.FindPackageRegistrationById(It.IsAny<string>())).Returns(packageRegistration); var userSvc = new Mock<IUserService>(); userSvc.Setup(x => x.FindByApiKey(It.IsAny<Guid>())).Returns(user); var controller = CreateController(userSvc: userSvc, packageSvc: packageSvc, packageFromInputStream: nuGetPackage.Object); // Act var result = controller.CreatePackagePut(Guid.NewGuid().ToString()); // Assert Assert.IsType<HttpStatusCodeWithBodyResult>(result); var statusCodeResult = (HttpStatusCodeWithBodyResult)result; Assert.Equal(409, statusCodeResult.StatusCode); Assert.Equal(String.Format(Strings.PackageExistsAndCannotBeModified, "theId", "1.0.42"), statusCodeResult.StatusDescription); }
public virtual void StartEditPackageRequest(Package p, EditPackageVersionRequest request, User editingUser) { PackageEdit edit = new PackageEdit { // Description User = editingUser, Authors = request.Authors, Copyright = request.Copyright, Description = request.Description, IconUrl = request.IconUrl, LicenseUrl = p.LicenseUrl, // Our current policy is not to allow editing the license URL, so just clone it from its previous value. ProjectUrl = request.ProjectUrl, ReleaseNotes = request.ReleaseNotes, RequiresLicenseAcceptance = request.RequiresLicenseAcceptance, Summary = request.Summary, Tags = request.Tags, Title = request.VersionTitle, // Other Package = p, Timestamp = DateTime.UtcNow, TriedCount = 0, }; EntitiesContext.Set<PackageEdit>().Add(edit); // Note: EditPackageRequests are completed asynchronously by the worker role. }
public async Task CreatePackageWillSavePackageFileToFileStorage() { // Arrange var user = new User() { EmailAddress = "*****@*****.**" }; var packageRegistration = new PackageRegistration(); packageRegistration.Id = "theId"; packageRegistration.Owners.Add(user); var package = new Package(); package.PackageRegistration = packageRegistration; package.Version = "1.0.42"; packageRegistration.Packages.Add(package); var controller = new TestableApiController(); controller.SetCurrentUser(user); controller.MockPackageFileService.Setup(p => p.SavePackageFileAsync(It.IsAny<Package>(), It.IsAny<Stream>())) .Returns(Task.CompletedTask).Verifiable(); controller.MockPackageService.Setup(p => p.FindPackageRegistrationById(It.IsAny<string>())) .Returns(packageRegistration); controller.MockPackageService.Setup(p => p.CreatePackageAsync(It.IsAny<PackageArchiveReader>(), It.IsAny<PackageStreamMetadata>(), It.IsAny<User>(), false)) .Returns(Task.FromResult(package)); var nuGetPackage = TestPackage.CreateTestPackageStream("theId", "1.0.42"); controller.SetupPackageFromInputStream(nuGetPackage); // Act await controller.CreatePackagePut(); // Assert controller.MockPackageFileService.Verify(); }
public bool ConfirmPackageOwner(PackageRegistration package, User pendingOwner, string token) { if (package == null) { throw new ArgumentNullException("package"); } if (pendingOwner == null) { throw new ArgumentNullException("pendingOwner"); } if (String.IsNullOrEmpty(token)) { throw new ArgumentNullException("token"); } if (package.IsOwner(pendingOwner)) { return true; } var request = FindExistingPackageOwnerRequest(package, pendingOwner); if (request != null && request.ConfirmationCode == token) { AddPackageOwner(package, pendingOwner); return true; } return false; }
public Package CreatePackage(IPackage nugetPackage, User currentUser) { ValidateNuGetPackage(nugetPackage); var packageRegistration = CreateOrGetPackageRegistration(currentUser, nugetPackage); var package = CreatePackageFromNuGetPackage(packageRegistration, nugetPackage); packageRegistration.Packages.Add(package); using (var tx = new TransactionScope()) { using (var stream = nugetPackage.GetStream()) { UpdateIsLatest(packageRegistration); packageRegistrationRepo.CommitChanges(); packageFileSvc.SavePackageFile(package, stream); tx.Complete(); } } if (package.Status != PackageStatusType.Approved && package.Status != PackageStatusType.Exempted) NotifyForModeration(package, comments: string.Empty); NotifyIndexingService(); return package; }
public IEnumerable<UserSiteProfile> GetUserProfiles(User user) { return profileRepo.GetAll().Where(x => x.Username == user.Username).ToList(); //return (from p in profileRepo.GetAll() // where p.Username == user.Username // select p).ToList(); }
public async Task WithTokenThatDoesNotMatchUserReturnsFalse() { var user = new User { Username = "******", EmailConfirmationToken = "token" }; var service = new TestableUserService(); var confirmed = await service.ConfirmEmailAddress(user, "not-token"); Assert.False(confirmed); }
public void ChangeEmailSubscription(User user, bool emailAllowed) { if (user == null) { throw new ArgumentNullException("user"); } user.EmailAllowed = emailAllowed; UserRepository.CommitChanges(); }
public void ChangeEmailAddress(User user, string newEmailAddress) { var existingUsers = FindAllByEmailAddress(newEmailAddress); if (existingUsers.AnySafe(u => u.Key != user.Key)) { throw new EntityException(Strings.EmailAddressBeingUsed, newEmailAddress); } user.UpdateEmailAddress(newEmailAddress, Crypto.GenerateToken); UserRepository.CommitChanges(); }
public async Task ChangeEmailSubscriptionAsync(User user, bool emailAllowed, bool notifyPackagePushed) { if (user == null) { throw new ArgumentNullException(nameof(user)); } user.EmailAllowed = emailAllowed; user.NotifyPackagePushed = notifyPackagePushed; await UserRepository.CommitChangesAsync(); }
public void IsInRoleReturnsCorrectValue(string expectedRole, bool isInRole) { // Arrange var user = new User("testuser"); user.Roles.Add(new Role { Key = 1, Name = "Admins" }); // Act var result = user.IsInRole(expectedRole); // Assert Assert.True(result == isInRole); }
public void AddPackageOwner(PackageRegistration package, User user) { package.Owners.Add(user); packageRepo.CommitChanges(); var request = FindExistingPackageOwnerRequest(package, user); if (request != null) { packageOwnerRequestRepository.DeleteOnCommit(request); packageOwnerRequestRepository.CommitChanges(); } }
public async Task ThrowsForDuplicateConfirmedEmailAddresses() { var user = new User { Username = "******", Key = 1, EmailAddress = "*****@*****.**", UnconfirmedEmailAddress = "*****@*****.**", EmailConfirmationToken = "token" }; var conflictingUser = new User { Username = "******", Key = 2, EmailAddress = "*****@*****.**" }; var service = new TestableUserServiceWithDBFaking { Users = new[] { user, conflictingUser } }; var ex = await AssertEx.Throws<EntityException>(() => service.ConfirmEmailAddress(user, "token")); Assert.Equal(String.Format(Strings.EmailAddressBeingUsed, "*****@*****.**"), ex.Message); }
public async Task SoftDeletePackagesAsync(IEnumerable<Package> packages, User deletedBy, string reason, string signature) { EntitiesConfiguration.SuspendExecutionStrategy = true; using (var transaction = _entitiesContext.GetDatabase().BeginTransaction()) { // Increase command timeout _entitiesContext.SetCommandTimeout(seconds: 300); // Keep package registrations var packageRegistrations = packages .GroupBy(p => p.PackageRegistration) .Select(g => g.First().PackageRegistration) .ToList(); // Backup the package binaries and remove from main storage // We're doing this early in the process as we need the metadata to still exist in the DB. await BackupPackageBinaries(packages); // Store the soft delete in the database var packageDelete = new PackageDelete { DeletedOn = DateTime.UtcNow, DeletedBy = deletedBy, Reason = reason, Signature = signature }; foreach (var package in packages) { package.Listed = false; package.Deleted = true; packageDelete.Packages.Add(package); await _auditingService.SaveAuditRecord(CreateAuditRecord(package, package.PackageRegistration, AuditedPackageAction.SoftDelete, reason)); } _packageDeletesRepository.InsertOnCommit(packageDelete); // Update latest versions await UpdateIsLatestAsync(packageRegistrations); // Commit changes await _packageRepository.CommitChangesAsync(); await _packageDeletesRepository.CommitChangesAsync(); transaction.Commit(); } EntitiesConfiguration.SuspendExecutionStrategy = false; // Force refresh the index UpdateSearchIndex(); }
public static bool VerifyPasswordHash(User user, string password) { bool canAuthenticate = CryptographyService.ValidateSaltedHash( user.HashedPassword, password, user.PasswordHashAlgorithm); bool sanity = CryptographyService.ValidateSaltedHash( user.HashedPassword, "not_the_password", user.PasswordHashAlgorithm); return canAuthenticate && !sanity; }
public void SaveProfiles(User user, EditProfileViewModel profile) { var siteProfiles = GetUserProfiles(user).AsQueryable(); CompareAndPrepareProfile(SiteProfileConstants.Blog, profile.BlogUrl, user.Username, string.Empty, siteProfiles, prefix: string.Empty); CompareAndPrepareProfile(SiteProfileConstants.Codeplex, profile.CodeplexUserName, user.Username, SiteProfileConstants.Images.codeplex, siteProfiles, prefix: SiteProfileConstants.CodeplexProfilePrefix); CompareAndPrepareProfile(SiteProfileConstants.Github, profile.GithubUserName, user.Username, SiteProfileConstants.Images.github, siteProfiles, prefix: SiteProfileConstants.GithubProfilePrefix); CompareAndPrepareProfile(SiteProfileConstants.Homepage, profile.HomepageUrl, user.Username, string.Empty, siteProfiles, prefix: string.Empty); CompareAndPrepareProfile(SiteProfileConstants.StackExchange, profile.StackExchangeUrl, user.Username, SiteProfileConstants.Images.stackexchange, siteProfiles, prefix: string.Empty); CompareAndPrepareProfile(SiteProfileConstants.Twitter, profile.TwitterUserName, user.Username, SiteProfileConstants.Images.twitter, siteProfiles, prefix: SiteProfileConstants.TwitterProfilePrefix); CompareAndPrepareProfile(SiteProfileConstants.PackagesRepository, profile.PackagesRepository, user.Username, string.Empty, siteProfiles, prefix: string.Empty); CompareAndPrepareProfile(SiteProfileConstants.PackagesRepositoryAuto, profile.PackagesRepositoryAuto, user.Username, string.Empty, siteProfiles, prefix: string.Empty); profileRepo.CommitChanges(); }
public void WillCreateAPackageWithTheUserMatchingTheApiKey() { var nuGetPackage = new Mock<IPackage>(); nuGetPackage.Setup(x => x.Id).Returns("theId"); nuGetPackage.Setup(x => x.Version).Returns(new SemanticVersion("1.0.42")); var packageSvc = new Mock<IPackageService>(); var userSvc = new Mock<IUserService>(); var matchingUser = new User(); userSvc.Setup(x => x.FindByApiKey(It.IsAny<Guid>())).Returns(matchingUser); var controller = CreateController(userSvc: userSvc, packageSvc: packageSvc, packageFromInputStream: nuGetPackage.Object); controller.CreatePackagePut(Guid.NewGuid()); packageSvc.Verify(x => x.CreatePackage(It.IsAny<IPackage>(), matchingUser)); }
public void ReturnsTrueWhenSuccessful() { var user = new User { Username = "******", HashedPassword = "******", PasswordHashAlgorithm = "PBKDF2" }; var userRepository = new Mock<IEntityRepository<User>>(); userRepository.Setup(r => r.GetAll()).Returns(new[] { user }.AsQueryable()); var cryptoService = new Mock<ICryptographyService>(MockBehavior.Strict); cryptoService.Setup(s => s.ValidateSaltedHash("old hash", "oldpwd", Constants.PBKDF2HashAlgorithmId)).Returns(true); cryptoService.Setup(s => s.GenerateSaltedHash("newpwd", Constants.PBKDF2HashAlgorithmId)).Returns("hash and bacon"); var service = CreateUsersService(userRepo: userRepository, cryptoService: cryptoService); var changed = service.ChangePassword("user", "oldpwd", "newpwd"); Assert.True(changed); Assert.Equal("hash and bacon", user.HashedPassword); }
public virtual User Create( string username, string password, string emailAddress) { // TODO: validate input // TODO: consider encrypting email address with a public key, and having the background process that send messages have the private key to decrypt var existingUser = FindByUsername(username); if (existingUser != null) { throw new EntityException(Strings.UsernameNotAvailable, username); } var existingUsers = FindAllByEmailAddress(emailAddress); if (existingUsers.AnySafe()) { throw new EntityException(Strings.EmailAddressBeingUsed, emailAddress); } var hashedPassword = Crypto.GenerateSaltedHash(password, Constants.PBKDF2HashAlgorithmId); var apiKey = Guid.NewGuid(); var newUser = new User(username) { ApiKey = apiKey, EmailAllowed = true, UnconfirmedEmailAddress = emailAddress, EmailConfirmationToken = Crypto.GenerateToken(), HashedPassword = hashedPassword, PasswordHashAlgorithm = Constants.PBKDF2HashAlgorithmId, CreatedUtc = DateTime.UtcNow }; // Add a credential for the password and the API Key newUser.Credentials.Add(CredentialBuilder.CreateV1ApiKey(apiKey)); newUser.Credentials.Add(new Credential(CredentialTypes.Password.Pbkdf2, newUser.HashedPassword)); if (!Config.ConfirmEmailAddresses) { newUser.ConfirmEmailAddress(); } UserRepository.InsertOnCommit(newUser); UserRepository.CommitChanges(); return newUser; }
public void WillGetCuratedFeedsManagedByTheCurrentUser() { var controller = GetController<UsersController>(); var user = new User { Username = "******", Key = 42 }; controller.SetUser(user); GetMock<IUserService>() .Setup(s => s.FindByUsername(It.IsAny<string>())) .Returns(user); // act controller.Account(); // verify GetMock<ICuratedFeedService>() .Verify(query => query.GetFeedsForManager(42)); }
public void WillReturnTheAccountViewModelWithTheUserApiKey() { var controller = GetController<UsersController>(); var stubApiKey = Guid.NewGuid(); var user = new User { Username = "******", Key = 42, ApiKey = stubApiKey }; GetMock<IUserService>() .Setup(s => s.FindByUsername(It.IsAny<string>())) .Returns(user); controller.SetUser(user); // act var model = ((ViewResult)controller.Account()).Model as AccountViewModel; // verify Assert.Equal(stubApiKey.ToString(), model.ApiKey); }
public void WillGetTheCurrentUserUsingTheRequestIdentityName() { var controller = GetController<UsersController>(); var user = new User { Username = "******" }; controller.SetUser(user); GetMock<IUserService>() .Setup(s => s.FindByUsername(It.IsAny<string>())) .Returns(user); //act controller.Account(); // verify GetMock<IUserService>() .Verify(stub => stub.FindByUsername("theUsername")); }
public void ReturnsConfirmedWhenTokenMatchesUser() { var user = new User { UnconfirmedEmailAddress = "*****@*****.**", EmailConfirmationToken = "the-token" }; var userService = new Mock<IUserService>(); userService.Setup(u => u.FindByUsername("username")).Returns(user); userService.Setup(u => u.ConfirmEmailAddress(user, "the-token")).Returns(true); var controller = CreateController(userSvc: userService); var model = (controller.Confirm("username", "the-token") as ViewResult).Model as EmailConfirmationModel; Assert.True(model.SuccessfulConfirmation); }
public void ReturnsTrueWhenSuccessful() { var user = new User { Username = "******", HashedPassword = "******", PasswordHashAlgorithm = "PBKDF2" }; var service = new TestableUserService(); service.MockUserRepository .Setup(r => r.GetAll()).Returns(new[] { user }.AsQueryable()); service.MockCrypto .Setup(s => s.ValidateSaltedHash("old hash", "oldpwd", Constants.PBKDF2HashAlgorithmId)).Returns(true); service.MockCrypto .Setup(s => s.GenerateSaltedHash("newpwd", Constants.PBKDF2HashAlgorithmId)).Returns("hash and bacon"); var changed = service.ChangePassword("user", "oldpwd", "newpwd"); Assert.True(changed); Assert.Equal("hash and bacon", user.HashedPassword); }
public void WillSendEmailToGalleryOwner() { var from = new MailAddress("*****@*****.**", "too"); var owner = new User { Username = "******", EmailAddress = "*****@*****.**", }; var package = new Package { PackageRegistration = new PackageRegistration { Id = "smangit", Owners = new Collection<User> { owner } }, Version = "1.42.0.1" }; var mailSender = new Mock<IMailSender>(); var config = new Mock<IConfiguration>(); config.Setup(x => x.GalleryOwnerName).Returns("NuGet Gallery"); config.Setup(x => x.GalleryOwnerEmail).Returns("*****@*****.**"); var messageService = new MessageService(mailSender.Object, config.Object); MailMessage message = null; mailSender.Setup(m => m.Send(It.IsAny<MailMessage>())).Callback<MailMessage>(m => { message = m; }); messageService.ReportMyPackage( new ReportPackageRequest { FromAddress = from, Message = "Abuse!", Package = package, Reason = "Reason!", RequestingUser = owner, Url = TestUtility.MockUrlHelper(), }); Assert.Equal("*****@*****.**", message.To[0].Address); Assert.Equal("*****@*****.**", message.From.Address); Assert.Equal("*****@*****.**", message.ReplyToList.Single().Address); Assert.Equal("[NuGet Gallery] Owner Support Request for 'smangit' version 1.42.0.1 (Reason: Reason!)", message.Subject); Assert.Contains("Reason!", message.Body); Assert.Contains("Abuse!", message.Body); Assert.Contains("too ([email protected])", message.Body); Assert.Contains("smangit", message.Body); Assert.Contains("1.42.0.1", message.Body); }
public Package CreatePackage(INupkg nugetPackage, User user, bool commitChanges = true) { ValidateNuGetPackageMetadata(nugetPackage.Metadata); var packageRegistration = CreateOrGetPackageRegistration(user, nugetPackage.Metadata); var package = CreatePackageFromNuGetPackage(packageRegistration, nugetPackage, user); packageRegistration.Packages.Add(package); UpdateIsLatest(packageRegistration, commitChanges); if (commitChanges) { _packageRegistrationRepository.CommitChanges(); NotifyIndexingService(); } return package; }
public void WillReturnTheAccountViewModelWithTheCuratedFeeds() { var user = new User { Key = 42, Username = "******" }; var controller = GetController<UsersController>(); GetMock<IUserService>() .Setup(s => s.FindByUsername(It.IsAny<string>())) .Returns(user); GetMock<ICuratedFeedService>() .Setup(stub => stub.GetFeedsForManager(It.IsAny<int>())) .Returns(new[] { new CuratedFeed { Name = "theCuratedFeed" } }); controller.SetUser(user); // act var model = ((ViewResult)controller.Account()).Model as AccountViewModel; // verify Assert.Equal("theCuratedFeed", model.CuratedFeeds.First()); }
public void WillMakeTheCurrentUserTheOwnerWhenCreatingANewPackageRegistration() { var packageRegistrationRepo = new Mock<IEntityRepository<PackageRegistration>>(); var service = CreateService( packageRegistrationRepo: packageRegistrationRepo, setup: mockPackageSvc => { mockPackageSvc.Setup(x => x.FindPackageRegistrationById(It.IsAny<string>())).Returns((PackageRegistration)null); }); var nugetPackage = CreateNuGetPackage(); var currentUser = new User(); var package = service.CreatePackage( nugetPackage.Object, currentUser); packageRegistrationRepo.Verify(x => x.InsertOnCommit(It.Is<PackageRegistration>(pr => pr.Owners.Contains(currentUser)))); }
public void WillCreateANewPackageRegistrationUsingTheNugetPackIdWhenOneDoesNotAlreadyExist() { var packageRegistrationRepo = new Mock<IEntityRepository<PackageRegistration>>(); var service = CreateService( packageRegistrationRepo: packageRegistrationRepo, setup: mockPackageSvc => { mockPackageSvc.Setup(x => x.FindPackageRegistrationById(It.IsAny<string>())).Returns((PackageRegistration)null); }); var nugetPackage = CreateNuGetPackage(); var currentUser = new User(); var package = service.CreatePackage( nugetPackage.Object, currentUser); packageRegistrationRepo.Verify(x => x.InsertOnCommit(It.Is<PackageRegistration>(pr => pr.Id == "theId"))); packageRegistrationRepo.Verify(x => x.CommitChanges()); }
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); var model = new DisplayPackageViewModel(package, scanResults); 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 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"; } // 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); model = new DisplayPackageViewModel(package, scanResults); TempData["Message"] = "Changes to package status have been saved."; return View("~/Views/Packages/DisplayPackage.cshtml", model); }