Skip to content

Commit 64d4737

Browse files
committed
feat: reworked ProviderConfiguration + audit filter + ParseRequestFilter
- refactored a lot of the provider setup code to be more clear. Since we rely on dynamic properties set in GitProxyProperties to enable/disable & tweak providers, we need to use BeanFactorys to create those instances. I was running into trouble with dependencies between GitProxyProvider, ProviderRepository, GitProxyFilter and GitProxyProviderServlet which requires pretty exact ordering. - ProviderRepository is now used for servlet setup. In the future, we will further abstract this to allow users to define their own classes. For now, it defaults to an InMemoryProviderRepository - finish implementing GitHubUserAuthenticatedFilter with configuration support - created a new WhitelistAggregateFilter which will handle individual WhitelistByUrlFilter - before, if a single whitelist filter didn't match, the entire request would be blocked. This is not desirable so the aggregate looks for the result after passing a request through all applicable whitelists - add new GitRequestDetails which mimicks the original project. For a given fetch or push, get some information about it up front and pass that as a request attribute for other filters to process and react to. - add support for an AuditFilter - the default implementation AuditLogFilter simply logs out the request object at the end of the filter chain - a bunch of spotless formatting - remove old test that no longer compiles or is relevant
1 parent 7272895 commit 64d4737

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+727
-414
lines changed

src/main/java/org/finos/gitproxy/api/AuthController.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.finos.gitproxy.api;
22

3+
import java.util.Collections;
4+
import java.util.Map;
35
import org.springframework.core.io.ClassPathResource;
46
import org.springframework.core.io.Resource;
57
import org.springframework.http.MediaType;
@@ -9,9 +11,6 @@
911
import org.springframework.web.bind.annotation.RequestMapping;
1012
import org.springframework.web.bind.annotation.RestController;
1113

12-
import java.util.Collections;
13-
import java.util.Map;
14-
1514
/** https://github.com/finos/git-proxy/blob/363f4ae0588c02b32c8bb3d987919bc0b4268d12/src/service/routes/auth.js */
1615
@RestController
1716
@RequestMapping(value = "/api/auth", produces = MediaType.APPLICATION_JSON_VALUE)

src/main/java/org/finos/gitproxy/api/ConfigController.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package org.finos.gitproxy.api;
22

3-
import org.finos.gitproxy.config.LegacyJSONConfiguration;
43
import lombok.RequiredArgsConstructor;
4+
import org.finos.gitproxy.config.LegacyJSONConfiguration;
55
import org.springframework.http.MediaType;
66
import org.springframework.http.ResponseEntity;
77
import org.springframework.web.bind.annotation.GetMapping;

src/main/java/org/finos/gitproxy/api/GenericErrorController.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package org.finos.gitproxy.api;
22

3+
import static org.finos.gitproxy.servlet.GitProxyProviderServlet.ERROR_ATTRIBUTE;
4+
35
import jakarta.servlet.http.HttpServletRequest;
46
import lombok.extern.slf4j.Slf4j;
57
import org.springframework.boot.web.servlet.error.ErrorController;
68
import org.springframework.http.ResponseEntity;
79
import org.springframework.web.bind.annotation.RequestMapping;
810
import org.springframework.web.bind.annotation.RestController;
911

10-
import static org.finos.gitproxy.servlet.filter.GitProxyFilter.ERROR_ATTRIBUTE;
11-
1212
@RestController
1313
@Slf4j
1414
public class GenericErrorController implements ErrorController {

src/main/java/org/finos/gitproxy/api/PushController.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
package org.finos.gitproxy.api;
22

3+
import java.util.Map;
34
import lombok.extern.slf4j.Slf4j;
45
import org.springframework.http.MediaType;
56
import org.springframework.http.ResponseEntity;
67
import org.springframework.web.bind.annotation.*;
78

8-
import java.util.Map;
9-
109
@RestController
1110
@RequestMapping(value = "/api/v1/push", produces = MediaType.APPLICATION_JSON_VALUE)
1211
@Slf4j

src/main/java/org/finos/gitproxy/api/RepoController.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
package org.finos.gitproxy.api;
22

3+
import java.util.ArrayList;
4+
import java.util.Map;
35
import lombok.extern.slf4j.Slf4j;
46
import org.springframework.http.MediaType;
57
import org.springframework.http.ResponseEntity;
68
import org.springframework.web.bind.annotation.*;
79

8-
import java.util.ArrayList;
9-
import java.util.Map;
10-
1110
@RestController
1211
@RequestMapping(value = "/api/v1/repo", produces = MediaType.APPLICATION_JSON_VALUE)
1312
@Slf4j

src/main/java/org/finos/gitproxy/api/StaticHealthCheck.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package org.finos.gitproxy.api;
22

3+
import java.util.Map;
34
import org.springframework.http.MediaType;
45
import org.springframework.web.bind.annotation.GetMapping;
56
import org.springframework.web.bind.annotation.RestController;
67

7-
import java.util.Map;
8-
98
// TODO: Deprecate and remove. Health checking is provided by actuator
109
// for users, use /actuator/health instead
1110
@RestController

src/main/java/org/finos/gitproxy/api/UserController.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.finos.gitproxy.api;
22

3+
import java.util.ArrayList;
34
import lombok.extern.slf4j.Slf4j;
45
import org.springframework.http.MediaType;
56
import org.springframework.http.ResponseEntity;
@@ -8,8 +9,6 @@
89
import org.springframework.web.bind.annotation.RequestMapping;
910
import org.springframework.web.bind.annotation.RestController;
1011

11-
import java.util.ArrayList;
12-
1312
@RestController
1413
@RequestMapping(value = "/api/v1/user", produces = MediaType.APPLICATION_JSON_VALUE)
1514
@Slf4j

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

+25-24
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
package org.finos.gitproxy.config;
22

3+
import java.net.URI;
4+
import java.util.*;
5+
6+
import lombok.Getter;
7+
import lombok.Setter;
8+
import lombok.ToString;
9+
import org.finos.gitproxy.git.HttpAuthScheme;
310
import org.finos.gitproxy.provider.BitbucketProvider;
411
import org.finos.gitproxy.provider.GitHubProvider;
512
import org.finos.gitproxy.provider.GitLabProvider;
613
import org.finos.gitproxy.servlet.filter.AuthorizedByUrlFilter;
714
import org.finos.gitproxy.servlet.filter.FilterProperties;
8-
import lombok.Getter;
9-
import lombok.Setter;
10-
import lombok.ToString;
1115
import org.springframework.boot.context.properties.ConfigurationProperties;
1216

13-
import java.net.URI;
14-
import java.util.ArrayList;
15-
import java.util.HashMap;
16-
import java.util.List;
17-
import java.util.Map;
18-
17+
/**
18+
* The main configuration properties for the GitProxy application. This class is used to configure the GitProxy
19+
* application, including the providers that are enabled, the filters that are applied to the proxy servlets, and the
20+
* base path for the proxy servlets.
21+
*/
1922
@ConfigurationProperties(value = "git-proxy", ignoreUnknownFields = false)
2023
@Getter
2124
@Setter
@@ -29,16 +32,15 @@ public class GitProxyProperties {
2932
* The base path for the proxy servlets. This is the path that will be used to register the servlets with the
3033
* servlet container. For each provider, the servlet will be registered at {@code basePath + provider.servletPath}.
3134
*/
32-
private String basePath = "/git";
35+
private String basePath = "";
3336

34-
// TODO: Find a way to force properties to be instantiated as a bean but early on in the lifecycle while still
35-
// delegating to Spring Boot to bind the properties.
36-
// This is an open problem with the use of Environment + Binder in the BeanFactoryPostProcessor where
37-
// the properties bean is still not bound at the time the factories execute _if_ no "git-proxy.*" properties are
38-
// defined at all. Use of that factory for creating beans dynamically implicitly makes it depend on config
39-
// properties
40-
// always being set. An ideal solution would be to simple create this instance using this method below if
41-
// @ConditionalOnMissingBean were true which is the standard idiom for this sort of thing.
37+
//TODO: Find a way to force properties to be instantiated as a bean but early on in the lifecycle while still
38+
// delegating to Spring Boot to bind the properties. This is an open problem with the use of Environment + Binder
39+
// in the BeanFactoryPostProcessor where the properties bean is still not bound at the time the factories execute
40+
// _if_ no "git-proxy.*" properties are defined at all. Use of that factory for creating beans dynamically
41+
// implicitly makes it depend on config properties always being set. An ideal solution would be to simple create
42+
// this instance using this method below if @ConditionalOnMissingBean were true which is the standard idiom for
43+
// this sort of thing.
4244
// https://www.baeldung.com/spring-properties-beanfactorypostprocessor
4345
public static GitProxyProperties createDefault() {
4446
var enabledProvider = new Provider();
@@ -84,20 +86,19 @@ public static class Provider {
8486
@ToString
8587
public static class Filters {
8688
private List<WhitelistFilterProperties> whitelists = new ArrayList<>();
87-
private GitHubRequiredAuthenticationFilterProperties githubRequiredAuthentication;
89+
private GitHubUserAuthenticatedFilterProperties githubUserAuthenticated;
8890
}
8991

9092
/**
91-
* Properties for the GitHub required authentication filter. This filter is used to require that all requests to
92-
* GitHub are authenticated. This filter can be configured to require either a bearer token or a basic
93+
* Properties for the GitHub user authentication required filter. This filter is used to require that all requests
94+
* to GitHub are authenticated. This filter can be configured to require either a bearer token or a basic
9395
* authentication header.
9496
*/
9597
@Getter
9698
@Setter
9799
@ToString
98-
public static class GitHubRequiredAuthenticationFilterProperties extends FilterProperties {
99-
private boolean requireBearer = false;
100-
private boolean requireBasic = false;
100+
public static class GitHubUserAuthenticatedFilterProperties extends FilterProperties {
101+
private Set<HttpAuthScheme> requiredAuthSchemes = Set.of(HttpAuthScheme.BEARER);
101102
}
102103

103104
@Getter

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package org.finos.gitproxy.config;
22

33
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4-
import lombok.Data;
5-
64
import java.util.List;
75
import java.util.Map;
6+
import lombok.Data;
87

98
/** Legacy configuration to bring users of the old configuration into the new configuration. */
109
@JsonIgnoreProperties(ignoreUnknown = true)

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
package org.finos.gitproxy.config;
22

33
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import java.io.IOException;
45
import lombok.extern.slf4j.Slf4j;
56
import org.springframework.boot.ApplicationArguments;
7+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
68
import org.springframework.context.annotation.Bean;
79
import org.springframework.context.annotation.Configuration;
810
import org.springframework.core.io.PathResource;
911

10-
import java.io.IOException;
11-
1212
@Configuration
1313
@Slf4j
14+
@EnableConfigurationProperties(GitProxyProperties.class)
1415
public class UserConfiguration {
1516

1617
// TODO: Remove once migrated over to configuration properties
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.finos.gitproxy.git;
2+
3+
import lombok.Data;
4+
5+
/** Represents a single commit. */
6+
@Data
7+
public class Commit {
8+
private String id;
9+
private Contributor author;
10+
private Contributor committer;
11+
private String message;
12+
private String date;
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.finos.gitproxy.git;
2+
3+
import lombok.Data;
4+
5+
/** A generic class that represents a contributor to a git repository. It can either be an author or a committer. */
6+
@Data
7+
public class Contributor {
8+
private String name;
9+
private String email;
10+
}

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

+5-1
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,16 @@ public enum SymbolCodes {
4444

4545
// https://codepoints.net/U+2705
4646
// https://emojipedia.org/check-mark-button#technical
47-
CHECK_MARK("\u2705"),
47+
HEAVY_CHECK_MARK("\u2705"),
4848

4949
// https://codepoints.net/U+26A0
5050
// https://emojipedia.org/warning#technical
5151
WARNING("\u26A0"),
5252

53+
// https://codepoints.net/U+274C
54+
// https://emojipedia.org/cross-mark#technical
55+
CROSS_MARK("\u274C"),
56+
5357
// Created using codepoints & the Character class due to the point values
5458
// falling outside the Unicode planes' range supported by Java's \\u escape
5559
// sequence syntax in Strings
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.finos.gitproxy.git;
2+
3+
import java.time.Instant;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
import java.util.UUID;
7+
import lombok.Data;
8+
import org.finos.gitproxy.provider.GitProxyProvider;
9+
import org.finos.gitproxy.servlet.filter.GitProxyFilter;
10+
11+
@Data
12+
public class GitRequestDetails {
13+
private UUID id = UUID.randomUUID();
14+
private Instant timestamp = Instant.now();
15+
private HttpOperation operation;
16+
private String owner;
17+
private String name;
18+
private String slug;
19+
private String branch; // null for fetch requests
20+
private List<Commit> commits = new ArrayList<>();
21+
private GitProxyProvider provider;
22+
private List<GitProxyFilter> filters = new ArrayList<>();
23+
private GitResult result = GitResult.PENDING;
24+
private String reason;
25+
26+
public enum GitResult {
27+
PENDING,
28+
ALLOWED,
29+
BLOCKED,
30+
ACCEPTED, // for async where a push or fetch is accepted but not yet complete
31+
ERROR;
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package org.finos.gitproxy.git;
22

3+
import lombok.Getter;
34
import lombok.RequiredArgsConstructor;
45

56
@RequiredArgsConstructor
7+
@Getter
68
public enum HttpAuthScheme {
79
BASIC("Basic"),
8-
BEARER("Bearer");
10+
BEARER("Bearer"),
11+
TOKEN("token");
912

10-
private final String scheme;
13+
private final String hedaderValue;
1114
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.finos.gitproxy.git;
2+
3+
import jakarta.servlet.http.HttpServletRequest;
4+
import org.eclipse.jgit.errors.RepositoryNotFoundException;
5+
import org.eclipse.jgit.lib.Repository;
6+
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
7+
import org.eclipse.jgit.transport.resolver.RepositoryResolver;
8+
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
9+
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
10+
11+
public class TemporaryRepositoryResolver implements RepositoryResolver<HttpServletRequest> {
12+
13+
@Override
14+
public Repository open(HttpServletRequest req, String name)
15+
throws RepositoryNotFoundException, ServiceNotAuthorizedException, ServiceNotEnabledException,
16+
ServiceMayNotContinueException {
17+
return null;
18+
}
19+
}

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

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package org.finos.gitproxy.provider;
22

3+
import java.net.URI;
34
import lombok.AllArgsConstructor;
45
import lombok.RequiredArgsConstructor;
56

6-
import java.net.URI;
7-
87
/** An upstream Git server that will be proxied by the application. */
98
@RequiredArgsConstructor
109
@AllArgsConstructor
@@ -17,9 +16,9 @@ public abstract class AbstractGitProxyProvider implements GitProxyProvider {
1716

1817
/**
1918
* Returns the path that the servlet will be mapped to. This is based on the host of the target URL or a custom path
20-
* if set.
21-
*
22-
* @return the servlet path to map to
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.
21+
* @return The base path that this provider will be mapped to.
2322
*/
2423
@Override
2524
public String servletPath() {
@@ -28,8 +27,7 @@ public String servletPath() {
2827

2928
/**
3029
* Returns the servlet mapping for the provider. This is used to map the servlet to a specific path in the
31-
* application. If the provider has a custom path set, this will be used as the mapping. Otherwise, the host of the
32-
* target URL will be used. Since this mapping is always used for setting up underlying proxying servlet, the
30+
* application. Since this mapping is always used for setting up underlying proxying servlet, the
3331
* mapping will always append a wildcard end of the path to ensure that all matching requests are proxied.
3432
*
3533
* <p>Matcher functions should use {@link #servletPath()} instead.

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
package org.finos.gitproxy.provider;
22

3-
import org.finos.gitproxy.provider.client.BitbucketApi;
43
import jakarta.annotation.Nullable;
5-
64
import java.net.URI;
5+
import org.finos.gitproxy.provider.client.BitbucketApi;
76

87
public class BitbucketProvider extends AbstractGitProxyProvider implements BitbucketApi {
98

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package org.finos.gitproxy.provider;
22

3+
import java.net.URI;
34
import org.finos.gitproxy.provider.client.GitHubApi;
45
import org.finos.gitproxy.provider.client.GitHubClient;
56

6-
import java.net.URI;
7-
87
public class GitHubProvider extends AbstractGitProxyProvider implements GitHubApi {
98

109
public static final String NAME = "github";

0 commit comments

Comments
 (0)