1
22
23 package com.liferay.portal.action;
24
25 import com.liferay.portal.DuplicateUserEmailAddressException;
26 import com.liferay.portal.NoSuchUserException;
27 import com.liferay.portal.kernel.log.Log;
28 import com.liferay.portal.kernel.log.LogFactoryUtil;
29 import com.liferay.portal.kernel.servlet.SessionErrors;
30 import com.liferay.portal.kernel.servlet.SessionMessages;
31 import com.liferay.portal.kernel.util.GetterUtil;
32 import com.liferay.portal.kernel.util.StringPool;
33 import com.liferay.portal.kernel.util.Validator;
34 import com.liferay.portal.model.User;
35 import com.liferay.portal.service.UserLocalServiceUtil;
36 import com.liferay.portal.theme.ThemeDisplay;
37 import com.liferay.portal.util.OpenIdUtil;
38 import com.liferay.portal.util.PortalUtil;
39 import com.liferay.portal.util.WebKeys;
40 import com.liferay.util.PwdGenerator;
41
42 import java.util.Calendar;
43 import java.util.List;
44 import java.util.Locale;
45
46 import javax.portlet.PortletURL;
47
48 import javax.servlet.http.HttpServletRequest;
49 import javax.servlet.http.HttpServletResponse;
50 import javax.servlet.http.HttpSession;
51
52 import org.apache.struts.action.Action;
53 import org.apache.struts.action.ActionForm;
54 import org.apache.struts.action.ActionForward;
55 import org.apache.struts.action.ActionMapping;
56
57 import org.openid4java.association.AssociationException;
58 import org.openid4java.consumer.ConsumerException;
59 import org.openid4java.consumer.ConsumerManager;
60 import org.openid4java.consumer.VerificationResult;
61 import org.openid4java.discovery.DiscoveryException;
62 import org.openid4java.discovery.DiscoveryInformation;
63 import org.openid4java.discovery.Identifier;
64 import org.openid4java.message.AuthSuccess;
65 import org.openid4java.message.MessageException;
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.FetchResponse;
70 import org.openid4java.message.sreg.SRegMessage;
71 import org.openid4java.message.sreg.SRegResponse;
72
73
79 public class OpenIdResponseAction extends Action {
80
81 public ActionForward execute(
82 ActionMapping mapping, ActionForm form, HttpServletRequest request,
83 HttpServletResponse response)
84 throws Exception {
85
86 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
87 WebKeys.THEME_DISPLAY);
88
89 if (!OpenIdUtil.isEnabled(themeDisplay.getCompanyId())) {
90 return null;
91 }
92
93 String redirect = null;
94
95 try {
96 redirect = readResponse(themeDisplay, request);
97 }
98 catch (Exception e) {
99 if (e instanceof AssociationException ||
100 e instanceof ConsumerException ||
101 e instanceof DiscoveryException ||
102 e instanceof DuplicateUserEmailAddressException ||
103 e instanceof MessageException) {
104
105 SessionErrors.add(request, e.getClass().getName());
106
107 return mapping.findForward("portal.login");
108 }
109 else {
110 _log.error("Error processing OpenID response", e);
111
112 PortalUtil.sendError(e, request, response);
113
114 return null;
115 }
116 }
117
118 if (Validator.isNull(redirect)) {
119 redirect =
120 PortalUtil.getPortalURL(request) + themeDisplay.getURLSignIn();
121 }
122
123 response.sendRedirect(redirect);
124
125 return null;
126 }
127
128 protected User addUser(
129 long companyId, String firstName, String lastName,
130 String emailAddress, String openId, Locale locale)
131 throws Exception {
132
133 long creatorUserId = 0;
134 boolean autoPassword = false;
135 String password1 = PwdGenerator.getPassword();
136 String password2 = password1;
137 boolean autoScreenName = true;
138 String screenName = StringPool.BLANK;
139 String middleName = StringPool.BLANK;
140 int prefixId = 0;
141 int suffixId = 0;
142 boolean male = true;
143 int birthdayMonth = Calendar.JANUARY;
144 int birthdayDay = 1;
145 int birthdayYear = 1970;
146 String jobTitle = StringPool.BLANK;
147 long[] organizationIds = new long[0];
148 boolean sendEmail = false;
149
150 User user = UserLocalServiceUtil.addUser(
151 creatorUserId, companyId, autoPassword, password1, password2,
152 autoScreenName, screenName, emailAddress, locale, firstName,
153 middleName, lastName, prefixId, suffixId, male, birthdayMonth,
154 birthdayDay, birthdayYear, jobTitle, organizationIds, sendEmail);
155
156 UserLocalServiceUtil.updateOpenId(user.getUserId(), openId);
157
158 return user;
159 }
160
161 protected String getFirstValue(List<String> values) {
162 if ((values == null) || (values.size() < 1)) {
163 return null;
164 }
165
166 return values.get(0);
167 }
168
169 protected String readResponse(
170 ThemeDisplay themeDisplay, HttpServletRequest request)
171 throws Exception {
172
173 HttpSession session = request.getSession();
174
175 ConsumerManager manager = OpenIdUtil.getConsumerManager();
176
177 ParameterList params = new ParameterList(request.getParameterMap());
178
179 DiscoveryInformation discovered =
180 (DiscoveryInformation)session.getAttribute(WebKeys.OPEN_ID_DISCO);
181
182 if (discovered == null) {
183 return null;
184 }
185
186 StringBuffer receivingURL = request.getRequestURL();
187 String queryString = request.getQueryString();
188
189 if ((queryString != null) && (queryString.length() > 0)) {
190 receivingURL.append(StringPool.QUESTION);
191 receivingURL.append(request.getQueryString());
192 }
193
194 VerificationResult verification = manager.verify(
195 receivingURL.toString(), params, discovered);
196
197 Identifier verified = verification.getVerifiedId();
198
199 if (verified == null) {
200 return null;
201 }
202
203 AuthSuccess authSuccess = (AuthSuccess)verification.getAuthResponse();
204
205 String firstName = null;
206 String lastName = null;
207 String emailAddress = null;
208
209 if (authSuccess.hasExtension(SRegMessage.OPENID_NS_SREG)) {
210 MessageExtension ext = authSuccess.getExtension(
211 SRegMessage.OPENID_NS_SREG);
212
213 if (ext instanceof SRegResponse) {
214 SRegResponse sregResp = (SRegResponse)ext;
215
216 String fullName = GetterUtil.getString(
217 sregResp.getAttributeValue("fullname"));
218
219 int pos = fullName.indexOf(StringPool.SPACE);
220
221 if ((pos != -1) && ((pos + 1) < fullName.length())) {
222 firstName = fullName.substring(0, pos);
223 lastName = fullName.substring(pos + 1);
224 }
225
226 emailAddress = sregResp.getAttributeValue("email");
227 }
228 }
229
230 if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
231 MessageExtension ext = authSuccess.getExtension(
232 AxMessage.OPENID_NS_AX);
233
234 if (ext instanceof FetchResponse) {
235 FetchResponse fetchResp = (FetchResponse)ext;
236
237 if (Validator.isNull(firstName)) {
238 firstName = getFirstValue(
239 fetchResp.getAttributeValues("firstName"));
240 }
241
242 if (Validator.isNull(lastName)) {
243 lastName = getFirstValue(
244 fetchResp.getAttributeValues("lastName"));
245 }
246
247 if (Validator.isNull(emailAddress)) {
248 emailAddress = getFirstValue(
249 fetchResp.getAttributeValues("email"));
250 }
251 }
252 }
253
254 String openId = OpenIdUtil.normalize(authSuccess.getIdentity());
255
256 User user = null;
257
258 try {
259 user = UserLocalServiceUtil.getUserByOpenId(openId);
260 }
261 catch (NoSuchUserException nsue) {
262 if (Validator.isNull(firstName) || Validator.isNull(lastName) ||
263 Validator.isNull(emailAddress)) {
264
265 SessionMessages.add(request, "missingOpenIdUserInformation");
266
267 if (_log.isInfoEnabled()) {
268 _log.info(
269 "The OpenID provider did not send the required " +
270 "attributes to create an account");
271 }
272
273 PortletURL createAccountURL =
274 themeDisplay.getURLCreateAccount();
275
276 createAccountURL.setParameter("openId", openId);
277
278 session.setAttribute(
279 WebKeys.OPEN_ID_LOGIN_PENDING, Boolean.TRUE);
280
281 return createAccountURL.toString();
282 }
283
284 user = addUser(
285 themeDisplay.getCompanyId(), firstName, lastName, emailAddress,
286 openId, themeDisplay.getLocale());
287 }
288
289 session.setAttribute(WebKeys.OPEN_ID_LOGIN, new Long(user.getUserId()));
290
291 return null;
292 }
293
294 private static Log _log = LogFactoryUtil.getLog(OpenIdResponseAction.class);
295
296 }