1
14
15 package com.liferay.portlet.login.action;
16
17 import com.liferay.portal.DuplicateUserEmailAddressException;
18 import com.liferay.portal.NoSuchUserException;
19 import com.liferay.portal.kernel.log.Log;
20 import com.liferay.portal.kernel.log.LogFactoryUtil;
21 import com.liferay.portal.kernel.servlet.SessionErrors;
22 import com.liferay.portal.kernel.servlet.SessionMessages;
23 import com.liferay.portal.kernel.util.CharPool;
24 import com.liferay.portal.kernel.util.Constants;
25 import com.liferay.portal.kernel.util.GetterUtil;
26 import com.liferay.portal.kernel.util.ParamUtil;
27 import com.liferay.portal.kernel.util.StringPool;
28 import com.liferay.portal.kernel.util.Validator;
29 import com.liferay.portal.model.User;
30 import com.liferay.portal.service.ServiceContext;
31 import com.liferay.portal.service.UserLocalServiceUtil;
32 import com.liferay.portal.struts.PortletAction;
33 import com.liferay.portal.theme.ThemeDisplay;
34 import com.liferay.portal.util.OpenIdUtil;
35 import com.liferay.portal.util.PortalUtil;
36 import com.liferay.portal.util.WebKeys;
37 import com.liferay.portlet.ActionResponseImpl;
38 import com.liferay.util.PwdGenerator;
39
40 import java.util.Calendar;
41 import java.util.List;
42 import java.util.Locale;
43
44 import javax.portlet.ActionRequest;
45 import javax.portlet.ActionResponse;
46 import javax.portlet.PortletConfig;
47 import javax.portlet.PortletURL;
48 import javax.portlet.RenderRequest;
49 import javax.portlet.RenderResponse;
50
51 import javax.servlet.http.HttpServletRequest;
52 import javax.servlet.http.HttpServletResponse;
53 import javax.servlet.http.HttpSession;
54
55 import org.apache.struts.action.ActionForm;
56 import org.apache.struts.action.ActionForward;
57 import org.apache.struts.action.ActionMapping;
58
59 import org.openid4java.OpenIDException;
60 import org.openid4java.consumer.ConsumerManager;
61 import org.openid4java.consumer.VerificationResult;
62 import org.openid4java.discovery.DiscoveryInformation;
63 import org.openid4java.discovery.Identifier;
64 import org.openid4java.message.AuthRequest;
65 import org.openid4java.message.AuthSuccess;
66 import org.openid4java.message.MessageExtension;
67 import org.openid4java.message.ParameterList;
68 import org.openid4java.message.ax.AxMessage;
69 import org.openid4java.message.ax.FetchRequest;
70 import org.openid4java.message.ax.FetchResponse;
71 import org.openid4java.message.sreg.SRegMessage;
72 import org.openid4java.message.sreg.SRegRequest;
73 import org.openid4java.message.sreg.SRegResponse;
74
75
81 public class OpenIdAction extends PortletAction {
82
83 public void processAction(
84 ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
85 ActionRequest actionRequest, ActionResponse actionResponse)
86 throws Exception {
87
88 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
89 WebKeys.THEME_DISPLAY);
90
91 if (actionRequest.getRemoteUser() != null) {
92 actionResponse.sendRedirect(themeDisplay.getPathMain());
93
94 return;
95 }
96
97 String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
98
99 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 public ActionForward render(
138 ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
139 RenderRequest renderRequest, RenderResponse renderResponse)
140 throws Exception {
141
142 ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(
143 WebKeys.THEME_DISPLAY);
144
145 renderResponse.setTitle(themeDisplay.translate("open-id"));
146
147 return mapping.findForward("portlet.login.open_id");
148 }
149
150 protected String getFirstValue(List<String> values) {
151 if ((values == null) || (values.size() < 1)) {
152 return null;
153 }
154
155 return values.get(0);
156 }
157
158 protected boolean isCheckMethodOnProcessAction() {
159 return _CHECK_METHOD_ON_PROCESS_ACTION;
160 }
161
162 protected String readOpenIdResponse(
163 ThemeDisplay themeDisplay, ActionRequest actionRequest,
164 ActionResponse actionResponse)
165 throws Exception {
166
167 HttpServletRequest request = PortalUtil.getHttpServletRequest(
168 actionRequest);
169 HttpSession session = request.getSession();
170
171 ConsumerManager manager = OpenIdUtil.getConsumerManager();
172
173 ParameterList params = new ParameterList(
174 actionRequest.getParameterMap());
175
176 DiscoveryInformation discovered =
177 (DiscoveryInformation)session.getAttribute(WebKeys.OPEN_ID_DISCO);
178
179 if (discovered == null) {
180 return null;
181 }
182
183 String receivingUrl = ParamUtil.getString(
184 actionRequest, "openid.return_to");
185
186 VerificationResult verification = manager.verify(
187 receivingUrl, params, discovered);
188
189 Identifier verified = verification.getVerifiedId();
190
191 if (verified == null) {
192 return null;
193 }
194
195 AuthSuccess authSuccess = (AuthSuccess)verification.getAuthResponse();
196
197 String firstName = null;
198 String lastName = null;
199 String emailAddress = null;
200
201 if (authSuccess.hasExtension(SRegMessage.OPENID_NS_SREG)) {
202 MessageExtension ext = authSuccess.getExtension(
203 SRegMessage.OPENID_NS_SREG);
204
205 if (ext instanceof SRegResponse) {
206 SRegResponse sregResp = (SRegResponse)ext;
207
208 String fullName = GetterUtil.getString(
209 sregResp.getAttributeValue("fullname"));
210
211 int pos = fullName.indexOf(CharPool.SPACE);
212
213 if ((pos != -1) && ((pos + 1) < fullName.length())) {
214 firstName = fullName.substring(0, pos);
215 lastName = fullName.substring(pos + 1);
216 }
217
218 emailAddress = sregResp.getAttributeValue("email");
219 }
220 }
221
222 if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
223 MessageExtension ext = authSuccess.getExtension(
224 AxMessage.OPENID_NS_AX);
225
226 if (ext instanceof FetchResponse) {
227 FetchResponse fetchResp = (FetchResponse)ext;
228
229 if (Validator.isNull(firstName)) {
230 firstName = getFirstValue(
231 fetchResp.getAttributeValues("firstName"));
232 }
233
234 if (Validator.isNull(lastName)) {
235 lastName = getFirstValue(
236 fetchResp.getAttributeValues("lastName"));
237 }
238
239 if (Validator.isNull(emailAddress)) {
240 emailAddress = getFirstValue(
241 fetchResp.getAttributeValues("email"));
242 }
243 }
244 }
245
246 String openId = OpenIdUtil.normalize(authSuccess.getIdentity());
247
248 User user = null;
249
250 try {
251 user = UserLocalServiceUtil.getUserByOpenId(openId);
252 }
253 catch (NoSuchUserException nsue) {
254 if (Validator.isNull(firstName) || Validator.isNull(lastName) ||
255 Validator.isNull(emailAddress)) {
256
257 SessionMessages.add(request, "missingOpenIdUserInformation");
258
259 if (_log.isInfoEnabled()) {
260 _log.info(
261 "The OpenID provider did not send the required " +
262 "attributes to create an account");
263 }
264
265 PortletURL createAccountURL =
266 themeDisplay.getURLCreateAccount();
267
268 createAccountURL.setParameter("openId", openId);
269
270 session.setAttribute(
271 WebKeys.OPEN_ID_LOGIN_PENDING, Boolean.TRUE);
272
273 return createAccountURL.toString();
274 }
275
276 long creatorUserId = 0;
277 long companyId = themeDisplay.getCompanyId();
278 boolean autoPassword = false;
279 String password1 = PwdGenerator.getPassword();
280 String password2 = password1;
281 boolean autoScreenName = true;
282 String screenName = StringPool.BLANK;
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, openId, locale,
303 firstName, middleName, lastName, prefixId, suffixId, male,
304 birthdayMonth, birthdayDay, birthdayYear, jobTitle, groupIds,
305 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(openId);
353 }
354 catch (NoSuchUserException nsue) {
355 String screenName = OpenIdUtil.getScreenName(openId);
356
357 try {
358 User user = UserLocalServiceUtil.getUserByScreenName(
359 themeDisplay.getCompanyId(), screenName);
360
361 UserLocalServiceUtil.updateOpenId(user.getUserId(), openId);
362 }
363 catch (NoSuchUserException nsue2) {
364 FetchRequest fetch = FetchRequest.createFetchRequest();
365
366 fetch.addAttribute(
367 "email", "http://schema.openid.net/contact/email", true);
368 fetch.addAttribute(
369 "firstName", "http://schema.openid.net/namePerson/first",
370 true);
371 fetch.addAttribute(
372 "lastName", "http://schema.openid.net/namePerson/last",
373 true);
374
375 authRequest.addExtension(fetch);
376
377 SRegRequest sregRequest = SRegRequest.createFetchRequest();
378
379 sregRequest.addAttribute("fullname", true);
380 sregRequest.addAttribute("email", true);
381
382 authRequest.addExtension(sregRequest);
383 }
384 }
385
386 response.sendRedirect(authRequest.getDestinationUrl(true));
387 }
388
389 private static final boolean _CHECK_METHOD_ON_PROCESS_ACTION = false;
390
391 private static Log _log = LogFactoryUtil.getLog(OpenIdAction.class);
392
393 }