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