public virtual async Task <ActionResult> TransformToOrganization(TransformAccountViewModel transformViewModel) { var accountToTransform = GetCurrentUser(); var adminUser = UserService.FindByUsername(transformViewModel.AdminUsername); if (adminUser == null) { ModelState.AddModelError(string.Empty, String.Format(CultureInfo.CurrentCulture, Strings.TransformAccount_AdminAccountDoesNotExist, transformViewModel.AdminUsername)); return(View(transformViewModel)); } if (!UserService.CanTransformUserToOrganization(accountToTransform, adminUser, out var errorReason)) { ModelState.AddModelError(string.Empty, errorReason); return(View(transformViewModel)); } // Get the user from the previous organization migration request (if there was one) so we can notify them that their request has been cancelled. var existingTransformRequestUser = accountToTransform.OrganizationMigrationRequest?.AdminUser; await UserService.RequestTransformToOrganizationAccount(accountToTransform, adminUser); if (existingTransformRequestUser != null) { MessageService.SendOrganizationTransformRequestCancelledNotice(accountToTransform, existingTransformRequestUser); } var returnUrl = Url.ConfirmTransformAccount(accountToTransform); var confirmUrl = Url.ConfirmTransformAccount(accountToTransform, relativeUrl: false); var rejectUrl = Url.RejectTransformAccount(accountToTransform, relativeUrl: false); MessageService.SendOrganizationTransformRequest(accountToTransform, adminUser, Url.User(accountToTransform, relativeUrl: false), confirmUrl, rejectUrl); var cancelUrl = Url.CancelTransformAccount(accountToTransform, relativeUrl: false); MessageService.SendOrganizationTransformInitiatedNotice(accountToTransform, adminUser, cancelUrl); TelemetryService.TrackOrganizationTransformInitiated(accountToTransform); // sign out pending organization and prompt for admin sign in OwinContext.Authentication.SignOut(); TempData[Constants.ReturnUrlMessageViewDataKey] = String.Format(CultureInfo.CurrentCulture, Strings.TransformAccount_SignInToConfirm, adminUser.Username, accountToTransform.Username); return(Redirect(Url.LogOn(returnUrl))); }
private HttpStatusCodeWithBodyResult GetHttpResultFromFailedApiScopeEvaluationHelper(ApiScopeEvaluationResult result, string id, NuGetVersion version, HttpStatusCode statusCodeOnFailure) { if (result.IsSuccessful()) { throw new ArgumentException($"{nameof(result)} is not a failed evaluation!", nameof(result)); } if (result.PermissionsCheckResult == PermissionsCheckResult.ReservedNamespaceFailure) { // We return a special error code for reserved namespace failures. TelemetryService.TrackPackagePushNamespaceConflictEvent(id, version.ToNormalizedString(), GetCurrentUser(), User.Identity); return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Conflict, Strings.UploadPackage_IdNamespaceConflict)); } return(new HttpStatusCodeWithBodyResult(statusCodeOnFailure, Strings.ApiKeyNotAuthorized)); }
public async virtual Task <ActionResult> VerifyPackageKeyAsync(string id, string version) { var user = GetCurrentUser(); var credential = GetCurrentCredential(user); var result = VerifyPackageKeyInternal(user, credential, id, version); // Expire and delete verification key after first use to avoid growing the database tables. if (CredentialTypes.IsPackageVerificationApiKey(credential.Type)) { await AuthenticationService.RemoveCredential(user, credential); } TelemetryService.TrackVerifyPackageKeyEvent(id, version, user, User.Identity, result?.StatusCode ?? 200); return((ActionResult)result ?? new EmptyResult()); }
public async virtual Task <ActionResult> CreatePackageVerificationKeyAsync(string id, string version) { // For backwards compatibility, we must preserve existing behavior where the client always pushes // symbols and the VerifyPackageKey callback returns the appropriate response. For this reason, we // always create a temp key scoped to the unverified package ID here and defer package and owner // validation until the VerifyPackageKey call. var credential = CredentialBuilder.CreatePackageVerificationApiKey(id); var user = GetCurrentUser(); await AuthenticationService.AddCredential(user, credential); TelemetryService.TrackCreatePackageVerificationKeyEvent(id, version, user, User.Identity); return(Json(new { Key = credential.Value, Expires = credential.Expires.Value.ToString("O") })); }
public async Task <ActionResult> Add(AddOrganizationViewModel model) { var organizationName = model.OrganizationName; var organizationEmailAddress = model.OrganizationEmailAddress; var adminUser = GetCurrentUser(); try { var organization = await UserService.AddOrganizationAsync(organizationName, organizationEmailAddress, adminUser); SendNewAccountEmail(organization); TelemetryService.TrackOrganizationAdded(organization); return(RedirectToAction(nameof(ManageOrganization), new { accountName = organization.Username })); } catch (EntityException e) { TempData["AddOrganizationErrorMessage"] = e.Message; return(View(model)); } }
public override async Task <ActionResult> RequestAccountDeletion(string accountName = null) { var user = GetAccount(accountName); if (user == null || user.IsDeleted) { return(HttpNotFound()); } TelemetryService.TrackRequestForAccountDeletion(user); if (!user.Confirmed) { // Unconfirmed users can be deleted immediately without creating a support request. DeleteUserAccountStatus accountDeleteStatus = await _deleteAccountService.DeleteAccountAsync(userToBeDeleted : user, userToExecuteTheDelete : user, orphanPackagePolicy : AccountDeletionOrphanPackagePolicy.UnlistOrphans, commitAsTransaction : true); if (!accountDeleteStatus.Success) { TempData["RequestFailedMessage"] = Strings.AccountSelfDelete_Fail; return(RedirectToAction("DeleteRequest")); } OwinContext.Authentication.SignOut(); return(SafeRedirect(Url.Home(false))); } var isSupportRequestCreated = await _supportRequestService.TryAddDeleteSupportRequestAsync(user); if (isSupportRequestCreated) { var emailMessage = new AccountDeleteNoticeMessage(MessageServiceConfiguration, user); await MessageService.SendMessageAsync(emailMessage); } else { TempData["RequestFailedMessage"] = Strings.AccountDelete_CreateSupportRequestFails; } return(RedirectToAction(nameof(DeleteRequest))); }
public virtual async Task <ActionResult> CancelTransformToOrganization(string token) { var accountToTransform = GetCurrentUser(); var adminUser = accountToTransform.OrganizationMigrationRequest?.AdminUser; if (await UserService.CancelTransformUserToOrganizationRequest(accountToTransform, token)) { MessageService.SendOrganizationTransformRequestCancelledNotice(accountToTransform, adminUser); TelemetryService.TrackOrganizationTransformCancelled(accountToTransform); TempData["Message"] = String.Format(CultureInfo.CurrentCulture, Strings.TransformAccount_Cancelled); } else { TempData["ErrorMessage"] = Strings.TransformAccount_FailedMissingRequestToCancel; } return(RedirectToAction(actionName: "Home", controllerName: "Pages")); }
public override async Task <ActionResult> RequestAccountDeletion(string accountName = null) { var user = GetAccount(accountName); if (user == null || user.IsDeleted) { return(HttpNotFound()); } TelemetryService.TrackRequestForAccountDeletion(user); if (_config.SelfServiceAccountDeleteEnabled && _featureFlagService.IsSelfServiceAccountDeleteEnabled()) { return(await DeleteAndCheckSuccess(user)); } else { if (!user.Confirmed) { // Unconfirmed users can be deleted immediately without creating a support request. return(await DeleteAndCheckSuccess(user)); } var isSupportRequestCreated = await _supportRequestService.TryAddDeleteSupportRequestAsync(user); if (isSupportRequestCreated) { var emailMessage = new AccountDeleteNoticeMessage(MessageServiceConfiguration, user); await MessageService.SendMessageAsync(emailMessage); return(RedirectToAction(nameof(DeleteRequest))); } else { TempData["RequestFailedMessage"] = Strings.AccountDelete_CreateSupportRequestFails; return(RedirectToAction(nameof(DeleteRequest))); } } }
public async virtual Task <ActionResult> VerifyPackageKeyAsync(string id, string version) { var policyResult = await SecurityPolicyService.EvaluateAsync(SecurityPolicyAction.PackageVerify, HttpContext); if (!policyResult.Success) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, policyResult.ErrorMessage)); } var user = GetCurrentUser(); var credential = user.GetCurrentApiKeyCredential(User.Identity); var result = await VerifyPackageKeyInternalAsync(user, credential, id, version); // Expire and delete verification key after first use to avoid growing the database tables. if (CredentialTypes.IsPackageVerificationApiKey(credential.Type)) { await AuthenticationService.RemoveCredential(user, credential); } TelemetryService.TrackVerifyPackageKeyEvent(id, version, user, User.Identity, result?.StatusCode ?? 200); return((ActionResult)result ?? new EmptyResult()); }
private async Task <ActionResult> CreatePackageInternal() { var policyResult = await SecurityPolicyService.EvaluateAsync(SecurityPolicyAction.PackagePush, HttpContext); if (!policyResult.Success) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, policyResult.ErrorMessage)); } // Get the user var currentUser = GetCurrentUser(); using (var packageStream = ReadPackageFromRequest()) { try { using (var archive = new ZipArchive(packageStream, ZipArchiveMode.Read, leaveOpen: true)) { var reference = DateTime.UtcNow.AddDays(1); // allow "some" clock skew var entryInTheFuture = archive.Entries.FirstOrDefault( e => e.LastWriteTime.UtcDateTime > reference); if (entryInTheFuture != null) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format( CultureInfo.CurrentCulture, Strings.PackageEntryFromTheFuture, entryInTheFuture.Name))); } } using (var packageToPush = new PackageArchiveReader(packageStream, leaveStreamOpen: false)) { try { PackageService.EnsureValid(packageToPush); } catch (Exception ex) { ex.Log(); var message = Strings.FailedToReadUploadFile; if (ex is InvalidPackageException || ex is InvalidDataException || ex is EntityException) { message = ex.Message; } return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, message)); } NuspecReader nuspec; var errors = ManifestValidator.Validate(packageToPush.GetNuspec(), out nuspec).ToArray(); if (errors.Length > 0) { var errorsString = string.Join("', '", errors.Select(error => error.ErrorMessage)); return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format( CultureInfo.CurrentCulture, errors.Length > 1 ? Strings.UploadPackage_InvalidNuspecMultiple : Strings.UploadPackage_InvalidNuspec, errorsString))); } if (nuspec.GetMinClientVersion() > Constants.MaxSupportedMinClientVersion) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format( CultureInfo.CurrentCulture, Strings.UploadPackage_MinClientVersionOutOfRange, nuspec.GetMinClientVersion()))); } User owner; // Ensure that the user can push packages for this partialId. var id = nuspec.GetId(); var version = nuspec.GetVersion(); var packageRegistration = PackageService.FindPackageRegistrationById(id); if (packageRegistration == null) { // Check if the current user's scopes allow pushing a new package ID var apiScopeEvaluationResult = EvaluateApiScope(ActionsRequiringPermissions.UploadNewPackageId, new ActionOnNewPackageContext(id, ReservedNamespaceService), NuGetScopes.PackagePush); owner = apiScopeEvaluationResult.Owner; if (!apiScopeEvaluationResult.IsSuccessful()) { // User cannot push a new package ID as the current user's scopes does not allow it return(GetHttpResultFromFailedApiScopeEvaluationForPush(apiScopeEvaluationResult, id, version)); } } else { // Check if the current user's scopes allow pushing a new version of an existing package ID var apiScopeEvaluationResult = EvaluateApiScope(ActionsRequiringPermissions.UploadNewPackageVersion, packageRegistration, NuGetScopes.PackagePushVersion, NuGetScopes.PackagePush); owner = apiScopeEvaluationResult.Owner; if (!apiScopeEvaluationResult.IsSuccessful()) { // User cannot push a package as the current user's scopes does not allow it await AuditingService.SaveAuditRecordAsync( new FailedAuthenticatedOperationAuditRecord( currentUser.Username, AuditedAuthenticatedOperationAction.PackagePushAttemptByNonOwner, attemptedPackage : new AuditedPackageIdentifier( id, version.ToNormalizedStringSafe()))); return(GetHttpResultFromFailedApiScopeEvaluationForPush(apiScopeEvaluationResult, id, version)); } if (packageRegistration.IsLocked) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.Forbidden, string.Format(CultureInfo.CurrentCulture, Strings.PackageIsLocked, packageRegistration.Id))); } // Check if a particular Id-Version combination already exists. We eventually need to remove this check. string normalizedVersion = version.ToNormalizedString(); bool packageExists = packageRegistration.Packages.Any( p => string.Equals( p.NormalizedVersion, normalizedVersion, StringComparison.OrdinalIgnoreCase)); if (packageExists) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.Conflict, string.Format(CultureInfo.CurrentCulture, Strings.PackageExistsAndCannotBeModified, id, nuspec.GetVersion().ToNormalizedStringSafe()))); } } var packageStreamMetadata = new PackageStreamMetadata { HashAlgorithm = Constants.Sha512HashAlgorithmId, Hash = CryptographyService.GenerateHash(packageStream.AsSeekableStream()), Size = packageStream.Length }; var package = await PackageUploadService.GeneratePackageAsync( id, packageToPush, packageStreamMetadata, owner, currentUser); await AutoCuratePackage.ExecuteAsync(package, packageToPush, commitChanges : false); PackageCommitResult commitResult; using (Stream uploadStream = packageStream) { uploadStream.Position = 0; commitResult = await PackageUploadService.CommitPackageAsync( package, uploadStream.AsSeekableStream()); } switch (commitResult) { case PackageCommitResult.Success: break; case PackageCommitResult.Conflict: return(new HttpStatusCodeWithBodyResult( HttpStatusCode.Conflict, Strings.UploadPackage_IdVersionConflict)); default: throw new NotImplementedException($"The package commit result {commitResult} is not supported."); } IndexingService.UpdatePackage(package); // Write an audit record await AuditingService.SaveAuditRecordAsync( new PackageAuditRecord(package, AuditedPackageAction.Create, PackageCreatedVia.Api)); if (!(ConfigurationService.Current.AsynchronousPackageValidationEnabled && ConfigurationService.Current.BlockingAsynchronousPackageValidationEnabled)) { // Notify user of push unless async validation in blocking mode is used MessageService.SendPackageAddedNotice(package, Url.Package(package.PackageRegistration.Id, package.NormalizedVersion, relativeUrl: false), Url.ReportPackage(package.PackageRegistration.Id, package.NormalizedVersion, relativeUrl: false), Url.AccountSettings(relativeUrl: false)); } TelemetryService.TrackPackagePushEvent(package, currentUser, User.Identity); if (package.SemVerLevelKey == SemVerLevelKey.SemVer2) { return(new HttpStatusCodeWithServerWarningResult(HttpStatusCode.Created, Strings.WarningSemVer2PackagePushed)); } return(new HttpStatusCodeResult(HttpStatusCode.Created)); } } catch (InvalidPackageException ex) { return(BadRequestForExceptionMessage(ex)); } catch (InvalidDataException ex) { return(BadRequestForExceptionMessage(ex)); } catch (EntityException ex) { return(BadRequestForExceptionMessage(ex)); } catch (FrameworkException ex) { return(BadRequestForExceptionMessage(ex)); } } }
protected override void Load(ContainerBuilder builder) { var services = new ServiceCollection(); var configuration = new ConfigurationService(); var secretReaderFactory = new SecretReaderFactory(configuration); var secretReader = secretReaderFactory.CreateSecretReader(); var secretInjector = secretReaderFactory.CreateSecretInjector(secretReader); builder.RegisterInstance(secretInjector) .AsSelf() .As <ISecretInjector>() .SingleInstance(); configuration.SecretInjector = secretInjector; // Register the ILoggerFactory and configure it to use AppInsights if an instrumentation key is provided. var instrumentationKey = configuration.Current.AppInsightsInstrumentationKey; if (!string.IsNullOrEmpty(instrumentationKey)) { TelemetryConfiguration.Active.InstrumentationKey = instrumentationKey; } var loggerConfiguration = LoggingSetup.CreateDefaultLoggerConfiguration(withConsoleLogger: false); var loggerFactory = LoggingSetup.CreateLoggerFactory(loggerConfiguration); var telemetryClient = TelemetryClientWrapper.Instance; builder.RegisterInstance(telemetryClient) .AsSelf() .As <ITelemetryClient>() .SingleInstance(); var diagnosticsService = new DiagnosticsService(telemetryClient); builder.RegisterInstance(diagnosticsService) .AsSelf() .As <IDiagnosticsService>() .SingleInstance(); services.AddSingleton(loggerFactory); services.AddSingleton(typeof(ILogger <>), typeof(Logger <>)); UrlHelperExtensions.SetConfigurationService(configuration); builder.RegisterInstance(configuration) .AsSelf() .As <IGalleryConfigurationService>(); builder.Register(c => configuration.Current) .AsSelf() .AsImplementedInterfaces(); // Force the read of this configuration, so it will be initialized on startup builder.Register(c => configuration.Features) .AsSelf() .As <FeatureConfiguration>(); builder.Register(c => configuration.PackageDelete) .As <IPackageDeleteConfiguration>(); var telemetryService = new TelemetryService(diagnosticsService, telemetryClient); builder.RegisterInstance(telemetryService) .AsSelf() .As <ITelemetryService>() .As <IFeatureFlagTelemetryService>() .SingleInstance(); builder.RegisterType <CredentialBuilder>().As <ICredentialBuilder>().SingleInstance(); builder.RegisterType <CredentialValidator>().As <ICredentialValidator>().SingleInstance(); builder.RegisterInstance(LuceneCommon.GetDirectory(configuration.Current.LuceneIndexLocation)) .As <Lucene.Net.Store.Directory>() .SingleInstance(); ConfigureResilientSearch(loggerFactory, configuration, telemetryService, services); ConfigureSearch(builder, configuration); builder.RegisterType <DateTimeProvider>().AsSelf().As <IDateTimeProvider>().SingleInstance(); builder.RegisterType <HttpContextCacheService>() .AsSelf() .As <ICacheService>() .InstancePerLifetimeScope(); var galleryDbConnectionFactory = CreateDbConnectionFactory( diagnosticsService, nameof(EntitiesContext), configuration.Current.SqlConnectionString, secretInjector); builder.RegisterInstance(galleryDbConnectionFactory) .AsSelf() .As <ISqlConnectionFactory>() .SingleInstance(); builder.Register(c => new EntitiesContext(CreateDbConnection(galleryDbConnectionFactory), configuration.Current.ReadOnlyMode)) .AsSelf() .As <IEntitiesContext>() .As <DbContext>() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <User> >() .AsSelf() .As <IEntityRepository <User> >() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <ReservedNamespace> >() .AsSelf() .As <IEntityRepository <ReservedNamespace> >() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <PackageRegistration> >() .AsSelf() .As <IEntityRepository <PackageRegistration> >() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <Package> >() .AsSelf() .As <IEntityRepository <Package> >() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <PackageDependency> >() .AsSelf() .As <IEntityRepository <PackageDependency> >() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <PackageDelete> >() .AsSelf() .As <IEntityRepository <PackageDelete> >() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <Certificate> >() .AsSelf() .As <IEntityRepository <Certificate> >() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <AccountDelete> >() .AsSelf() .As <IEntityRepository <AccountDelete> >() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <Credential> >() .AsSelf() .As <IEntityRepository <Credential> >() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <Scope> >() .AsSelf() .As <IEntityRepository <Scope> >() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <PackageOwnerRequest> >() .AsSelf() .As <IEntityRepository <PackageOwnerRequest> >() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <Organization> >() .AsSelf() .As <IEntityRepository <Organization> >() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <SymbolPackage> >() .AsSelf() .As <IEntityRepository <SymbolPackage> >() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <PackageDeprecation> >() .AsSelf() .As <IEntityRepository <PackageDeprecation> >() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <Cve> >() .AsSelf() .As <IEntityRepository <Cve> >() .InstancePerLifetimeScope(); builder.RegisterType <EntityRepository <Cwe> >() .AsSelf() .As <IEntityRepository <Cwe> >() .InstancePerLifetimeScope(); var supportDbConnectionFactory = CreateDbConnectionFactory( diagnosticsService, nameof(SupportRequestDbContext), configuration.Current.SqlConnectionStringSupportRequest, secretInjector); builder.Register(c => new SupportRequestDbContext(CreateDbConnection(supportDbConnectionFactory))) .AsSelf() .As <ISupportRequestDbContext>() .InstancePerLifetimeScope(); builder.RegisterType <SupportRequestService>() .AsSelf() .As <ISupportRequestService>() .InstancePerLifetimeScope(); builder.RegisterType <UserService>() .AsSelf() .As <IUserService>() .InstancePerLifetimeScope(); builder.RegisterType <PackageService>() .AsSelf() .As <IPackageService>() .InstancePerLifetimeScope(); builder.RegisterType <PackageDeleteService>() .AsSelf() .As <IPackageDeleteService>() .InstancePerLifetimeScope(); builder.RegisterType <DeleteAccountService>() .AsSelf() .As <IDeleteAccountService>() .InstancePerLifetimeScope(); builder.RegisterType <PackageOwnerRequestService>() .AsSelf() .As <IPackageOwnerRequestService>() .InstancePerLifetimeScope(); builder.RegisterType <FormsAuthenticationService>() .As <IFormsAuthenticationService>() .InstancePerLifetimeScope(); builder.RegisterType <CookieTempDataProvider>() .As <ITempDataProvider>() .InstancePerLifetimeScope(); builder.RegisterType <StatusService>() .AsSelf() .As <IStatusService>() .InstancePerLifetimeScope(); builder.RegisterType <SecurityPolicyService>() .AsSelf() .As <ISecurityPolicyService>() .InstancePerLifetimeScope(); builder.RegisterType <ReservedNamespaceService>() .AsSelf() .As <IReservedNamespaceService>() .InstancePerLifetimeScope(); builder.RegisterType <SymbolPackageService>() .AsSelf() .As <ISymbolPackageService>() .InstancePerLifetimeScope(); builder.RegisterType <PackageUploadService>() .AsSelf() .As <IPackageUploadService>() .InstancePerLifetimeScope(); builder.RegisterType <SymbolPackageUploadService>() .AsSelf() .As <ISymbolPackageUploadService>() .InstancePerLifetimeScope(); builder.RegisterType <PackageOwnershipManagementService>() .AsSelf() .As <IPackageOwnershipManagementService>() .InstancePerLifetimeScope(); builder.RegisterType <ValidationService>() .AsSelf() .As <IValidationService>() .InstancePerLifetimeScope(); builder.RegisterType <ReadMeService>() .AsSelf() .As <IReadMeService>() .InstancePerLifetimeScope(); builder.RegisterType <ApiScopeEvaluator>() .AsSelf() .As <IApiScopeEvaluator>() .InstancePerLifetimeScope(); builder.RegisterType <ContentObjectService>() .AsSelf() .As <IContentObjectService>() .SingleInstance(); builder.RegisterType <CertificateValidator>() .AsSelf() .As <ICertificateValidator>() .SingleInstance(); builder.RegisterType <CertificateService>() .AsSelf() .As <ICertificateService>() .InstancePerLifetimeScope(); builder.RegisterType <TyposquattingService>() .AsSelf() .As <ITyposquattingService>() .InstancePerLifetimeScope(); builder.RegisterType <TyposquattingCheckListCacheService>() .AsSelf() .As <ITyposquattingCheckListCacheService>() .SingleInstance(); builder.Register <ServiceDiscoveryClient>(c => new ServiceDiscoveryClient(c.Resolve <IAppConfiguration>().ServiceDiscoveryUri)) .As <IServiceDiscoveryClient>(); builder.RegisterType <LicenseExpressionSplitter>() .As <ILicenseExpressionSplitter>() .InstancePerLifetimeScope(); builder.RegisterType <LicenseExpressionParser>() .As <ILicenseExpressionParser>() .InstancePerLifetimeScope(); builder.RegisterType <LicenseExpressionSegmentator>() .As <ILicenseExpressionSegmentator>() .InstancePerLifetimeScope(); builder.RegisterType <PackageDeprecationService>() .As <IPackageDeprecationService>() .InstancePerLifetimeScope(); RegisterFeatureFlagsService(builder, configuration); RegisterMessagingService(builder, configuration); builder.Register(c => HttpContext.Current.User) .AsSelf() .As <IPrincipal>() .InstancePerLifetimeScope(); IAuditingService defaultAuditingService = null; switch (configuration.Current.StorageType) { case StorageType.FileSystem: case StorageType.NotSpecified: ConfigureForLocalFileSystem(builder, configuration); defaultAuditingService = GetAuditingServiceForLocalFileSystem(configuration); break; case StorageType.AzureStorage: ConfigureForAzureStorage(builder, configuration, telemetryClient); defaultAuditingService = GetAuditingServiceForAzureStorage(builder, configuration); break; } RegisterAsynchronousValidation(builder, diagnosticsService, configuration, secretInjector); RegisterAuditingServices(builder, defaultAuditingService); RegisterCookieComplianceService(builder, configuration, diagnosticsService); builder.RegisterType <MicrosoftTeamSubscription>() .AsSelf() .InstancePerLifetimeScope(); if (configuration.Current.Environment == GalleryConstants.DevelopmentEnvironment) { builder.RegisterType <AllowLocalHttpRedirectPolicy>() .As <ISourceDestinationRedirectPolicy>() .InstancePerLifetimeScope(); } else { builder.RegisterType <NoLessSecureDestinationRedirectPolicy>() .As <ISourceDestinationRedirectPolicy>() .InstancePerLifetimeScope(); } ConfigureAutocomplete(builder, configuration); builder.Populate(services); }
private async Task <ActionResult> CreatePackageInternal() { var policyResult = await SecurityPolicyService.EvaluateAsync(SecurityPolicyAction.PackagePush, HttpContext); if (!policyResult.Success) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, policyResult.ErrorMessage)); } // Get the user var user = GetCurrentUser(); using (var packageStream = ReadPackageFromRequest()) { try { using (var archive = new ZipArchive(packageStream, ZipArchiveMode.Read, leaveOpen: true)) { var reference = DateTime.UtcNow.AddDays(1); // allow "some" clock skew var entryInTheFuture = archive.Entries.FirstOrDefault( e => e.LastWriteTime.UtcDateTime > reference); if (entryInTheFuture != null) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format( CultureInfo.CurrentCulture, Strings.PackageEntryFromTheFuture, entryInTheFuture.Name))); } } using (var packageToPush = new PackageArchiveReader(packageStream, leaveStreamOpen: false)) { try { PackageService.EnsureValid(packageToPush); } catch (Exception ex) { ex.Log(); var message = Strings.FailedToReadUploadFile; if (ex is InvalidPackageException || ex is InvalidDataException || ex is EntityException) { message = ex.Message; } return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, message)); } NuspecReader nuspec; var errors = ManifestValidator.Validate(packageToPush.GetNuspec(), out nuspec).ToArray(); if (errors.Length > 0) { var errorsString = string.Join("', '", errors.Select(error => error.ErrorMessage)); return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format( CultureInfo.CurrentCulture, errors.Length > 1 ? Strings.UploadPackage_InvalidNuspecMultiple : Strings.UploadPackage_InvalidNuspec, errorsString))); } if (nuspec.GetMinClientVersion() > Constants.MaxSupportedMinClientVersion) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format( CultureInfo.CurrentCulture, Strings.UploadPackage_MinClientVersionOutOfRange, nuspec.GetMinClientVersion()))); } // Ensure that the user can push packages for this partialId. var packageRegistration = PackageService.FindPackageRegistrationById(nuspec.GetId()); if (packageRegistration == null) { // Check if API key allows pushing a new package id if (!ApiKeyScopeAllows( subject: nuspec.GetId(), requestedActions: NuGetScopes.PackagePush)) { // User cannot push a new package ID as the API key scope does not allow it return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Unauthorized, Strings.ApiKeyNotAuthorized)); } } else { // Is the user allowed to push this Id? if (!packageRegistration.IsOwner(user)) { // Audit that a non-owner tried to push the package await AuditingService.SaveAuditRecordAsync( new FailedAuthenticatedOperationAuditRecord( user.Username, AuditedAuthenticatedOperationAction.PackagePushAttemptByNonOwner, attemptedPackage : new AuditedPackageIdentifier( nuspec.GetId(), nuspec.GetVersion().ToNormalizedStringSafe()))); // User cannot push a package to an ID owned by another user. return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Conflict, string.Format(CultureInfo.CurrentCulture, Strings.PackageIdNotAvailable, nuspec.GetId()))); } // Check if API key allows pushing the current package id if (!ApiKeyScopeAllows( packageRegistration.Id, NuGetScopes.PackagePushVersion, NuGetScopes.PackagePush)) { // User cannot push a package as the API key scope does not allow it return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Unauthorized, Strings.ApiKeyNotAuthorized)); } // Check if a particular Id-Version combination already exists. We eventually need to remove this check. string normalizedVersion = nuspec.GetVersion().ToNormalizedString(); bool packageExists = packageRegistration.Packages.Any( p => string.Equals( p.NormalizedVersion, normalizedVersion, StringComparison.OrdinalIgnoreCase)); if (packageExists) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.Conflict, string.Format(CultureInfo.CurrentCulture, Strings.PackageExistsAndCannotBeModified, nuspec.GetId(), nuspec.GetVersion().ToNormalizedStringSafe()))); } } var packageStreamMetadata = new PackageStreamMetadata { HashAlgorithm = Constants.Sha512HashAlgorithmId, Hash = CryptographyService.GenerateHash(packageStream.AsSeekableStream()), Size = packageStream.Length }; var package = await PackageService.CreatePackageAsync( packageToPush, packageStreamMetadata, user, commitChanges : false); await AutoCuratePackage.ExecuteAsync(package, packageToPush, commitChanges : false); using (Stream uploadStream = packageStream) { uploadStream.Position = 0; try { await PackageFileService.SavePackageFileAsync(package, uploadStream.AsSeekableStream()); } catch (InvalidOperationException ex) { ex.Log(); return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Conflict, Strings.UploadPackage_IdVersionConflict)); } } try { await EntitiesContext.SaveChangesAsync(); } catch { // If saving to the DB fails for any reason, we need to delete the package we just saved. await PackageFileService.DeletePackageFileAsync(nuspec.GetId(), nuspec.GetVersion().ToNormalizedString()); throw; } IndexingService.UpdatePackage(package); // Write an audit record await AuditingService.SaveAuditRecordAsync( new PackageAuditRecord(package, AuditedPackageAction.Create, PackageCreatedVia.Api)); // Notify user of push MessageService.SendPackageAddedNotice(package, Url.Action("DisplayPackage", "Packages", routeValues: new { id = package.PackageRegistration.Id, version = package.NormalizedVersion }, protocol: Request.Url.Scheme), Url.Action("ReportMyPackage", "Packages", routeValues: new { id = package.PackageRegistration.Id, version = package.NormalizedVersion }, protocol: Request.Url.Scheme), Url.Action("Account", "Users", routeValues: null, protocol: Request.Url.Scheme)); TelemetryService.TrackPackagePushEvent(package, user, User.Identity); return(new HttpStatusCodeResult(HttpStatusCode.Created)); } } catch (InvalidPackageException ex) { return(BadRequestForExceptionMessage(ex)); } catch (InvalidDataException ex) { return(BadRequestForExceptionMessage(ex)); } catch (EntityException ex) { return(BadRequestForExceptionMessage(ex)); } catch (FrameworkException ex) { return(BadRequestForExceptionMessage(ex)); } } }