1
22
23 package com.liferay.portal.action;
24
25 import com.liferay.portal.NoSuchUserException;
26 import com.liferay.portal.kernel.util.GetterUtil;
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.UserLocalServiceUtil;
31 import com.liferay.portal.struts.ActionConstants;
32 import com.liferay.portal.theme.ThemeDisplay;
33 import com.liferay.portal.util.OpenIdUtil;
34 import com.liferay.portal.util.PortalUtil;
35 import com.liferay.portal.util.WebKeys;
36 import com.liferay.util.PwdGenerator;
37 import com.liferay.util.servlet.SessionErrors;
38
39 import java.util.Calendar;
40 import java.util.List;
41 import java.util.Locale;
42
43 import javax.servlet.http.HttpServletRequest;
44 import javax.servlet.http.HttpServletResponse;
45 import javax.servlet.http.HttpSession;
46 import javax.servlet.jsp.PageContext;
47
48 import org.apache.commons.logging.Log;
49 import org.apache.commons.logging.LogFactory;
50 import org.apache.struts.action.Action;
51 import org.apache.struts.action.ActionForm;
52 import org.apache.struts.action.ActionForward;
53 import org.apache.struts.action.ActionMapping;
54
55 import org.openid4java.association.AssociationException;
56 import org.openid4java.consumer.ConsumerException;
57 import org.openid4java.consumer.ConsumerManager;
58 import org.openid4java.consumer.VerificationResult;
59 import org.openid4java.discovery.DiscoveryException;
60 import org.openid4java.discovery.DiscoveryInformation;
61 import org.openid4java.discovery.Identifier;
62 import org.openid4java.message.AuthSuccess;
63 import org.openid4java.message.MessageException;
64 import org.openid4java.message.MessageExtension;
65 import org.openid4java.message.ParameterList;
66 import org.openid4java.message.ax.AxMessage;
67 import org.openid4java.message.ax.FetchResponse;
68 import org.openid4java.message.sreg.SRegMessage;
69 import org.openid4java.message.sreg.SRegResponse;
70
71
77 public class OpenIdResponseAction extends Action {
78
79 public ActionForward execute(
80 ActionMapping mapping, ActionForm form, HttpServletRequest req,
81 HttpServletResponse res)
82 throws Exception {
83
84 ThemeDisplay themeDisplay =
85 (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
86
87 if (!OpenIdUtil.isEnabled(themeDisplay.getCompanyId())) {
88 return null;
89 }
90
91 try {
92 readResponse(themeDisplay, req);
93 }
94 catch (Exception e) {
95 if (e instanceof AssociationException ||
96 e instanceof ConsumerException ||
97 e instanceof DiscoveryException ||
98 e instanceof MessageException) {
99
100 SessionErrors.add(req, e.getClass().getName());
101
102 return mapping.findForward("portal.login");
103 }
104 else {
105 req.setAttribute(PageContext.EXCEPTION, e);
106
107 return mapping.findForward(ActionConstants.COMMON_ERROR);
108 }
109 }
110
111 String loginURL =
112 PortalUtil.getPortalURL(req) + themeDisplay.getURLSignIn();
113
114 res.sendRedirect(loginURL);
115
116 return null;
117 }
118
119 protected User addUser(
120 long companyId, String firstName, String lastName,
121 String emailAddress, String screenName, Locale locale)
122 throws Exception {
123
124 long creatorUserId = 0;
125 boolean autoPassword = false;
126 String password1 = PwdGenerator.getPassword();
127 String password2 = password1;
128 boolean autoScreenName = false;
129 String middleName = StringPool.BLANK;
130 int prefixId = 0;
131 int suffixId = 0;
132 boolean male = true;
133 int birthdayMonth = Calendar.JANUARY;
134 int birthdayDay = 1;
135 int birthdayYear = 1970;
136 String jobTitle = StringPool.BLANK;
137 long[] organizationIds = new long[0];
138 boolean sendEmail = false;
139
140 return UserLocalServiceUtil.addUser(
141 creatorUserId, companyId, autoPassword, password1, password2,
142 autoScreenName, screenName, emailAddress, locale, firstName,
143 middleName, lastName, prefixId, suffixId, male, birthdayMonth,
144 birthdayDay, birthdayYear, jobTitle, organizationIds, sendEmail);
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 User readResponse(
156 ThemeDisplay themeDisplay, HttpServletRequest req)
157 throws Exception {
158
159 HttpSession ses = req.getSession();
160
161 ConsumerManager manager = OpenIdUtil.getConsumerManager();
162
163 ParameterList params = new ParameterList(req.getParameterMap());
164
165 DiscoveryInformation discovered =
166 (DiscoveryInformation)ses.getAttribute(WebKeys.OPEN_ID_DISCO);
167
168 if (discovered == null) {
169 return null;
170 }
171
172 StringBuffer receivingURL = req.getRequestURL();
173 String queryString = req.getQueryString();
174
175 if ((queryString != null) && (queryString.length() > 0)) {
176 receivingURL.append(StringPool.QUESTION);
177 receivingURL.append(req.getQueryString());
178 }
179
180 VerificationResult verification = manager.verify(
181 receivingURL.toString(), 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 screenName = OpenIdUtil.getScreenName(authSuccess.getIdentity());
241
242 User user = null;
243
244 try {
245 user = UserLocalServiceUtil.getUserByScreenName(
246 themeDisplay.getCompanyId(), screenName);
247 }
248 catch (NoSuchUserException nsue) {
249 if (Validator.isNull(firstName) || Validator.isNull(lastName) ||
250 Validator.isNull(emailAddress)) {
251
252 SessionErrors.add(req, "missingOpenIdUserInformation");
253
254 _log.error(
255 "The OpenID provider did not send the required " +
256 "attributes to create an account");
257
258 return null;
259 }
260
261 user = addUser(
262 themeDisplay.getCompanyId(), firstName, lastName, emailAddress,
263 screenName, themeDisplay.getLocale());
264 }
265
266 ses.setAttribute(WebKeys.OPEN_ID_LOGIN, new Long(user.getUserId()));
267
268 return user;
269 }
270
271 private static Log _log = LogFactory.getLog(OpenIdResponseAction.class);
272
273 }