Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jetty 10 7918 root pathspec #7920

Merged
merged 4 commits into from Apr 26, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -201,6 +201,8 @@ public static PathSpec asPathSpec(String pathSpecString)
{
if ((pathSpecString == null) || (pathSpecString.length() < 1))
{
if (pathSpecString != null)
gregw marked this conversation as resolved.
Show resolved Hide resolved
return new ServletPathSpec("");
throw new RuntimeException("Path Spec String must start with '^', '/', or '*.': got [" + pathSpecString + "]");
}
return pathSpecString.charAt(0) == '^' ? new RegexPathSpec(pathSpecString) : new ServletPathSpec(pathSpecString);
Expand Down
Expand Up @@ -20,6 +20,7 @@
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.jupiter.api.Assertions.assertEquals;
Expand Down Expand Up @@ -456,4 +457,18 @@ public void testRemoveServletPathSpec()
assertThat(p.remove(new ServletPathSpec("/a/b/c")), is(true));
assertThat(p.remove(new ServletPathSpec("/a/b/c")), is(false));
}

@Test
public void testAsPathSpec()
{
assertThat(PathMappings.asPathSpec(""), instanceOf(ServletPathSpec.class));
assertThat(PathMappings.asPathSpec("/"), instanceOf(ServletPathSpec.class));
assertThat(PathMappings.asPathSpec("/*"), instanceOf(ServletPathSpec.class));
assertThat(PathMappings.asPathSpec("/foo/*"), instanceOf(ServletPathSpec.class));
assertThat(PathMappings.asPathSpec("*.jsp"), instanceOf(ServletPathSpec.class));

assertThat(PathMappings.asPathSpec("^$"), instanceOf(RegexPathSpec.class));
assertThat(PathMappings.asPathSpec("^.*"), instanceOf(RegexPathSpec.class));
assertThat(PathMappings.asPathSpec("^/"), instanceOf(RegexPathSpec.class));
}
}
Expand Up @@ -35,6 +35,7 @@
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.pathmap.MappedResource;
import org.eclipse.jetty.http.pathmap.PathMappings;
import org.eclipse.jetty.http.pathmap.PathSpec;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
Expand Down Expand Up @@ -422,7 +423,7 @@ protected void doStop() throws Exception
*/
protected void processConstraintMapping(ConstraintMapping mapping)
{
Map<String, RoleInfo> mappings = _constraintRoles.get(PathMappings.asPathSpec(mapping.getPathSpec()));
Map<String, RoleInfo> mappings = _constraintRoles.get(asPathSpec(mapping));
if (mappings == null)
{
mappings = new HashMap<>();
Expand Down Expand Up @@ -467,6 +468,13 @@ protected void processConstraintMapping(ConstraintMapping mapping)
}
}

protected PathSpec asPathSpec(ConstraintMapping mapping)
{
// As currently written, this allows regex patterns to be used.
// This may not be supported by default in future releases.
return PathMappings.asPathSpec(mapping.getPathSpec());
}

/**
* Constraints that name method omissions are dealt with differently.
* We create an entry in the mappings with key "&lt;method&gt;.omission". This entry
Expand Down
Expand Up @@ -1869,6 +1869,44 @@ public void testForbidTraceAndOptions() throws Exception
assertThat(response, startsWith("HTTP/1.1 403 "));
}

@Test
public void testDefaultConstraint() throws Exception
{
_security.setAuthenticator(new BasicAuthenticator());

ConstraintMapping forbidDefault = new ConstraintMapping();
forbidDefault.setPathSpec("/");
forbidDefault.setConstraint(_forbidConstraint);
_security.addConstraintMapping(forbidDefault);

ConstraintMapping allowRoot = new ConstraintMapping();
allowRoot.setPathSpec("");
allowRoot.setConstraint(_relaxConstraint);
_security.addConstraintMapping(allowRoot);

_server.start();
String response;

response = _connector.getResponse("GET /ctx/ HTTP/1.0\r\n\r\n");
assertThat(response, startsWith("HTTP/1.1 200 OK"));

response = _connector.getResponse("GET /ctx/anything HTTP/1.0\r\n\r\n");
assertThat(response, startsWith("HTTP/1.1 403 Forbidden"));

response = _connector.getResponse("GET /ctx/noauth/info HTTP/1.0\r\n\r\n");
assertThat(response, startsWith("HTTP/1.1 403 Forbidden"));

response = _connector.getResponse("GET /ctx/forbid/info HTTP/1.0\r\n\r\n");
assertThat(response, startsWith("HTTP/1.1 403 Forbidden"));

response = _connector.getResponse("GET /ctx/auth/info HTTP/1.0\r\n\r\n");
assertThat(response, startsWith("HTTP/1.1 401 Unauthorized"));
assertThat(response, containsString("WWW-Authenticate: basic realm=\"TestRealm\""));

response = _connector.getResponse("GET /ctx/admin/relax/info HTTP/1.0\r\n\r\n");
assertThat(response, startsWith("HTTP/1.1 200 OK"));
}

private static String authBase64(String authorization)
{
byte[] raw = authorization.getBytes(ISO_8859_1);
Expand Down