001
014
015 package com.liferay.portlet.login.action;
016
017 import com.liferay.portal.DuplicateUserEmailAddressException;
018 import com.liferay.portal.NoSuchUserException;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.servlet.SessionErrors;
022 import com.liferay.portal.kernel.servlet.SessionMessages;
023 import com.liferay.portal.kernel.util.CharPool;
024 import com.liferay.portal.kernel.util.Constants;
025 import com.liferay.portal.kernel.util.GetterUtil;
026 import com.liferay.portal.kernel.util.ParamUtil;
027 import com.liferay.portal.kernel.util.StringPool;
028 import com.liferay.portal.kernel.util.Validator;
029 import com.liferay.portal.model.User;
030 import com.liferay.portal.service.ServiceContext;
031 import com.liferay.portal.service.UserLocalServiceUtil;
032 import com.liferay.portal.struts.PortletAction;
033 import com.liferay.portal.theme.ThemeDisplay;
034 import com.liferay.portal.util.OpenIdUtil;
035 import com.liferay.portal.util.PortalUtil;
036 import com.liferay.portal.util.WebKeys;
037 import com.liferay.portlet.ActionResponseImpl;
038 import com.liferay.util.PwdGenerator;
039
040 import java.util.Calendar;
041 import java.util.List;
042 import java.util.Locale;
043
044 import javax.portlet.ActionRequest;
045 import javax.portlet.ActionResponse;
046 import javax.portlet.PortletConfig;
047 import javax.portlet.PortletURL;
048 import javax.portlet.RenderRequest;
049 import javax.portlet.RenderResponse;
050
051 import javax.servlet.http.HttpServletRequest;
052 import javax.servlet.http.HttpServletResponse;
053 import javax.servlet.http.HttpSession;
054
055 import org.apache.struts.action.ActionForm;
056 import org.apache.struts.action.ActionForward;
057 import org.apache.struts.action.ActionMapping;
058
059 import org.openid4java.OpenIDException;
060 import org.openid4java.consumer.ConsumerManager;
061 import org.openid4java.consumer.VerificationResult;
062 import org.openid4java.discovery.DiscoveryInformation;
063 import org.openid4java.discovery.Identifier;
064 import org.openid4java.message.AuthRequest;
065 import org.openid4java.message.AuthSuccess;
066 import org.openid4java.message.MessageExtension;
067 import org.openid4java.message.ParameterList;
068 import org.openid4java.message.ax.AxMessage;
069 import org.openid4java.message.ax.FetchRequest;
070 import org.openid4java.message.ax.FetchResponse;
071 import org.openid4java.message.sreg.SRegMessage;
072 import org.openid4java.message.sreg.SRegRequest;
073 import org.openid4java.message.sreg.SRegResponse;
074
075
079 public class OpenIdAction extends PortletAction {
080
081 public void processAction(
082 ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
083 ActionRequest actionRequest, ActionResponse actionResponse)
084 throws Exception {
085
086 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
087 WebKeys.THEME_DISPLAY);
088
089 if (actionRequest.getRemoteUser() != null) {
090 actionResponse.sendRedirect(themeDisplay.getPathMain());
091
092 return;
093 }
094
095 String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
096
097 try {
098 if (cmd.equals(Constants.READ)) {
099 String redirect = readOpenIdResponse(
100 themeDisplay, actionRequest, actionResponse);
101
102 if (Validator.isNull(redirect)) {
103 redirect =
104 PortalUtil.getPortalURL(actionRequest) +
105 themeDisplay.getURLSignIn();
106 }
107
108 sendRedirect(actionRequest, actionResponse, redirect);
109 }
110 else {
111 sendOpenIdRequest(themeDisplay, actionRequest, actionResponse);
112 }
113 }
114 catch (Exception e) {
115 if (e instanceof DuplicateUserEmailAddressException) {
116 SessionErrors.add(actionRequest, e.getClass().getName());
117 }
118 else if (e instanceof OpenIDException) {
119 if (_log.isInfoEnabled()) {
120 _log.info(
121 "Error communicating with OpenID provider: " +
122 e.getMessage());
123 }
124
125 SessionErrors.add(actionRequest, e.getClass().getName());
126 }
127 else {
128 _log.error("Error processing the OpenID login", e);
129
130 PortalUtil.sendError(e, actionRequest, actionResponse);
131 }
132 }
133 }
134
135 public ActionForward render(
136 ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
137 RenderRequest renderRequest, RenderResponse renderResponse)
138 throws Exception {
139
140 ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(
141 WebKeys.THEME_DISPLAY);
142
143 renderResponse.setTitle(themeDisplay.translate("open-id"));
144
145 return mapping.findForward("portlet.login.open_id");
146 }
147
148 protected String getFirstValue(List<String> values) {
149 if ((values == null) || (values.size() < 1)) {
150 return null;
151 }
152
153 return values.get(0);
154 }
155
156 protected boolean isCheckMethodOnProcessAction() {
157 return _CHECK_METHOD_ON_PROCESS_ACTION;
158 }
159
160 protected String readOpenIdResponse(
161 ThemeDisplay themeDisplay, ActionRequest actionRequest,
162 ActionResponse actionResponse)
163 throws Exception {
164
165 HttpServletRequest request = PortalUtil.getHttpServletRequest(
166 actionRequest);
167 HttpSession session = request.getSession();
168
169 ConsumerManager manager = OpenIdUtil.getConsumerManager();
170
171 ParameterList params = new ParameterList(
172 actionRequest.getParameterMap());
173
174 DiscoveryInformation discovered =
175 (DiscoveryInformation)session.getAttribute(WebKeys.OPEN_ID_DISCO);
176
177 if (discovered == null) {
178 return null;
179 }
180
181 String receivingUrl = ParamUtil.getString(
182 actionRequest, "openid.return_to");
183
184 VerificationResult verification = manager.verify(
185 receivingUrl, params, discovered);
186
187 Identifier verified = verification.getVerifiedId();
188
189 if (verified == null) {
190 return null;
191 }
192
193 AuthSuccess authSuccess = (AuthSuccess)verification.getAuthResponse();
194
195 String firstName = null;
196 String lastName = null;
197 String emailAddress = null;
198
199 if (authSuccess.hasExtension(SRegMessage.OPENID_NS_SREG)) {
200 MessageExtension ext = authSuccess.getExtension(
201 SRegMessage.OPENID_NS_SREG);
202
203 if (ext instanceof SRegResponse) {
204 SRegResponse sregResp = (SRegResponse)ext;
205
206 String fullName = GetterUtil.getString(
207 sregResp.getAttributeValue("fullname"));
208
209 int pos = fullName.indexOf(CharPool.SPACE);
210
211 if ((pos != -1) && ((pos + 1) < fullName.length())) {
212 firstName = fullName.substring(0, pos);
213 lastName = fullName.substring(pos + 1);
214 }
215
216 emailAddress = sregResp.getAttributeValue("email");
217 }
218 }
219
220 if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
221 MessageExtension ext = authSuccess.getExtension(
222 AxMessage.OPENID_NS_AX);
223
224 if (ext instanceof FetchResponse) {
225 FetchResponse fetchResp = (FetchResponse)ext;
226
227 if (Validator.isNull(firstName)) {
228 firstName = getFirstValue(
229 fetchResp.getAttributeValues("firstName"));
230 }
231
232 if (Validator.isNull(lastName)) {
233 lastName = getFirstValue(
234 fetchResp.getAttributeValues("lastName"));
235 }
236
237 if (Validator.isNull(emailAddress)) {
238 emailAddress = getFirstValue(
239 fetchResp.getAttributeValues("email"));
240 }
241 }
242 }
243
244 String openId = OpenIdUtil.normalize(authSuccess.getIdentity());
245
246 User user = null;
247
248 try {
249 user = UserLocalServiceUtil.getUserByOpenId(
250 themeDisplay.getCompanyId(), openId);
251 }
252 catch (NoSuchUserException nsue) {
253 if (Validator.isNull(firstName) || Validator.isNull(lastName) ||
254 Validator.isNull(emailAddress)) {
255
256 SessionMessages.add(request, "missingOpenIdUserInformation");
257
258 if (_log.isInfoEnabled()) {
259 _log.info(
260 "The OpenID provider did not send the required " +
261 "attributes to create an account");
262 }
263
264 PortletURL createAccountURL =
265 themeDisplay.getURLCreateAccount();
266
267 createAccountURL.setParameter("openId", openId);
268
269 session.setAttribute(
270 WebKeys.OPEN_ID_LOGIN_PENDING, Boolean.TRUE);
271
272 return createAccountURL.toString();
273 }
274
275 long creatorUserId = 0;
276 long companyId = themeDisplay.getCompanyId();
277 boolean autoPassword = false;
278 String password1 = PwdGenerator.getPassword();
279 String password2 = password1;
280 boolean autoScreenName = true;
281 String screenName = StringPool.BLANK;
282 long facebookId = 0;
283 Locale locale = themeDisplay.getLocale();
284 String middleName = StringPool.BLANK;
285 int prefixId = 0;
286 int suffixId = 0;
287 boolean male = true;
288 int birthdayMonth = Calendar.JANUARY;
289 int birthdayDay = 1;
290 int birthdayYear = 1970;
291 String jobTitle = StringPool.BLANK;
292 long[] groupIds = null;
293 long[] organizationIds = null;
294 long[] roleIds = null;
295 long[] userGroupIds = null;
296 boolean sendEmail = false;
297
298 ServiceContext serviceContext = new ServiceContext();
299
300 user = UserLocalServiceUtil.addUser(
301 creatorUserId, companyId, autoPassword, password1, password2,
302 autoScreenName, screenName, emailAddress, facebookId, openId,
303 locale, firstName, middleName, lastName, prefixId, suffixId,
304 male, birthdayMonth, birthdayDay, birthdayYear, jobTitle,
305 groupIds, organizationIds, roleIds, userGroupIds, sendEmail,
306 serviceContext);
307 }
308
309 session.setAttribute(WebKeys.OPEN_ID_LOGIN, new Long(user.getUserId()));
310
311 return null;
312 }
313
314 protected void sendOpenIdRequest(
315 ThemeDisplay themeDisplay, ActionRequest actionRequest,
316 ActionResponse actionResponse)
317 throws Exception {
318
319 if (!OpenIdUtil.isEnabled(themeDisplay.getCompanyId())) {
320 return;
321 }
322
323 HttpServletRequest request = PortalUtil.getHttpServletRequest(
324 actionRequest);
325 HttpServletResponse response = PortalUtil.getHttpServletResponse(
326 actionResponse);
327 HttpSession session = request.getSession();
328
329 ActionResponseImpl actionResponseImpl =
330 (ActionResponseImpl)actionResponse;
331
332 String openId = ParamUtil.getString(actionRequest, "openId");
333
334 PortletURL portletURL = actionResponseImpl.createActionURL();
335
336 portletURL.setParameter("struts_action", "/login/open_id");
337 portletURL.setParameter(Constants.CMD, Constants.READ);
338 portletURL.setParameter("saveLastPath", "0");
339
340 ConsumerManager manager = OpenIdUtil.getConsumerManager();
341
342 List<DiscoveryInformation> discoveries = manager.discover(openId);
343
344 DiscoveryInformation discovered = manager.associate(discoveries);
345
346 session.setAttribute(WebKeys.OPEN_ID_DISCO, discovered);
347
348 AuthRequest authRequest = manager.authenticate(
349 discovered, portletURL.toString(), themeDisplay.getPortalURL());
350
351 try {
352 UserLocalServiceUtil.getUserByOpenId(
353 themeDisplay.getCompanyId(), openId);
354 }
355 catch (NoSuchUserException nsue) {
356 String screenName = OpenIdUtil.getScreenName(openId);
357
358 try {
359 User user = UserLocalServiceUtil.getUserByScreenName(
360 themeDisplay.getCompanyId(), screenName);
361
362 UserLocalServiceUtil.updateOpenId(user.getUserId(), openId);
363 }
364 catch (NoSuchUserException nsue2) {
365 FetchRequest fetch = FetchRequest.createFetchRequest();
366
367 fetch.addAttribute(
368 "email", "http:
369 fetch.addAttribute(
370 "firstName", "http:
371 true);
372 fetch.addAttribute(
373 "lastName", "http:
374 true);
375
376 authRequest.addExtension(fetch);
377
378 SRegRequest sregRequest = SRegRequest.createFetchRequest();
379
380 sregRequest.addAttribute("fullname", true);
381 sregRequest.addAttribute("email", true);
382
383 authRequest.addExtension(sregRequest);
384 }
385 }
386
387 response.sendRedirect(authRequest.getDestinationUrl(true));
388 }
389
390 private static final boolean _CHECK_METHOD_ON_PROCESS_ACTION = false;
391
392 private static Log _log = LogFactoryUtil.getLog(OpenIdAction.class);
393
394 }