001    /**
002     * Copyright (c) 2000-2011 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.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                    User user = null;
174    
175                    long facebookId = jsonObject.getLong("id");
176    
177                    if (facebookId > 0) {
178                            session.setAttribute(
179                                    WebKeys.FACEBOOK_USER_ID, String.valueOf(facebookId));
180    
181                            try {
182                                    user = UserLocalServiceUtil.getUserByFacebookId(
183                                            companyId, facebookId);
184                            }
185                            catch (NoSuchUserException nsue) {
186                            }
187                    }
188    
189                    String emailAddress = jsonObject.getString("email");
190    
191                    if ((user == null) && Validator.isNotNull(emailAddress)) {
192                            session.setAttribute(
193                                    WebKeys.FACEBOOK_USER_EMAIL_ADDRESS, emailAddress);
194    
195                            try {
196                                    user = UserLocalServiceUtil.getUserByEmailAddress(
197                                            companyId, emailAddress);
198                            }
199                            catch (NoSuchUserException nsue) {
200                            }
201                    }
202    
203                    if (user != null) {
204                            updateUser(user, jsonObject);
205                    }
206                    else {
207                            addUser(session, companyId, jsonObject);
208                    }
209            }
210    
211            protected void updateUser(User user, JSONObject jsonObject)
212                    throws Exception {
213    
214                    long facebookId = jsonObject.getLong("id");
215                    String emailAddress = jsonObject.getString("email");
216                    String firstName = jsonObject.getString("first_name");
217                    String lastName = jsonObject.getString("last_name");
218                    boolean male = Validator.equals(jsonObject.getString("gender"), "male");
219    
220                    if ((facebookId == user.getFacebookId()) &&
221                            emailAddress.equals(user.getEmailAddress()) &&
222                            firstName.equals(user.getFirstName()) &&
223                            lastName.equals(user.getLastName()) && (male == user.isMale())) {
224    
225                            return;
226                    }
227    
228                    Contact contact = user.getContact();
229    
230                    Calendar birthdayCal = CalendarFactoryUtil.getCalendar();
231    
232                    birthdayCal.setTime(contact.getBirthday());
233    
234                    int birthdayMonth = birthdayCal.get(Calendar.MONTH);
235                    int birthdayDay = birthdayCal.get(Calendar.DAY_OF_MONTH);
236                    int birthdayYear = birthdayCal.get(Calendar.YEAR);
237    
238                    long[] groupIds = null;
239                    long[] organizationIds = null;
240                    long[] roleIds = null;
241                    List<UserGroupRole> userGroupRoles = null;
242                    long[] userGroupIds = null;
243    
244                    ServiceContext serviceContext = new ServiceContext();
245    
246                    if (!emailAddress.equalsIgnoreCase(user.getEmailAddress())) {
247                            UserLocalServiceUtil.updateEmailAddress(
248                                    user.getUserId(), StringPool.BLANK, emailAddress, emailAddress);
249                    }
250    
251                    UserLocalServiceUtil.updateEmailAddressVerified(user.getUserId(), true);
252    
253                    UserLocalServiceUtil.updateUser(
254                            user.getUserId(), StringPool.BLANK, StringPool.BLANK,
255                            StringPool.BLANK, false, user.getReminderQueryQuestion(),
256                            user.getReminderQueryAnswer(), user.getScreenName(),
257                            emailAddress, facebookId, user.getOpenId(), user.getLanguageId(),
258                            user.getTimeZoneId(), user.getGreeting(), user.getComments(),
259                            firstName, user.getMiddleName(), lastName, contact.getPrefixId(),
260                            contact.getSuffixId(), male, birthdayMonth, birthdayDay,
261                            birthdayYear, contact.getSmsSn(), contact.getAimSn(),
262                            contact.getFacebookSn(), contact.getIcqSn(), contact.getJabberSn(),
263                            contact.getMsnSn(), contact.getMySpaceSn(), contact.getSkypeSn(),
264                            contact.getTwitterSn(), contact.getYmSn(), contact.getJobTitle(),
265                            groupIds, organizationIds, roleIds, userGroupRoles, userGroupIds,
266                            serviceContext);
267            }
268    
269    }