001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.login.action;
016    
017    import com.liferay.portal.NoSuchUserException;
018    import com.liferay.portal.kernel.facebook.FacebookConnectUtil;
019    import com.liferay.portal.kernel.json.JSONObject;
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.Validator;
025    import com.liferay.portal.model.Contact;
026    import com.liferay.portal.model.User;
027    import com.liferay.portal.model.UserGroupRole;
028    import com.liferay.portal.service.ServiceContext;
029    import com.liferay.portal.service.UserLocalServiceUtil;
030    import com.liferay.portal.struts.ActionConstants;
031    import com.liferay.portal.struts.PortletAction;
032    import com.liferay.portal.theme.ThemeDisplay;
033    import com.liferay.portal.util.WebKeys;
034    
035    import java.util.Calendar;
036    import java.util.List;
037    import java.util.Locale;
038    
039    import javax.portlet.PortletConfig;
040    import javax.portlet.RenderRequest;
041    import javax.portlet.RenderResponse;
042    
043    import javax.servlet.http.HttpServletRequest;
044    import javax.servlet.http.HttpServletResponse;
045    import javax.servlet.http.HttpSession;
046    
047    import org.apache.struts.action.ActionForm;
048    import org.apache.struts.action.ActionForward;
049    import org.apache.struts.action.ActionMapping;
050    
051    /**
052     * @author Wilson Man
053     * @author Sergio González
054     * @author Mika Koivisto
055     */
056    public class FacebookConnectAction extends PortletAction {
057    
058            @Override
059            public ActionForward render(
060                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
061                            RenderRequest renderRequest, RenderResponse renderResponse)
062                    throws Exception {
063    
064                    ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(
065                            WebKeys.THEME_DISPLAY);
066    
067                    if (!FacebookConnectUtil.isEnabled(themeDisplay.getCompanyId())) {
068                            return null;
069                    }
070    
071                    return mapping.findForward("portlet.login.facebook_login");
072            }
073    
074            @Override
075            public ActionForward strutsExecute(
076                            ActionMapping mapping, ActionForm form, HttpServletRequest request,
077                            HttpServletResponse response)
078                    throws Exception {
079    
080                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
081                            WebKeys.THEME_DISPLAY);
082    
083                    if (!FacebookConnectUtil.isEnabled(themeDisplay.getCompanyId())) {
084                            return null;
085                    }
086    
087                    HttpSession session = request.getSession();
088    
089                    String redirect = ParamUtil.getString(request, "redirect");
090    
091                    String code = ParamUtil.getString(request, "code");
092    
093                    String token = FacebookConnectUtil.getAccessToken(
094                            themeDisplay.getCompanyId(), redirect, code);
095    
096                    if (Validator.isNotNull(token)) {
097                            session.setAttribute(WebKeys.FACEBOOK_ACCESS_TOKEN, token);
098    
099                            setFacebookCredentials(session, themeDisplay.getCompanyId(), token);
100                    }
101                    else {
102                            return mapping.findForward(ActionConstants.COMMON_REFERER);
103                    }
104    
105                    response.sendRedirect(redirect);
106    
107                    return null;
108            }
109    
110            protected void addUser(
111                            HttpSession session, long companyId, JSONObject jsonObject)
112                    throws Exception {
113    
114                    long creatorUserId = 0;
115                    boolean autoPassword = true;
116                    String password1 = StringPool.BLANK;
117                    String password2 = StringPool.BLANK;
118                    boolean autoScreenName = true;
119                    String screenName = StringPool.BLANK;
120                    String emailAddress = jsonObject.getString("email");
121                    long facebookId = jsonObject.getLong("id");
122                    String openId = StringPool.BLANK;
123                    Locale locale = LocaleUtil.getDefault();
124                    String firstName = jsonObject.getString("first_name");
125                    String middleName = StringPool.BLANK;
126                    String lastName = jsonObject.getString("last_name");
127                    int prefixId = 0;
128                    int suffixId = 0;
129                    boolean male = Validator.equals(jsonObject.getString("gender"), "male");
130                    int birthdayMonth = Calendar.JANUARY;
131                    int birthdayDay = 1;
132                    int birthdayYear = 1970;
133                    String jobTitle = StringPool.BLANK;
134                    long[] groupIds = null;
135                    long[] organizationIds = null;
136                    long[] roleIds = null;
137                    long[] userGroupIds = null;
138                    boolean sendEmail = true;
139    
140                    ServiceContext serviceContext = new ServiceContext();
141    
142                    User user = UserLocalServiceUtil.addUser(
143                            creatorUserId, companyId, autoPassword, password1, password2,
144                            autoScreenName, screenName, emailAddress, facebookId, openId,
145                            locale, firstName, middleName, lastName, prefixId, suffixId, male,
146                            birthdayMonth, birthdayDay, birthdayYear, jobTitle, groupIds,
147                            organizationIds, roleIds, userGroupIds, sendEmail, serviceContext);
148    
149                    UserLocalServiceUtil.updateLastLogin(
150                            user.getUserId(), user.getLoginIP());
151    
152                    UserLocalServiceUtil.updatePasswordReset(user.getUserId(), false);
153    
154                    UserLocalServiceUtil.updateEmailAddressVerified(user.getUserId(), true);
155    
156                    session.setAttribute(WebKeys.FACEBOOK_USER_EMAIL_ADDRESS, emailAddress);
157            }
158    
159            protected void setFacebookCredentials(
160                            HttpSession session, long companyId, String token)
161                    throws Exception {
162    
163                    JSONObject jsonObject = FacebookConnectUtil.getGraphResources(
164                            companyId, "/me", token,
165                            "id,email,first_name,last_name,gender");
166    
167                    if ((jsonObject == null) ||
168                            (jsonObject.getJSONObject("error") != null)) {
169    
170                            return;
171                    }
172    
173                    if (FacebookConnectUtil.isVerifiedAccountRequired(companyId) &&
174                            !jsonObject.getBoolean("verified")) {
175    
176                            return;
177                    }
178    
179                    User user = null;
180    
181                    long facebookId = jsonObject.getLong("id");
182    
183                    if (facebookId > 0) {
184                            session.setAttribute(
185                                    WebKeys.FACEBOOK_USER_ID, String.valueOf(facebookId));
186    
187                            try {
188                                    user = UserLocalServiceUtil.getUserByFacebookId(
189                                            companyId, facebookId);
190                            }
191                            catch (NoSuchUserException nsue) {
192                            }
193                    }
194    
195                    String emailAddress = jsonObject.getString("email");
196    
197                    if ((user == null) && Validator.isNotNull(emailAddress)) {
198                            session.setAttribute(
199                                    WebKeys.FACEBOOK_USER_EMAIL_ADDRESS, emailAddress);
200    
201                            try {
202                                    user = UserLocalServiceUtil.getUserByEmailAddress(
203                                            companyId, emailAddress);
204                            }
205                            catch (NoSuchUserException nsue) {
206                            }
207                    }
208    
209                    if (user != null) {
210                            updateUser(user, jsonObject);
211                    }
212                    else {
213                            addUser(session, companyId, jsonObject);
214                    }
215            }
216    
217            protected void updateUser(User user, JSONObject jsonObject)
218                    throws Exception {
219    
220                    long facebookId = jsonObject.getLong("id");
221                    String emailAddress = jsonObject.getString("email");
222                    String firstName = jsonObject.getString("first_name");
223                    String lastName = jsonObject.getString("last_name");
224                    boolean male = Validator.equals(jsonObject.getString("gender"), "male");
225    
226                    if ((facebookId == user.getFacebookId()) &&
227                            emailAddress.equals(user.getEmailAddress()) &&
228                            firstName.equals(user.getFirstName()) &&
229                            lastName.equals(user.getLastName()) && (male == user.isMale())) {
230    
231                            return;
232                    }
233    
234                    Contact contact = user.getContact();
235    
236                    Calendar birthdayCal = CalendarFactoryUtil.getCalendar();
237    
238                    birthdayCal.setTime(contact.getBirthday());
239    
240                    int birthdayMonth = birthdayCal.get(Calendar.MONTH);
241                    int birthdayDay = birthdayCal.get(Calendar.DAY_OF_MONTH);
242                    int birthdayYear = birthdayCal.get(Calendar.YEAR);
243    
244                    long[] groupIds = null;
245                    long[] organizationIds = null;
246                    long[] roleIds = null;
247                    List<UserGroupRole> userGroupRoles = null;
248                    long[] userGroupIds = null;
249    
250                    ServiceContext serviceContext = new ServiceContext();
251    
252                    if (!emailAddress.equalsIgnoreCase(user.getEmailAddress())) {
253                            UserLocalServiceUtil.updateEmailAddress(
254                                    user.getUserId(), StringPool.BLANK, emailAddress, emailAddress);
255                    }
256    
257                    UserLocalServiceUtil.updateEmailAddressVerified(user.getUserId(), true);
258    
259                    UserLocalServiceUtil.updateUser(
260                            user.getUserId(), StringPool.BLANK, StringPool.BLANK,
261                            StringPool.BLANK, false, user.getReminderQueryQuestion(),
262                            user.getReminderQueryAnswer(), user.getScreenName(),
263                            emailAddress, facebookId, user.getOpenId(), user.getLanguageId(),
264                            user.getTimeZoneId(), user.getGreeting(), user.getComments(),
265                            firstName, user.getMiddleName(), lastName, contact.getPrefixId(),
266                            contact.getSuffixId(), male, birthdayMonth, birthdayDay,
267                            birthdayYear, contact.getSmsSn(), contact.getAimSn(),
268                            contact.getFacebookSn(), contact.getIcqSn(), contact.getJabberSn(),
269                            contact.getMsnSn(), contact.getMySpaceSn(), contact.getSkypeSn(),
270                            contact.getTwitterSn(), contact.getYmSn(), contact.getJobTitle(),
271                            groupIds, organizationIds, roleIds, userGroupRoles, userGroupIds,
272                            serviceContext);
273            }
274    
275    }