public async Task ExecuteAsync(InitiateUserAccountRecoveryViaEmailCommand command, IExecutionContext executionContext)
        {
            var options = _userAreaDefinitionRepository.GetOptionsByCode(command.UserAreaCode).AccountRecovery;

            await using (_executionDurationRandomizerScopeManager.Create(options.ExecutionDuration))
            {
                await ExecuteInternalAsync(command, executionContext);
            }
        }
        private AddUserCommand MapCommand(AddUserWithTemporaryPasswordCommand command)
        {
            // The password policy should be configured with the definitive min-length
            // as an attribute, but otherwise fall-back to the configured option
            var passwordPolicy     = _passwordPolicyService.GetDescription(command.UserAreaCode);
            var minLengthAttribute = passwordPolicy.Attributes.GetOrDefault(PasswordPolicyAttributes.MinLength);
            var options            = _userAreaDefinitionRepository.GetOptionsByCode(command.UserAreaCode);
            var minLength          = IntParser.ParseOrDefault(minLengthAttribute, options.Password.MinLength);

            var newUserCommand = new AddUserCommand()
            {
                FirstName             = command.FirstName,
                LastName              = command.LastName,
                DisplayName           = command.DisplayName,
                Email                 = command.Email,
                Username              = command.Username,
                Password              = _passwordGenerationService.Generate(minLength),
                RequirePasswordChange = true,
                UserAreaCode          = command.UserAreaCode,
                RoleId                = command.RoleId,
                RoleCode              = command.RoleCode
            };

            return(newUserCommand);
        }
        public async Task ExecuteAsync(ResetUserPasswordCommand command, IExecutionContext executionContext)
        {
            var user = await GetUserAsync(command.UserId);

            await ValidatePermissionsAsync(user, executionContext);

            ValidateUserArea(user.UserAreaCode);

            var options           = _userAreaDefinitionRepository.GetOptionsByCode(user.UserAreaCode);
            var temporaryPassword = _passwordGenerationService.Generate(options.Password.MinLength);

            var hashResult = _passwordCryptographyService.CreateHash(temporaryPassword);

            user.Password               = hashResult.Hash;
            user.PasswordHashVersion    = hashResult.HashVersion;
            user.RequirePasswordChange  = true;
            user.LastPasswordChangeDate = executionContext.ExecutionDate;
            _userSecurityStampUpdateHelper.Update(user);

            using (var scope = _domainRepository.Transactions().CreateScope())
            {
                await _dbContext.SaveChangesAsync();
                await SendNotificationAsync(user, temporaryPassword, executionContext);

                scope.QueueCompletionTask(() => OnTransactionComplete(user));
                await scope.CompleteAsync();
            }
        }
        public async Task <bool> ExecuteAsync(HasExceededMaxAuthenticationAttemptsQuery query, IExecutionContext executionContext)
        {
            var options = _userAreaDefinitionRepository.GetOptionsByCode(query.UserAreaCode).Authentication;

            if ((options.IPAddressRateLimit == null || !options.IPAddressRateLimit.HasValidQuantityAndWindow()) &&
                (options.UsernameRateLimit == null || !options.UsernameRateLimit.HasValidQuantityAndWindow()))
            {
                return(false);
            }

            var connectionInfo = _clientConnectionService.GetConnectionInfo();

            var isValid = await _userStoredProcedures.IsAuthenticationAttemptValidAsync(
                query.UserAreaCode,
                TextFormatter.Limit(query.Username, 150),
                connectionInfo.IPAddress,
                executionContext.ExecutionDate,
                GetRateLimitQuantityIfValid(options.IPAddressRateLimit),
                RateLimitWindowToSeconds(options.IPAddressRateLimit),
                GetRateLimitQuantityIfValid(options.UsernameRateLimit),
                RateLimitWindowToSeconds(options.UsernameRateLimit)
                );

            return(!isValid);
        }
        public async Task SendPasswordChangedNotification(User user)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            var options = _userAreaDefinitionRepository.GetOptionsByCode(user.UserAreaCode).Password;

            if (!options.SendNotificationOnUpdate)
            {
                return;
            }

            var userSummary         = _userSummaryMapper.Map(user);
            var context             = _userMailTemplateBuilderContextFactory.CreatePasswordChangedContext(userSummary);
            var mailTemplateBuilder = _userMailTemplateBuilderFactory.Create(user.UserAreaCode);
            var mailTemplate        = await mailTemplateBuilder.BuildPasswordChangedTemplateAsync(context);

            // Null template means don't send a notification
            if (mailTemplate == null)
            {
                return;
            }

            await _mailService.SendAsync(user.Email, mailTemplate);
        }
Example #6
0
        /// <summary>
        /// Validates that the email is not shorter then the limit defined in the
        /// <see cref="EmailAddressOptions"/> configuration settings.
        /// </summary>
        protected virtual ValidationError ValidateMinLength(IEmailAddressValidationContext context)
        {
            var options = _userAreaDefinitionRepository.GetOptionsByCode(context.UserAreaCode).EmailAddress;

            if (context.Email.NormalizedEmailAddress.Length >= options.MinLength)
            {
                return(null);
            }

            return(UserValidationErrors
                   .EmailAddress
                   .MinLengthNotMet
                   .Customize()
                   .WithMessageFormatParameters(options.MinLength)
                   .WithProperties(context.PropertyName)
                   .Create());
        }
        public async Task <UserCredentialsAuthenticationResult> ExecuteAsync(AuthenticateUserCredentialsQuery query, IExecutionContext executionContext)
        {
            var options = _userAreaDefinitionRepository.GetOptionsByCode(query.UserAreaCode).Authentication;

            await using (_executionDurationRandomizerScopeManager.Create(options.ExecutionDuration))
            {
                return(await ExecuteInternalAsync(query, executionContext));
            }
        }
        public IAccountRecoveryTemplateBuilderContext CreateAccountRecoveryContext(UserSummary user, string token)
        {
            var definition       = _userAreaDefinitionRepository.GetRequiredByCode(user.UserArea.UserAreaCode);
            var options          = _userAreaDefinitionRepository.GetOptionsByCode(user.UserArea.UserAreaCode).AccountRecovery;
            var isCofoundryAdmin = definition is CofoundryAdminUserArea;

            var context = new AccountRecoveryTemplateBuilderContext()
            {
                User  = user,
                Token = token,
                DefaultTemplateFactory = AccountRecoveryTemplateFactory
            };

            // Can be null to allow a custom IDefaultMailTemplateBuilder implementation to the path explicitly
            if (options.RecoveryUrlBase != null)
            {
                context.RecoveryUrlPath = _authorizedTaskTokenUrlHelper.MakeUrl(options.RecoveryUrlBase, token);
            }

            return(context);
        }
Example #9
0
        private void SetDisplayName(AddUserCommand command, User user)
        {
            var options = _userAreaRepository.GetOptionsByCode(command.UserAreaCode);

            if (options.Username.UseAsDisplayName)
            {
                user.DisplayName = user.Username;
            }
            else
            {
                user.DisplayName = command.DisplayName?.Trim();
            }
        }
        private TimeSpan GetClaimsValidationInterval(CookieValidatePrincipalContext validationContext)
        {
            var userAreaCode = validationContext.Principal.FindFirstValue(CofoundryClaimTypes.UserAreaCode);

            if (!_userAreaDefinitionRepository.Exists(userAreaCode))
            {
                // Invalid or missing user area claim: the cookie should be invalidated immediately
                _logger.LogInformation("Invalid or missing user area claim: {userAreaCode}.", userAreaCode);
                return(TimeSpan.Zero);
            }

            var options = _userAreaDefinitionRepository.GetOptionsByCode(userAreaCode);

            return(options.Cookies.ClaimsValidationInterval);
        }
        public async Task ExecuteAsync(InitiateUserAccountVerificationViaEmailCommand command, IExecutionContext executionContext)
        {
            var user = await GetUserAndVerifyAsync(command);

            var options = _userAreaDefinitionRepository.GetOptionsByCode(user.UserArea.UserAreaCode).AccountVerification;

            using (var scope = _domainRepository.Transactions().CreateScope())
            {
                var addAuthorizedTaskCommand = await GenerateTokenAsync(user, options, executionContext);
                await SendNotificationAsync(addAuthorizedTaskCommand, user);

                scope.QueueCompletionTask(() => OnTransactionComplete(user, addAuthorizedTaskCommand));
                await scope.CompleteAsync();
            }
        }
Example #12
0
        private void UpdateName(UpdateCurrentUserCommand command, User user)
        {
            var options = _userAreaDefinitionRepository.GetOptionsByCode(user.UserAreaCode);

            if (options.Username.UseAsDisplayName)
            {
                user.DisplayName = user.Username;
            }
            else
            {
                user.DisplayName = command.DisplayName?.Trim();
            }

            user.FirstName = command.FirstName?.Trim();
            user.LastName  = command.LastName?.Trim();
        }
        private void ValidateUserCanLogin(User user)
        {
            if (user.RequirePasswordChange)
            {
                UserValidationErrors.Authentication.PasswordChangeRequired.Throw();
            }

            if (!user.AccountVerifiedDate.HasValue)
            {
                var options = _userAreaDefinitionRepository.GetOptionsByCode(user.UserAreaCode);

                if (options.AccountVerification.RequireVerification)
                {
                    UserValidationErrors.Authentication.AccountNotVerified.Throw();
                }
            }
        }
        public ActionResult Index()
        {
            var userArea        = RouteData.DataTokens["UserArea"] as IUserAreaDefinition;
            var userAreaOptions = _userAreaDefinitionRepository.GetOptionsByCode(userArea.UserAreaCode);

            var options = new UsersModuleOptions()
            {
                UserAreaCode        = userArea.UserAreaCode,
                Name                = userArea.Name,
                AllowPasswordSignIn = userArea.AllowPasswordSignIn,
                UseEmailAsUsername  = userArea.UseEmailAsUsername,
                ShowDisplayName     = !userAreaOptions.Username.UseAsDisplayName
            };

            var viewPath = ViewPathFormatter.View("Users", nameof(Index));

            return(View(viewPath, options));
        }
        public IPasswordPolicy Create(IUserAreaDefinition userArea)
        {
            // See if a custom user area configuration has been implemented
            var userAreaConfigurationType = typeof(IPasswordPolicyConfiguration <>).MakeGenericType(userArea.GetType());
            var configuration             = _serviceProvider.GetService(userAreaConfigurationType) as IPasswordPolicyConfigurationBase;

            if (configuration == null)
            {
                // Get Default
                configuration = _serviceProvider.GetRequiredService <IDefaultPasswordPolicyConfiguration>();
            }

            var options = _userAreaDefinitionRepository.GetOptionsByCode(userArea.UserAreaCode);
            var builder = new PasswordPolicyBuilder(_serviceProvider, options.Password);

            configuration.Configure(builder);

            return(builder.Build());
        }
        public string GetNamespace(string userAreaCode)
        {
            var options = _userAreaDefinitionRepository.GetOptionsByCode(userAreaCode).Cookies;

            if (!string.IsNullOrWhiteSpace(options.Namespace))
            {
                return(options.Namespace);
            }

            // Try and build a short and somewhat unique name using the
            // application name, which should suffice for most scenarios.
            var appName = _hostingEnvironment.ApplicationName;

            var reasonablyUniqueName = appName
                                       .Take(3)
                                       .Union(appName.Reverse())
                                       .Take(6);

            return("CFA_" + string.Concat(reasonablyUniqueName));
        }
        public async Task ExecuteAsync()
        {
            foreach (var userArea in _userAreaDefinitionRepository.GetAll())
            {
                var options = _userAreaDefinitionRepository.GetOptionsByCode(userArea.UserAreaCode).Cleanup;

                if (!options.Enabled)
                {
                    return;
                }

                await _domainRepository
                .WithElevatedPermissions()
                .ExecuteCommandAsync(new CleanupUsersCommand()
                {
                    UserAreaCode                         = userArea.UserAreaCode,
                    DefaultRetentionPeriod               = DaysToTimeSpan(options.DefaultRetentionPeriodInDays),
                    AuthenticationLogRetentionPeriod     = DaysToTimeSpan(options.AuthenticationLogRetentionPeriodInDays),
                    AuthenticationFailLogRetentionPeriod = DaysToTimeSpan(options.AuthenticationFailLogRetentionPeriodInDays)
                });
            }
        }
Example #18
0
        private AccountVerificationOptions GetOptions(ValidateUserAccountVerificationByEmailQuery query)
        {
            var options = _userAreaDefinitionRepository.GetOptionsByCode(query.UserAreaCode).AccountVerification;

            return(options);
        }