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.10 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-security.git
commit bd06fa0c24bac969ea59c38c9fc53bfe797729be Author: Antonio Sanso <[email protected]> AuthorDate: Thu Apr 2 09:49:38 2015 +0000 SLING-3829 - Add support for Content-Disposition attachment git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/security@1670869 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 23 + .../security/impl/ContentDispositionFilter.java | 224 +++++++ .../impl/ContentDispositionFilterTest.java | 653 +++++++++++++++++++++ 3 files changed, 900 insertions(+) diff --git a/pom.xml b/pom.xml index a401dc6..25f13bf 100644 --- a/pom.xml +++ b/pom.xml @@ -73,6 +73,12 @@ <dependencies> <dependency> <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.api</artifactId> + <version>2.1.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.commons.osgi</artifactId> <version>2.1.0</version> <scope>provided</scope> @@ -111,5 +117,22 @@ <version>1.8.2</version> <scope>test</scope> </dependency> + <!-- Testing --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + <dependency> + <groupId>org.jmock</groupId> + <artifactId>jmock-junit4</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit-addons</groupId> + <artifactId>junit-addons</artifactId> + <version>1.4</version> + <scope>test</scope> + </dependency> </dependencies> + </project> diff --git a/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java b/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java new file mode 100644 index 0000000..aae95dc --- /dev/null +++ b/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java @@ -0,0 +1,224 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sling.security.impl; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.PropertyUnbounded; +import org.apache.felix.scr.annotations.Service; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.wrappers.SlingHttpServletResponseWrapper; +import org.apache.sling.commons.osgi.PropertiesUtil; +import org.osgi.service.component.ComponentContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Component(metatype = true, +description = "Request filter adding Content Disposition attachment for certain paths/content types", +label=" Apache Sling Content Disposition Filter") +@Service(value = Filter.class) +@Properties({ + @Property(name = "sling.filter.scope", value = { "request" }, propertyPrivate = true), + @Property(name = "service.ranking", intValue = -25000, propertyPrivate = true) }) +public class ContentDispositionFilter implements Filter { + + /** Logger. */ + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Property(label = "Content Disposition Paths", + description = "These paths are filtered 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"; + + /** + * Set of paths + */ + Set<String> contentDispositionPaths; + + /** + * Array of prefixes of paths + */ + private String[] contentDispositionPathsPfx; + + private Map<String, Set<String>> contentTypesMapping; + + @Activate + private void activate(final ComponentContext ctx) { + final Dictionary props = ctx.getProperties(); + + String[] contentDispostionProps = PropertiesUtil.toStringArray(props.get(PROP_CONTENT_DISPOSTION_PATHS)); + + Set<String> paths = new HashSet<String>(); + List<String> pfxs = new ArrayList<String>(); + Map<String, Set<String>> contentTypesMap = new HashMap<String, Set<String>>(); + + for (String path : contentDispostionProps) { + path = path.trim(); + if (path.length() > 0) { + int idx = path.indexOf('*'); + int colonIdx = path.indexOf(":"); + + if (colonIdx > -1 && colonIdx < idx) { + // ':' in paths is not allowed + logger.info("':' in paths is not allowed."); + } else { + String p = null; + if (idx >= 0) { + if (idx > 0) { + p = path.substring(0, idx); + pfxs.add(p); + } else { + // we don't allow "*" - that would defeat the + // purpose. + logger.info("catch-all wildcard for paths not allowed."); + } + } else { + if (colonIdx > -1) { + p = path.substring(0, colonIdx); + } else { + p = path; + } + paths.add(p); + } + if (colonIdx != -1 && p != null) { + Set <String> contentTypes = getContentTypes(path.substring(colonIdx+1)); + contentTypesMap.put(p, contentTypes); + } + } + + } + } + + contentDispositionPaths = paths.isEmpty() ? Collections.<String>emptySet() : paths; + contentDispositionPathsPfx = pfxs.toArray(new String[pfxs.size()]); + contentTypesMapping = contentTypesMap.isEmpty()?Collections.<String, Set<String>>emptyMap(): contentTypesMap; + + logger.info("Initialized. content disposition paths: {}, content disposition paths-pfx {}", new Object[]{ + contentDispositionPaths, contentDispositionPathsPfx} + ); + } + + + public void init(FilterConfig filterConfig) throws ServletException { + // nothing to do + } + + public void destroy() { + // nothing to do + } + + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + + final SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request; + final SlingHttpServletResponse slingResponse = (SlingHttpServletResponse) response; + + final RewriterResponse rewriterResponse = new RewriterResponse(slingRequest, slingResponse); + + chain.doFilter(request, rewriterResponse); + } + + //---------- PRIVATE METHODS --------- + + private static Set<String> getContentTypes(String contentTypes) { + Set<String> contentTypesSet = new HashSet<String>(); + if (contentTypes != null && contentTypes.length() > 0) { + String[] contentTypesArray = contentTypes.split(","); + for (String contentType : contentTypesArray) { + contentTypesSet.add(contentType); + } + } + return contentTypesSet; + } + + //----------- INNER CLASSES ------------ + + protected class RewriterResponse extends SlingHttpServletResponseWrapper { + + private static final String CONTENT_DISPOSTION = "Content-Disposition"; + + private static final String CONTENT_DISPOSTION_ATTACHMENT = "attachment"; + + /** The current request. */ + private final SlingHttpServletRequest request; + + public RewriterResponse(SlingHttpServletRequest request, SlingHttpServletResponse wrappedResponse) { + super(wrappedResponse); + this.request = request; + } + + /** + * @see javax.servlet.ServletResponseWrapper#setContentType(java.lang.String) + */ + public void setContentType(String type) { + String pathInfo = request.getPathInfo(); + + if (contentDispositionPaths.contains(pathInfo)) { + + if (contentTypesMapping.containsKey(pathInfo)) { + Set exceptions = contentTypesMapping.get(pathInfo); + if (!exceptions.contains(type)) { + setContentDisposition(); + } + } else { + setContentDisposition(); + } + } + + for (String path : contentDispositionPathsPfx) { + if (request.getPathInfo().startsWith(path)) { + if (contentTypesMapping.containsKey(path)) { + Set exceptions = contentTypesMapping.get(path); + if (!exceptions.contains(type)) { + setContentDisposition(); + break; + } + } else { + setContentDisposition(); + break; + } + + } + } + super.setContentType(type); + } + + private void setContentDisposition() { + this.addHeader(CONTENT_DISPOSTION, CONTENT_DISPOSTION_ATTACHMENT); + } + } +} diff --git a/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java b/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java new file mode 100644 index 0000000..91d26b1 --- /dev/null +++ b/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java @@ -0,0 +1,653 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sling.security.impl; + +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.Map; +import java.util.Set; +import junitx.util.PrivateAccessor; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.SlingHttpServletResponse; +import org.jmock.Expectations; +import org.jmock.Mockery; +import org.jmock.integration.junit4.JUnit4Mockery; +import org.junit.Assert; +import org.junit.Test; +import org.osgi.service.component.ComponentContext; + +public class ContentDispositionFilterTest { + + private ContentDispositionFilter contentDispositionFilter; + private final Mockery context = new JUnit4Mockery(); + + @Test + public void test_activator1() 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 []{"/content/usergenerated"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + Set<String> contentDispositionPaths = ( Set<String> ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionPaths"); + Assert.assertEquals(1, contentDispositionPaths.size()); + String[] contentDispositionPathsPfx = ( String[] ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionPathsPfx"); + Assert.assertEquals(0, contentDispositionPathsPfx.length); + Map <String, Set<String>> contentTypesMapping = ( Map <String, Set<String>> ) PrivateAccessor.getField(contentDispositionFilter, "contentTypesMapping"); + Assert.assertEquals(0, contentTypesMapping.size()); + } + + @Test + public void test_activator2() 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 []{"/content/usergenerated/*"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + Set<String> contentDispositionPaths = ( Set<String> ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionPaths"); + Assert.assertEquals(0, contentDispositionPaths.size()); + String[] contentDispositionPathsPfx = ( String[] ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionPathsPfx"); + Assert.assertEquals(1, contentDispositionPathsPfx.length); + Map <String, Set<String>> contentTypesMapping = ( Map <String, Set<String>> ) PrivateAccessor.getField(contentDispositionFilter, "contentTypesMapping"); + Assert.assertEquals(0, contentTypesMapping.size()); + } + + @Test + public void test_activator3() 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", "/content/usergenerated/*"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + Set<String> contentDispositionPaths = ( Set<String> ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionPaths"); + Assert.assertEquals(1, contentDispositionPaths.size()); + String[] contentDispositionPathsPfx = ( String[] ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionPathsPfx"); + Assert.assertEquals(1, contentDispositionPathsPfx.length); + Map <String, Set<String>> contentTypesMapping = ( Map <String, Set<String>> ) PrivateAccessor.getField(contentDispositionFilter, "contentTypesMapping"); + Assert.assertEquals(0, contentTypesMapping.size()); + } + + @Test + public void test_activator5() 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 []{"*"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + Set<String> contentDispositionPaths = ( Set<String> ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionPaths"); + Assert.assertEquals(0, contentDispositionPaths.size()); + String[] contentDispositionPathsPfx = ( String[] ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionPathsPfx"); + Assert.assertEquals(0, contentDispositionPathsPfx.length); + Map <String, Set<String>> contentTypesMapping = ( Map <String, Set<String>> ) PrivateAccessor.getField(contentDispositionFilter, "contentTypesMapping"); + Assert.assertEquals(0, contentTypesMapping.size()); + } + + @Test + public void test_activator6() 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:*"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + Set<String> contentDispositionPaths = ( Set<String> ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionPaths"); + Assert.assertEquals(0, contentDispositionPaths.size()); + String[] contentDispositionPathsPfx = ( String[] ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionPathsPfx"); + Assert.assertEquals(0, contentDispositionPathsPfx.length); + Map <String, Set<String>> contentTypesMapping = ( Map <String, Set<String>> ) PrivateAccessor.getField(contentDispositionFilter, "contentTypesMapping"); + Assert.assertEquals(0, contentTypesMapping.size()); + } + + @Test + public void test_activator7() 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"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + Set<String> contentDispositionPaths = ( Set<String> ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionPaths"); + Assert.assertEquals(1, contentDispositionPaths.size()); + String[] contentDispositionPathsPfx = ( String[] ) PrivateAccessor.getField(contentDispositionFilter, "contentDispositionPathsPfx"); + Assert.assertEquals(1, contentDispositionPathsPfx.length); + Map <String, Set<String>> contentTypesMapping = ( Map <String, Set<String>> ) PrivateAccessor.getField(contentDispositionFilter, "contentTypesMapping"); + Assert.assertEquals(2, contentTypesMapping.size()); + Set<String> libsMapping = contentTypesMapping.get("/libs"); + Assert.assertEquals(2, libsMapping.size()); + libsMapping.contains("text/html"); + libsMapping.contains("text/plain"); + + Set<String> userGeneratedMapping = contentTypesMapping.get("/content/usergenerated/"); + Assert.assertEquals(1, userGeneratedMapping.size()); + userGeneratedMapping.contains("image/jpeg"); + } + + @Test + public void test_getContentTypes() throws Throwable{ + // null content types + String contentType = null; + Set <String> contentTypesSet = ( Set <String>) PrivateAccessor.invoke(ContentDispositionFilter.class,"getContentTypes", new Class[]{String.class},new Object[]{contentType}); + Assert.assertEquals(0, contentTypesSet.size()); + // empty content types + contentType = ""; + contentTypesSet = ( Set <String>) PrivateAccessor.invoke(ContentDispositionFilter.class,"getContentTypes", new Class[]{String.class},new Object[]{contentType}); + Assert.assertEquals(0, contentTypesSet.size()); + contentType = "text/html"; + contentTypesSet = ( Set <String>) PrivateAccessor.invoke(ContentDispositionFilter.class,"getContentTypes", new Class[]{String.class},new Object[]{contentType}); + Assert.assertEquals(1, contentTypesSet.size()); + contentType = "text/html,text/plain"; + contentTypesSet = ( Set <String>) PrivateAccessor.invoke(ContentDispositionFilter.class,"getContentTypes", new Class[]{String.class},new Object[]{contentType}); + Assert.assertEquals(2, contentTypesSet.size()); + } + + @Test + public void test_doFilter1() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.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"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response); + + context.checking(new Expectations() { + { + allowing(request).getPathInfo(); + will(returnValue("/libs")); + allowing(response).setContentType("text/html"); + //CONTENT DISPOSITION MUST NOT SET + never(response).addHeader("Content-Disposition", "attachment"); + + } + }); + rewriterResponse.setContentType("text/html"); + } + + @Test + public void test_doFilter2() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.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"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response); + + context.checking(new Expectations() { + { + allowing(request).getPathInfo(); + will(returnValue("/content/usergenerated/author")); + allowing(response).setContentType("text/html"); + //CONTENT DISPOSITION MUST NOT SET + never(response).addHeader("Content-Disposition", "attachment"); + } + }); + rewriterResponse.setContentType("text/html"); + } + + @Test + public void test_doFilter3() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.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"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response); + + context.checking(new Expectations() { + { + allowing(request).getPathInfo(); + will(returnValue("/content/usergenerated")); + allowing(response).setContentType("text/html"); + //CONTENT DISPOSITION IS SET + exactly(1).of(response).addHeader("Content-Disposition", "attachment"); + } + }); + rewriterResponse.setContentType("text/html"); + } + + @Test + public void test_doFilter4() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.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/*"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response); + + context.checking(new Expectations() { + { + allowing(request).getPathInfo(); + will(returnValue("/libs")); + allowing(response).setContentType("text/html"); + //CONTENT DISPOSITION MUST NOT SET + never(response).addHeader("Content-Disposition", "attachment"); + + } + }); + rewriterResponse.setContentType("text/html"); + } + + @Test + public void test_doFilter5() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.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/*"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response); + + context.checking(new Expectations() { + { + allowing(request).getPathInfo(); + will(returnValue("/content/usergenerated/author")); + allowing(response).setContentType("text/html"); + //CONTENT DISPOSITION IS SET + exactly(1).of(response).addHeader("Content-Disposition", "attachment"); + } + }); + rewriterResponse.setContentType("text/html"); + } + + @Test + public void test_doFilter6() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.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/*"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response); + + context.checking(new Expectations() { + { + allowing(request).getPathInfo(); + will(returnValue("/content/usergenerated")); + allowing(response).setContentType("text/html"); + //CONTENT DISPOSITION IS SET + exactly(1).of(response).addHeader("Content-Disposition", "attachment"); + } + }); + rewriterResponse.setContentType("text/html"); + } + + @Test + public void test_doFilter7() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.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:text/html,text/plain"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response); + + context.checking(new Expectations() { + { + allowing(request).getPathInfo(); + will(returnValue("/libs")); + allowing(response).setContentType("text/html"); + //CONTENT DISPOSITION MUST NOT SET + never(response).addHeader("Content-Disposition", "attachment"); + + } + }); + rewriterResponse.setContentType("text/html"); + } + + @Test + public void test_doFilter8() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.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:text/html,text/plain"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response); + + context.checking(new Expectations() { + { + allowing(request).getPathInfo(); + will(returnValue("/content/usergenerated/author")); + allowing(response).setContentType("text/html"); + //CONTENT DISPOSITION MUST NOT SET + never(response).addHeader("Content-Disposition", "attachment"); + } + }); + rewriterResponse.setContentType("text/html"); + } + + @Test + public void test_doFilter9() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.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:text/html,text/plain"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response); + + context.checking(new Expectations() { + { + allowing(request).getPathInfo(); + will(returnValue("/content/usergenerated")); + allowing(response).setContentType("text/html"); + //CONTENT DISPOSITION MUST NOT SET + never(response).addHeader("Content-Disposition", "attachment"); + } + }); + rewriterResponse.setContentType("text/html"); + } + + @Test + public void test_doFilter10() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.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:text/html,text/plain"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response); + + context.checking(new Expectations() { + { + allowing(request).getPathInfo(); + will(returnValue("/content/usergenerated")); + allowing(response).setContentType("image/jpeg"); + //CONTENT DISPOSITION IS SET + exactly(1).of(response).addHeader("Content-Disposition", "attachment"); + } + }); + rewriterResponse.setContentType("image/jpeg"); + } + + @Test + public void test_doFilter11() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.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/*:text/html,text/plain"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response); + + context.checking(new Expectations() { + { + allowing(request).getPathInfo(); + will(returnValue("/libs")); + allowing(response).setContentType("text/html"); + //CONTENT DISPOSITION MUST NOT SET + never(response).addHeader("Content-Disposition", "attachment"); + + } + }); + rewriterResponse.setContentType("text/html"); + } + + @Test + public void test_doFilter12() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.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/*:text/html,text/plain"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response); + + context.checking(new Expectations() { + { + allowing(request).getPathInfo(); + will(returnValue("/content/usergenerated/author")); + allowing(response).setContentType("text/html"); + //CONTENT DISPOSITION MUST NOT SET + never(response).addHeader("Content-Disposition", "attachment"); + } + }); + rewriterResponse.setContentType("text/html"); + } + + @Test + public void test_doFilter13() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.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/*:text/html,text/plain"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response); + + context.checking(new Expectations() { + { + allowing(request).getPathInfo(); + will(returnValue("/content/usergenerated/author")); + allowing(response).setContentType("text/html"); + //CONTENT DISPOSITION MUST NOT SET + never(response).addHeader("Content-Disposition", "attachment"); + } + }); + rewriterResponse.setContentType("text/html"); + } + + @Test + public void test_doFilter14() throws Throwable{ + final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); + final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.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/*:text/html,text/plain"}); + + context.checking(new Expectations() { + { + allowing(ctx).getProperties(); + will(returnValue(props)); + + } + }); + PrivateAccessor.invoke(contentDispositionFilter,"activate", new Class[]{ComponentContext.class},new Object[]{ctx}); + ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response); + + context.checking(new Expectations() { + { + allowing(request).getPathInfo(); + will(returnValue("/content/usergenerated/author")); + allowing(response).setContentType("image/jpeg"); + //CONTENT DISPOSITION IS SET + exactly(1).of(response).addHeader("Content-Disposition", "attachment"); + } + }); + rewriterResponse.setContentType("image/jpeg"); + } +} -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
