RE: How to disable password change notification in 7/DXP?

thumbnail
Fernando Fernandez, modified 7 Years ago. Expert Posts: 401 Join Date: 8/22/07 Recent Posts
Hi,

I have a requirement that is to totally disable the password notification email and I can't find a way of doing this.

I don't need just to remove the password from the notification email, which can be achieved by editing the template in Control Panel / Configuration / Instance Settings / Email Notifications. I'm really required to abolish the email sending.

Something like the "Enabled" checkbox in the "Account Created" notification, but for the "Password Changed Notification".

Any ideas?

TIA

Fernando
thumbnail
David H Nebinger, modified 7 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
The only way you're going to be able to do that is through a UserLocalService wrapper to override the methods which send the various emails.
thumbnail
Fernando Fernandez, modified 7 Years ago. Expert Posts: 401 Join Date: 8/22/07 Recent Posts
David H Nebinger:
The only way you're going to be able to do that is through a UserLocalService wrapper to override the methods which send the various emails.


Hi David,

I tried, but it seems a hard way... :-)

Just intercepting sendPassword() in the UserLocalServiceWrapper doesn't seem to be enough.

Password is being changed by the OOTB portlets through a call to updateUser(). This can be intercepted in the wrapper, but when the super.updateUser() is calling sendPassword() it will not go through the wrapper again.

So, the only solution I see is to reimplement (just copy, really) all the stuff that updateUser() does, without calling sendPassword().

It seems ugly, but if there's no other way, I guess that's what will have to be done.

Thanks

Fernando
thumbnail
David H Nebinger, modified 7 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
Fernando Fernandez:
Password is being changed by the OOTB portlets through a call to updateUser(). This can be intercepted in the wrapper, but when the super.updateUser() is calling sendPassword() it will not go through the wrapper again.

So, the only solution I see is to reimplement (just copy, really) all the stuff that updateUser() does, without calling sendPassword().


Yep, that's pretty much what you're stuck with, as well as hitting the other methods that may be updating passwords.
Jan Tošovský, modified 5 Years ago. Liferay Master Posts: 576 Join Date: 7/22/10 Recent Posts
Hi Fernando, I ended up cloning almost all UserLocalServiceImp stuff, but I am still receiving emails with my changed password. While I can hit breakpoint for sending reset password link, when new password is set and submitted, it really continues without touching my wrapper code. 
What exactly is meant by " So, the only solution I see is to reimplement (just copy, really) all the stuff that updateUser() does, without calling sendPassword()." ?
Does this approach works for you?
Montej Shah, modified 5 Years ago. Junior Member Posts: 48 Join Date: 2/18/15 Recent Posts
Finally, i got the way to remove the notification only for the update password.I had used service-wrapper to override 2 methods for update passwords. Override with the same code as existing one,  just comment out send notification part.Liferay version 7.1

package com.motus.aspire.service.wrapper;import java.util.Date;import org.osgi.service.component.annotations.Component;import com.liferay.mail.kernel.service.MailServiceUtil;
import com.liferay.portal.kernel.exception.ModelListenerException;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.UserPasswordException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.PasswordPolicy;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.security.auth.PasswordModificationThreadLocal;
import com.liferay.portal.kernel.security.ldap.LDAPSettingsUtil;
import com.liferay.portal.kernel.security.pwd.PasswordEncryptorUtil;
import com.liferay.portal.kernel.service.PasswordPolicyLocalServiceUtil;
import com.liferay.portal.kernel.service.PasswordTrackerLocalServiceUtil;
import com.liferay.portal.kernel.service.ServiceWrapper;
import com.liferay.portal.kernel.service.UserLocalServiceUtil;
import com.liferay.portal.kernel.service.UserLocalServiceWrapper;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.security.pwd.PwdToolkitUtil;/**
 * @author aspire48
 */
@Component(immediate = true, property = {}, service = ServiceWrapper.class)
public class UserServiceOverride extends UserLocalServiceWrapper {  public UserServiceOverride() {
    super(null);
  }  private static final Log log = LogFactoryUtil.getLog(UserServiceOverride.class.getName());  @Override
  public User updatePassword(long userId, String password1, String password2, boolean passwordReset)
      throws PortalException {
    log.info("Executing updatePassword ====");
    return updatePassword(userId, password1, password2, passwordReset, true);
  }  @Override
  public User updatePassword(long userId, String password1, String password2, boolean passwordReset,
      boolean silentUpdate) throws PortalException {
    log.info("Executing updatePassword  method which is overriden");
    // Password hashing takes a long time. Therefore, encrypt the password
    // before we get the user to avoid
    // an org.hibernate.StaleObjectStateException.    String newEncPwd = PasswordEncryptorUtil.encrypt(password1);    User user = UserLocalServiceUtil.getUser(userId);    if (!silentUpdate) {
      validatePassword(user.getCompanyId(), userId, password1, password2);      trackPassword(user);
    }    if (user.hasCompanyMx()) {
      MailServiceUtil.updatePassword(user.getCompanyId(), userId, password1);
    }    user.setPassword(newEncPwd);
    user.setPasswordUnencrypted(password1);
    user.setPasswordEncrypted(true);
    user.setPasswordReset(passwordReset);    if (!silentUpdate || (user.getPasswordModifiedDate() == null)) {
      user.setPasswordModifiedDate(new Date());
    }    user.setDigest(StringPool.BLANK);
    user.setGraceLoginCount(0);    if (!silentUpdate) {
      user.setPasswordModified(true);
    }    PasswordModificationThreadLocal.setPasswordModified(user.getPasswordModified());
    PasswordModificationThreadLocal.setPasswordUnencrypted(user.getPasswordUnencrypted());    try {
      user = UserLocalServiceUtil.updateUser(user);
    } catch (ModelListenerException mle) {
      Throwable throwable = mle.getCause();      String msg = GetterUtil.getString(throwable.getMessage());      if (LDAPSettingsUtil.isPasswordPolicyEnabled(user.getCompanyId())) {
        String[] errorPasswordHistoryKeywords =
            LDAPSettingsUtil.getErrorPasswordHistoryKeywords(user.getCompanyId());        for (String errorPasswordHistoryKeyword : errorPasswordHistoryKeywords) {          if (msg.contains(errorPasswordHistoryKeyword)) {
            throw new UserPasswordException.MustNotBeRecentlyUsed(userId);
          }
        }
      }      throw new UserPasswordException.MustComplyWithModelListeners(userId, mle);
    }    if (!silentUpdate) {
      user.setPasswordModified(false);
    }    // Override service to don't send notification
    // if (!silentUpdate && (PrincipalThreadLocal.getUserId() != userId)) {
    // sendPasswordNotification(user, user.getCompanyId(), password1, null, null, null, null, null,
    // ServiceContextThreadLocal.getServiceContext());
    // }
    return user;
  }  protected void validatePassword(long companyId, long userId, String password1, String password2)
      throws PortalException {    if (Validator.isNull(password1) || Validator.isNull(password2)) {
      throw new UserPasswordException.MustNotBeNull(userId);
    }    if (!password1.equals(password2)) {
      throw new UserPasswordException.MustMatch(userId);
    }    PasswordPolicy passwordPolicy =
        PasswordPolicyLocalServiceUtil.getPasswordPolicyByUserId(userId);    PwdToolkitUtil.validate(companyId, userId, password1, password2, passwordPolicy);
  }  protected void trackPassword(User user) throws PortalException {
    String oldEncPwd = user.getPassword();    if (!user.isPasswordEncrypted()) {
      oldEncPwd = PasswordEncryptorUtil.encrypt(user.getPassword());
    }    PasswordTrackerLocalServiceUtil.trackPassword(user.getUserId(), oldEncPwd);
  }
}

Dependency need to add for the override the above service
<dependency>
            <groupId>com.liferay.portal</groupId>
            <artifactId>com.liferay.portal.kernel</artifactId>
            <version>3.0.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>osgi.cmpn</artifactId>
            <version>6.0.0</version>
            <scope>provided</scope>
        </dependency>
<dependency>
            <groupId>com.liferay.portal</groupId>
            <artifactId>com.liferay.portal.impl</artifactId>
            <version>3.49.8</version>
            <scope>provided</scope>
        </dependency>

Reference:Source code: https://github.com/liferay/liferay-portal/blob/master/portal-impl/src/com/liferay/portal/service/impl/UserLocalServiceImpl.java