示例#1
0
        private static PackageSecurityPolicyEvaluationContext CreateTestContext(
            bool microsoftUserExists,
            IEnumerable <UserSecurityPolicy> policies,
            Package package,
            bool packageRegistrationAlreadyExists,
            IPackageOwnershipManagementService packageOwnershipManagementService = null,
            IReservedNamespaceService reservedNamespaceService = null)
        {
            var userService = new Mock <IUserService>(MockBehavior.Strict);

            if (microsoftUserExists)
            {
                userService
                .Setup(m => m.FindByUsername(MicrosoftTeamSubscription.MicrosoftUsername, false))
                .Returns(Fakes.RequiredCoOwner);
            }
            else
            {
                userService
                .Setup(m => m.FindByUsername(MicrosoftTeamSubscription.MicrosoftUsername, false))
                .Returns((User)null);
            }

            packageOwnershipManagementService = packageOwnershipManagementService ?? new Mock <IPackageOwnershipManagementService>(MockBehavior.Strict).Object;

            var context = new PackageSecurityPolicyEvaluationContext(
                userService.Object,
                packageOwnershipManagementService,
                policies,
                package,
                It.IsAny <HttpContextBase>());

            return(context);
        }
        public async Task Evaluate_DoesNotCommitChangesToEntityContext()
        {
            // Arrange
            var subscription  = new MicrosoftTeamSubscription();
            var policyHandler = new RequirePackageMetadataCompliancePolicy();

            var nugetUser = new User("NuGet");
            var newPackageRegistration = new PackageRegistration {
                Id = "NewPackageId", Owners = new List <User> {
                    nugetUser
                }
            };
            var newMicrosoftCompliantPackage = Fakes.CreateCompliantPackage("1.0", newPackageRegistration);

            var packageOwnershipManagementService = new Mock <IPackageOwnershipManagementService>(MockBehavior.Strict);

            packageOwnershipManagementService
            .Setup(m => m.AddPackageOwnerAsync(newPackageRegistration, It.IsAny <User>(), false /* commitChanges: false */))
            .Returns(Task.CompletedTask)
            .Verifiable();

            var userService = new Mock <IUserService>(MockBehavior.Strict);

            userService
            .Setup(m => m.FindByUsername(MicrosoftTeamSubscription.MicrosoftUsername, It.IsAny <bool>()))
            .Returns(Fakes.RequiredCoOwner)
            .Verifiable();

            var telemetryService = new Mock <ITelemetryService>().Object;

            var context = new PackageSecurityPolicyEvaluationContext(
                userService.Object,
                packageOwnershipManagementService.Object,
                telemetryService,
                subscription.Policies,
                newMicrosoftCompliantPackage,
                sourceAccount: nugetUser,
                targetAccount: nugetUser,
                httpContext: It.IsAny <HttpContextBase>());

            // Act
            var result = await policyHandler.EvaluateAsync(context);

            // Assert
            packageOwnershipManagementService.VerifyAll();
            userService.VerifyAll();
        }
        /// <summary>
        /// Evaluate if this package compliance policy is met.
        /// </summary>
        public override async Task <SecurityPolicyResult> EvaluateAsync(PackageSecurityPolicyEvaluationContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            // This particular package policy assumes the existence of a particular user.
            // Succeed silently (effectively ignoring this policy when enabled) when that user does not exist.
            var state           = GetState(context);
            var requiredCoOwner = context.UserService.FindByUsername(state.RequiredCoOwnerUsername);

            if (requiredCoOwner == null)
            {
                // This may happen on gallery deployments that don't have this particular user.
                return(SecurityPolicyResult.SuccessResult);
            }

            // Evaluate package metadata validations
            if (!IsPackageMetadataCompliant(context.Package, state, out var complianceFailures))
            {
                // Package policy not met.
                return(SecurityPolicyResult.CreateErrorResult(
                           string.Format(
                               CultureInfo.CurrentCulture,
                               state.ErrorMessageFormat,
                               Environment.NewLine + string.Join(Environment.NewLine, complianceFailures))));
            }

            // Automatically add the required co-owner when metadata is compliant.
            if (!context.Package.PackageRegistration.Owners.Select(o => o.Username).Contains(state.RequiredCoOwnerUsername, StringComparer.OrdinalIgnoreCase))
            {
                // This will also mark the package as verified if the prefix has been reserved by the co-owner.
                // The entities context is committed later as a single atomic transaction (see PackageUploadService).
                await context.PackageOwnershipManagementService.AddPackageOwnerAsync(context.Package.PackageRegistration, requiredCoOwner, commitChanges : false);
            }

            // If the PackageRegistration is not marked as verified,
            // the account pushing the package has not registered the prefix yet.
            if (!context.Package.PackageRegistration.IsVerified)
            {
                return(SecurityPolicyResult.CreateWarningResult(Strings.SecurityPolicy_RequirePackagePrefixReserved));
            }

            // All good!
            return(SecurityPolicyResult.SuccessResult);
        }
        private async Task <SecurityPolicyResult> EvaluatePackagePoliciesInternalAsync(
            SecurityPolicyAction action,
            Package package,
            User sourceAccount,
            User targetAccount,
            HttpContextBase httpContext,
            IEnumerable <UserSecurityPolicy> policies = null,
            bool auditSuccess = true)
        {
            policies = policies ?? targetAccount.SecurityPolicies;

            var relevantHandlers = PackageHandlers.Where(h => h.Action == action).ToList();

            var packagePoliciesResult = SecurityPolicyResult.SuccessResult;

            foreach (var handler in relevantHandlers)
            {
                var foundPolicies = policies.Where(p => p.Name.Equals(handler.Name, StringComparison.OrdinalIgnoreCase)).ToList();

                if (foundPolicies.Any())
                {
                    var context = new PackageSecurityPolicyEvaluationContext(
                        _userService.Value,
                        _packageOwnershipManagementService.Value,
                        _telemetryService,
                        foundPolicies,
                        package,
                        sourceAccount,
                        targetAccount,
                        httpContext);

                    var result = await handler.EvaluateAsync(context);

                    if (auditSuccess || !result.Success)
                    {
                        await Auditing.SaveAuditRecordAsync(new UserSecurityPolicyAuditRecord(
                                                                context.TargetAccount.Username, GetAuditAction(action), foundPolicies, result.Success, result.ErrorMessage));
                    }

                    if (!result.Success)
                    {
                        Diagnostics.Information(
                            $"Security policy from subscription '{foundPolicies.First().Subscription}' - '{handler.Name}' failed with error '{result.ErrorMessage}'.");

                        return(result);
                    }

                    if (result.HasWarnings)
                    {
                        if (packagePoliciesResult == SecurityPolicyResult.SuccessResult)
                        {
                            packagePoliciesResult = result;
                        }
                        else
                        {
                            packagePoliciesResult.AddWarnings(result.WarningMessages);
                        }
                    }
                }
            }

            return(packagePoliciesResult);
        }