diff --git a/infrastructures/infrastructure-factory/src/main/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesPersonalAccessTokenManager.java b/infrastructures/infrastructure-factory/src/main/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesPersonalAccessTokenManager.java index 800edaef86..0b50187336 100644 --- a/infrastructures/infrastructure-factory/src/main/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesPersonalAccessTokenManager.java +++ b/infrastructures/infrastructure-factory/src/main/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesPersonalAccessTokenManager.java @@ -23,6 +23,7 @@ import io.fabric8.kubernetes.api.model.SecretBuilder; import io.fabric8.kubernetes.client.KubernetesClientException; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Base64; import java.util.Collections; import java.util.Comparator; @@ -152,7 +153,7 @@ public PersonalAccessToken fetchAndSave(Subject cheUser, String scmServerUrl) @Override public Optional get(Subject cheUser, String scmServerUrl) throws ScmConfigurationPersistenceException { - return doGetPersonalAccessToken(cheUser, null, scmServerUrl); + return doGetPersonalAccessTokens(cheUser, null, scmServerUrl).stream().findFirst(); } @Override @@ -174,12 +175,13 @@ public PersonalAccessToken get(String scmServerUrl) public Optional get( Subject cheUser, String oAuthProviderName, @Nullable String scmServerUrl) throws ScmConfigurationPersistenceException { - return doGetPersonalAccessToken(cheUser, oAuthProviderName, scmServerUrl); + return doGetPersonalAccessTokens(cheUser, oAuthProviderName, scmServerUrl).stream().findFirst(); } - private Optional doGetPersonalAccessToken( + private List doGetPersonalAccessTokens( Subject cheUser, @Nullable String oAuthProviderName, @Nullable String scmServerUrl) throws ScmConfigurationPersistenceException { + List result = new ArrayList<>(); try { LOG.debug( "Fetching personal access token for user {} and OAuth provider {}", @@ -231,7 +233,8 @@ private Optional doGetPersonalAccessToken( personalAccessTokenParams.getScmTokenName(), personalAccessTokenParams.getScmTokenId(), personalAccessTokenParams.getToken()); - return Optional.of(personalAccessToken); + result.add(personalAccessToken); + continue; } // Removing token that is no longer valid. If several tokens exist the next one could @@ -251,7 +254,7 @@ private Optional doGetPersonalAccessToken( LOG.debug("Failed to get personal access token", e); throw new ScmConfigurationPersistenceException(e.getMessage(), e); } - return Optional.empty(); + return result; } /** @@ -351,6 +354,29 @@ public void forceRefreshPersonalAccessToken(String scmServerUrl) scmPersonalAccessTokenFetcher.refreshPersonalAccessToken(subject, scmServerUrl); gitCredentialManager.createOrReplace(personalAccessToken); store(personalAccessToken); + removePreviousTokensIfPresent(subject, scmServerUrl); + } + + private void removePreviousTokensIfPresent(Subject subject, String scmServerUrl) + throws ScmConfigurationPersistenceException, UnsatisfiedScmPreconditionException { + List personalAccessTokens = + doGetPersonalAccessTokens(subject, null, scmServerUrl); + for (int i = 1; i < personalAccessTokens.size(); i++) { + PersonalAccessToken token = personalAccessTokens.get(i); + if (token.getScmProviderUrl().equals(scmServerUrl)) { + try { + String namespace = getFirstNamespace(); + cheServerKubernetesClientFactory + .create() + .secrets() + .inNamespace(namespace) + .withName(token.getScmTokenId()) + .delete(); + } catch (InfrastructureException e) { + throw new ScmConfigurationPersistenceException(e.getMessage(), e); + } + } + } } @Override diff --git a/infrastructures/infrastructure-factory/src/test/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesPersonalAccessTokenManagerTest.java b/infrastructures/infrastructure-factory/src/test/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesPersonalAccessTokenManagerTest.java index 48e622d2f8..56053ac085 100644 --- a/infrastructures/infrastructure-factory/src/test/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesPersonalAccessTokenManagerTest.java +++ b/infrastructures/infrastructure-factory/src/test/java/org/eclipse/che/api/factory/server/scm/kubernetes/KubernetesPersonalAccessTokenManagerTest.java @@ -464,7 +464,7 @@ public void shouldDeleteInvalidTokensOnGet() throws Exception { } @Test(dependsOnMethods = "shouldDeleteInvalidTokensOnGet") - public void shouldReturnFirstValidToken() throws Exception { + public void shouldReturnFirstValidTokenAndDeleteTheOlderOne() throws Exception { // given KubernetesNamespaceMeta meta = new KubernetesNamespaceMetaImpl("test"); when(namespaceFactory.list()).thenReturn(singletonList(meta)); @@ -481,10 +481,10 @@ public void shouldReturnFirstValidToken() throws Exception { ? Optional.of("user") : Optional.empty(); }); - // when(cheServerKubernetesClientFactory.create()).thenReturn(kubeClient); - // when(kubeClient.secrets()).thenReturn(secretsMixedOperation); - // - // when(secretsMixedOperation.inNamespace(eq(meta.getName()))).thenReturn(nonNamespaceOperation); + when(cheServerKubernetesClientFactory.create()).thenReturn(kubeClient); + when(kubeClient.secrets()).thenReturn(secretsMixedOperation); + + when(secretsMixedOperation.inNamespace(eq(meta.getName()))).thenReturn(nonNamespaceOperation); Map data1 = Map.of("token", Base64.getEncoder().encodeToString("token1".getBytes(UTF_8))); Map data2 = @@ -527,5 +527,6 @@ public void shouldReturnFirstValidToken() throws Exception { // then assertTrue(token.isPresent()); assertEquals(token.get().getScmTokenId(), "id2"); + verify(nonNamespaceOperation, times(1)).delete(eq(secret1)); } }