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)));
        }
示例#2
0
        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());
        }
示例#4
0
        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));
            }
        }
示例#6
0
        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)));
        }
示例#7
0
        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"));
        }
示例#8
0
        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)));
                }
            }
        }
示例#9
0
        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());
        }
示例#10
0
        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);
        }
示例#12
0
        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));
                }
            }
        }