/// <summary> /// Processes a request to update the password for a contact. /// </summary> /// <returns>true if the password was updated successfully; otherwise, false.</returns> /// <param name="username">The contact to update the password for. </param> /// <param name="oldPassword">The current password for the specified contact. </param> /// <param name="newPassword">The new password for the specified contact. </param> /// <exception cref="NotSupportedException">Couldn't change password as the CRM provider is in read-only mode.</exception> /// <exception cref="NotSupportedException">The CRM provider is not configured to store password.</exception> public override bool ChangePassword(string username, string oldPassword, string newPassword) { if (this.initialized) { if (this.ReadOnly) { throw new NotSupportedException("Couldn't change password as the CRM provider is in read-only mode."); } if (String.IsNullOrEmpty(this.PasswordFieldName)) { throw new NotSupportedException("The CRM provider is not configured to store password."); } var password = this.profileRepository.GetUserProperty(username, this.PasswordFieldName) as string; if (String.IsNullOrEmpty(password)) { ConditionalLog.Warn(String.Format("CrmSecurityProvider: user \"{0}\" doesn't have a password. You should reset it before changing.", username), this); return(false); } SHA1Managed sha1 = new SHA1Managed(); byte[] oldPasswordBytes = Encoding.UTF8.GetBytes(oldPassword); byte[] hashedOldPasswordBytes = sha1.ComputeHash(oldPasswordBytes); string hashedOldPassword = System.Convert.ToBase64String(hashedOldPasswordBytes); if (password != hashedOldPassword) { return(false); } if (!IsPasswordValid(newPassword)) { return(false); } byte[] newPasswordBytes = Encoding.UTF8.GetBytes(newPassword); byte[] hashedNewPasswordBytes = sha1.ComputeHash(newPasswordBytes); string hashedNewPassword = System.Convert.ToBase64String(hashedNewPasswordBytes); var properties = new Dictionary <string, object>(); properties.Add(PasswordFieldName, hashedNewPassword); return(this.profileRepository.UpdateUserProperties(username, properties)); } return(false); }
/// <summary> /// Processes a request to update the password question and answer for a contact. /// </summary> /// <returns>true if the password question and answer are updated successfully; otherwise, false.</returns> /// <param name="username">The contact to change the password question and answer for. </param> /// <param name="password">The password for the specified contact. </param> /// <param name="newPasswordQuestion">The new password question for the specified contact. </param> /// <param name="newPasswordAnswer">The new password answer for the specified contact. </param> /// <exception cref="NotSupportedException">Couldn't change password question or(and) password answer as the CRM provider is in read-only mode.</exception> /// <exception cref="NotSupportedException">The CRM provider is not configured to store password.</exception> public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) { if (this.initialized) { if (this.ReadOnly) { throw new NotSupportedException("Couldn't change password question or(and) password answer as the CRM provider is in read-only mode."); } if (String.IsNullOrEmpty(this.PasswordFieldName)) { throw new NotSupportedException("The CRM provider is not configured to store password."); } var validPassword = this.profileRepository.GetUserProperty(username, this.PasswordFieldName) as string; if (String.IsNullOrEmpty(validPassword)) { ConditionalLog.Warn(String.Format("CrmSecurityProvider: user \"{0}\" doesn't have a password.", username), this); return(false); } SHA1Managed sha1 = new SHA1Managed(); byte[] passwordBytes = Encoding.UTF8.GetBytes(password); byte[] hashedPasswordBytes = sha1.ComputeHash(passwordBytes); string hashedPassword = System.Convert.ToBase64String(hashedPasswordBytes); if (validPassword != hashedPassword) { return(false); } var properties = new Dictionary <string, object>(); properties.Add(this.PasswordQuestionFieldName, newPasswordQuestion); properties.Add(this.PasswordAnswerFieldName, newPasswordAnswer); return(this.profileRepository.UpdateUserProperties(username, properties)); } return(false); }
/// <summary> /// Initializes the provider. /// </summary> /// <param name="name">The friendly name of the provider.</param> /// <param name="config">A collection of the name/value pairs representing the provider-specific attributes specified in the configuration for this provider.</param> /// <exception cref="T:System.ArgumentNullException">The name of the provider is null.</exception> /// <exception cref="T:System.ArgumentException">The name of the provider has a length of zero.</exception> /// <exception cref="T:System.InvalidOperationException">An attempt is made to call <see cref="M:System.Configuration.Provider.ProviderBase.Initialize(System.String,System.Collections.Specialized.NameValueCollection)"/> on a provider after the provider has already been initialized.</exception> public override void Initialize(string name, NameValueCollection config) { base.Initialize(name, config); try { Error.AssertLicense("Sitecore.MSCRM", "Microsoft Dynamics CRM security provider."); this.ApplicationName = config["applicationName"]; this.ReadOnly = (String.IsNullOrEmpty(config["readOnly"]) || config["readOnly"] == "true"); this.AutoCreatePasswordField = MainUtil.GetBool(config["autoCreatePasswordField"], false); this.PasswordFieldName = StringUtil.GetString((object)config["passwordFieldName"]); this.minRequiredPasswordLength = MainUtil.GetInt(config["minRequiredPasswordLength"], 7); this.minRequiredNonalphanumericCharacters = MainUtil.GetInt(config["minRequiredNonalphanumericCharacters"], 1); this.maxInvalidPasswordAttempts = MainUtil.GetInt(config["maxInvalidPasswordAttempts"], 5); this.passwordAttemptWindow = MainUtil.GetInt(config["passwordAttemptWindow"], 0); this.passwordStrengthRegularExpression = StringUtil.GetString((object)config["passwordStrengthRegularExpression"]).Trim(); this.requiresUniqueEmail = MainUtil.GetBool(config["requiresUniqueEmail"], false); this.enablePasswordReset = MainUtil.GetBool(config["enablePasswordReset"], true); this.requiresQuestionAndAnswer = MainUtil.GetBool(config["requiresQuestionAndAnswer"], false); if (this.RequiresQuestionAndAnswer) { this.PasswordQuestionFieldName = config["passwordQuestionFieldName"]; this.PasswordAnswerFieldName = config["passwordAnswerFieldName"]; } if (!String.IsNullOrEmpty(this.passwordStrengthRegularExpression)) { new Regex(this.passwordStrengthRegularExpression); } var connectionStringName = config["connectionStringName"]; var connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString; var settings = Configuration.ConfigurationSettings.Parse(connectionString); this.userRepository = this.userRepositoryFactory.GetRepository(settings); this.profileRepository = this.profileRepositoryFactory.GetRepository(settings); this.initialized = true; } catch (Exception e) { this.initialized = false; ConditionalLog.Error("The CRM provider couldn't be initialized.", e, this); return; } try { if (!String.IsNullOrEmpty(this.PasswordFieldName)) { var passwordFieldType = this.profileRepository.GetPropertyType(this.PasswordFieldName); if (passwordFieldType != SupportedTypes.String) { this.PasswordFieldName = String.Empty; ConditionalLog.Warn("The attribute for the password storage isn't of String type. Password storage feature disabled.", this); } } } catch (ProviderException) { if ((this.userRepository is UserRepositoryV4 || this.userRepository is UserRepositoryV5) && this.AutoCreatePasswordField) { if (!this.profileRepository.CreateContactAttribute(this.PasswordFieldName, SupportedTypes.String, false)) { this.PasswordFieldName = String.Empty; ConditionalLog.Warn("The attribute for password storage couldn't be created. Password storage feature disabled.", this); } } else { this.PasswordFieldName = String.Empty; ConditionalLog.Warn("The attribute for the password storage doesn't exist. Password storage feature disabled.", this); } } }