Use hardcoded string as username for Azure git credentials (#529)

Since Azure git provider do not support username for its user object, use username string as username in the git credentials file if the PAT is related to Azure Devops: https://username:<token>@dev.azure.com
pull/531/head
Igor Vinokur 2023-07-06 09:37:33 +03:00 committed by GitHub
parent 21323d1b12
commit aee2079322
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 3 deletions

View File

@ -11,6 +11,7 @@
*/
package org.eclipse.che.api.factory.server.scm.kubernetes;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.eclipse.che.api.factory.server.scm.PersonalAccessTokenFetcher.OAUTH_2_PREFIX;
@ -156,9 +157,7 @@ public class KubernetesGitCredentialManager implements GitCredentialManager {
format(
"%s://%s:%s@%s%s",
scmUrl.getProtocol(),
personalAccessToken.getScmTokenName().startsWith(OAUTH_2_PREFIX)
? "oauth2"
: personalAccessToken.getScmUserName(),
getUsernameSegment(personalAccessToken),
URLEncoder.encode(personalAccessToken.getToken(), UTF_8),
scmUrl.getHost(),
scmUrl.getPort() != 80 && scmUrl.getPort() != -1
@ -171,6 +170,21 @@ public class KubernetesGitCredentialManager implements GitCredentialManager {
}
}
/**
* Returns username URL segment for git credentials. For OAuth2 tokens it is "oauth2", for others
* - {@param personalAccessToken#getScmUserName()} or just "username" string if the token has a
* non-null {@param personalAccessToken#getScmOrganization()}. This is needed to support providers
* that do not have username in their user object. Such providers have an additional organization
* field.
*/
private String getUsernameSegment(PersonalAccessToken personalAccessToken) {
return personalAccessToken.getScmTokenName().startsWith(OAUTH_2_PREFIX)
? "oauth2"
: isNullOrEmpty(personalAccessToken.getScmOrganization())
? personalAccessToken.getScmUserName()
: "username";
}
/**
* It is not guaranteed that this code will always return same namespace, but since credentials
* are now added into manually pre-created user namespace, we can expect always the same result

View File

@ -108,6 +108,58 @@ public class KubernetesGitCredentialManagerTest {
assertFalse(createdSecret.getMetadata().getName().contains(token.getScmUserName()));
}
@Test
public void shouldUseHardcodedUsernameIfScmOrganizationIsDefined() throws Exception {
// given
KubernetesNamespaceMeta namespaceMeta = new KubernetesNamespaceMetaImpl("test");
PersonalAccessToken token =
new PersonalAccessToken(
"https://bitbucket-server.com:5648",
"cheUser",
"cheOrganization",
"username",
"token-name",
"tid-23434",
"token123");
Map<String, String> annotations = new HashMap<>(DEFAULT_SECRET_ANNOTATIONS);
annotations.put(ANNOTATION_SCM_URL, token.getScmProviderUrl() + "/");
annotations.put(ANNOTATION_SCM_USERNAME, token.getScmUserName());
annotations.put(ANNOTATION_CHE_USERID, token.getCheUserId());
ObjectMeta objectMeta =
new ObjectMetaBuilder()
.withName(NameGenerator.generate(NAME_PATTERN, 5))
.withAnnotations(annotations)
.build();
Secret existing =
new SecretBuilder()
.withMetadata(objectMeta)
.withData(Map.of("credentials", "foo 123"))
.build();
when(namespaceFactory.list()).thenReturn(Collections.singletonList(namespaceMeta));
when(cheServerKubernetesClientFactory.create()).thenReturn(kubeClient);
when(kubeClient.secrets()).thenReturn(secretsMixedOperation);
when(secretsMixedOperation.inNamespace(eq(namespaceMeta.getName())))
.thenReturn(nonNamespaceOperation);
when(nonNamespaceOperation.withLabels(anyMap())).thenReturn(filterWatchDeletable);
when(filterWatchDeletable.list()).thenReturn(secretList);
when(secretList.getItems()).thenReturn(singletonList(existing));
// when
kubernetesGitCredentialManager.createOrReplace(token);
// then
ArgumentCaptor<Secret> captor = ArgumentCaptor.forClass(Secret.class);
verify(nonNamespaceOperation).createOrReplace(captor.capture());
Secret createdSecret = captor.getValue();
assertNotNull(createdSecret);
assertEquals(
new String(Base64.getDecoder().decode(createdSecret.getData().get("credentials"))),
"https://username:token123@bitbucket-server.com:5648");
}
@Test
public void testCreateAndSaveNewOAuthGitCredential() throws Exception {
KubernetesNamespaceMeta meta = new KubernetesNamespaceMetaImpl("test");