/** * */ package org.archive.wayback.resourceindex.cdxserver; import java.util.List; import java.util.logging.Logger; import org.archive.cdxserver.CDXServer; import org.archive.cdxserver.auth.AuthChecker; import org.archive.cdxserver.auth.AuthToken; import org.archive.cdxserver.auth.PrivTokenAuthChecker; import org.archive.cdxserver.filter.CDXAccessFilter; import org.archive.cdxserver.filter.CDXFilter; import org.archive.cdxserver.filter.FilenamePrefixFilter; import org.archive.format.cdx.CDXLine; import org.archive.wayback.accesscontrol.ExclusionFilterFactory; import org.archive.wayback.accesscontrol.oracleclient.CustomPolicyOracleFilter; import org.archive.wayback.resourceindex.filters.ExclusionFilter; import org.archive.wayback.webapp.AccessPoint; /** * {@link AuthChecker} implementation that runs {@link ExclusionFilter} provided * through {@link AccessPoint#getExclusionFactory()} as well as the filtering * provided by {@link WaybackAPAuthChecker}. * <p> * This is primarily meant for running {@link CustomPolicyOracleFilter} in * {@link CDXServer} rather than in {@link EmbeddedCDXServerIndex}, making * {@link WaybackAPAuthChecker} obsolete. Current implementation is very * specific to this usage. * </p> * Needs {@link APContextAuthToken} as token.</p> */ public class AccessPointAuthChecker extends PrivTokenAuthChecker { private static final Logger logger = Logger .getLogger(AccessPointAuthChecker.class.getName()); protected ExclusionFilterFactory fallbackExclusionFactory; /** * {@link ExclusionFilterFactory} used if token passed to * {@link #createAccessFilter(AuthToken)} is not an instance of * {@link APContextAuthToken} (CDX server query, for example). * @param fallbackExclusionFactory */ public void setFallbackExclusionFactory( ExclusionFilterFactory fallbackExclusionFactory) { this.fallbackExclusionFactory = fallbackExclusionFactory; } public ExclusionFilterFactory getFallbackExclusionFactory() { return fallbackExclusionFactory; } /** * {@link CDXFilter} on prefix of filename field. * <p> * It first accepts all captures that have any of {@code includePrefixes} as * filename prefixes, then rejects captures that have any of * {@code excludePrefixes}. If {@code includePrefixes} is {@code null} (as * opposed to empty), all captures are accepted. * </p> */ protected class CombinedFilenamePrefixFilter implements CDXFilter { FilenamePrefixFilter includeFilter; FilenamePrefixFilter excludeFilter; public CombinedFilenamePrefixFilter(List<String> includePrefixes, List<String> excludePrefixes) { if (includePrefixes != null) this.includeFilter = new FilenamePrefixFilter(includePrefixes, false); if (excludePrefixes != null) this.excludeFilter = new FilenamePrefixFilter(excludePrefixes, true); } @Override public boolean include(CDXLine line) { return (includeFilter == null || includeFilter.include(line)) && (excludeFilter == null || excludeFilter.include(line)); } } @Override public CDXAccessFilter createAccessFilter(AuthToken token) { if (token instanceof APContextAuthToken) { AccessPoint ap = ((APContextAuthToken)token).getAccessPoint(); CDXFilter prefixFilter = new CombinedFilenamePrefixFilter( ap.getFileIncludePrefixes(), ap.getFileExcludePrefixes()); ExclusionFilter apFilter = null; try { apFilter = ap.createExclusionFilter(); } catch (Exception ex) { // FIXME: createExclusionFilter throws a sub-class of // AccessControlException when it fails to initialize // the exclusion component. Unfortunately it cannot be // thrown from this method because AuthChecker interface // is part of cdx-server project which cannot depend on // wayback-core, where AccessControlException is defined. // Yet, we should not just ignore this error because // exclusion system failure can be highly risky. // For now, we throw AccessControlException wrapped in // RuntimeException, assuming caller is catching it. // (See EmbeddedCDXServerIndex#doQuery(WaybackRequest)) // Probably we should define a new exception in cdx-server. throw new RuntimeException(ex); } return new AccessCheckFilter(token, apFilter, null, prefixFilter); } else { ExclusionFilter apFilter = null; if (fallbackExclusionFactory != null) { apFilter = fallbackExclusionFactory.get(); } return new AccessCheckFilter(token, apFilter, null, null); } } }