Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8842 anupam.sin 1
package in.shop2020.serving.interceptors;
2
 
3
import in.shop2020.serving.services.UserSessionInfo;
4
import in.shop2020.serving.utils.DesEncrypter;
5
 
6
import java.util.HashMap;
7
import java.util.List;
8
import java.util.Map;
9
 
10
import javax.servlet.http.Cookie;
11
import javax.servlet.http.HttpServletRequest;
12
import javax.servlet.http.HttpServletResponse;
13
import javax.servlet.http.HttpSession;
14
 
15
import org.apache.log4j.Logger;
16
import org.apache.struts2.ServletActionContext;
17
import org.apache.struts2.StrutsStatics;
18
 
19
import com.opensymphony.xwork2.ActionContext;
20
import com.opensymphony.xwork2.ActionInvocation;
21
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
22
import com.opensymphony.xwork2.interceptor.PreResultListener;
23
 
24
public class UserInterceptor extends AbstractInterceptor implements PreResultListener{
25
 
26
	public static final int SECONDS_IN_YEAR = 60*60*24*365; 
27
	public static final int FACEBOOK_USER_COOKIE_EXPIRY_TIME = 60*60*24*60; 
28
 
29
	private static final long serialVersionUID = -4125815700236506235L;
30
	private static Logger log = Logger.getLogger(UserInterceptor.class);
31
 
32
	public static final String USER_INFO_COOKIE_NAME = "uic";
33
	public static final String USER_ID_COOKIE_NAME = "uid";
34
	public static final String COOKIE_DECRYPTION_STRING = "shop2020";
35
 
36
	private DesEncrypter desEncrypter = new DesEncrypter(COOKIE_DECRYPTION_STRING);
37
 
38
	private String cookieDomain = "";
39
 
40
	public void setCookieDomain(String cookieDomain) {
41
		this.cookieDomain = cookieDomain;
42
	}
43
 
44
	@Override
45
	public String intercept(ActionInvocation invocation) throws Exception {
46
		final Object action = invocation.getAction();
47
 
48
		log.debug("inside user intercepror");
49
 
50
		HttpServletRequest request = ServletActionContext.getRequest();
51
        HttpSession session = request.getSession(); // Do not remove it, session id is used for session tracking.
52
 
53
        Map<String, Cookie> cookiesMap = createCookiesMap(request);
54
 
55
        // CreateUserInterceptor may have set the userinfo object in the request
56
        // itself. If we can get the userinfo object here, we don't need to
57
        // parse the cookies that came in with the request.
58
		UserSessionInfo userInfo = (UserSessionInfo) request.getAttribute(USER_INFO_COOKIE_NAME);
59
 
60
		Cookie userCookie = cookiesMap.get(UserInterceptor.USER_ID_COOKIE_NAME);
61
		Cookie userinfoCookie = cookiesMap.get(USER_INFO_COOKIE_NAME);
62
 
63
		if(userInfo == null ){
64
		    //Okay, we didn't get the userinfo object from the request. Time to parse the UIC cookie.
65
			if(userinfoCookie!=null){
66
				userInfo = UserSessionInfo.getUserSessionInfoFromCookieValue(userinfoCookie.getValue());
67
				if(userInfo.getUserId() == -1){
68
				    //This means that the cookie couldn't be parsed. So, we should remove the cookie.
69
				    expireUicCookie();
70
				    expireUidCookie();
71
				}
72
			} else {
73
			    //No UIC cookie too. Try the old UID cookie. This method is guaranteed  to return a userinfo object, cookie or not.
74
				userInfo = createAndGetSessionFromUIDCookie(session, cookiesMap, userCookie);
75
			}
76
		}
77
 
78
		//Set the request attribute for access by other interceptors.
79
		request.setAttribute(USER_INFO_COOKIE_NAME, userInfo);
80
 
81
		//Set the userinfo object for use by actions.
82
		if (action instanceof UserAware) {
83
        	UserAware sessionAction = (UserAware) action;
84
        	sessionAction.setSession(session);
85
        	sessionAction.setUserSessionInfo(userInfo);
86
        	sessionAction.setCookiesMap(cookiesMap);
87
        	sessionAction.setUserCookie(userCookie);
88
        	sessionAction.setCookieDomainName(cookieDomain);
89
        }
90
 
91
        // Ensure that the response of the action is presented to the pre-result
92
        // listened of this interceptor. We want to add the cookies there.
93
		invocation.addPreResultListener(this);
94
 
95
		return invocation.invoke();
96
	}
97
 
98
 
99
	@Override
100
	public void beforeResult(ActionInvocation invocation, String resultCode) {
101
		ActionContext ac = invocation.getInvocationContext();
102
		HttpServletResponse response = (HttpServletResponse) ac.get(StrutsStatics.HTTP_RESPONSE);
103
		addCookiesToResponse(invocation.getAction(), response);
104
	}	
105
 
106
	/**
107
	 * Adds cookies to the response object after the action has been executed.
108
	 * 
109
	 * @param action
110
	 * @param response
111
	 */
112
	private void addCookiesToResponse(Object action, HttpServletResponse response) {
113
	    log.debug("Setting cookies in response");
114
		if (action instanceof UserAware) {
115
			List<Cookie> cookies = ((UserAware) action).getCookies();
116
			if (cookies != null) {
117
				for (Cookie cookie : cookies) {
118
				    log.debug("Adding cookie " + cookie.getName() + " to the response");
119
					response.addCookie(cookie);
120
				}
121
			}
122
		}
123
	}
124
 
125
    /**
126
     * Expires the UID cookie if the domain is not set or is set as the empty
127
     * domain. Creates a new UID cookie with the cookie domain set.
128
     * 
129
     * This is mostly to handle legacy issue wherein we were not setting the
130
     * cookie domain explicitly to .saholic.com and different cookies were set
131
     * for saholic.com and www.saholic.com.
132
     * 
133
     * @param request
134
     */
135
	private Map<String, Cookie> createCookiesMap(HttpServletRequest request) {
136
		Map<String, Cookie> cookiesMap  = new HashMap<String, Cookie>();
137
		Cookie[] cookies = request.getCookies();
138
		if(cookies==null)
139
			return cookiesMap;
140
		for (Cookie cookie : cookies) {
141
			if (cookie.getName().equals(UserInterceptor.USER_ID_COOKIE_NAME)) {
142
				if (cookie.getDomain() == null || cookie.getDomain().isEmpty()
143
						|| !cookie.getDomain().equals(this.cookieDomain)) 
144
				{
145
					if (!cookieDomain.isEmpty()) {
146
						cookie.setMaxAge(0);
147
						Cookie newUserCookie = new Cookie(UserInterceptor.USER_ID_COOKIE_NAME, cookie.getValue());
148
						newUserCookie.setMaxAge(SECONDS_IN_YEAR); // one year
149
						newUserCookie.setPath("/");
150
						newUserCookie.setDomain(cookieDomain);
151
 
152
						HttpServletResponse response = ServletActionContext.getResponse();
153
						response.addCookie(newUserCookie);
154
						response.addCookie(cookie);
155
					} else {
156
					    log.error("cookieDomain not set");
157
					}
158
				}
159
			}
160
		    cookiesMap.put(cookie.getName(), cookie);
161
		}
162
		return cookiesMap;
163
	}
164
 
165
    /**
166
     * Creates and gets session information from the UID cookie. This should be
167
     * called only when the required information couldn't be had from the UIC
168
     * cookie.
169
     * 
170
     * It also expires the UID cookie if it can't parse the cookie value.
171
     * 
172
     * @param session
173
     * @return A user session info object.
174
     */
175
	private UserSessionInfo createAndGetSessionFromUIDCookie(HttpSession session, Map<String, Cookie> cookiesMap, Cookie userCookie) {
176
		UserSessionInfo userInfo = null;
177
		if(userCookie != null){
178
			String uidString = userCookie.getValue();
179
			if(uidString != null){
180
				try {
181
					Long receivedUID = Long.parseLong(desEncrypter.decrypt(uidString));
182
                    log.info("Invalid session with user cookie : " + receivedUID);
183
					userInfo = new UserSessionInfo(receivedUID, session.getId());
184
					if(userInfo.getUserId() == -1){
185
					    log.error("The User for the UID cookie has been deleted in our database. So cleaning up the UID cookie.");
186
					    expireUidCookie();
187
					}
188
				} catch (NumberFormatException nfe) {
189
					log.error("The UID cookie contains an unparseable userID");
190
					expireUidCookie();
191
					userInfo = new UserSessionInfo();
192
				}
193
			}
194
		} else{
195
		    log.info("Invalid session without user cookie.");
196
		    userInfo = new UserSessionInfo();
197
		}
198
		return userInfo;
199
	}
200
 
201
	/**
202
	 * Expires the UIC cookie.
203
	 */
204
    private void expireUicCookie() {
205
        Cookie newUserCookie = new Cookie(UserInterceptor.USER_INFO_COOKIE_NAME, "-1"); //The value here is immaterial
206
        newUserCookie.setMaxAge(0);                     // Expire this cookie now
207
        newUserCookie.setPath("/");
208
        newUserCookie.setDomain(cookieDomain);
209
 
210
        HttpServletResponse response = ServletActionContext.getResponse();
211
        response.addCookie(newUserCookie);
212
    }	
213
 
214
    /**
215
     * Expires the UID cookie.
216
     */
217
    private void expireUidCookie() {
218
        Cookie newUserCookie = new Cookie(UserInterceptor.USER_ID_COOKIE_NAME, "-1"); //The value here is immaterial
219
        newUserCookie.setMaxAge(0);                     // Expire this cookie now
220
        newUserCookie.setPath("/");
221
        newUserCookie.setDomain(cookieDomain);
222
 
223
        HttpServletResponse response = ServletActionContext.getResponse();
224
        response.addCookie(newUserCookie);
225
    }
226
 
227
}