/// <summary> /// Create member controller to test /// </summary> /// <param name="memberService">Member service</param> /// <param name="memberTypeService">Member type service</param> /// <param name="memberGroupService">Member group service</param> /// <param name="membersUserManager">Members user manager</param> /// <param name="dataTypeService">Data type service</param> /// <param name="backOfficeSecurityAccessor">Back office security accessor</param> /// <param name="mockPasswordChanger">Password changer class</param> /// <returns>A member controller for the tests</returns> private MemberController CreateSut( IMemberService memberService, IMemberTypeService memberTypeService, IMemberGroupService memberGroupService, IUmbracoUserManager <MemberIdentityUser> membersUserManager, IDataTypeService dataTypeService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor, IPasswordChanger <MemberIdentityUser> passwordChanger, IOptions <GlobalSettings> globalSettings, IUser user) { var httpContextAccessor = new HttpContextAccessor(); var mockShortStringHelper = new MockShortStringHelper(); var textService = new Mock <ILocalizedTextService>(); var contentTypeBaseServiceProvider = new Mock <IContentTypeBaseServiceProvider>(); contentTypeBaseServiceProvider.Setup(x => x.GetContentTypeOf(It.IsAny <IContentBase>())).Returns(new ContentType(mockShortStringHelper, 123)); var contentAppFactories = new Mock <List <IContentAppFactory> >(); var mockContentAppFactoryCollection = new Mock <ILogger <ContentAppFactoryCollection> >(); var hybridBackOfficeSecurityAccessor = new BackOfficeSecurityAccessor(httpContextAccessor); var contentAppFactoryCollection = new ContentAppFactoryCollection( () => contentAppFactories.Object, mockContentAppFactoryCollection.Object, hybridBackOfficeSecurityAccessor); var mockUserService = new Mock <IUserService>(); var commonMapper = new CommonMapper( mockUserService.Object, contentTypeBaseServiceProvider.Object, contentAppFactoryCollection, textService.Object); var mockCultureDictionary = new Mock <ICultureDictionary>(); var mockPasswordConfig = new Mock <IOptions <MemberPasswordConfigurationSettings> >(); mockPasswordConfig.Setup(x => x.Value).Returns(() => new MemberPasswordConfigurationSettings()); IDataEditor dataEditor = Mock.Of <IDataEditor>( x => x.Type == EditorType.PropertyValue && x.Alias == Constants.PropertyEditors.Aliases.Label); Mock.Get(dataEditor).Setup(x => x.GetValueEditor()).Returns(new TextOnlyValueEditor(new DataEditorAttribute(Constants.PropertyEditors.Aliases.TextBox, "Test Textbox", "textbox"), textService.Object, Mock.Of <IShortStringHelper>(), Mock.Of <IJsonSerializer>(), Mock.Of <IIOHelper>())); var propertyEditorCollection = new PropertyEditorCollection(new DataEditorCollection(() => new[] { dataEditor })); IMapDefinition memberMapDefinition = new MemberMapDefinition( commonMapper, new CommonTreeNodeMapper(Mock.Of <LinkGenerator>()), new MemberTabsAndPropertiesMapper( mockCultureDictionary.Object, backOfficeSecurityAccessor, textService.Object, memberTypeService, memberService, memberGroupService, mockPasswordConfig.Object, contentTypeBaseServiceProvider.Object, propertyEditorCollection)); var map = new MapDefinitionCollection(() => new List <IMapDefinition>() { new global::Umbraco.Cms.Core.Models.Mapping.MemberMapDefinition(), memberMapDefinition, new ContentTypeMapDefinition( commonMapper, propertyEditorCollection, dataTypeService, new Mock <IFileService>().Object, new Mock <IContentTypeService>().Object, new Mock <IMediaTypeService>().Object, memberTypeService, new Mock <ILoggerFactory>().Object, mockShortStringHelper, globalSettings, new Mock <IHostingEnvironment>().Object) }); var scopeProvider = Mock.Of <IScopeProvider>(x => x.CreateScope( It.IsAny <IsolationLevel>(), It.IsAny <RepositoryCacheMode>(), It.IsAny <IEventDispatcher>(), It.IsAny <IScopedNotificationPublisher>(), It.IsAny <bool?>(), It.IsAny <bool>(), It.IsAny <bool>()) == Mock.Of <IScope>()); _mapper = new UmbracoMapper(map, scopeProvider); return(new MemberController( new DefaultCultureDictionary( new Mock <ILocalizationService>().Object, NoAppCache.Instance), new LoggerFactory(), mockShortStringHelper, new DefaultEventMessagesFactory( new Mock <IEventMessagesAccessor>().Object), textService.Object, propertyEditorCollection, _mapper, memberService, memberTypeService, (IMemberManager)membersUserManager, dataTypeService, backOfficeSecurityAccessor, new ConfigurationEditorJsonSerializer(), passwordChanger, scopeProvider )); }
/// <summary> /// Changes the password for a user based on the many different rules and config options /// </summary> /// <param name="changingPasswordModel">The changing password model</param> /// <param name="userMgr">The identity manager to use to update the password</param> /// Create an adapter to pass through everything - adapting the member into a user for this functionality /// <returns>The outcome of the password changed model</returns> public async Task <Attempt <PasswordChangedModel> > ChangePasswordWithIdentityAsync( ChangingPasswordModel changingPasswordModel, IUmbracoUserManager <TUser> userMgr) { if (changingPasswordModel == null) { throw new ArgumentNullException(nameof(changingPasswordModel)); } if (userMgr == null) { throw new ArgumentNullException(nameof(userMgr)); } if (changingPasswordModel.NewPassword.IsNullOrWhiteSpace()) { return(Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Cannot set an empty password", new[] { "value" }) })); } var userId = changingPasswordModel.Id.ToString(); TUser identityUser = await userMgr.FindByIdAsync(userId); if (identityUser == null) { // this really shouldn't ever happen... but just in case return(Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Password could not be verified", new[] { "oldPassword" }) })); } // Are we just changing another user/member's password? if (changingPasswordModel.OldPassword.IsNullOrWhiteSpace()) { // ok, we should be able to reset it string resetToken = await userMgr.GeneratePasswordResetTokenAsync(identityUser); IdentityResult resetResult = await userMgr.ChangePasswordWithResetAsync(userId, resetToken, changingPasswordModel.NewPassword); if (resetResult.Succeeded == false) { string errors = resetResult.Errors.ToErrorMessage(); _logger.LogWarning("Could not reset user password {PasswordErrors}", errors); return(Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult(errors, new[] { "value" }) })); } return(Attempt.Succeed(new PasswordChangedModel())); } // is the old password correct? bool validateResult = await userMgr.CheckPasswordAsync(identityUser, changingPasswordModel.OldPassword); if (validateResult == false) { // no, fail with an error message for "oldPassword" return(Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Incorrect password", new[] { "oldPassword" }) })); } // can we change to the new password? IdentityResult changeResult = await userMgr.ChangePasswordAsync(identityUser, changingPasswordModel.OldPassword, changingPasswordModel.NewPassword); if (changeResult.Succeeded == false) { // no, fail with error messages for "password" string errors = changeResult.Errors.ToErrorMessage(); _logger.LogWarning("Could not change user password {PasswordErrors}", errors); return(Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult(errors, new[] { "password" }) })); } return(Attempt.Succeed(new PasswordChangedModel())); }