Merge pull request #99 from cloudbees/feature/UX-159
UX-159: Add a crumb exclusion for json
This commit is contained in:
commit
79865fe196
|
@ -4,6 +4,7 @@ This is the BlueOcean repo. It is a multi-module maven project. Each sub-directo
|
|||
|
||||
Blue Ocean is the new UI project for Jenkins.
|
||||
|
||||
|
||||
![Pirate logo, because it's ocean and stuff](logo-yarrr.png)
|
||||
Yarr...
|
||||
|
||||
|
|
|
@ -44,6 +44,70 @@ public class ProfileApiTest {
|
|||
.body("fullName", Matchers.equalTo(system.getFullName()));
|
||||
}
|
||||
|
||||
//UX-159
|
||||
@Test
|
||||
public void postCrumbTest() throws Exception {
|
||||
User system = j.jenkins.getUser("SYSTEM");
|
||||
|
||||
RestAssured.given().contentType("application/json").log().all().post("/users/{id}/", system.getId())
|
||||
.then().log().all()
|
||||
.statusCode(200)
|
||||
.body("id", Matchers.equalTo(system.getId()))
|
||||
.body("fullName", Matchers.equalTo(system.getFullName()));
|
||||
}
|
||||
|
||||
//UX-159
|
||||
@Test
|
||||
public void postCrumbFailTest() throws Exception {
|
||||
User system = j.jenkins.getUser("SYSTEM");
|
||||
|
||||
RestAssured.given().log().all().post("/users/{id}/", system.getId())
|
||||
.then().log().all()
|
||||
.statusCode(403);
|
||||
}
|
||||
|
||||
//UX-159
|
||||
@Test
|
||||
public void putMimeTest() throws Exception {
|
||||
User system = j.jenkins.getUser("SYSTEM");
|
||||
|
||||
RestAssured.given().contentType("application/json").log().all().put("/users/{id}/", system.getId())
|
||||
.then().log().all()
|
||||
.statusCode(200)
|
||||
.body("id", Matchers.equalTo(system.getId()))
|
||||
.body("fullName", Matchers.equalTo(system.getFullName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void putMimeFailTest() throws Exception {
|
||||
User system = j.jenkins.getUser("SYSTEM");
|
||||
|
||||
RestAssured.given().log().all().put("/users/{id}/", system.getId())
|
||||
.then().log().all()
|
||||
.statusCode(415);
|
||||
}
|
||||
|
||||
//UX-159
|
||||
@Test
|
||||
public void patchMimeTest() throws Exception {
|
||||
User system = j.jenkins.getUser("SYSTEM");
|
||||
|
||||
RestAssured.given().contentType("application/json").log().all().patch("/users/{id}/", system.getId())
|
||||
.then().log().all()
|
||||
.statusCode(200)
|
||||
.body("id", Matchers.equalTo(system.getId()))
|
||||
.body("fullName", Matchers.equalTo(system.getFullName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchMimeFailTest() throws Exception {
|
||||
User system = j.jenkins.getUser("SYSTEM");
|
||||
|
||||
RestAssured.given().log().all().patch("/users/{id}/", system.getId())
|
||||
.then().log().all()
|
||||
.statusCode(415);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUserDetailsTest() throws Exception {
|
||||
hudson.model.User user = j.jenkins.getUser("alice");
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# Usage
|
||||
|
||||
## Crumbs
|
||||
|
||||
Jenkins usually requires a "crumb" with posted reuqests to prevent request forgery and other shenanigans.
|
||||
To avoid needing a crumb to POST data, the header `Content-Type: application/json` *must* be used.
|
||||
|
||||
## Run BlueOcean plugin
|
||||
|
||||
cd bluecoean-plugin
|
||||
|
@ -16,7 +21,6 @@ BlueOcean rest API base URL is:
|
|||
|
||||
http://localhost:8080/jenkins/blue/rest
|
||||
|
||||
|
||||
## Get a user
|
||||
|
||||
curl -v -X GET http://localhost:8080/jenkins/blue/rest/users/alice
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
package io.jenkins.blueocean.rest;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import hudson.Extension;
|
||||
import hudson.ExtensionList;
|
||||
import hudson.security.csrf.CrumbExclusion;
|
||||
import io.jenkins.blueocean.RootRoutable;
|
||||
|
||||
/**
|
||||
* This class forces the Blueocean API to require json for POSTs so that we do not need a crumb.
|
||||
* @author Ivan Meredith
|
||||
*/
|
||||
@Extension
|
||||
public class APICrumbExclusion extends CrumbExclusion{
|
||||
@Override
|
||||
public boolean process(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
String pathInfo = httpServletRequest.getPathInfo();
|
||||
|
||||
for (RootRoutable r : ExtensionList.lookup(RootRoutable.class)) {
|
||||
String path = getExclusionPath(r.getUrlName());
|
||||
if (pathInfo != null && pathInfo.startsWith(path)) {
|
||||
String header = httpServletRequest.getHeader("Content-Type");
|
||||
if(header != null && header.contains("application/json")) {
|
||||
filterChain.doFilter(httpServletRequest, httpServletResponse);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public String getExclusionPath(String route) {
|
||||
return "/blue/" + route + "/";
|
||||
}
|
||||
|
||||
}
|
|
@ -3,10 +3,13 @@ package io.jenkins.blueocean.rest;
|
|||
import hudson.Extension;
|
||||
import hudson.ExtensionList;
|
||||
import io.jenkins.blueocean.RootRoutable;
|
||||
import io.jenkins.blueocean.commons.ServiceException;
|
||||
import io.jenkins.blueocean.rest.pageable.Pageable;
|
||||
import io.jenkins.blueocean.rest.pageable.Pageables;
|
||||
import io.jenkins.blueocean.rest.pageable.PagedResponse;
|
||||
import org.kohsuke.stapler.QueryParameter;
|
||||
import org.kohsuke.stapler.Stapler;
|
||||
import org.kohsuke.stapler.StaplerRequest;
|
||||
import org.kohsuke.stapler.WebMethod;
|
||||
import org.kohsuke.stapler.verb.GET;
|
||||
|
||||
|
@ -64,6 +67,14 @@ public final class ApiHead implements RootRoutable {
|
|||
* @return {@link ApiRoutable} object
|
||||
*/
|
||||
public ApiRoutable getDynamic(String route) {
|
||||
StaplerRequest request = Stapler.getCurrentRequest();
|
||||
String m = request.getMethod();
|
||||
if(m.equalsIgnoreCase("POST") || m.equalsIgnoreCase("PUT") || m.equalsIgnoreCase("PATCH")) {
|
||||
String header = request.getHeader("Content-Type");
|
||||
if(header == null || !header.contains("application/json")) {
|
||||
throw new ServiceException(415, "Content-Type: application/json required");
|
||||
}
|
||||
}
|
||||
return apis.get(route);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue