Skip to content

Commit 0d96613

Browse files
committed
Modernize to Jenkins 2.479 and Jakarta EE 9
* Adapter methods are added for old overrides. * Switch to JUnit 5 for tests
1 parent 9fa1b09 commit 0d96613

12 files changed

+198
-180
lines changed

pom.xml

+6-6
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
<parent>
55
<groupId>org.jenkins-ci.plugins</groupId>
66
<artifactId>plugin</artifactId>
7-
<version>4.86</version>
8-
<relativePath/>
7+
<version>5.3</version>
98
</parent>
109

1110
<artifactId>git-server</artifactId>
@@ -17,7 +16,8 @@
1716

1817
<properties>
1918
<changelist>999999-SNAPSHOT</changelist>
20-
<jenkins.version>2.440.3</jenkins.version>
19+
<jenkins.baseline>2.479</jenkins.baseline>
20+
<jenkins.version>${jenkins.baseline}.1</jenkins.version>
2121
<gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo>
2222
</properties>
2323

@@ -40,8 +40,8 @@
4040
<dependencies>
4141
<dependency>
4242
<groupId>io.jenkins.tools.bom</groupId>
43-
<artifactId>bom-2.440.x</artifactId>
44-
<version>3234.v5ca_5154341ef</version>
43+
<artifactId>bom-${jenkins.baseline}.x</artifactId>
44+
<version>3696.vb_b_4e2d1a_0542</version>
4545
<scope>import</scope>
4646
<type>pom</type>
4747
</dependency>
@@ -65,7 +65,7 @@
6565
<dependency>
6666
<groupId>org.eclipse.jgit</groupId>
6767
<artifactId>org.eclipse.jgit.ssh.apache</artifactId>
68-
<version>6.9.0.202403050737-r</version>
68+
<version>7.0.0.202409031743-r</version>
6969
<scope>test</scope>
7070
</dependency>
7171
<dependency>

src/main/java/org/jenkinsci/plugins/gitserver/CSRFExclusionImpl.java

+28-24
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
import hudson.Extension;
44
import hudson.security.csrf.CrumbExclusion;
55

6-
import javax.servlet.FilterChain;
7-
import javax.servlet.ReadListener;
8-
import javax.servlet.ServletException;
9-
import javax.servlet.ServletInputStream;
10-
import javax.servlet.http.HttpServletRequest;
11-
import javax.servlet.http.HttpServletRequestWrapper;
12-
import javax.servlet.http.HttpServletResponse;
6+
import jakarta.servlet.FilterChain;
7+
import jakarta.servlet.ReadListener;
8+
import jakarta.servlet.ServletException;
9+
import jakarta.servlet.ServletInputStream;
10+
import jakarta.servlet.http.HttpServletRequest;
11+
import jakarta.servlet.http.HttpServletRequestWrapper;
12+
import jakarta.servlet.http.HttpServletResponse;
1313
import java.io.IOException;
1414
import java.util.Collections;
1515
import java.util.Enumeration;
1616
import java.util.Map;
17-
import java.util.Vector;
17+
import java.util.Set;
1818

1919
/**
2020
* CSRF exclusion for git-upload-pack.
@@ -24,9 +24,10 @@
2424
* because of the dynamic nature of the URL structure, this doesn't guarantee
2525
* that we have no leak.
2626
*
27+
* <p>
2728
* So to further protect Jenkins, we pass through a fake {@link HttpServletRequest}
2829
* that masks the values of the submission.
29-
*
30+
*
3031
* <p>
3132
* If the fake request is routed to {@link HttpGitRepository}, which is
3233
* the only legitimate destination of the request, we'll unwrap this fake request
@@ -40,48 +41,51 @@
4041
*/
4142
@Extension
4243
public class CSRFExclusionImpl extends CrumbExclusion {
44+
private static final Set<String> ALLOWED_CONTENT_TYPES = Set.of(
45+
"application/x-git-receive-pack-request",
46+
"application/x-git-upload-pack-request"
47+
);
48+
private static final String BOGUS = "bogus";
4349

50+
@Override
4451
public boolean process(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
45-
if (!"application/x-git-receive-pack-request".equals(request.getHeader("Content-Type")))
52+
String contentType = request.getHeader("Content-Type");
53+
if (contentType == null || !ALLOWED_CONTENT_TYPES.contains(contentType))
4654
return false;
4755

48-
// String path = request.getPathInfo();
49-
// if(!path.contains("/repo.git/") || !path.endsWith("/git-receive-pack"))
50-
// return false;
51-
5256
HttpServletRequestWrapper w = new HttpServletRequestWrapper(request) {
5357
@Override
5458
public String getQueryString() {
55-
return "bogus";
59+
return BOGUS;
5660
}
5761

5862
@Override
5963
public String getParameter(String name) {
60-
return "bogus";
64+
return BOGUS;
6165
}
6266

6367
@Override
64-
public Map getParameterMap() {
68+
public Map<String, String[]> getParameterMap() {
6569
return Collections.emptyMap();
6670
}
6771

6872
@Override
69-
public Enumeration getParameterNames() {
70-
return new Vector().elements();
73+
public Enumeration<String> getParameterNames() {
74+
return Collections.emptyEnumeration();
7175
}
7276

7377
@Override
7478
public String[] getParameterValues(String name) {
75-
return new String[]{"bogus"};
79+
return new String[]{BOGUS};
7680
}
7781

7882
@Override
7983
public String getMethod() {
80-
return "BOGUS";
84+
return BOGUS.toUpperCase();
8185
}
8286

8387
@Override
84-
public ServletInputStream getInputStream() throws IOException {
88+
public ServletInputStream getInputStream() {
8589
return new ServletInputStream() {
8690
@Override
8791
public boolean isFinished() {
@@ -94,7 +98,7 @@ public boolean isReady() {
9498
}
9599

96100
@Override
97-
public int read() throws IOException {
101+
public int read() {
98102
return -1;
99103
}
100104

@@ -106,7 +110,7 @@ public void setReadListener(ReadListener readListener) {
106110
}
107111
};
108112
w.setAttribute(ORIGINAL_REQUEST,request);
109-
113+
110114
chain.doFilter(w,response);
111115
return true;
112116
}

src/main/java/org/jenkinsci/plugins/gitserver/ChannelTransport.java

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.jenkinsci.plugins.gitserver;
22

33
import hudson.FilePath;
4-
import hudson.FilePath.FileCallable;
54
import hudson.remoting.Pipe;
65
import hudson.remoting.VirtualChannel;
76
import jenkins.MasterToSlaveFileCallable;
@@ -56,6 +55,7 @@ public FetchConnection openFetch() throws NotSupportedException, TransportExcept
5655
} catch (IOException e) {
5756
throw new TransportException("Failed to open a fetch connection",e);
5857
} catch (InterruptedException e) {
58+
Thread.currentThread().interrupt();
5959
throw new TransportException("Failed to open a fetch connection",e);
6060
}
6161

@@ -99,15 +99,13 @@ public GitFetchTask(Pipe l2r, Pipe r2l) {
9999
}
100100

101101
public Void invoke(File f, VirtualChannel channel) throws IOException, InterruptedException {
102-
Repository repo = new FileRepositoryBuilder().setWorkTree(f).build();
103-
try {
102+
try (Repository repo = new FileRepositoryBuilder().setWorkTree(f).build()) {
104103
final UploadPack rp = new UploadPack(repo);
105104
rp.upload(new BufferedInputStream(l2r.getIn()), new BufferedOutputStream(r2l.getOut()), null);
106105
return null;
107106
} finally {
108107
IOUtils.closeQuietly(l2r.getIn());
109108
IOUtils.closeQuietly(r2l.getOut());
110-
repo.close();
111109
}
112110
}
113111
}
@@ -122,15 +120,13 @@ public GitPushTask(Pipe l2r, Pipe r2l) {
122120
}
123121

124122
public Void invoke(File f, VirtualChannel channel) throws IOException, InterruptedException {
125-
Repository repo = new FileRepositoryBuilder().setWorkTree(f).build();
126-
try {
123+
try (Repository repo = new FileRepositoryBuilder().setWorkTree(f).build()) {
127124
final ReceivePack rp = new ReceivePack(repo);
128125
rp.receive(new BufferedInputStream(l2r.getIn()), new BufferedOutputStream(r2l.getOut()), null);
129126
return null;
130127
} finally {
131128
IOUtils.closeQuietly(l2r.getIn());
132129
IOUtils.closeQuietly(r2l.getOut());
133-
repo.close();
134130
}
135131
}
136132
}

src/main/java/org/jenkinsci/plugins/gitserver/FileBackedHttpGitRepository.java

+29-21
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package org.jenkinsci.plugins.gitserver;
22

3+
import jakarta.servlet.http.HttpServletRequest;
34
import jenkins.model.Jenkins;
4-
import org.acegisecurity.Authentication;
55
import org.eclipse.jgit.api.AddCommand;
66
import org.eclipse.jgit.api.CommitCommand;
77
import org.eclipse.jgit.api.Git;
@@ -11,19 +11,19 @@
1111
import org.eclipse.jgit.lib.PersonIdent;
1212
import org.eclipse.jgit.lib.Repository;
1313
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
14-
import org.eclipse.jgit.transport.PostReceiveHook;
15-
import org.eclipse.jgit.transport.ReceiveCommand;
1614
import org.eclipse.jgit.transport.ReceivePack;
1715
import org.eclipse.jgit.transport.UploadPack;
1816
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
1917
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
18+
import org.springframework.security.core.Authentication;
2019

21-
import javax.servlet.http.HttpServletRequest;
2220
import java.io.File;
2321
import java.io.IOException;
2422
import java.io.PrintWriter;
2523
import java.io.StringWriter;
26-
import java.util.Collection;
24+
import java.nio.file.FileAlreadyExistsException;
25+
import java.nio.file.Files;
26+
import java.nio.file.Path;
2727
import java.util.logging.Level;
2828
import java.util.logging.Logger;
2929

@@ -39,19 +39,27 @@ public abstract class FileBackedHttpGitRepository extends HttpGitRepository {
3939
* Directory of the local workspace on the controller.
4040
* There will be "./.git" that hosts the actual repository.
4141
*/
42-
public final File workspace;
42+
public final Path workspace;
4343

44-
protected FileBackedHttpGitRepository(File workspace) {
44+
protected FileBackedHttpGitRepository(Path workspace) {
4545
this.workspace = workspace;
46-
if (!workspace.exists() && !workspace.mkdirs()) {
47-
LOGGER.log(Level.WARNING, "Cannot create a workspace in {0}", workspace);
46+
try {
47+
Files.createDirectory(workspace);
48+
} catch (FileAlreadyExistsException ignored) {
49+
// don't need to worry about this; if it already exists, we don't care!
50+
} catch (IOException e) {
51+
LOGGER.log(Level.WARNING, e, () -> "Cannot create a workspace in " + workspace);
4852
}
4953
}
5054

55+
protected FileBackedHttpGitRepository(File workspace) {
56+
this(workspace.toPath());
57+
}
58+
5159
@Override
5260
public Repository openRepository() throws IOException {
5361
checkPullPermission();
54-
Repository r = new FileRepositoryBuilder().setWorkTree(workspace).build();
62+
Repository r = new FileRepositoryBuilder().setWorkTree(workspace.toFile()).build();
5563

5664
// if the repository doesn't exist, create it
5765
if (!r.getObjectDatabase().exists()) {
@@ -63,6 +71,7 @@ public Repository openRepository() throws IOException {
6371
/**
6472
* Called when there's no .git directory to create one.
6573
*
74+
* <p>
6675
* This implementation also imports whatever currently in there into the repository.
6776
*/
6877
protected void createInitialRepository(Repository r) throws IOException {
@@ -80,14 +89,15 @@ protected void createInitialRepository(Repository r) throws IOException {
8089
co.setMessage("Initial import of the existing contents");
8190
co.call();
8291
} catch (GitAPIException e) {
83-
LOGGER.log(Level.WARNING, "Initial import of "+workspace+" into Git repository failed",e);
92+
LOGGER.log(Level.WARNING, e, () -> "Initial import of "+workspace+" into Git repository failed");
8493
}
8594
}
8695

8796
/**
8897
* This default implementation allows read access to anyone
8998
* who can access the HTTP URL this repository is bound to.
9099
*
100+
* <p>
91101
* For example, if this object is used as a project action,
92102
* and the project isn't readable to Alice, then Alice won't be
93103
* able to pull from this repository (think of a POSIX file system
@@ -103,7 +113,7 @@ public UploadPack createUploadPack(HttpServletRequest context, Repository db) th
103113
*/
104114
@Override
105115
public ReceivePack createReceivePack(HttpServletRequest context, Repository db) throws ServiceNotEnabledException, ServiceNotAuthorizedException {
106-
Authentication a = Jenkins.getAuthentication();
116+
Authentication a = Jenkins.getAuthentication2();
107117

108118
ReceivePack rp = createReceivePack(db);
109119

@@ -118,15 +128,13 @@ public ReceivePack createReceivePack(Repository db) {
118128
ReceivePack rp = new ReceivePack(db);
119129

120130
// update userContent after the push
121-
rp.setPostReceiveHook(new PostReceiveHook() {
122-
public void onPostReceive(ReceivePack rp, Collection<ReceiveCommand> commands) {
123-
try {
124-
updateWorkspace(rp.getRepository());
125-
} catch (Exception e) {
126-
StringWriter sw = new StringWriter();
127-
e.printStackTrace(new PrintWriter(sw));
128-
rp.sendMessage("Failed to update workspace: "+sw);
129-
}
131+
rp.setPostReceiveHook((rp1, commands) -> {
132+
try {
133+
updateWorkspace(rp1.getRepository());
134+
} catch (Exception e) {
135+
StringWriter sw = new StringWriter();
136+
e.printStackTrace(new PrintWriter(sw));
137+
rp1.sendMessage("Failed to update workspace: "+sw);
130138
}
131139
});
132140
return rp;

0 commit comments

Comments
 (0)