Skip to content

Commit

Permalink
fixup! Add Azure DevOps Server support
Browse files Browse the repository at this point in the history
  • Loading branch information
vinokurig committed Feb 12, 2025
1 parent 3531467 commit d5941b1
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public class GitconfigAutomauntSecretConfigurator implements NamespaceConfigurat
private final Pattern emailPattern =
Pattern.compile("\\[user](.|\\s)*email\\s*=\\s*(?<email>.*)");

Check failure

Code scanning / CodeQL

Inefficient regular expression High

This part of the regular expression may cause exponential backtracking on strings starting with '[user]' and containing many repetitions of ' '.
private final Pattern emptyStringPattern = Pattern.compile("[\"']\\s*[\"']");
private final Pattern gitconfigSectionPattern =
Pattern.compile("\\[(?<sectionName>[a-zA-Z0-9]+)](\\n\\s*\\S*\\s*=.*)*");

@Inject
public GitconfigAutomauntSecretConfigurator(
Expand Down Expand Up @@ -101,7 +103,8 @@ public void configure(NamespaceResolutionContext namespaceResolutionContext, Str
? usernameAndEmailFromGitconfigOptional
: usernameAndEmailFromFetcherOptional;
Optional<String> gitconfigSectionsOptional =
generateGitconfigSections(usernameAndEmailOptional, tokenFromSecretOptional);
generateGitconfigSections(
gitconfigOptional, usernameAndEmailOptional, tokenFromSecretOptional);
gitconfigSecret.setData(
ImmutableMap.of(
CONFIGMAP_DATA_KEY,
Expand Down Expand Up @@ -136,7 +139,9 @@ private boolean needUpdateGitconfigSecret(
}

private Optional<String> generateGitconfigSections(
Optional<Pair<String, String>> usernameAndEmailOptional, Optional<String> tokenOptional) {
Optional<String> gitconfigOptional,
Optional<Pair<String, String>> usernameAndEmailOptional,
Optional<String> tokenOptional) {
Optional<String> userSectionOptional = Optional.empty();
Optional<String> httpSectionOPtional = Optional.empty();
if (usernameAndEmailOptional.isPresent()) {
Expand All @@ -149,11 +154,27 @@ private Optional<String> generateGitconfigSections(
httpSectionOPtional = Optional.of(generateHttpSection(tokenOptional.get()));
}
StringJoiner joiner = new StringJoiner("\n");
if (gitconfigOptional.isPresent()) {
Optional<String> otherSectionsOptional = getOtherStoredSections(gitconfigOptional.get());
otherSectionsOptional.ifPresent(joiner::add);
}
userSectionOptional.ifPresent(joiner::add);
httpSectionOPtional.ifPresent(joiner::add);
return joiner.length() > 0 ? Optional.of(joiner.toString()) : Optional.empty();
}

Optional<String> getOtherStoredSections(String gitconfig) {
StringJoiner joiner = new StringJoiner("\n");
Matcher matcher = gitconfigSectionPattern.matcher(gitconfig);
while (matcher.find()) {
String sectionName = matcher.group("sectionName");
if (!sectionName.equals("user") && !sectionName.equals("http")) {
joiner.add(matcher.group());
}
}
return joiner.length() > 0 ? Optional.of(joiner.toString()) : Optional.empty();
}

private Optional<Pair<String, String>> getUsernameAndEmailFromGitconfig(String gitconfig) {
if (gitconfig.contains("[user]")) {
Matcher usernameMatcher = usernmaePattern.matcher(gitconfig);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,48 @@ public void shouldUpdateGitconfigSecretWithHttpSection()
Assert.assertEquals(secrets.get(1).getData().get("gitconfig"), encode(expected));
}

@Test
public void shouldUpdateGitconfigSecretWithStoredSectionsWithHttpSection()
throws InfrastructureException, InterruptedException {
// given
Secret tokenSecret =
new SecretBuilder()
.withNewMetadata()
.withName("personal-access-token-name")
.withLabels(TOKEN_SECRET_LABELS)
.withAnnotations(ImmutableMap.of("che.eclipse.org/scm-provider-name", "azure-devops"))
.endMetadata()
.build();
tokenSecret.setData(Collections.singletonMap("token", encode("new-token")));
serverMock.getClient().secrets().inNamespace(TEST_NAMESPACE_NAME).create(tokenSecret);
Secret gitconfigSecret =
new SecretBuilder()
.withNewMetadata()
.withName(GITCONFIG_SECRET_NAME)
.withLabels(GITCONFIG_SECRET_LABELS)
.withAnnotations(GITCONFIG_SECRET_ANNOTATIONS)
.endMetadata()
.build();
gitconfigSecret.setData(
Collections.singletonMap(
"gitconfig",
encode(
"[other]\n\tkey = value\n[http]\n\textraHeader = Authorization: Basic "
+ encode((":old-token")))));
serverMock.getClient().secrets().inNamespace(TEST_NAMESPACE_NAME).create(gitconfigSecret);
// when
configurator.configure(namespaceResolutionContext, TEST_NAMESPACE_NAME);
// then
Assert.assertEquals(serverMock.getLastRequest().getMethod(), "PUT");
var secrets =
serverMock.getClient().secrets().inNamespace(TEST_NAMESPACE_NAME).list().getItems();
Assert.assertEquals(secrets.size(), 2);
String expected =
"[other]\n\tkey = value\n[http]\n\textraHeader = Authorization: Basic "
+ encode(":new-token");
Assert.assertEquals(secrets.get(1).getData().get("gitconfig"), encode(expected));
}

@Test
public void shouldClearGitconfigSecretIfNoTokenSecretIsFound()
throws InfrastructureException, InterruptedException {
Expand Down Expand Up @@ -329,6 +371,43 @@ public void shouldUpdateGitconfigSecretWithUserSection()
Assert.assertEquals(secrets.get(0).getData().get("gitconfig"), encode(expected));
}

@Test
public void shouldUpdateGitconfigSecretWithStoredSectionsWithUserSection()
throws InfrastructureException, InterruptedException, ScmItemNotFoundException,
ScmCommunicationException, ScmUnauthorizedException, ScmConfigurationPersistenceException,
ScmBadRequestException {
// given
Secret gitconfigSecret =
new SecretBuilder()
.withNewMetadata()
.withName(GITCONFIG_SECRET_NAME)
.withLabels(GITCONFIG_SECRET_LABELS)
.withAnnotations(GITCONFIG_SECRET_ANNOTATIONS)
.endMetadata()
.build();
gitconfigSecret.setData(
Collections.singletonMap(
"gitconfig",
encode(
"[other]\n\tkey = value\n[other1]\n\tkey = value\n[user]\n\tname = \"\"\n\temail= \"\"")));
serverMock.getClient().secrets().inNamespace(TEST_NAMESPACE_NAME).create(gitconfigSecret);
configurator =
new GitconfigAutomauntSecretConfigurator(
cheServerKubernetesClientFactory, Set.of(gitUserDataFetcher));
when(gitUserDataFetcher.fetchGitUserData())
.thenReturn(new GitUserData("username", "userEmail"));
// when
configurator.configure(namespaceResolutionContext, TEST_NAMESPACE_NAME);
// then
Assert.assertEquals(serverMock.getLastRequest().getMethod(), "PUT");
var secrets =
serverMock.getClient().secrets().inNamespace(TEST_NAMESPACE_NAME).list().getItems();
Assert.assertEquals(secrets.size(), 1);
String expected =
"[other]\n\tkey = value\n[other1]\n\tkey = value\n[user]\n\tname = username\n\temail = userEmail";
Assert.assertEquals(secrets.get(0).getData().get("gitconfig"), encode(expected));
}

@Test
public void shouldNotUpdateGitconfigSecretWithUserSection()
throws InfrastructureException, InterruptedException, ScmItemNotFoundException,
Expand Down

0 comments on commit d5941b1

Please # to comment.