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 }
77 catch (AccessDeniedException e) {
78
79 log.debug(e.getMessage(), e);
80 if (!response.isCommitted()) {
81 response.setStatus(HttpServletResponse.SC_FORBIDDEN);
82 }
83
84 return;
85 }
86 catch (RepositoryException e) {
87 log.error(e.getMessage(), e);
88 throw new ServletException(e.getMessage(), e);
89 }
90
91 if (!success) {
92 log.debug("Resource not found, redirecting request for [{}] to 404 URI", request.getRequestURI());
93
94 if (!response.isCommitted()) {
95 response.sendError(HttpServletResponse.SC_NOT_FOUND);
96 }
97 else {
98 log.info("Unable to redirect to 404 page, response is already committed. URI was {}", request.getRequestURI());
99 }
100
101 return;
102 }
103 chain.doFilter(request, response);
104 }
105
106
107
108
109 protected boolean collect() throws RepositoryException {
110 final AggregationState aggregationState = MgnlContext.getAggregationState();
111 final String handle = aggregationState.getHandle();
112 final String repository = aggregationState.getRepository();
113
114 final HierarchyManager hierarchyManager = MgnlContext.getHierarchyManager(repository);
115
116 Content requestedPage = null;
117 NodeData requestedData = null;
118 String templateName;
119
120 if (!isJcrPathValid(handle)) {
121
122 return false;
123 }
124 if (hierarchyManager.isExist(handle) && !hierarchyManager.isNodeData(handle)) {
125 requestedPage = hierarchyManager.getContent(handle);
126
127
128 if (MgnlContext.getAttribute(VERSION_NUMBER) != null) {
129
130 try {
131 requestedPage = requestedPage.getVersionedContent((String)MgnlContext.getAttribute(VERSION_NUMBER));
132 }
133 catch (RepositoryException re) {
134 log.debug(re.getMessage(), re);
135 log.error("Unable to get versioned state, rendering current state of {}", handle);
136 }
137 }
138
139 try {
140 templateName = NodeTypes.Renderable.getTemplate(requestedPage.getJCRNode());
141 } catch (RepositoryException e) {
142 templateName = null;
143 }
144
145 if (StringUtils.isBlank(templateName)) {
146 log.error("No template configured for page [{}].", requestedPage.getHandle());
147 }
148 }
149 else {
150 if (hierarchyManager.isNodeData(handle)) {
151 requestedData = hierarchyManager.getNodeData(handle);
152 }
153 else {
154
155 int lastIndexOfSlash = handle.lastIndexOf("/");
156
157 if (lastIndexOfSlash > 0) {
158
159 final String handleToUse = StringUtils.substringBeforeLast(handle, "/");
160
161 try {
162 requestedData = hierarchyManager.getNodeData(handleToUse);
163 aggregationState.setHandle(handleToUse);
164
165
166
167
168 }
169 catch (PathNotFoundException e) {
170
171 return false;
172 }
173 catch (RepositoryException e) {
174 log.debug(e.getMessage(), e);
175 return false;
176 }
177 }
178 }
179
180 if (requestedData != null) {
181 templateName = requestedData.getAttribute(FileProperties.PROPERTY_TEMPLATE);
182 }
183 else {
184 return false;
185 }
186 }
187
188
189 if (requestedPage != null) {
190 aggregationState.setMainContentNode(requestedPage.getJCRNode());
191 aggregationState.setCurrentContentNode(requestedPage.getJCRNode());
192 }
193 if ((requestedData != null) && (requestedData.getType() == PropertyType.BINARY)) {
194 File file = new File(requestedData);
195 aggregationState.setFile(file);
196 }
197
198 aggregationState.setTemplateName(templateName);
199
200 return true;
201 }
202
203
204
205
206
207
208 private boolean isJcrPathValid(String handle) {
209 if (StringUtils.isBlank(handle) || StringUtils.equals(handle, "/")) {
210
211 return false;
212 }
213 if (StringUtils.containsAny(handle, ':', '*', '\n')) {
214
215 return false;
216 }
217 if (StringUtils.contains(handle, " /")) {
218
219 return false;
220 }
221 return true;
222 }
223
224 }