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