This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.security-1.0.14 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-security.git
commit 0e3d293a0a2c9f0c1c4ce1684c8931ec3c0f7f58 Author: Antonio Sanso <[email protected]> AuthorDate: Fri Aug 28 09:11:29 2015 +0000 SLING-4973 - Add Content Disposition Excluded Paths git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/security@1698280 13f79535-47bb-0310-9956-ffa450edef68 --- .../security/impl/ContentDispositionFilter.java | 69 +++-- .../impl/ContentDispositionFilterTest.java | 290 +++++++++++++++++++++ 2 files changed, 333 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java b/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java index 985d263..09f4424 100644 --- a/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java +++ b/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java @@ -18,6 +18,7 @@ package org.apache.sling.security.impl; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Dictionary; import java.util.HashMap; @@ -62,12 +63,18 @@ public class ContentDispositionFilter implements Filter { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Property(label = "Content Disposition Paths", - description = "These paths are filtered by the filter. "+ + description = "These paths are checked by the filter. "+ "Each entry is of the form 'path [ \":\" CSV of excluded content types ]'. " + "Invalid entries are logged and ignored." , unbounded = PropertyUnbounded.ARRAY, value = { "" }) private static final String PROP_CONTENT_DISPOSTION_PATHS = "sling.content.disposition.paths"; + @Property(label = "Content Disposition Excluded Paths", + description = "These paths are excluded by the filter. "+ + "Each entry is of the form 'path'. " + , unbounded = PropertyUnbounded.ARRAY, value = { "" }) + private static final String PROP_CONTENT_DISPOSTION_EXCLUDED_PATHS = "sling.content.disposition.excluded.paths"; + private static final boolean DEFAULT_ENABLE_CONTENT_DISPOSTION_ALL_PATHS = false; @Property(boolValue = DEFAULT_ENABLE_CONTENT_DISPOSTION_ALL_PATHS , label = "Enable Content Disposition for all paths", @@ -84,6 +91,8 @@ public class ContentDispositionFilter implements Filter { * Array of prefixes of paths */ private String[] contentDispositionPathsPfx; + + Set contentDispositionExcludedPaths; private Map<String, Set<String>> contentTypesMapping; @@ -142,8 +151,13 @@ public class ContentDispositionFilter implements Filter { enableContentDispositionAllPaths = PropertiesUtil.toBoolean(props.get(PROP_ENABLE_CONTENT_DISPOSTION_ALL_PATHS),DEFAULT_ENABLE_CONTENT_DISPOSTION_ALL_PATHS); - logger.info("Initialized. content disposition paths: {}, content disposition paths-pfx {}. Enable Content Disposition for all paths is set to {}", new Object[]{ - contentDispositionPaths, contentDispositionPathsPfx, enableContentDispositionAllPaths} + + String[] contentDispostionExcludedPathsArray = PropertiesUtil.toStringArray(props.get(PROP_CONTENT_DISPOSTION_EXCLUDED_PATHS)); + + contentDispositionExcludedPaths = new HashSet<String>(Arrays.asList(contentDispostionExcludedPathsArray)); + + logger.info("Initialized. content disposition paths: {}, content disposition paths-pfx {}, content disposition excluded paths: {}. Enable Content Disposition for all paths is set to {}", new Object[]{ + contentDispositionPaths, contentDispositionPathsPfx, contentDispositionExcludedPaths, enableContentDispositionAllPaths} ); } @@ -214,38 +228,41 @@ public class ContentDispositionFilter implements Filter { } request.setAttribute(ATTRIBUTE_NAME, type); Resource resource = request.getResource(); + String resourcePath = resource.getPath(); - if (enableContentDispositionAllPaths) { - setContentDisposition(resource); - } else { - String resourcePath = resource.getPath(); + if (!contentDispositionExcludedPaths.contains(resourcePath)) { + + if (enableContentDispositionAllPaths) { + setContentDisposition(resource); + } else { - boolean contentDispositionAdded = false; - if (contentDispositionPaths.contains(resourcePath)) { + boolean contentDispositionAdded = false; + if (contentDispositionPaths.contains(resourcePath)) { - if (contentTypesMapping.containsKey(resourcePath)) { - Set <String> exceptions = contentTypesMapping.get(resourcePath); - if (!exceptions.contains(type)) { + if (contentTypesMapping.containsKey(resourcePath)) { + Set <String> exceptions = contentTypesMapping.get(resourcePath); + if (!exceptions.contains(type)) { + contentDispositionAdded = setContentDisposition(resource); + } + } else { contentDispositionAdded = setContentDisposition(resource); } - } else { - contentDispositionAdded = setContentDisposition(resource); - } - } - if (!contentDispositionAdded) { - for (String path : contentDispositionPathsPfx) { - if (resourcePath.startsWith(path)) { - if (contentTypesMapping.containsKey(path)) { - Set <String> exceptions = contentTypesMapping.get(path); - if (!exceptions.contains(type)) { + } + if (!contentDispositionAdded) { + for (String path : contentDispositionPathsPfx) { + if (resourcePath.startsWith(path)) { + if (contentTypesMapping.containsKey(path)) { + Set <String> exceptions = contentTypesMapping.get(path); + if (!exceptions.contains(type)) { + setContentDisposition(resource); + break; + } + } else { setContentDisposition(resource); break; } - } else { - setContentDisposition(resource); - break; - } + } } } } diff --git a/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java b/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java index aaf9ddb..f601135 100644 --- a/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java +++ b/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java @@ -51,6 +51,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -74,6 +75,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -97,6 +99,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/libs", "/content/usergenerated/*"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -120,6 +123,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"*"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -143,6 +147,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/libs:*"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -166,6 +171,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/libs:text/html,text/plain","/content/usergenerated/*:image/jpeg"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -192,6 +198,46 @@ public class ContentDispositionFilterTest { } @Test + public void test_activator8() throws Throwable{ + contentDispositionFilter = new ContentDispositionFilter(); + final ComponentContext ctx = context.mock(ComponentContext.class); + final Dictionary props = new Hashtable<String, String[]>(); + props.put("sling.content.disposition.paths", new String []{"/libs:text/html,text/plain","/content/usergenerated/*:image/jpeg"}); + props.put("sling.content.disposition.excluded.paths", new String []{}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + Set<String> contentDispositionExcludedPaths = ( Set<String> ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionExcludedPaths"); + Assert.assertEquals(0, contentDispositionExcludedPaths.size()); + } + + @Test + public void test_activator9() throws Throwable{ + contentDispositionFilter = new ContentDispositionFilter(); + final ComponentContext ctx = context.mock(ComponentContext.class); + final Dictionary props = new Hashtable<String, String[]>(); + props.put("sling.content.disposition.paths", new String []{"/libs:text/html,text/plain","/content/usergenerated/*:image/jpeg"}); + props.put("sling.content.disposition.excluded.paths", new String []{"/content", "/libs"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + Set<String> contentDispositionExcludedPaths = ( Set<String> ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionExcludedPaths"); + Assert.assertEquals(2, contentDispositionExcludedPaths.size()); + } + + @Test public void test_getContentTypes() throws Throwable{ // null content types String contentType = null; @@ -220,6 +266,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -259,6 +306,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -298,6 +346,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -349,6 +398,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -389,6 +439,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -440,6 +491,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -490,6 +542,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated:text/html,text/plain"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -529,6 +582,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated:text/html,text/plain"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -567,6 +621,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated:text/html,text/plain"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -606,6 +661,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated:text/html,text/plain"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -656,6 +712,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*:text/html,text/plain"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -695,6 +752,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*:text/html,text/plain"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -733,6 +791,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*:text/html,text/plain"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -772,6 +831,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated/*:text/html,text/plain"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -828,6 +888,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -886,6 +947,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); context.checking(new Expectations() { { @@ -946,6 +1008,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); props.put("sling.content.disposition.all.paths", false); context.checking(new Expectations() { @@ -1006,6 +1069,7 @@ public class ContentDispositionFilterTest { final ComponentContext ctx = context.mock(ComponentContext.class); final Dictionary props = new Hashtable<String, String[]>(); props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"}); + props.put("sling.content.disposition.excluded.paths", new String []{""}); props.put("sling.content.disposition.all.paths", true); context.checking(new Expectations() { @@ -1055,6 +1119,232 @@ public class ContentDispositionFilterTest { } @Test + public void test_doFilter19() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); + final ValueMap properties = context.mock(ValueMap.class); + contentDispositionFilter = new ContentDispositionFilter(); + + final ComponentContext ctx = context.mock(ComponentContext.class); + final Dictionary props = new Hashtable<String, String[]>(); + props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"}); + props.put("sling.content.disposition.excluded.paths", new String []{"/content"}); + props.put("sling.content.disposition.all.paths", true); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + final AtomicInteger counter = new AtomicInteger(); + final ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response) { + public void addHeader(String name, String value) { + counter.incrementAndGet(); + } + }; + + + context.checking(new Expectations() { + { + exactly(1).of(response).containsHeader("Content-Disposition"); + will(returnValue(false)); + exactly(1).of(response).containsHeader("Content-Disposition"); + will(returnValue(true)); + exactly(1).of(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); + will(returnValue(null)); + exactly(1).of(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); + will(returnValue("text/html")); + allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/xml"); + allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); + will(returnValue("/content/other")); + allowing(resource).adaptTo(ValueMap.class); + will(returnValue(properties)); + allowing(properties).containsKey(PROP_JCR_DATA); + will(returnValue(true)); + allowing(response).setContentType("text/html"); + allowing(response).setContentType("text/xml"); + //CONTENT DISPOSITION IS SET + exactly(1).of(response).addHeader("Content-Disposition", "attachment"); + } + }); + rewriterResponse.setContentType("text/html"); + Assert.assertEquals(1, counter.intValue()); + } + + @Test + public void test_doFilter20() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); + final ValueMap properties = context.mock(ValueMap.class); + contentDispositionFilter = new ContentDispositionFilter(); + + final ComponentContext ctx = context.mock(ComponentContext.class); + final Dictionary props = new Hashtable<String, String[]>(); + props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"}); + props.put("sling.content.disposition.excluded.paths", new String []{"/content/other"}); + props.put("sling.content.disposition.all.paths", true); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + final AtomicInteger counter = new AtomicInteger(); + final ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response) { + public void addHeader(String name, String value) { + counter.incrementAndGet(); + } + }; + + + context.checking(new Expectations() { + { + exactly(1).of(response).containsHeader("Content-Disposition"); + will(returnValue(false)); + exactly(1).of(response).containsHeader("Content-Disposition"); + will(returnValue(true)); + exactly(1).of(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); + will(returnValue(null)); + exactly(1).of(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); + will(returnValue("text/html")); + allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/xml"); + allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); + will(returnValue("/content/other")); + allowing(resource).adaptTo(ValueMap.class); + will(returnValue(properties)); + allowing(properties).containsKey(PROP_JCR_DATA); + will(returnValue(true)); + allowing(response).setContentType("text/html"); + allowing(response).setContentType("text/xml"); + //CONTENT DISPOSITION IS NOT SET + never(response).addHeader("Content-Disposition", "attachment"); + } + }); + rewriterResponse.setContentType("text/html"); + Assert.assertEquals(0, counter.intValue()); + } + + @Test + public void test_doFilter21() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); + final ValueMap properties = context.mock(ValueMap.class); + contentDispositionFilter = new ContentDispositionFilter(); + + final ComponentContext ctx = context.mock(ComponentContext.class); + final Dictionary props = new Hashtable<String, String[]>(); + props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"}); + props.put("sling.content.disposition.excluded.paths", new String []{"/content"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + + final AtomicInteger counter = new AtomicInteger(); + final ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response) { + public void addHeader(String name, String value) { + counter.incrementAndGet(); + } + }; + + context.checking(new Expectations() { + { + allowing(response).containsHeader("Content-Disposition"); + will(returnValue(false)); + allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); + will(returnValue(null)); + allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); + will(returnValue("/content/usergenerated")); + allowing(resource).adaptTo(ValueMap.class); + will(returnValue(properties)); + allowing(properties).containsKey(PROP_JCR_DATA); + will(returnValue(true)); + allowing(response).setContentType("text/html"); + //CONTENT DISPOSITION IS SET + exactly(1).of(response).addHeader("Content-Disposition", "attachment"); + } + }); + rewriterResponse.setContentType("text/html"); + Assert.assertEquals(1, counter.intValue()); + } + + @Test + public void test_doFilter22() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); + final ValueMap properties = context.mock(ValueMap.class); + contentDispositionFilter = new ContentDispositionFilter(); + + final ComponentContext ctx = context.mock(ComponentContext.class); + final Dictionary props = new Hashtable<String, String[]>(); + props.put("sling.content.disposition.paths", new String []{"/content/usergenerated"}); + props.put("sling.content.disposition.excluded.paths", new String []{"/content/usergenerated"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + + final AtomicInteger counter = new AtomicInteger(); + final ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response) { + public void addHeader(String name, String value) { + counter.incrementAndGet(); + } + }; + + context.checking(new Expectations() { + { + allowing(response).containsHeader("Content-Disposition"); + will(returnValue(false)); + allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); + will(returnValue(null)); + allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); + will(returnValue("/content/usergenerated")); + allowing(resource).adaptTo(ValueMap.class); + will(returnValue(properties)); + allowing(properties).containsKey(PROP_JCR_DATA); + will(returnValue(true)); + allowing(response).setContentType("text/html"); + //CONTENT DISPOSITION IS NOT SET + never(response).addHeader("Content-Disposition", "attachment"); + } + }); + rewriterResponse.setContentType("text/html"); + Assert.assertEquals(0, counter.intValue()); + } + + @Test public void test_isJcrData1() throws Throwable { contentDispositionFilter = new ContentDispositionFilter(); final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
