package org.springmodules.feedxt.web.auth;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.context.ApplicationEvent;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.util.UrlPathHelper;
import org.springmodules.feedxt.domain.User;
import org.springmodules.feedxt.event.LoginEvent;
import org.springmodules.feedxt.event.LogoutEvent;
import org.springmodules.feedxt.web.controller.support.UserHolder;
import org.springmodules.xt.ajax.AjaxInterceptor;
import org.springmodules.xt.ajax.util.AjaxRedirectSender;
/**
* Interceptor implementation for user access control. It ensures that:
* <ul>
* <li>Only logged in users can access protected web resources.</li>
* <li>Double user logins are not allowed.</li>
* </ul>
*
* @author Sergio Bossa
*/
public class AccessControlInterceptor extends HandlerInterceptorAdapter {
private AjaxInterceptor ajaxInterceptor;
private UserHolder userHolder;
private String redirectUrl;
private List<String> protectedPaths = new LinkedList();
private UrlPathHelper urlPathHelper = new UrlPathHelper();
private PathMatcher pathMatcher = new AntPathMatcher();
private Map<User, HttpSession> users = new ConcurrentHashMap<User, HttpSession>();
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
User user = this.userHolder.getUser();
if (user == null) {
String actualPath = this.urlPathHelper.getLookupPathForRequest(request);
for (String protectedPath : this.protectedPaths) {
if (this.pathMatcher.match(protectedPath, actualPath)) {
String fullUrl = null;
if (this.redirectUrl.startsWith("/")) {
fullUrl = request.getContextPath() + this.redirectUrl;
} else {
fullUrl = this.redirectUrl;
}
if (this.ajaxInterceptor.isAjaxRequest(request)) {
AjaxRedirectSender.sendRedirect(response, fullUrl, null);
} else {
response.sendRedirect(fullUrl);
}
return false;
}
}
} else if ((user != null) && (this.users.get(user) != null) && (!this.users.get(user).equals(request.getSession()))) {
this.userHolder.setUser(null);
request.getSession().invalidate();
String fullUrl = null;
if (this.redirectUrl.startsWith("/")) {
fullUrl = request.getContextPath() + this.redirectUrl;
} else {
fullUrl = this.redirectUrl;
}
if (this.ajaxInterceptor.isAjaxRequest(request)) {
AjaxRedirectSender.sendRedirect(response, fullUrl, null);
} else {
response.sendRedirect(fullUrl);
}
return false;
}
return true;
}
public Class[] getSupportedEventClasses() {
return new Class[]{LoginEvent.class, LogoutEvent.class};
}
public boolean accepts(ApplicationEvent applicationEvent) {
return true;
}
public void onEvent(LoginEvent event) {
HttpSession session = event.getSession();
User user = event.getUser();
this.users.put(user, session);
}
public void onEvent(LogoutEvent event) {
HttpSession session = event.getSession();
User user = event.getUser();
this.users.remove(user);
}
public void setAjaxInterceptor(AjaxInterceptor ajaxInterceptor) {
this.ajaxInterceptor = ajaxInterceptor;
}
public void setUserHolder(UserHolder userHolder) {
this.userHolder = userHolder;
}
public void setRedirectUrl(String redirectUrl) {
this.redirectUrl = redirectUrl;
}
public void setProtectedPaths(List<String> protectedPaths) {
this.protectedPaths = protectedPaths;
}
}