001: /**
002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
003: *
004: * Permission is hereby granted, free of charge, to any person obtaining a copy
005: * of this software and associated documentation files (the "Software"), to deal
006: * in the Software without restriction, including without limitation the rights
007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008: * copies of the Software, and to permit persons to whom the Software is
009: * furnished to do so, subject to the following conditions:
010: *
011: * The above copyright notice and this permission notice shall be included in
012: * all copies or substantial portions of the Software.
013: *
014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
020: * SOFTWARE.
021: */package com.liferay.portal.action;
022:
023: import com.liferay.portal.NoSuchUserException;
024: import com.liferay.portal.kernel.util.GetterUtil;
025: import com.liferay.portal.kernel.util.StringPool;
026: import com.liferay.portal.kernel.util.Validator;
027: import com.liferay.portal.model.User;
028: import com.liferay.portal.service.UserLocalServiceUtil;
029: import com.liferay.portal.struts.ActionConstants;
030: import com.liferay.portal.theme.ThemeDisplay;
031: import com.liferay.portal.util.OpenIdUtil;
032: import com.liferay.portal.util.PortalUtil;
033: import com.liferay.portal.util.WebKeys;
034: import com.liferay.util.PwdGenerator;
035: import com.liferay.util.servlet.SessionErrors;
036:
037: import java.util.Calendar;
038: import java.util.List;
039: import java.util.Locale;
040:
041: import javax.servlet.http.HttpServletRequest;
042: import javax.servlet.http.HttpServletResponse;
043: import javax.servlet.http.HttpSession;
044: import javax.servlet.jsp.PageContext;
045:
046: import org.apache.commons.logging.Log;
047: import org.apache.commons.logging.LogFactory;
048: import org.apache.struts.action.Action;
049: import org.apache.struts.action.ActionForm;
050: import org.apache.struts.action.ActionForward;
051: import org.apache.struts.action.ActionMapping;
052:
053: import org.openid4java.association.AssociationException;
054: import org.openid4java.consumer.ConsumerException;
055: import org.openid4java.consumer.ConsumerManager;
056: import org.openid4java.consumer.VerificationResult;
057: import org.openid4java.discovery.DiscoveryException;
058: import org.openid4java.discovery.DiscoveryInformation;
059: import org.openid4java.discovery.Identifier;
060: import org.openid4java.message.AuthSuccess;
061: import org.openid4java.message.MessageException;
062: import org.openid4java.message.MessageExtension;
063: import org.openid4java.message.ParameterList;
064: import org.openid4java.message.ax.AxMessage;
065: import org.openid4java.message.ax.FetchResponse;
066: import org.openid4java.message.sreg.SRegMessage;
067: import org.openid4java.message.sreg.SRegResponse;
068:
069: /**
070: * <a href="OpenIdResponseAction.java.html"><b><i>View Source</i></b></a>
071: *
072: * @author Jorge Ferrer
073: *
074: */
075: public class OpenIdResponseAction extends Action {
076:
077: public ActionForward execute(ActionMapping mapping,
078: ActionForm form, HttpServletRequest req,
079: HttpServletResponse res) throws Exception {
080:
081: ThemeDisplay themeDisplay = (ThemeDisplay) req
082: .getAttribute(WebKeys.THEME_DISPLAY);
083:
084: if (!OpenIdUtil.isEnabled(themeDisplay.getCompanyId())) {
085: return null;
086: }
087:
088: try {
089: readResponse(themeDisplay, req);
090: } catch (Exception e) {
091: if (e instanceof AssociationException
092: || e instanceof ConsumerException
093: || e instanceof DiscoveryException
094: || e instanceof MessageException) {
095:
096: SessionErrors.add(req, e.getClass().getName());
097:
098: return mapping.findForward("portal.login");
099: } else {
100: req.setAttribute(PageContext.EXCEPTION, e);
101:
102: return mapping
103: .findForward(ActionConstants.COMMON_ERROR);
104: }
105: }
106:
107: String loginURL = PortalUtil.getPortalURL(req)
108: + themeDisplay.getPathMain() + "/portal/login";
109:
110: res.sendRedirect(loginURL);
111:
112: return null;
113: }
114:
115: protected User addUser(long companyId, String firstName,
116: String lastName, String emailAddress, String screenName,
117: Locale locale) throws Exception {
118:
119: long creatorUserId = 0;
120: boolean autoPassword = false;
121: String password1 = PwdGenerator.getPassword();
122: String password2 = password1;
123: boolean autoScreenName = false;
124: String middleName = StringPool.BLANK;
125: int prefixId = 0;
126: int suffixId = 0;
127: boolean male = true;
128: int birthdayMonth = Calendar.JANUARY;
129: int birthdayDay = 1;
130: int birthdayYear = 1970;
131: String jobTitle = StringPool.BLANK;
132: long[] organizationIds = new long[0];
133: boolean sendEmail = false;
134:
135: return UserLocalServiceUtil.addUser(creatorUserId, companyId,
136: autoPassword, password1, password2, autoScreenName,
137: screenName, emailAddress, locale, firstName,
138: middleName, lastName, prefixId, suffixId, male,
139: birthdayMonth, birthdayDay, birthdayYear, jobTitle,
140: organizationIds, sendEmail);
141: }
142:
143: protected String getFirstValue(List values) {
144: if ((values == null) || (values.size() < 1)) {
145: return null;
146: }
147:
148: return (String) values.get(0);
149: }
150:
151: protected User readResponse(ThemeDisplay themeDisplay,
152: HttpServletRequest req) throws Exception {
153:
154: HttpSession ses = req.getSession();
155:
156: ConsumerManager manager = OpenIdUtil.getConsumerManager();
157:
158: ParameterList params = new ParameterList(req.getParameterMap());
159:
160: DiscoveryInformation discovered = (DiscoveryInformation) ses
161: .getAttribute(WebKeys.OPEN_ID_DISCO);
162:
163: if (discovered == null) {
164: return null;
165: }
166:
167: StringBuffer receivingURL = req.getRequestURL();
168: String queryString = req.getQueryString();
169:
170: if ((queryString != null) && (queryString.length() > 0)) {
171: receivingURL.append(StringPool.QUESTION);
172: receivingURL.append(req.getQueryString());
173: }
174:
175: VerificationResult verification = manager.verify(receivingURL
176: .toString(), params, discovered);
177:
178: Identifier verified = verification.getVerifiedId();
179:
180: if (verified == null) {
181: return null;
182: }
183:
184: AuthSuccess authSuccess = (AuthSuccess) verification
185: .getAuthResponse();
186:
187: String firstName = null;
188: String lastName = null;
189: String emailAddress = null;
190:
191: if (authSuccess.hasExtension(SRegMessage.OPENID_NS_SREG)) {
192: MessageExtension ext = authSuccess
193: .getExtension(SRegMessage.OPENID_NS_SREG);
194:
195: if (ext instanceof SRegResponse) {
196: SRegResponse sregResp = (SRegResponse) ext;
197:
198: String fullName = GetterUtil.getString(sregResp
199: .getAttributeValue("fullname"));
200:
201: int pos = fullName.indexOf(StringPool.SPACE);
202:
203: if ((pos != -1) && ((pos + 1) < fullName.length())) {
204: firstName = fullName.substring(0, pos);
205: lastName = fullName.substring(pos + 1);
206: }
207:
208: emailAddress = sregResp.getAttributeValue("email");
209: }
210: }
211:
212: if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
213: MessageExtension ext = authSuccess
214: .getExtension(AxMessage.OPENID_NS_AX);
215:
216: if (ext instanceof FetchResponse) {
217: FetchResponse fetchResp = (FetchResponse) ext;
218:
219: if (Validator.isNull(firstName)) {
220: firstName = getFirstValue(fetchResp
221: .getAttributeValues("firstName"));
222: }
223:
224: if (Validator.isNull(lastName)) {
225: lastName = getFirstValue(fetchResp
226: .getAttributeValues("lastName"));
227: }
228:
229: if (Validator.isNull(emailAddress)) {
230: emailAddress = getFirstValue(fetchResp
231: .getAttributeValues("email"));
232: }
233: }
234: }
235:
236: String screenName = OpenIdUtil.getScreenName(authSuccess
237: .getIdentity());
238:
239: User user = null;
240:
241: try {
242: user = UserLocalServiceUtil.getUserByScreenName(
243: themeDisplay.getCompanyId(), screenName);
244: } catch (NoSuchUserException nsue) {
245: if (Validator.isNull(firstName)
246: || Validator.isNull(lastName)
247: || Validator.isNull(emailAddress)) {
248:
249: SessionErrors.add(req, "missingOpenIdUserInformation");
250:
251: _log
252: .error("The OpenID provider did not send the required "
253: + "attributes to create an account");
254:
255: return null;
256: }
257:
258: user = addUser(themeDisplay.getCompanyId(), firstName,
259: lastName, emailAddress, screenName, themeDisplay
260: .getLocale());
261: }
262:
263: ses.setAttribute(WebKeys.OPEN_ID_LOGIN, new Long(user
264: .getUserId()));
265:
266: return user;
267: }
268:
269: private static Log _log = LogFactory
270: .getLog(OpenIdResponseAction.class);
271:
272: }
|