Blame | Last modification | View Log | RSS feed
package in.shop2020.serving.interceptors;import in.shop2020.serving.services.UserSessionInfo;import in.shop2020.serving.utils.DesEncrypter;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import org.apache.log4j.Logger;import org.apache.struts2.ServletActionContext;import org.apache.struts2.StrutsStatics;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.AbstractInterceptor;import com.opensymphony.xwork2.interceptor.PreResultListener;public class UserInterceptor extends AbstractInterceptor implements PreResultListener{public static final int SECONDS_IN_YEAR = 60*60*24*365;public static final int FACEBOOK_USER_COOKIE_EXPIRY_TIME = 60*60*24*60;private static final long serialVersionUID = -4125815700236506235L;private static Logger log = Logger.getLogger(UserInterceptor.class);public static final String USER_INFO_COOKIE_NAME = "uic";public static final String USER_ID_COOKIE_NAME = "uid";public static final String COOKIE_DECRYPTION_STRING = "shop2020";private DesEncrypter desEncrypter = new DesEncrypter(COOKIE_DECRYPTION_STRING);private String cookieDomain = "";public void setCookieDomain(String cookieDomain) {this.cookieDomain = cookieDomain;}@Overridepublic String intercept(ActionInvocation invocation) throws Exception {final Object action = invocation.getAction();log.debug("inside user intercepror");HttpServletRequest request = ServletActionContext.getRequest();HttpSession session = request.getSession(); // Do not remove it, session id is used for session tracking.Map<String, Cookie> cookiesMap = createCookiesMap(request);// CreateUserInterceptor may have set the userinfo object in the request// itself. If we can get the userinfo object here, we don't need to// parse the cookies that came in with the request.UserSessionInfo userInfo = (UserSessionInfo) request.getAttribute(USER_INFO_COOKIE_NAME);Cookie userCookie = cookiesMap.get(UserInterceptor.USER_ID_COOKIE_NAME);Cookie userinfoCookie = cookiesMap.get(USER_INFO_COOKIE_NAME);if(userInfo == null ){//Okay, we didn't get the userinfo object from the request. Time to parse the UIC cookie.if(userinfoCookie!=null){userInfo = UserSessionInfo.getUserSessionInfoFromCookieValue(userinfoCookie.getValue());if(userInfo.getUserId() == -1){//This means that the cookie couldn't be parsed. So, we should remove the cookie.expireUicCookie();expireUidCookie();}} else {//No UIC cookie too. Try the old UID cookie. This method is guaranteed to return a userinfo object, cookie or not.userInfo = createAndGetSessionFromUIDCookie(session, cookiesMap, userCookie);}}//Set the request attribute for access by other interceptors.request.setAttribute(USER_INFO_COOKIE_NAME, userInfo);//Set the userinfo object for use by actions.if (action instanceof UserAware) {UserAware sessionAction = (UserAware) action;sessionAction.setSession(session);sessionAction.setUserSessionInfo(userInfo);sessionAction.setCookiesMap(cookiesMap);sessionAction.setUserCookie(userCookie);sessionAction.setCookieDomainName(cookieDomain);}// Ensure that the response of the action is presented to the pre-result// listened of this interceptor. We want to add the cookies there.invocation.addPreResultListener(this);return invocation.invoke();}@Overridepublic void beforeResult(ActionInvocation invocation, String resultCode) {ActionContext ac = invocation.getInvocationContext();HttpServletResponse response = (HttpServletResponse) ac.get(StrutsStatics.HTTP_RESPONSE);addCookiesToResponse(invocation.getAction(), response);}/*** Adds cookies to the response object after the action has been executed.** @param action* @param response*/private void addCookiesToResponse(Object action, HttpServletResponse response) {log.debug("Setting cookies in response");if (action instanceof UserAware) {List<Cookie> cookies = ((UserAware) action).getCookies();if (cookies != null) {for (Cookie cookie : cookies) {log.debug("Adding cookie " + cookie.getName() + " to the response");response.addCookie(cookie);}}}}/*** Expires the UID cookie if the domain is not set or is set as the empty* domain. Creates a new UID cookie with the cookie domain set.** This is mostly to handle legacy issue wherein we were not setting the* cookie domain explicitly to .saholic.com and different cookies were set* for saholic.com and www.saholic.com.** @param request*/private Map<String, Cookie> createCookiesMap(HttpServletRequest request) {Map<String, Cookie> cookiesMap = new HashMap<String, Cookie>();Cookie[] cookies = request.getCookies();if(cookies==null)return cookiesMap;for (Cookie cookie : cookies) {if (cookie.getName().equals(UserInterceptor.USER_ID_COOKIE_NAME)) {if (cookie.getDomain() == null || cookie.getDomain().isEmpty()|| !cookie.getDomain().equals(this.cookieDomain)){if (!cookieDomain.isEmpty()) {cookie.setMaxAge(0);Cookie newUserCookie = new Cookie(UserInterceptor.USER_ID_COOKIE_NAME, cookie.getValue());newUserCookie.setMaxAge(SECONDS_IN_YEAR); // one yearnewUserCookie.setPath("/");newUserCookie.setDomain(cookieDomain);HttpServletResponse response = ServletActionContext.getResponse();response.addCookie(newUserCookie);response.addCookie(cookie);} else {log.error("cookieDomain not set");}}}cookiesMap.put(cookie.getName(), cookie);}return cookiesMap;}/*** Creates and gets session information from the UID cookie. This should be* called only when the required information couldn't be had from the UIC* cookie.** It also expires the UID cookie if it can't parse the cookie value.** @param session* @return A user session info object.*/private UserSessionInfo createAndGetSessionFromUIDCookie(HttpSession session, Map<String, Cookie> cookiesMap, Cookie userCookie) {UserSessionInfo userInfo = null;if(userCookie != null){String uidString = userCookie.getValue();if(uidString != null){try {Long receivedUID = Long.parseLong(desEncrypter.decrypt(uidString));log.info("Invalid session with user cookie : " + receivedUID);userInfo = new UserSessionInfo(receivedUID, session.getId());if(userInfo.getUserId() == -1){log.error("The User for the UID cookie has been deleted in our database. So cleaning up the UID cookie.");expireUidCookie();}} catch (NumberFormatException nfe) {log.error("The UID cookie contains an unparseable userID");expireUidCookie();userInfo = new UserSessionInfo();}}} else{log.info("Invalid session without user cookie.");userInfo = new UserSessionInfo();}return userInfo;}/*** Expires the UIC cookie.*/private void expireUicCookie() {Cookie newUserCookie = new Cookie(UserInterceptor.USER_INFO_COOKIE_NAME, "-1"); //The value here is immaterialnewUserCookie.setMaxAge(0); // Expire this cookie nownewUserCookie.setPath("/");newUserCookie.setDomain(cookieDomain);HttpServletResponse response = ServletActionContext.getResponse();response.addCookie(newUserCookie);}/*** Expires the UID cookie.*/private void expireUidCookie() {Cookie newUserCookie = new Cookie(UserInterceptor.USER_ID_COOKIE_NAME, "-1"); //The value here is immaterialnewUserCookie.setMaxAge(0); // Expire this cookie nownewUserCookie.setPath("/");newUserCookie.setDomain(cookieDomain);HttpServletResponse response = ServletActionContext.getResponse();response.addCookie(newUserCookie);}}