The aim for this post is to show a possible solution for allowing multiple users with the same email address.
The solution is for Liferay 6.0.5, so compatibility with different versions might not apply.
The first task is to enable the registration with an email address that already exists.
In order to do this two things should be done: first, the constraint in the database must be deleted, then the check during the registration process must be eliminated.
The database constraint is a unique index on table _user consisting of two columns, the companyid and the emailaddress. In our test case, it has the name ix_615e9f7a, but this may vary. Its creation on Postgres database is the following:
This index must be dropped, otherwise an SQL exception will be thrown during the addition or modification of a user if the email address already exists.CREATE UNIQUE INDEX ix_615e9f7a
ON user_
USING btree
(companyid , emailaddress );
The next task is to eliminate the checks during the user save process that throw DuplicateUserEmailAddressException. This can be done by modifying the UserLocalServiceImpl class which is located in liferay-portal.war/WEB-INF/lib/portal-impl.jar/com/liferay/portal/service/impl.
This class has two protected void validate() functions with different arguments. In these function can be found the parts that should be eliminated:
protected void validate(long companyId, long userId, boolean autoPassword, String password1, String password2, boolean autoScreenName, String screenName, String emailAddress, String firstName, String middleName, String lastName, long[] organizationIds) throws PortalException, SystemException { .... if (Validator.isNotNull(emailAddress)) { User user = this.userPersistence.fetchByC_EA(companyId, emailAddress); if (user != null) { throw new DuplicateUserEmailAddressException(); } } ..... }
Now duplicated email addresses can be registered. But how can we guarantee that although the users share the same email address, they must not share their registration. In other words, authentication must be done without the email address.protected void validate(long userId, String screenName, String emailAddress, String firstName, String middleName, String lastName, String smsSn) throws PortalException, SystemException { ..... if ((Validator.isNotNull(emailAddress)) && (!user.getEmailAddress().equalsIgnoreCase(emailAddress))) { if (this.userPersistence.fetchByC_EA( user.getCompanyId(), emailAddress) != null) { throw new DuplicateUserEmailAddressException(); } } ..... }
The liferay-portal.war/WEB-INF/struts-config.xml should be edited. The following part is responsible for the login:
The simplest methood is to replace wit a custom Login action:<action path="/login/login" type="com.liferay.portlet.login.action.LoginAction"> <forward name="portlet.login.login" path="portlet.login.login" /> </action>
<action path="/login/login" type="com.liferay.portlet.login.action.MyLoginAction"> <forward name="portlet.login.login" path="portlet.login.login" /> </action>Now the only thing to do, is to create a com.liferay.portlet.action.MyLoginAction. Here is a sample implementation. In this class, the original LoginAction is extended, and the some parts of the original methods are kept, but the login authentication is changed from email to screenname:
package com.liferay.portlet.login.action;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletPreferences;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.model.Company;
import com.liferay.portal.model.CompanyConstants;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.portal.util.PortalUtil;
import com.liferay.portal.util.PropsValues;
import com.liferay.portlet.login.util.LoginUtil;
public class MyLoginAction extends LoginAction {
@Override
protected void login(
final ThemeDisplay themeDisplay, final ActionRequest actionRequest,
final ActionResponse actionResponse, final PortletPreferences preferences)
throws Exception {
HttpServletRequest request = PortalUtil.getHttpServletRequest(actionRequest);
HttpServletResponse response = PortalUtil.getHttpServletResponse(actionResponse);String login = ParamUtil.getString(actionRequest, "login");
String password = ParamUtil.getString(actionRequest, "password");boolean rememberMe = ParamUtil.getBoolean(actionRequest, "rememberMe");
String authType = CompanyConstants.AUTH_TYPE_SN;
LoginUtil.login(request, response, login, password, rememberMe, authType);
if (PropsValues.PORTAL_JAAS_ENABLE) {
actionResponse.sendRedirect(themeDisplay.getPathMain() + "/portal/protected");
} else {
String redirect = ParamUtil.getString(actionRequest, "redirect");
if (Validator.isNotNull(redirect)) {
redirect = PortalUtil.escapeRedirect(redirect);
actionResponse.sendRedirect(redirect);
} else {
actionResponse.sendRedirect(themeDisplay.getPathMain());
}
}
}
}
No comments:
Post a Comment