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