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