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