1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.cms.filters;
35
36 import info.magnolia.cms.beans.runtime.File;
37 import info.magnolia.cms.beans.runtime.FileProperties;
38 import info.magnolia.cms.core.AggregationState;
39 import info.magnolia.cms.core.Content;
40 import info.magnolia.cms.core.HierarchyManager;
41 import info.magnolia.cms.core.NodeData;
42 import info.magnolia.cms.security.AccessDeniedException;
43 import info.magnolia.context.MgnlContext;
44 import info.magnolia.jcr.util.NodeTypes;
45
46 import java.io.IOException;
47
48 import javax.jcr.PathNotFoundException;
49 import javax.jcr.PropertyType;
50 import javax.jcr.RepositoryException;
51 import javax.servlet.FilterChain;
52 import javax.servlet.ServletException;
53 import javax.servlet.http.HttpServletRequest;
54 import javax.servlet.http.HttpServletResponse;
55
56 import org.apache.commons.lang3.StringUtils;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60
61
62
63
64 public class AggregatorFilter extends AbstractMgnlFilter {
65 private static final Logger log = LoggerFactory.getLogger(AggregatorFilter.class);
66
67 private final String VERSION_NUMBER = "mgnlVersion";
68
69
70 @Override
71 public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
72
73 boolean success;
74 try {
75 success = collect();
76 } catch (AccessDeniedException e) {
77
78 log.debug(e.getMessage(), e);
79 if (!response.isCommitted()) {
80 response.setStatus(HttpServletResponse.SC_FORBIDDEN);
81 }
82
83 return;
84 } catch (RepositoryException e) {
85 log.error(e.getMessage(), e);
86 throw new ServletException(e.getMessage(), e);
87 }
88
89 if (!success) {
90 log.debug("Resource not found, redirecting request for [{}] to 404 URI", request.getRequestURI());
91
92 if (!response.isCommitted()) {
93 response.sendError(HttpServletResponse.SC_NOT_FOUND);
94 } else {
95 log.info("Unable to redirect to 404 page, response is already committed. URI was {}", request.getRequestURI());
96 }
97
98 return;
99 }
100 chain.doFilter(request, response);
101 }
102
103
104
105
106 protected boolean collect() throws RepositoryException {
107 final AggregationState aggregationState = MgnlContext.getAggregationState();
108 final String handle = aggregationState.getHandle();
109 final String repository = aggregationState.getRepository();
110
111 final HierarchyManager hierarchyManager = MgnlContext.getHierarchyManager(repository);
112
113 Content requestedPage = null;
114 NodeData requestedData = null;
115 String templateName;
116
117 if (!isJcrPathValid(handle)) {
118
119 return false;
120 }
121 if (hierarchyManager.isExist(handle) && !hierarchyManager.isNodeData(handle)) {
122 requestedPage = hierarchyManager.getContent(handle);
123
124
125 if (MgnlContext.getAttribute(VERSION_NUMBER) != null) {
126
127 try {
128 requestedPage = requestedPage.getVersionedContent((String) MgnlContext.getAttribute(VERSION_NUMBER));
129 } catch (RepositoryException re) {
130 log.debug(re.getMessage(), re);
131 log.error("Unable to get versioned state, rendering current state of {}", handle);
132 }
133 }
134
135 try {
136 templateName = NodeTypes.Renderable.getTemplate(requestedPage.getJCRNode());
137 } catch (RepositoryException e) {
138 templateName = null;
139 }
140
141 if (StringUtils.isBlank(templateName)) {
142 log.error("No template configured for page [{}].", requestedPage.getHandle());
143 }
144 } else {
145 if (hierarchyManager.isNodeData(handle)) {
146 requestedData = hierarchyManager.getNodeData(handle);
147 } else {
148
149 int lastIndexOfSlash = handle.lastIndexOf("/");
150
151 if (lastIndexOfSlash > 0) {
152
153 final String handleToUse = StringUtils.substringBeforeLast(handle, "/");
154
155 try {
156 requestedData = hierarchyManager.getNodeData(handleToUse);
157 aggregationState.setHandle(handleToUse);
158
159
160
161
162 } catch (PathNotFoundException e) {
163
164 return false;
165 } catch (RepositoryException e) {
166 log.debug(e.getMessage(), e);
167 return false;
168 }
169 }
170 }
171
172 if (requestedData != null) {
173 templateName = requestedData.getAttribute(FileProperties.PROPERTY_TEMPLATE);
174 } else {
175 return false;
176 }
177 }
178
179
180 if (requestedPage != null) {
181 aggregationState.setMainContentNode(requestedPage.getJCRNode());
182 aggregationState.setCurrentContentNode(requestedPage.getJCRNode());
183 }
184 if ((requestedData != null) && (requestedData.getType() == PropertyType.BINARY)) {
185 File file = new File(requestedData);
186 aggregationState.setFile(file);
187 }
188
189 aggregationState.setTemplateName(templateName);
190
191 return true;
192 }
193
194
195
196
197
198
199
200 private boolean isJcrPathValid(String handle) {
201 if (StringUtils.isBlank(handle) || StringUtils.equals(handle, "/")) {
202
203 return false;
204 }
205 if (StringUtils.containsAny(handle, ':', '*', '\n')) {
206
207 return false;
208 }
209 if (StringUtils.contains(handle, " /")) {
210
211 return false;
212 }
213 return true;
214 }
215
216 }