1 package net.sourceforge.blogentis.slide;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import java.io.IOException;
26 import java.security.Principal;
27 import java.util.Date;
28 import java.util.regex.Pattern;
29
30 import javax.servlet.Filter;
31 import javax.servlet.FilterChain;
32 import javax.servlet.FilterConfig;
33 import javax.servlet.RequestDispatcher;
34 import javax.servlet.ServletException;
35 import javax.servlet.ServletRequest;
36 import javax.servlet.ServletResponse;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.servlet.http.HttpServletResponse;
39 import javax.servlet.http.HttpSession;
40
41 import org.apache.commons.httpclient.util.URIUtil;
42 import org.apache.commons.logging.Log;
43 import org.apache.commons.logging.LogFactory;
44 import org.apache.turbine.om.security.User;
45 import org.apache.turbine.services.security.TurbineSecurity;
46 import org.apache.turbine.util.TurbineException;
47
48 import sun.misc.BASE64Decoder;
49
50 /***
51 * Filter that redirects direct file access or DAV requests to slide.
52 *
53 * @author abas
54 */
55 public class SlideAdapterFilter
56 implements Filter {
57 private static final Log log = LogFactory.getLog(SlideAdapterFilter.class);
58
59 private Pattern matchingPattern = null;
60 private Pattern publicPattern = null;
61 private RequestDispatcher slideDispatcher = null;
62
63 public void init(FilterConfig config)
64 throws ServletException {
65 matchingPattern = Pattern.compile(config
66 .getInitParameter("matchingPattern"));
67 publicPattern = Pattern.compile(config
68 .getInitParameter("publicPattern"));
69 slideDispatcher = config.getServletContext()
70 .getNamedDispatcher(config.getInitParameter("slideServlet"));
71 }
72
73 private User isAuthorized(HttpServletRequest req) {
74 String auth = req.getHeader("Authorization");
75 if (auth == null)
76 return null;
77 if (!auth.toUpperCase().startsWith("BASIC "))
78 return null;
79 BASE64Decoder dec = new sun.misc.BASE64Decoder();
80 String userpassDecoded;
81 try {
82 userpassDecoded = new String(dec.decodeBuffer(auth.substring(6)));
83 } catch (IOException e) {
84 return null;
85 }
86 String[] userPass = userpassDecoded.split(":");
87 if (userPass.length != 2)
88 return null;
89 User u;
90 try {
91 u = TurbineSecurity.getAuthenticatedUser(userPass[0], userPass[1]);
92 } catch (TurbineException e1) {
93 return null;
94 }
95 return u;
96 }
97
98 public void doFilter(ServletRequest request, ServletResponse response,
99 FilterChain chain)
100 throws IOException, ServletException {
101 Date d = new Date();
102 HttpServletRequest req = (HttpServletRequest)request;
103 HttpServletResponse resp = (HttpServletResponse)response;
104 String s = req.getServletPath();
105
106 boolean isGetOrPost = "GET".equals(req.getMethod())
107 || "HEAD".equals(req.getMethod())
108 || "POST".equals(req.getMethod());
109
110 try {
111 if (s == null
112 || (!matchingPattern.matcher(s).matches() && isGetOrPost)) {
113 chain.doFilter(req, resp);
114 return;
115 }
116
117 HttpSession session = req.getSession(false);
118 User user = session == null ? null : (User)session
119 .getAttribute(User.SESSION_KEY);
120 if (user == null
121 && !(isGetOrPost && publicPattern.matcher(s).matches())) {
122 user = isAuthorized(req);
123 if (user == null) {
124 resp
125 .setHeader("WWW-Authenticate",
126 "BASIC realm=\"blogentis\"");
127 resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
128 return;
129 }
130 }
131 if (user != null && session != null)
132 session.setAttribute(User.SESSION_KEY, user);
133 if (log.isDebugEnabled())
134 log.debug("Performing method " + req.getMethod() + " on "
135 + URIUtil.encodePath(s));
136 Principal principal = (user != null) ? new TurbinePrincipal(user)
137 : null;
138 MutablePrincipalHttpRequestWrapper wrapper = new MutablePrincipalHttpRequestWrapper(
139 req, principal);
140 slideDispatcher.forward(wrapper, resp);
141 } finally {
142 if (log.isInfoEnabled())
143 log.info("Request took " + (new Date().getTime() - d.getTime())
144 + "ms");
145 }
146 }
147
148 public void destroy() {}
149 }