Skip to content

Commit

Permalink
tenant: revisit filtering logic in TenantFilter
Browse files Browse the repository at this point in the history
The previous behavior was to either require tenant information
in the request and validate it or bypass the filter completly.

This wasn't enough for plugins which can choose to expose tenant
specific (e.g. Analytics export data API) or agnostic
(e.g. Stripe tokenize credit card page) endpoints.

This new patch will always honor tenant headers if specified
and only fail the request when these are mandatory.

Signed-off-by: Pierre-Alexandre Meyer <pierre@mouraf.org>
  • Loading branch information
pierre committed Jan 14, 2015
1 parent 0dac038 commit 4dbc635
Showing 1 changed file with 18 additions and 36 deletions.
Expand Up @@ -73,11 +73,6 @@ public void init(final FilterConfig filterConfig) throws ServletException {

@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
if (shouldSkipFilter(request)) {
chain.doFilter(request, response);
return;
}

// Lookup tenant information in the headers
String apiKey = null;
String apiSecret = null;
Expand All @@ -89,8 +84,12 @@ public void doFilter(final ServletRequest request, final ServletResponse respons

// Multi-tenancy is enabled if this filter is installed, we can't continue without credentials
if (apiKey == null || apiSecret == null) {
final String errorMessage = String.format("Make sure to set the %s and %s headers", JaxrsResource.HDR_API_KEY, JaxrsResource.HDR_API_SECRET);
sendAuthError(response, errorMessage);
if (shouldContinueIfTenantInformationIsMissing(request)) {
chain.doFilter(request, response);
} else {
final String errorMessage = String.format("Make sure to set the %s and %s headers", JaxrsResource.HDR_API_KEY, JaxrsResource.HDR_API_SECRET);
sendAuthError(response, errorMessage);
}
return;
}

Expand Down Expand Up @@ -120,8 +119,8 @@ public void doFilter(final ServletRequest request, final ServletResponse respons
public void destroy() {
}

private boolean shouldSkipFilter(final ServletRequest request) {
boolean shouldSkip = false;
private boolean shouldContinueIfTenantInformationIsMissing(final ServletRequest request) {
boolean shouldContinue = false;

if (request instanceof HttpServletRequest) {
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
Expand All @@ -136,14 +135,16 @@ private boolean shouldSkipFilter(final ServletRequest request) {
isMetricsRequest(path, httpMethod) ||
// See KillBillShiroWebModule#CorsBasicHttpAuthenticationFilter
isOptionsRequest(httpMethod) ||
// Static resources
isStaticResourceRequest(path, httpMethod)
// Shift the responsibility to the plugin
isPluginRequest(path) ||
// Static resources (welcome screen, Swagger, etc.)
isNotKbNorPluginResourceRequest(path, httpMethod)
) {
shouldSkip = true;
shouldContinue = true;
}
}

return shouldSkip;
return shouldContinue;
}

private boolean isPermissionRequest(final String path, final String httpMethod) {
Expand All @@ -162,35 +163,16 @@ private boolean isOptionsRequest(final String httpMethod) {
return "OPTIONS".equals(httpMethod);
}

private boolean isStaticResourceRequest(final String path, final String httpMethod) {
if (isPluginRequest(path)) {
// For plugins requests, we want to validate the Tenant except for HTML, JS, etc. files
return isStaticFileRequest(path) && "GET".equals(httpMethod);
} else {
// Welcome screen, Swagger, etc.
return !isKbApiRequest(path) && "GET".equals(httpMethod);
}
private boolean isNotKbNorPluginResourceRequest(final String path, final String httpMethod) {
return !isPluginRequest(path) && !isKbApiRequest(path) && "GET".equals(httpMethod);
}

private boolean isKbApiRequest(final String path) {
return path.startsWith(JaxrsResource.PREFIX);
return path != null && path.startsWith(JaxrsResource.PREFIX);
}

private boolean isPluginRequest(final String path) {
return path.startsWith(JaxrsResource.PLUGINS_PATH);
}

private boolean isStaticFileRequest(final String path) {
return path.endsWith(".htm") ||
path.endsWith(".html") ||
path.endsWith(".js") ||
path.endsWith(".css") ||
path.endsWith(".gz") ||
path.endsWith(".xml") ||
path.endsWith(".txt") ||
path.endsWith(".map")||
path.endsWith(".woff")||
path.endsWith(".ttf");
return path != null && path.startsWith(JaxrsResource.PLUGINS_PATH);
}

private void sendAuthError(final ServletResponse response, final String errorMessage) throws IOException {
Expand Down

0 comments on commit 4dbc635

Please sign in to comment.