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