001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.login.action;
016    
017    import com.liferay.portal.kernel.facebook.FacebookConnectUtil;
018    import com.liferay.portal.kernel.json.JSONObject;
019    import com.liferay.portal.kernel.portlet.LiferayWindowState;
020    import com.liferay.portal.kernel.util.CalendarFactoryUtil;
021    import com.liferay.portal.kernel.util.LocaleUtil;
022    import com.liferay.portal.kernel.util.ParamUtil;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.kernel.util.Validator;
026    import com.liferay.portal.kernel.workflow.WorkflowConstants;
027    import com.liferay.portal.model.Contact;
028    import com.liferay.portal.model.User;
029    import com.liferay.portal.model.UserGroupRole;
030    import com.liferay.portal.security.auth.PrincipalException;
031    import com.liferay.portal.service.ServiceContext;
032    import com.liferay.portal.service.UserLocalServiceUtil;
033    import com.liferay.portal.struts.ActionConstants;
034    import com.liferay.portal.struts.PortletAction;
035    import com.liferay.portal.theme.ThemeDisplay;
036    import com.liferay.portal.util.PortalUtil;
037    import com.liferay.portal.util.PortletKeys;
038    import com.liferay.portal.util.WebKeys;
039    import com.liferay.portlet.PortletURLFactoryUtil;
040    
041    import java.util.Calendar;
042    import java.util.List;
043    import java.util.Locale;
044    
045    import javax.portlet.PortletConfig;
046    import javax.portlet.PortletMode;
047    import javax.portlet.PortletRequest;
048    import javax.portlet.PortletURL;
049    import javax.portlet.RenderRequest;
050    import javax.portlet.RenderResponse;
051    
052    import javax.servlet.http.HttpServletRequest;
053    import javax.servlet.http.HttpServletResponse;
054    import javax.servlet.http.HttpSession;
055    
056    import org.apache.struts.action.ActionForm;
057    import org.apache.struts.action.ActionForward;
058    import org.apache.struts.action.ActionMapping;
059    
060    /**
061     * @author Wilson Man
062     * @author Sergio Gonz??lez
063     * @author Mika Koivisto
064     */
065    public class FacebookConnectAction extends PortletAction {
066    
067            @Override
068            public ActionForward render(
069                            ActionMapping actionMapping, ActionForm actionForm,
070                            PortletConfig portletConfig, RenderRequest renderRequest,
071                            RenderResponse renderResponse)
072                    throws Exception {
073    
074                    ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(
075                            WebKeys.THEME_DISPLAY);
076    
077                    if (!FacebookConnectUtil.isEnabled(themeDisplay.getCompanyId())) {
078                            return actionMapping.findForward("portlet.login.login");
079                    }
080    
081                    return actionMapping.findForward("portlet.login.facebook_login");
082            }
083    
084            @Override
085            public ActionForward strutsExecute(
086                            ActionMapping actionMapping, ActionForm actionForm,
087                            HttpServletRequest request, HttpServletResponse response)
088                    throws Exception {
089    
090                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
091                            WebKeys.THEME_DISPLAY);
092    
093                    if (!FacebookConnectUtil.isEnabled(themeDisplay.getCompanyId())) {
094                            throw new PrincipalException();
095                    }
096    
097                    HttpSession session = request.getSession();
098    
099                    String redirect = ParamUtil.getString(request, "redirect");
100    
101                    redirect = PortalUtil.escapeRedirect(redirect);
102    
103                    String code = ParamUtil.getString(request, "code");
104    
105                    String token = FacebookConnectUtil.getAccessToken(
106                            themeDisplay.getCompanyId(), redirect, code);
107    
108                    if (Validator.isNotNull(token)) {
109                            User user = setFacebookCredentials(
110                                    session, themeDisplay.getCompanyId(), token);
111    
112                            if ((user != null) &&
113                                    (user.getStatus() == WorkflowConstants.STATUS_INCOMPLETE)) {
114    
115                                    redirectUpdateAccount(request, response, user);
116    
117                                    return null;
118                            }
119                    }
120                    else {
121                            return actionMapping.findForward(
122                                    ActionConstants.COMMON_REFERER_JSP);
123                    }
124    
125                    response.sendRedirect(redirect);
126    
127                    return null;
128            }
129    
130            protected User addUser(
131                            HttpSession session, long companyId, JSONObject jsonObject)
132                    throws Exception {
133    
134                    long creatorUserId = 0;
135                    boolean autoPassword = true;
136                    String password1 = StringPool.BLANK;
137                    String password2 = StringPool.BLANK;
138                    boolean autoScreenName = true;
139                    String screenName = StringPool.BLANK;
140                    String emailAddress = jsonObject.getString("email");
141                    long facebookId = jsonObject.getLong("id");
142                    String openId = StringPool.BLANK;
143                    Locale locale = LocaleUtil.getDefault();
144                    String firstName = jsonObject.getString("first_name");
145                    String middleName = StringPool.BLANK;
146                    String lastName = jsonObject.getString("last_name");
147                    int prefixId = 0;
148                    int suffixId = 0;
149                    boolean male = Validator.equals(jsonObject.getString("gender"), "male");
150                    int birthdayMonth = Calendar.JANUARY;
151                    int birthdayDay = 1;
152                    int birthdayYear = 1970;
153                    String jobTitle = StringPool.BLANK;
154                    long[] groupIds = null;
155                    long[] organizationIds = null;
156                    long[] roleIds = null;
157                    long[] userGroupIds = null;
158                    boolean sendEmail = true;
159    
160                    ServiceContext serviceContext = new ServiceContext();
161    
162                    User user = UserLocalServiceUtil.addUser(
163                            creatorUserId, companyId, autoPassword, password1, password2,
164                            autoScreenName, screenName, emailAddress, facebookId, openId,
165                            locale, firstName, middleName, lastName, prefixId, suffixId, male,
166                            birthdayMonth, birthdayDay, birthdayYear, jobTitle, groupIds,
167                            organizationIds, roleIds, userGroupIds, sendEmail, serviceContext);
168    
169                    user = UserLocalServiceUtil.updateLastLogin(
170                            user.getUserId(), user.getLoginIP());
171    
172                    user = UserLocalServiceUtil.updatePasswordReset(
173                            user.getUserId(), false);
174    
175                    user = UserLocalServiceUtil.updateEmailAddressVerified(
176                            user.getUserId(), true);
177    
178                    session.setAttribute(WebKeys.FACEBOOK_USER_EMAIL_ADDRESS, emailAddress);
179    
180                    return user;
181            }
182    
183            protected void redirectUpdateAccount(
184                            HttpServletRequest request, HttpServletResponse response, User user)
185                    throws Exception {
186    
187                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
188                            WebKeys.THEME_DISPLAY);
189    
190                    PortletURL portletURL = PortletURLFactoryUtil.create(
191                            request, PortletKeys.LOGIN, themeDisplay.getPlid(),
192                            PortletRequest.RENDER_PHASE);
193    
194                    portletURL.setParameter("saveLastPath", Boolean.FALSE.toString());
195                    portletURL.setParameter("struts_action", "/login/update_account");
196    
197                    PortletURL redirectURL = PortletURLFactoryUtil.create(
198                            request, PortletKeys.FAST_LOGIN, themeDisplay.getPlid(),
199                            PortletRequest.RENDER_PHASE);
200    
201                    redirectURL.setParameter("struts_action", "/login/login_redirect");
202                    redirectURL.setParameter("emailAddress", user.getEmailAddress());
203                    redirectURL.setParameter("anonymousUser", Boolean.FALSE.toString());
204                    redirectURL.setPortletMode(PortletMode.VIEW);
205                    redirectURL.setWindowState(LiferayWindowState.POP_UP);
206    
207                    portletURL.setParameter("redirect", redirectURL.toString());
208                    portletURL.setParameter("userId", String.valueOf(user.getUserId()));
209                    portletURL.setParameter("emailAddress", user.getEmailAddress());
210                    portletURL.setParameter("firstName", user.getFirstName());
211                    portletURL.setParameter("lastName", user.getLastName());
212                    portletURL.setPortletMode(PortletMode.VIEW);
213                    portletURL.setWindowState(LiferayWindowState.POP_UP);
214    
215                    response.sendRedirect(portletURL.toString());
216            }
217    
218            protected User setFacebookCredentials(
219                            HttpSession session, long companyId, String token)
220                    throws Exception {
221    
222                    JSONObject jsonObject = FacebookConnectUtil.getGraphResources(
223                            companyId, "/me", token,
224                            "id,email,first_name,last_name,gender");
225    
226                    if ((jsonObject == null) ||
227                            (jsonObject.getJSONObject("error") != null)) {
228    
229                            return null;
230                    }
231    
232                    if (FacebookConnectUtil.isVerifiedAccountRequired(companyId) &&
233                            !jsonObject.getBoolean("verified")) {
234    
235                            return null;
236                    }
237    
238                    User user = null;
239    
240                    long facebookId = jsonObject.getLong("id");
241    
242                    if (facebookId > 0) {
243                            session.setAttribute(WebKeys.FACEBOOK_ACCESS_TOKEN, token);
244    
245                            user = UserLocalServiceUtil.fetchUserByFacebookId(
246                                    companyId, facebookId);
247    
248                            if ((user != null) &&
249                                    (user.getStatus() != WorkflowConstants.STATUS_INCOMPLETE)) {
250    
251                                    session.setAttribute(
252                                            WebKeys.FACEBOOK_USER_ID, String.valueOf(facebookId));
253                            }
254                    }
255    
256                    String emailAddress = jsonObject.getString("email");
257    
258                    if ((user == null) && Validator.isNotNull(emailAddress)) {
259                            user = UserLocalServiceUtil.fetchUserByEmailAddress(
260                                    companyId, emailAddress);
261    
262                            if ((user != null) &&
263                                    (user.getStatus() != WorkflowConstants.STATUS_INCOMPLETE)) {
264    
265                                    session.setAttribute(
266                                            WebKeys.FACEBOOK_USER_EMAIL_ADDRESS, emailAddress);
267                            }
268                    }
269    
270                    if (user != null) {
271                            if (user.getStatus() == WorkflowConstants.STATUS_INCOMPLETE) {
272                                    session.setAttribute(
273                                            WebKeys.FACEBOOK_INCOMPLETE_USER_ID, facebookId);
274    
275                                    user.setEmailAddress(jsonObject.getString("email"));
276                                    user.setFirstName(jsonObject.getString("first_name"));
277                                    user.setLastName(jsonObject.getString("last_name"));
278    
279                                    return user;
280                            }
281    
282                            user = updateUser(user, jsonObject);
283                    }
284                    else {
285                            user = addUser(session, companyId, jsonObject);
286                    }
287    
288                    return user;
289            }
290    
291            protected User updateUser(User user, JSONObject jsonObject)
292                    throws Exception {
293    
294                    long facebookId = jsonObject.getLong("id");
295                    String emailAddress = jsonObject.getString("email");
296                    String firstName = jsonObject.getString("first_name");
297                    String lastName = jsonObject.getString("last_name");
298                    boolean male = Validator.equals(jsonObject.getString("gender"), "male");
299    
300                    if ((facebookId == user.getFacebookId()) &&
301                            emailAddress.equals(user.getEmailAddress()) &&
302                            firstName.equals(user.getFirstName()) &&
303                            lastName.equals(user.getLastName()) && (male == user.isMale())) {
304    
305                            return user;
306                    }
307    
308                    Contact contact = user.getContact();
309    
310                    Calendar birthdayCal = CalendarFactoryUtil.getCalendar();
311    
312                    birthdayCal.setTime(contact.getBirthday());
313    
314                    int birthdayMonth = birthdayCal.get(Calendar.MONTH);
315                    int birthdayDay = birthdayCal.get(Calendar.DAY_OF_MONTH);
316                    int birthdayYear = birthdayCal.get(Calendar.YEAR);
317    
318                    long[] groupIds = null;
319                    long[] organizationIds = null;
320                    long[] roleIds = null;
321                    List<UserGroupRole> userGroupRoles = null;
322                    long[] userGroupIds = null;
323    
324                    ServiceContext serviceContext = new ServiceContext();
325    
326                    if (!StringUtil.equalsIgnoreCase(
327                                    emailAddress, user.getEmailAddress())) {
328    
329                            UserLocalServiceUtil.updateEmailAddress(
330                                    user.getUserId(), StringPool.BLANK, emailAddress, emailAddress);
331                    }
332    
333                    UserLocalServiceUtil.updateEmailAddressVerified(user.getUserId(), true);
334    
335                    return UserLocalServiceUtil.updateUser(
336                            user.getUserId(), StringPool.BLANK, StringPool.BLANK,
337                            StringPool.BLANK, false, user.getReminderQueryQuestion(),
338                            user.getReminderQueryAnswer(), user.getScreenName(), emailAddress,
339                            facebookId, user.getOpenId(), user.getLanguageId(),
340                            user.getTimeZoneId(), user.getGreeting(), user.getComments(),
341                            firstName, user.getMiddleName(), lastName, contact.getPrefixId(),
342                            contact.getSuffixId(), male, birthdayMonth, birthdayDay,
343                            birthdayYear, contact.getSmsSn(), contact.getAimSn(),
344                            contact.getFacebookSn(), contact.getIcqSn(), contact.getJabberSn(),
345                            contact.getMsnSn(), contact.getMySpaceSn(), contact.getSkypeSn(),
346                            contact.getTwitterSn(), contact.getYmSn(), contact.getJobTitle(),
347                            groupIds, organizationIds, roleIds, userGroupRoles, userGroupIds,
348                            serviceContext);
349            }
350    
351    }