Skip to content

Commit

Permalink
Merge pull request #70 from tbouffard/issue_crumb_and_sessionId_with_…
Browse files Browse the repository at this point in the history
…Jenkins_2.176.2+

fix crumb issue with Jenkins 2.176.2+/2.186+
  • Loading branch information
cdancy authored Dec 16, 2019
2 parents 1be331a + d963969 commit 6077aa4
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 11 deletions.
3 changes: 1 addition & 2 deletions src/main/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# api calls 403 error with jenkins 2.176.2+/2.186+ because of security changes: https://jenkins.io/security/advisory/2019-07-17/#SECURITY-626
ARG jenkins_tag=2.176.1-alpine
ARG jenkins_tag=2.190.3-alpine

FROM jenkins/jenkins:$jenkins_tag

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/cdancy/jenkins/rest/JenkinsConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public class JenkinsConstants {

public static final String OPTIONAL_FOLDER_PATH_PARAM = "optionalFolderPath";

public static final String JENKINS_COOKIES_JSESSIONID = "JSESSIONID";

protected JenkinsConstants() {
throw new UnsupportedOperationException("Purposefully not implemented");
}
Expand Down
26 changes: 21 additions & 5 deletions src/main/java/com/cdancy/jenkins/rest/domain/crumb/Crumb.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,34 @@

import com.cdancy.jenkins.rest.domain.common.Error;
import com.cdancy.jenkins.rest.domain.common.ErrorsHolder;
import com.cdancy.jenkins.rest.domain.common.Value;
import com.cdancy.jenkins.rest.JenkinsUtils;
import com.google.auto.value.AutoValue;

@AutoValue
public abstract class Crumb implements Value<String>, ErrorsHolder {
public abstract class Crumb implements ErrorsHolder {

@Nullable
public abstract String value();

@Nullable
public abstract String sessionIdCookie();

@SerializedNames({ "value", "errors" })
public static Crumb create(@Nullable final String value,
public static Crumb create(final String value,
final List<Error> errors) {

return create(value, null, errors);
}

@SerializedNames({ "value", "sessionIdCookie" })
public static Crumb create(final String value, final String sessionIdCookie) {
return create(value, sessionIdCookie, null);
}

private static Crumb create(final String value, final String sessionIdCookie,
final List<Error> errors) {

return new AutoValue_Crumb(value,
JenkinsUtils.nullToEmpty(errors));
return new AutoValue_Crumb(JenkinsUtils.nullToEmpty(errors), value,
sessionIdCookie);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package com.cdancy.jenkins.rest.filters;

import java.util.Optional;
import javax.inject.Inject;
import javax.inject.Singleton;

Expand All @@ -39,7 +40,7 @@ public class JenkinsAuthenticationFilter implements HttpRequestFilter {
private final JenkinsApi jenkinsApi;

// key = Crumb, value = true if exception is ResourceNotFoundException false otherwise
private static volatile Pair<Crumb, Boolean> crumbPair = null;
private static volatile Pair<Crumb, Boolean> crumbPair = null;
private static final String CRUMB_HEADER = "Jenkins-Crumb";

@Inject
Expand All @@ -61,6 +62,8 @@ public HttpRequest filter(final HttpRequest request) throws HttpException {
final Pair<Crumb, Boolean> localCrumb = getCrumb();
if (localCrumb.getKey().value() != null) {
builder.addHeader(CRUMB_HEADER, localCrumb.getKey().value());
Optional.ofNullable(localCrumb.getKey().sessionIdCookie())
.ifPresent(sessionId -> builder.addHeader(HttpHeaders.COOKIE, sessionId));
} else {
if (localCrumb.getValue() == false) {
throw new RuntimeException("Unexpected exception being thrown: error=" + localCrumb.getKey().errors().get(0));
Expand All @@ -87,7 +90,7 @@ private Pair<Crumb, Boolean> getCrumb() {
}
return crumbValueInit;
}

// simple impl/copy of javafx.util.Pair
private class Pair<A, B> {
private final A a;
Expand Down
18 changes: 16 additions & 2 deletions src/main/java/com/cdancy/jenkins/rest/parsers/CrumbParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@

package com.cdancy.jenkins.rest.parsers;

import static com.cdancy.jenkins.rest.JenkinsConstants.JENKINS_COOKIES_JSESSIONID;

import com.cdancy.jenkins.rest.domain.crumb.Crumb;

import com.google.common.base.Function;
import java.io.IOException;

import javax.inject.Singleton;
import javax.ws.rs.core.HttpHeaders;

import org.jclouds.http.HttpResponse;
import org.jclouds.util.Strings2;
Expand All @@ -38,13 +41,24 @@ public Crumb apply(final HttpResponse input) {
final int statusCode = input.getStatusCode();
if (statusCode >= 200 && statusCode < 400) {
try {
final String response = Strings2.toStringAndClose(input.getPayload().openStream());
return Crumb.create(response.split(":")[1], null);
return Crumb.create(crumbValue(input), sessionIdCookie(input));
} catch (final IOException e) {
throw new RuntimeException(input.getStatusLine(), e);
}
} else {
throw new RuntimeException(input.getStatusLine());
}
}

private static String crumbValue(HttpResponse input) throws IOException {
return Strings2.toStringAndClose(input.getPayload().openStream())
.split(":")[1];
}

private static String sessionIdCookie(HttpResponse input) {
return input.getHeaders().get(HttpHeaders.SET_COOKIE).stream()
.filter(c -> c.startsWith(JENKINS_COOKIES_JSESSIONID))
.findFirst()
.orElse("");
}
}

0 comments on commit 6077aa4

Please sign in to comment.