Skip to content

Commit 8c1061f

Browse files
committed
feat: port parsePush into ParseRequestFilter to get commit details
1 parent 64d4737 commit 8c1061f

14 files changed

+460
-84
lines changed

src/main/java/org/finos/gitproxy/config/GitProxyProperties.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import java.net.URI;
44
import java.util.*;
5-
65
import lombok.Getter;
76
import lombok.Setter;
87
import lombok.ToString;
@@ -34,7 +33,7 @@ public class GitProxyProperties {
3433
*/
3534
private String basePath = "";
3635

37-
//TODO: Find a way to force properties to be instantiated as a bean but early on in the lifecycle while still
36+
// TODO: Find a way to force properties to be instantiated as a bean but early on in the lifecycle while still
3837
// delegating to Spring Boot to bind the properties. This is an open problem with the use of Environment + Binder
3938
// in the BeanFactoryPostProcessor where the properties bean is still not bound at the time the factories execute
4039
// _if_ no "git-proxy.*" properties are defined at all. Use of that factory for creating beans dynamically
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package org.finos.gitproxy.git;
22

3+
import java.time.Instant;
4+
import lombok.Builder;
35
import lombok.Data;
46

57
/** Represents a single commit. */
68
@Data
9+
@Builder
710
public class Commit {
811
private String id;
912
private Contributor author;
1013
private Contributor committer;
1114
private String message;
12-
private String date;
15+
private Instant date;
16+
private String signature;
1317
}

src/main/java/org/finos/gitproxy/git/Contributor.java

+4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package org.finos.gitproxy.git;
22

3+
import lombok.AllArgsConstructor;
34
import lombok.Data;
5+
import lombok.NoArgsConstructor;
46

57
/** A generic class that represents a contributor to a git repository. It can either be an author or a committer. */
68
@Data
9+
@NoArgsConstructor
10+
@AllArgsConstructor
711
public class Contributor {
812
private String name;
913
private String email;

src/main/java/org/finos/gitproxy/provider/AbstractGitProxyProvider.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ public abstract class AbstractGitProxyProvider implements GitProxyProvider {
1616

1717
/**
1818
* Returns the path that the servlet will be mapped to. This is based on the host of the target URL or a custom path
19-
* if set along with an optional application-wide base path. To configure a {@link org.finos.gitproxy.servlet.GitProxyProviderServlet}
20-
* for proxying, use {@link #servletMapping()} instead.
19+
* if set along with an optional application-wide base path. To configure a
20+
* {@link org.finos.gitproxy.servlet.GitProxyProviderServlet} for proxying, use {@link #servletMapping()} instead.
21+
*
2122
* @return The base path that this provider will be mapped to.
2223
*/
2324
@Override
@@ -27,8 +28,8 @@ public String servletPath() {
2728

2829
/**
2930
* Returns the servlet mapping for the provider. This is used to map the servlet to a specific path in the
30-
* application. Since this mapping is always used for setting up underlying proxying servlet, the
31-
* mapping will always append a wildcard end of the path to ensure that all matching requests are proxied.
31+
* application. Since this mapping is always used for setting up underlying proxying servlet, the mapping will
32+
* always append a wildcard end of the path to ensure that all matching requests are proxied.
3233
*
3334
* <p>Matcher functions should use {@link #servletPath()} instead.
3435
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package org.finos.gitproxy.servlet;
2+
3+
import jakarta.servlet.ReadListener;
4+
import jakarta.servlet.ServletInputStream;
5+
import jakarta.servlet.http.HttpServletRequest;
6+
import jakarta.servlet.http.HttpServletRequestWrapper;
7+
import java.io.*;
8+
import lombok.Getter;
9+
10+
@Getter
11+
public class RequestBodyWrapper extends HttpServletRequestWrapper {
12+
13+
private final byte[] body;
14+
15+
/**
16+
* Constructs a request object wrapping the given request.
17+
*
18+
* @param request The request to wrap
19+
* @throws IllegalArgumentException if the request is null
20+
*/
21+
public RequestBodyWrapper(HttpServletRequest request) throws IOException {
22+
super(request);
23+
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
24+
BufferedInputStream bufferedInputStream = null;
25+
try {
26+
InputStream inputStream = request.getInputStream();
27+
if (inputStream != null) {
28+
bufferedInputStream = new BufferedInputStream(inputStream);
29+
byte[] byteBuffer = new byte[128];
30+
int bytesRead = -1;
31+
while ((bytesRead = bufferedInputStream.read(byteBuffer)) > 0) {
32+
byteArrayOutputStream.write(byteBuffer, 0, bytesRead);
33+
}
34+
}
35+
} catch (IOException ex) {
36+
throw ex;
37+
} finally {
38+
if (bufferedInputStream != null) {
39+
try {
40+
bufferedInputStream.close();
41+
} catch (IOException ex) {
42+
throw ex;
43+
}
44+
}
45+
}
46+
body = byteArrayOutputStream.toByteArray();
47+
}
48+
49+
@Override
50+
public ServletInputStream getInputStream() throws IOException {
51+
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
52+
return new ServletInputStream() {
53+
@Override
54+
public int read() throws IOException {
55+
return byteArrayInputStream.read();
56+
}
57+
58+
@Override
59+
public boolean isFinished() {
60+
return byteArrayInputStream.available() == 0;
61+
}
62+
63+
@Override
64+
public boolean isReady() {
65+
return true;
66+
}
67+
68+
@Override
69+
public void setReadListener(ReadListener readListener) {
70+
// No implementation needed
71+
}
72+
};
73+
}
74+
75+
@Override
76+
public BufferedReader getReader() throws IOException {
77+
return new BufferedReader(new InputStreamReader(this.getInputStream()));
78+
}
79+
}

src/main/java/org/finos/gitproxy/servlet/filter/AuditLogFilter.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
import jakarta.servlet.http.HttpServletRequest;
88
import jakarta.servlet.http.HttpServletResponse;
99
import java.io.IOException;
10+
import java.util.Collections;
1011
import java.util.Set;
12+
import java.util.stream.Collectors;
1113
import lombok.extern.slf4j.Slf4j;
1214
import org.finos.gitproxy.git.HttpOperation;
1315
import org.springframework.core.Ordered;
@@ -20,8 +22,6 @@ public class AuditLogFilter extends AbstractGitProxyFilter implements AuditFilte
2022

2123
/**
2224
* Apply audit logging to all operations by default and after all other filters.
23-
*
24-
* @param provider the provider this filter applies to
2525
*/
2626
public AuditLogFilter() {
2727
super(Ordered.LOWEST_PRECEDENCE, DEFAULT_OPERATIONS);
@@ -36,6 +36,13 @@ public void audit(String message) {
3636
public void doHttpFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
3737
throws IOException, ServletException {
3838
audit("" + request.getAttribute(GIT_REQUEST_ATTRIBUTE));
39+
var headers = Collections.list(request.getHeaderNames()).stream()
40+
.collect(Collectors.toMap(
41+
name -> name,
42+
name -> "authorization".equalsIgnoreCase(name)
43+
? "REDACTED"
44+
: Collections.list(request.getHeaders(name))));
45+
audit("headers" + headers);
3946
chain.doFilter(request, response);
4047
}
4148
}

src/main/java/org/finos/gitproxy/servlet/filter/FilterConfiguration.java

+16-10
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,16 @@ public static BeanFactoryPostProcessor providerFilterFactory(
7272
whitelistFilters.size(),
7373
provider.getName());
7474

75-
int order = whitelistFilters.stream().mapToInt(WhitelistByUrlFilter::getOrder).min()
75+
int order = whitelistFilters.stream()
76+
.mapToInt(WhitelistByUrlFilter::getOrder)
77+
.min()
7678
.orElse(0);
77-
var ops = whitelistFilters.stream().flatMap(f -> f.applicableOperations.stream()).collect(Collectors.toSet());
78-
var whitelistAggregateBean =
79-
createWhitelistAggregateBean(provider, order, ops, whitelistFilters);
80-
beanFactory.registerSingleton(whitelistAggregateBean.getFilter().beanName(), whitelistAggregateBean);
79+
var ops = whitelistFilters.stream()
80+
.flatMap(f -> f.applicableOperations.stream())
81+
.collect(Collectors.toSet());
82+
var whitelistAggregateBean = createWhitelistAggregateBean(provider, order, ops, whitelistFilters);
83+
beanFactory.registerSingleton(
84+
whitelistAggregateBean.getFilter().beanName(), whitelistAggregateBean);
8185
}
8286
// TODO: Generalize this logic
8387
if (provider instanceof GitHubProvider gitHubProvider
@@ -113,9 +117,7 @@ private static FilterRegistrationBean<WhitelistAggregateFilter> createWhitelistA
113117
int order,
114118
Set<HttpOperation> operations,
115119
List<WhitelistByUrlFilter> whitelistFilters) {
116-
var filter = new WhitelistAggregateFilter(
117-
order,
118-
operations, provider, whitelistFilters);
120+
var filter = new WhitelistAggregateFilter(order, operations, provider, whitelistFilters);
119121
log.info("Creating {} with {} whitelists", filter, whitelistFilters.size());
120122
var filterBean = new FilterRegistrationBean<WhitelistAggregateFilter>();
121123
filterBean.setName(filter.beanName());
@@ -177,9 +179,13 @@ private static FilterRegistrationBean<GitHubUserAuthenticatedFilter> createGithu
177179
if (filterProperties.getOperations() != null
178180
&& !filterProperties.getOperations().isEmpty()) {
179181
filter = new GitHubUserAuthenticatedFilter(
180-
filterProperties.getOrder(), filterProperties.getOperations(), gitHubProvider, filterProperties.getRequiredAuthSchemes());
182+
filterProperties.getOrder(),
183+
filterProperties.getOperations(),
184+
gitHubProvider,
185+
filterProperties.getRequiredAuthSchemes());
181186
} else {
182-
filter = new GitHubUserAuthenticatedFilter(filterProperties.getOrder(), gitHubProvider, filterProperties.getRequiredAuthSchemes());
187+
filter = new GitHubUserAuthenticatedFilter(
188+
filterProperties.getOrder(), gitHubProvider, filterProperties.getRequiredAuthSchemes());
183189
}
184190
log.info("Creating {}", filter);
185191
var filterBean = new FilterRegistrationBean<GitHubUserAuthenticatedFilter>();

src/main/java/org/finos/gitproxy/servlet/filter/ForceGitClientFilter.java

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import jakarta.servlet.http.HttpServletResponse;
99
import java.io.IOException;
1010
import java.util.function.Predicate;
11-
import lombok.extern.slf4j.Slf4j;
1211
import org.eclipse.jgit.http.server.GitSmartHttpTools;
1312
import org.springframework.core.Ordered;
1413

src/main/java/org/finos/gitproxy/servlet/filter/GitHubUserAuthenticatedFilter.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ public GitHubUserAuthenticatedFilter(int order, GitHubProvider provider, Set<Htt
3434
this.requiredAuthSchemes = requiredAuthSchemes;
3535
}
3636

37-
public GitHubUserAuthenticatedFilter(int order, Set<HttpOperation> appliedOperations, GitHubProvider provider, Set<HttpAuthScheme> requiredAuthSchemes) {
37+
public GitHubUserAuthenticatedFilter(
38+
int order,
39+
Set<HttpOperation> appliedOperations,
40+
GitHubProvider provider,
41+
Set<HttpAuthScheme> requiredAuthSchemes) {
3842
super(order, appliedOperations, provider);
3943
this.requiredAuthSchemes = requiredAuthSchemes;
4044
}

0 commit comments

Comments
 (0)