Skip to content

Commit ab264e5

Browse files
committed
Merge branch 'main' into readonly-per-repository
2 parents 745ba0c + 07b6fdb commit ab264e5

32 files changed

Lines changed: 1179 additions & 906 deletions

File tree

dependencies.toml

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
# If its classes are exposed in Javadoc, update offline links as well.
44
#
55
[versions]
6-
armeria = "1.39.0"
6+
armeria = "1.40.0"
77
assertj = "3.27.7"
88
awaitility = "4.3.0"
99
bouncycastle = "1.84"
1010
caffeine = "3.2.4"
1111
checkstyle = "10.3.3"
1212
conscrypt = "2.5.2"
13-
controlplane = "1.0.52"
13+
controlplane = "1.0.53"
1414
# Ensure that we use the same ZooKeeper version as what Curator depends on.
1515
# See: https://github.com/apache/curator/blob/master/pom.xml
1616
# (Switch to the right tag to find out the right version.)
@@ -19,19 +19,19 @@ curator = "5.9.0"
1919
cron-utils = "9.2.0"
2020
diffutils = "1.3.0"
2121
download = "5.7.0"
22-
dropwizard-metrics = "4.2.38"
22+
dropwizard-metrics = "4.2.39"
2323
eddsa = "0.3.0"
2424
findbugs = "3.0.2"
2525
freemarker = "2.3.34"
2626
futures-completable = "0.3.6"
27-
grpc-java = "1.81.0"
27+
grpc-java = "1.82.0"
2828
guava = "33.6.0-jre"
2929
guava-failureaccess = "1.0.1"
3030
hamcrest-library = "3.0"
3131
hibernate-validator6 = "6.2.5.Final"
3232
hibernate-validator8 = "8.0.3.Final"
3333
hibernate-validator9 = "9.1.0.Final"
34-
jackson = "2.21.3"
34+
jackson = "2.22.0"
3535
javassist = "3.31.0-GA"
3636
javax-annotation = "1.3.2"
3737
javax-inject = "1"
@@ -43,7 +43,7 @@ jetty-alpn-agent = "2.0.10"
4343
jgit6 = "6.10.1.202505221210-r"
4444
junit4 = "4.13.2"
4545
# junit6 requires java 17
46-
junit5 = "5.14.2"
46+
junit5 = "5.14.4"
4747
junit-pioneer = "2.3.0"
4848
jsch = "0.1.55"
4949
# Don't update `json-path` version
@@ -56,41 +56,41 @@ jmh-core = "1.37"
5656
jmh-gradle-plugin = "0.7.3"
5757
jxr = "0.2.1"
5858
kubernetes-client = "7.7.0"
59-
logback15 = "1.5.32"
60-
micrometer = "1.16.5"
61-
mina-sshd = "2.17.1"
59+
logback15 = "1.5.34"
60+
micrometer = "1.17.0"
61+
mina-sshd = "2.18.0"
6262
mockito = "5.23.0"
63-
nimbus-jose-jwt = "10.9"
63+
nimbus-jose-jwt = "10.9.1"
6464
nexus-publish-plugin = "2.0.0"
6565
node-gradle-plugin = "7.1.0"
6666
osdetector = "1.7.3"
6767
owasp = "1.4.0"
68-
proguard = "7.8.1"
69-
prometheus-metrics = "1.6.1"
70-
protobuf = "3.25.8"
71-
protobuf-gradle-plugin = "0.9.5"
68+
proguard = "7.9.1"
69+
prometheus-metrics = "1.8.0"
70+
protobuf = "3.25.9"
71+
protobuf-gradle-plugin = "0.10.0"
7272
quartz = "2.5.2"
7373
reflections = "0.9.11"
7474
rocksdb = "10.10.1.1"
75-
shadow-gradle-plugin = "8.3.9"
75+
shadow-gradle-plugin = "9.4.2"
7676
# Don't update `shiro` version
7777
shiro = "1.3.2"
78-
slf4j2 = "2.0.17"
78+
slf4j2 = "2.0.18"
7979
# Ensure that we use the same Snappy version as what Curator depends on.
8080
# See: https://github.com/apache/curator/blob/master/pom.xml
8181
snappy = "1.1.10.8"
8282
sphinx = "2.10.1"
8383
spring-boot2 = "2.7.18"
84-
spring-boot3 = "3.5.10"
85-
spring-boot4 = "4.0.6"
84+
spring-boot3 = "3.5.15"
85+
spring-boot4 = "4.1.0"
8686
spring-test-junit5 = "1.5.0"
8787
testcontainers = "2.0.5"
8888
thrift09 = { strictly = "0.9.3-1" }
8989
# Ensure that we use the same ZooKeeper version as what Curator depends on.
9090
# See: https://github.com/apache/curator/blob/master/pom.xml
9191
# (Switch to the right tag to find out the right version.)
9292
zookeeper = "3.9.3"
93-
zstd = "1.5.7-8"
93+
zstd = "1.5.7-11"
9494

9595
[boms]
9696
armeria = { module = "com.linecorp.armeria:armeria-bom", version.ref = "armeria" }

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
group=com.linecorp.centraldogma
2-
version=0.83.1-SNAPSHOT
2+
version=0.84.1-SNAPSHOT
33
projectName=Central Dogma
44
projectUrl=https://line.github.io/centraldogma/
55
projectDescription=Highly-available version-controlled service configuration repository based on Git, ZooKeeper and HTTP/2

it/mirror/src/test/java/com/linecorp/centraldogma/it/mirror/git/ZoneAwareMirrorTest.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,25 @@ void shouldWarnUnknownZoneForScheduledJob() throws Exception {
184184
final CentralDogmaRepository repo = client.forRepo(FOO_PROJ, Project.REPO_DOGMA);
185185
final String mirrorId = TEST_MIRROR_ID + "-unknown-zone";
186186
final String unknownZone = "unknown-zone";
187+
188+
// Create a valid SSH credential so that the mirror can be loaded and reach the zone validation.
189+
// Otherwise, the git+ssh mirror fails to be constructed and is skipped before the zone is checked.
190+
final BlockingWebClient webClient = WebClient.builder("http://127.0.0.1:" + serverPort)
191+
.auth(AuthToken.ofOAuth2(accessToken))
192+
.build()
193+
.blocking();
194+
final CreateCredentialRequest credential =
195+
getCreateCredentialRequest(FOO_PROJ, "bar-unknown-zone");
196+
final ResponseEntity<PushResultDto> credentialResponse =
197+
webClient.prepare()
198+
.post("/api/v1/projects/{proj}/repos/{repo}/credentials")
199+
.pathParam("proj", FOO_PROJ)
200+
.pathParam("repo", "bar-unknown-zone")
201+
.contentJson(credential)
202+
.asJson(PushResultDto.class)
203+
.execute();
204+
assertThat(credentialResponse.status()).isEqualTo(HttpStatus.CREATED);
205+
187206
final MirrorConfig mirrorConfig =
188207
new MirrorConfig(mirrorId,
189208
true,
@@ -194,7 +213,7 @@ void shouldWarnUnknownZoneForScheduledJob() throws Exception {
194213
URI.create("git+ssh://github.com/line/centraldogma-authtest.git/#main"),
195214
null,
196215
null,
197-
credentialName("foo", "bar-unknown-zone", "credential-id"),
216+
credentialName(FOO_PROJ, "bar-unknown-zone", PRIVATE_KEY_FILE),
198217
unknownZone);
199218
final Change<JsonNode> change = Change.ofJsonUpsert(
200219
"/repos/bar-unknown-zone/mirrors/" + mirrorId + ".json",

server-auth/shiro/src/main/java/com/linecorp/centraldogma/server/auth/shiro/realm/SearchFirstActiveDirectoryRealm.java

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import static java.util.Objects.requireNonNull;
2121

2222
import java.time.Duration;
23-
import java.util.regex.Pattern;
2423

2524
import javax.naming.AuthenticationException;
2625
import javax.naming.NamingEnumeration;
@@ -58,18 +57,16 @@
5857
*/
5958
public class SearchFirstActiveDirectoryRealm extends ActiveDirectoryRealm {
6059

61-
private static final Pattern USERNAME_PLACEHOLDER = Pattern.compile("\\{0}");
60+
private static final String USERNAME_PLACEHOLDER = "{0}";
6261
private static final String DEFAULT_SEARCH_FILTER = "cn={0}";
6362
private static final int DEFAULT_SEARCH_TIMEOUT_MILLIS = (int) Duration.ofSeconds(10).toMillis();
6463

65-
@Nullable
6664
private String searchFilter = DEFAULT_SEARCH_FILTER;
6765
private int searchTimeoutMillis = DEFAULT_SEARCH_TIMEOUT_MILLIS;
6866

6967
/**
7068
* Returns a search filter string.
7169
*/
72-
@Nullable
7370
protected String getSearchFilter() {
7471
return searchFilter;
7572
}
@@ -78,7 +75,10 @@ protected String getSearchFilter() {
7875
* Sets a search filter string.
7976
*/
8077
protected void setSearchFilter(String searchFilter) {
81-
this.searchFilter = requireNonNull(searchFilter, "searchFilter");
78+
requireNonNull(searchFilter, "searchFilter");
79+
checkArgument(searchFilter.contains("{0}"),
80+
"searchFilter must contain '{0}' placeholder: %s", searchFilter);
81+
this.searchFilter = searchFilter;
8282
}
8383

8484
/**
@@ -157,11 +157,9 @@ protected String findUserDn(LdapContextFactory ldapContextFactory, String userna
157157
ctrl.setSearchScope(SearchControls.SUBTREE_SCOPE);
158158
ctrl.setTimeLimit(searchTimeoutMillis);
159159

160-
final String filter =
161-
searchFilter != null ? USERNAME_PLACEHOLDER.matcher(searchFilter)
162-
.replaceAll(username)
163-
: username;
164-
final NamingEnumeration<SearchResult> result = ctx.search(searchBase, filter, ctrl);
160+
final String escaped = encodeLdapFilter(username);
161+
final String filtered = searchFilter.replace(USERNAME_PLACEHOLDER, escaped);
162+
final NamingEnumeration<SearchResult> result = ctx.search(searchBase, filtered, ctrl);
165163
try {
166164
if (!result.hasMore()) {
167165
return null;
@@ -175,6 +173,40 @@ protected String findUserDn(LdapContextFactory ldapContextFactory, String userna
175173
}
176174
}
177175

176+
/**
177+
* Escapes special characters in the given value for use in an LDAP search filter,
178+
* as specified in <a href="https://datatracker.ietf.org/doc/html/rfc4515#section-3">RFC 4515 §3</a>.
179+
*/
180+
static String encodeLdapFilter(String value) {
181+
if (value == null) {
182+
return "";
183+
}
184+
final StringBuilder sb = new StringBuilder(value.length());
185+
for (int i = 0; i < value.length(); i++) {
186+
final char c = value.charAt(i);
187+
switch (c) {
188+
case '\\':
189+
sb.append("\\5c");
190+
break;
191+
case '*':
192+
sb.append("\\2a");
193+
break;
194+
case '(':
195+
sb.append("\\28");
196+
break;
197+
case ')':
198+
sb.append("\\29");
199+
break;
200+
case '\0':
201+
sb.append("\\00");
202+
break;
203+
default:
204+
sb.append(c);
205+
}
206+
}
207+
return sb.toString();
208+
}
209+
178210
private static UsernamePasswordToken ensureUsernamePasswordToken(AuthenticationToken token) {
179211
if (token instanceof UsernamePasswordToken) {
180212
return (UsernamePasswordToken) token;

0 commit comments

Comments
 (0)