Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class AuthObject {
private final boolean cacheEnabled;
private final boolean mustMatchAll;
private final boolean allowCmsUsers;
private final boolean previewTokenEnabled;
private final String forwardedForHeader;
private final Set<String> hosts;
private final Set<String> ranges;
Expand All @@ -61,19 +62,22 @@ private AuthObject() {
this.ipMatchers = Collections.emptySet();
this.allowCmsUsers = false;
this.mustMatchAll = false;
this.previewTokenEnabled = false;
this.forwardedForHeader = IpFilterConstants.HEADER_X_FORWARDED_FOR;
}

public AuthObject(final Set<String> ignoredPaths, final Set<String> hosts,
final Set<String> ranges, final Map<String, Set<String>> ignoredHeaders,
final boolean allowCmsUsers, final String forwardHeader, final boolean cacheEnabled, final boolean mustMatchAll) {
final boolean allowCmsUsers, final String forwardHeader, final boolean cacheEnabled, final boolean mustMatchAll,
final boolean previewTokenEnabled) {
this.valid = true;
this.cacheEnabled = cacheEnabled;
this.ignoredPaths = ignoredPaths;
this.hosts = hosts;
this.ranges = ranges;
this.allowCmsUsers = allowCmsUsers;
this.mustMatchAll = mustMatchAll;
this.previewTokenEnabled = previewTokenEnabled;
this.forwardedForHeader = forwardHeader;
this.ignoredHeaders = ImmutableMap.copyOf(ignoredHeaders);
this.ignoredPathPatterns = parsePatterns();
Expand All @@ -94,6 +98,9 @@ public boolean isMustMatchAll() {
return mustMatchAll;
}

public boolean isPreviewTokenEnabled() {
return previewTokenEnabled;
}

public List<Pattern> getHostPatterns() {
return hostPatterns;
Expand Down Expand Up @@ -182,6 +189,7 @@ public String toString() {
", cacheEnabled=" + cacheEnabled +
", mustMatchAll=" + mustMatchAll +
", allowCmsUsers=" + allowCmsUsers +
", previewTokenEnabled=" + previewTokenEnabled +
", forwardedForHeader='" + forwardedForHeader + '\'' +
", hosts=" + hosts +
", ranges=" + ranges +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ private void printRequestCookies(final HttpServletRequest request) {
/**
* Check if path is ignored
*/
private boolean isIgnored(final HttpServletRequest request, final AuthObject authObject) {
protected boolean isIgnored(final HttpServletRequest request, final AuthObject authObject) {
final String path = IpFilterUtils.getPath(request);
final List<Pattern> ignoredPaths = authObject.getIgnoredPathPatterns();
for (final Pattern ignoredPath : ignoredPaths) {
Expand All @@ -298,6 +298,17 @@ private boolean isIgnored(final HttpServletRequest request, final AuthObject aut
}
}

// check if preview token is present and enabled
if (authObject.isPreviewTokenEnabled()) {
final String previewToken = request.getParameter(IpFilterConstants.PREVIEW_TOKEN_PARAM_NAME);
if (!Strings.isNullOrEmpty(previewToken)) {
if (log.isDebugEnabled()) {
log.debug("Preview token detected in request, bypassing IP filter");
}
return true;
}
}

// check if we have header ignore:
final Map<String, Set<String>> multimap = authObject.getIgnoredHeaders();
if (multimap == null || multimap.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,9 @@ private AuthObject parse(final Node node, final Multimap<String, String> globalS
final String forwardHeader = JcrUtils.getStringProperty(node, IpFilterConstants.CONFIG_FORWARDED_FOR_HEADER, IpFilterConstants.HEADER_X_FORWARDED_FOR);
final boolean matchAll = JcrUtils.getBooleanProperty(node, IpFilterConstants.CONFIG_MATCH_ALL, false);
final boolean cacheEnabled = JcrUtils.getBooleanProperty(node, IpFilterConstants.CONFIG_CACHE_ENABLED, true);
final boolean previewTokenEnabled = JcrUtils.getBooleanProperty(node, IpFilterConstants.CONFIG_PREVIEW_TOKEN_ENABLED, false);

return new AuthObject(ignoredPathSet, hostSet, rangesSet, ignoredHeaders, allowCmsUsers, forwardHeader, cacheEnabled, matchAll);
return new AuthObject(ignoredPathSet, hostSet, rangesSet, ignoredHeaders, allowCmsUsers, forwardHeader, cacheEnabled, matchAll, previewTokenEnabled);
}

private Map<String, Set<String>> parseHeaders(final Node root) throws RepositoryException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public final class IpFilterConstants {
public static final String CONFIG_CACHE_ENABLED = "cache-enabled";
public static final String CONFIG_FORWARDED_FOR_HEADER = "forwarded-for-header";
public static final String CONFIG_FORWARDED_HOST_HEADER = "forwarded-host-header";
public static final String CONFIG_PREVIEW_TOKEN_ENABLED = "preview-token-enabled";
public static final String PREVIEW_TOKEN_PARAM_NAME = "preview-token";

public static final int BASIC_AUTH_PREFIX_LENGTH = "Basic ".length();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class IpFilterUtilsTest {
@Test
public void testGetIp() {
final Set<String> E = Collections.emptySet();
final AuthObject object = new AuthObject(E, E, E, Collections.emptyMap(), true, null,true, true);
final AuthObject object = new AuthObject(E, E, E, Collections.emptyMap(), true, null,true, true, false);
HttpServletRequest request = createMock(HttpServletRequest.class);
expect(request.getRemoteAddr()).andReturn("127.0.0.1").anyTimes();
expect(request.getHeader(IpFilterConstants.HEADER_X_FORWARDED_FOR)).andReturn(null).anyTimes();
Expand Down Expand Up @@ -82,5 +82,140 @@ protected String getDisabledPropertyName() {

}

@Test
public void testPreviewTokenBypassesFilter() {
final Set<String> E = Collections.emptySet();
final AuthObject authObject = new AuthObject(E, E, E, Collections.emptyMap(), false, null, true, false, true);
assertTrue("Preview token should be enabled", authObject.isPreviewTokenEnabled());

final BaseIpFilter baseIpFilter = new BaseIpFilter() {
@Override
protected Status authenticate(final AuthObject authObject, final HttpServletRequest request) {
return Status.FORBIDDEN;
}

@Override
protected void initializeConfigManager() {
}

@Override
protected String getDisabledPropertyName() {
return null;
}
};
baseIpFilter.configLoader = new TestConfigLoader();

HttpServletRequest request = createMock(HttpServletRequest.class);
expect(request.getRequestURI()).andReturn("/site/").anyTimes();
expect(request.getContextPath()).andReturn("").anyTimes();
expect(request.getParameter(IpFilterConstants.PREVIEW_TOKEN_PARAM_NAME))
.andReturn("e071af76-68f4-4d79-9e3c-4bbca02d655f").anyTimes();
replay(request);

final boolean ignored = baseIpFilter.isIgnored(request, authObject);
assertTrue("Request with preview token should be ignored", ignored);
}

@Test
public void testPreviewTokenDisabledDoesNotBypass() {
final Set<String> E = Collections.emptySet();
final AuthObject authObject = new AuthObject(E, E, E, Collections.emptyMap(), false, null, true, false, false);
assertFalse("Preview token should be disabled", authObject.isPreviewTokenEnabled());

final BaseIpFilter baseIpFilter = new BaseIpFilter() {
@Override
protected Status authenticate(final AuthObject authObject, final HttpServletRequest request) {
return Status.FORBIDDEN;
}

@Override
protected void initializeConfigManager() {
}

@Override
protected String getDisabledPropertyName() {
return null;
}
};
baseIpFilter.configLoader = new TestConfigLoader();

HttpServletRequest request = createMock(HttpServletRequest.class);
expect(request.getRequestURI()).andReturn("/site/").anyTimes();
expect(request.getContextPath()).andReturn("").anyTimes();
expect(request.getParameter(IpFilterConstants.PREVIEW_TOKEN_PARAM_NAME))
.andReturn("e071af76-68f4-4d79-9e3c-4bbca02d655f").anyTimes();
replay(request);

final boolean ignored = baseIpFilter.isIgnored(request, authObject);
assertFalse("Request with preview token should not be ignored when preview token is disabled", ignored);
}

@Test
public void testMissingPreviewTokenDoesNotBypass() {
final Set<String> E = Collections.emptySet();
final AuthObject authObject = new AuthObject(E, E, E, Collections.emptyMap(), false, null, true, false, true);
assertTrue("Preview token should be enabled", authObject.isPreviewTokenEnabled());

final BaseIpFilter baseIpFilter = new BaseIpFilter() {
@Override
protected Status authenticate(final AuthObject authObject, final HttpServletRequest request) {
return Status.FORBIDDEN;
}

@Override
protected void initializeConfigManager() {
}

@Override
protected String getDisabledPropertyName() {
return null;
}
};
baseIpFilter.configLoader = new TestConfigLoader();

HttpServletRequest request = createMock(HttpServletRequest.class);
expect(request.getRequestURI()).andReturn("/site/").anyTimes();
expect(request.getContextPath()).andReturn("").anyTimes();
expect(request.getParameter(IpFilterConstants.PREVIEW_TOKEN_PARAM_NAME))
.andReturn(null).anyTimes();
replay(request);

final boolean ignored = baseIpFilter.isIgnored(request, authObject);
assertFalse("Request without preview token should not be ignored", ignored);
}

@Test
public void testEmptyPreviewTokenDoesNotBypass() {
final Set<String> E = Collections.emptySet();
final AuthObject authObject = new AuthObject(E, E, E, Collections.emptyMap(), false, null, true, false, true);
assertTrue("Preview token should be enabled", authObject.isPreviewTokenEnabled());

final BaseIpFilter baseIpFilter = new BaseIpFilter() {
@Override
protected Status authenticate(final AuthObject authObject, final HttpServletRequest request) {
return Status.FORBIDDEN;
}

@Override
protected void initializeConfigManager() {
}

@Override
protected String getDisabledPropertyName() {
return null;
}
};
baseIpFilter.configLoader = new TestConfigLoader();

HttpServletRequest request = createMock(HttpServletRequest.class);
expect(request.getRequestURI()).andReturn("/site/").anyTimes();
expect(request.getContextPath()).andReturn("").anyTimes();
expect(request.getParameter(IpFilterConstants.PREVIEW_TOKEN_PARAM_NAME))
.andReturn("").anyTimes();
replay(request);

final boolean ignored = baseIpFilter.isIgnored(request, authObject);
assertFalse("Request with empty preview token should not be ignored", ignored);
}

}
20 changes: 20 additions & 0 deletions docs/css/forge-maven-skin-3.2.1.min.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/css/forge-maven-skin-syntaxhighlighter-3.2.1.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions docs/css/print.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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.
*/

/* $Id: print.css 1201871 2011-11-14 20:18:24Z simonetripodi $ */

#banner, #footer, #leftcol, #breadcrumbs, .docs #toc, .docs .courtesylinks, #leftColumn, #navColumn {display: none !important;}
#bodyColumn, body.docs div.docs {margin: 0 !important;border: none !important}
1 change: 1 addition & 0 deletions docs/css/site.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* You can override this file with your own styles */
Loading