Search in sources :

Example 1 with PersonalAccessToken

use of org.eclipse.che.api.factory.server.scm.PersonalAccessToken in project che-server by eclipse-che.

the class KubernetesGitCredentialManager method createOrReplace.

@Override
public void createOrReplace(PersonalAccessToken personalAccessToken) throws UnsatisfiedScmPreconditionException, ScmConfigurationPersistenceException {
    try {
        final String namespace = getFirstNamespace();
        final KubernetesClient client = clientFactory.create();
        // to avoid duplicating secrets we try to reuse existing one by matching
        // hostname/username if possible, and update it. Otherwise, create new one.
        Optional<Secret> existing = client.secrets().inNamespace(namespace).withLabels(SEARCH_LABELS).list().getItems().stream().filter(s -> s.getMetadata().getAnnotations() != null).filter(s -> Boolean.parseBoolean(s.getMetadata().getAnnotations().get(ANNOTATION_GIT_CREDENTIALS)) && personalAccessToken.getScmProviderUrl().equals(StringUtils.trimEnd(s.getMetadata().getAnnotations().get(ANNOTATION_SCM_URL), '/')) && personalAccessToken.getCheUserId().equals(s.getMetadata().getAnnotations().get(ANNOTATION_CHE_USERID)) && personalAccessToken.getScmUserName().equals(s.getMetadata().getAnnotations().get(ANNOTATION_SCM_USERNAME))).findFirst();
        Secret secret = existing.orElseGet(() -> {
            Map<String, String> annotations = new HashMap<>(DEFAULT_SECRET_ANNOTATIONS);
            annotations.put(ANNOTATION_SCM_URL, personalAccessToken.getScmProviderUrl());
            annotations.put(ANNOTATION_SCM_USERNAME, personalAccessToken.getScmUserName());
            annotations.put(ANNOTATION_CHE_USERID, personalAccessToken.getCheUserId());
            ObjectMeta meta = new ObjectMetaBuilder().withName(NameGenerator.generate(NAME_PATTERN, 5)).withAnnotations(annotations).withLabels(NEW_SECRET_LABELS).build();
            return new SecretBuilder().withMetadata(meta).build();
        });
        URL scmUrl = new URL(personalAccessToken.getScmProviderUrl());
        secret.setData(Map.of("credentials", Base64.getEncoder().encodeToString(format("%s://%s:%s@%s%s", scmUrl.getProtocol(), personalAccessToken.getScmTokenName().startsWith(OAUTH_2_PREFIX) ? "oauth2" : personalAccessToken.getScmUserName(), URLEncoder.encode(personalAccessToken.getToken(), UTF_8), scmUrl.getHost(), scmUrl.getPort() != 80 && scmUrl.getPort() != -1 ? ":" + scmUrl.getPort() : "").getBytes())));
        client.secrets().inNamespace(namespace).createOrReplace(secret);
    } catch (InfrastructureException | MalformedURLException e) {
        throw new ScmConfigurationPersistenceException(e.getMessage(), e);
    }
}
Also used : ANNOTATION_MOUNT_PATH(org.eclipse.che.workspace.infrastructure.kubernetes.provision.secret.KubernetesSecretAnnotationNames.ANNOTATION_MOUNT_PATH) KubernetesClientFactory(org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesClientFactory) ANNOTATION_DEV_WORKSPACE_MOUNT_PATH(org.eclipse.che.workspace.infrastructure.kubernetes.provision.secret.KubernetesSecretAnnotationNames.ANNOTATION_DEV_WORKSPACE_MOUNT_PATH) URL(java.net.URL) ANNOTATION_AUTOMOUNT(org.eclipse.che.workspace.infrastructure.kubernetes.provision.secret.KubernetesSecretAnnotationNames.ANNOTATION_AUTOMOUNT) HashMap(java.util.HashMap) OAUTH_2_PREFIX(org.eclipse.che.api.factory.server.scm.PersonalAccessTokenFetcher.OAUTH_2_PREFIX) Singleton(javax.inject.Singleton) Inject(javax.inject.Inject) PersonalAccessToken(org.eclipse.che.api.factory.server.scm.PersonalAccessToken) DEV_WORKSPACE_PREFIX(org.eclipse.che.workspace.infrastructure.kubernetes.provision.secret.KubernetesSecretAnnotationNames.DEV_WORKSPACE_PREFIX) Map(java.util.Map) ScmConfigurationPersistenceException(org.eclipse.che.api.factory.server.scm.exception.ScmConfigurationPersistenceException) ANNOTATION_MOUNT_AS(org.eclipse.che.workspace.infrastructure.kubernetes.provision.secret.KubernetesSecretAnnotationNames.ANNOTATION_MOUNT_AS) NameGenerator(org.eclipse.che.commons.lang.NameGenerator) ObjectMetaBuilder(io.fabric8.kubernetes.api.model.ObjectMetaBuilder) ImmutableMap(com.google.common.collect.ImmutableMap) MalformedURLException(java.net.MalformedURLException) GitCredentialManager(org.eclipse.che.api.factory.server.scm.GitCredentialManager) KubernetesNamespaceMeta(org.eclipse.che.workspace.infrastructure.kubernetes.api.shared.KubernetesNamespaceMeta) UTF_8(java.nio.charset.StandardCharsets.UTF_8) String.format(java.lang.String.format) KubernetesNamespaceFactory(org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespaceFactory) InfrastructureException(org.eclipse.che.api.workspace.server.spi.InfrastructureException) URLEncoder(java.net.URLEncoder) Base64(java.util.Base64) UnsatisfiedScmPreconditionException(org.eclipse.che.api.factory.server.scm.exception.UnsatisfiedScmPreconditionException) ANNOTATION_GIT_CREDENTIALS(org.eclipse.che.workspace.infrastructure.kubernetes.provision.secret.KubernetesSecretAnnotationNames.ANNOTATION_GIT_CREDENTIALS) ObjectMeta(io.fabric8.kubernetes.api.model.ObjectMeta) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) Secret(io.fabric8.kubernetes.api.model.Secret) Optional(java.util.Optional) SecretBuilder(io.fabric8.kubernetes.api.model.SecretBuilder) StringUtils(org.eclipse.che.commons.lang.StringUtils) ObjectMeta(io.fabric8.kubernetes.api.model.ObjectMeta) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) MalformedURLException(java.net.MalformedURLException) HashMap(java.util.HashMap) ObjectMetaBuilder(io.fabric8.kubernetes.api.model.ObjectMetaBuilder) URL(java.net.URL) Secret(io.fabric8.kubernetes.api.model.Secret) SecretBuilder(io.fabric8.kubernetes.api.model.SecretBuilder) InfrastructureException(org.eclipse.che.api.workspace.server.spi.InfrastructureException) ScmConfigurationPersistenceException(org.eclipse.che.api.factory.server.scm.exception.ScmConfigurationPersistenceException)

Example 2 with PersonalAccessToken

use of org.eclipse.che.api.factory.server.scm.PersonalAccessToken in project che-server by eclipse-che.

the class KubernetesGitCredentialManagerTest method testCreateAndSaveNewPATGitCredential.

@Test
public void testCreateAndSaveNewPATGitCredential() throws Exception {
    KubernetesNamespaceMeta meta = new KubernetesNamespaceMetaImpl("test");
    when(namespaceFactory.list()).thenReturn(Collections.singletonList(meta));
    when(clientFactory.create()).thenReturn(kubeClient);
    when(kubeClient.secrets()).thenReturn(secretsMixedOperation);
    when(secretsMixedOperation.inNamespace(eq(meta.getName()))).thenReturn(nonNamespaceOperation);
    when(nonNamespaceOperation.withLabels(anyMap())).thenReturn(filterWatchDeletable);
    when(filterWatchDeletable.list()).thenReturn(secretList);
    when(secretList.getItems()).thenReturn(emptyList());
    ArgumentCaptor<Secret> captor = ArgumentCaptor.forClass(Secret.class);
    PersonalAccessToken token = new PersonalAccessToken("https://bitbucket.com", "cheUser", "username", "userId", "token-name", "tid-23434", "token123");
    // when
    kubernetesGitCredentialManager.createOrReplace(token);
    // then
    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.com");
    assertTrue(createdSecret.getMetadata().getName().startsWith(NAME_PATTERN));
    assertFalse(createdSecret.getMetadata().getName().contains(token.getScmUserName()));
}
Also used : Secret(io.fabric8.kubernetes.api.model.Secret) KubernetesNamespaceMetaImpl(org.eclipse.che.workspace.infrastructure.kubernetes.api.server.impls.KubernetesNamespaceMetaImpl) PersonalAccessToken(org.eclipse.che.api.factory.server.scm.PersonalAccessToken) KubernetesNamespaceMeta(org.eclipse.che.workspace.infrastructure.kubernetes.api.shared.KubernetesNamespaceMeta) Test(org.testng.annotations.Test)

Example 3 with PersonalAccessToken

use of org.eclipse.che.api.factory.server.scm.PersonalAccessToken in project che-server by eclipse-che.

the class KubernetesGitCredentialManagerTest method testUpdateTokenInExistingCredential.

@Test
public void testUpdateTokenInExistingCredential() throws Exception {
    KubernetesNamespaceMeta namespaceMeta = new KubernetesNamespaceMetaImpl("test");
    PersonalAccessToken token = new PersonalAccessToken("https://bitbucket.com:5648", "cheUser", "username", "userId", "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(clientFactory.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.com:5648");
    assertEquals(createdSecret.getMetadata().getName(), objectMeta.getName());
}
Also used : Secret(io.fabric8.kubernetes.api.model.Secret) SecretBuilder(io.fabric8.kubernetes.api.model.SecretBuilder) KubernetesNamespaceMetaImpl(org.eclipse.che.workspace.infrastructure.kubernetes.api.server.impls.KubernetesNamespaceMetaImpl) ObjectMeta(io.fabric8.kubernetes.api.model.ObjectMeta) HashMap(java.util.HashMap) PersonalAccessToken(org.eclipse.che.api.factory.server.scm.PersonalAccessToken) KubernetesNamespaceMeta(org.eclipse.che.workspace.infrastructure.kubernetes.api.shared.KubernetesNamespaceMeta) ObjectMetaBuilder(io.fabric8.kubernetes.api.model.ObjectMetaBuilder) Test(org.testng.annotations.Test)

Example 4 with PersonalAccessToken

use of org.eclipse.che.api.factory.server.scm.PersonalAccessToken in project che-server by eclipse-che.

the class KubernetesPersonalAccessTokenManagerTest method testSavingOfPersonalAccessToken.

@Test
public void testSavingOfPersonalAccessToken() throws Exception {
    KubernetesNamespaceMeta meta = new KubernetesNamespaceMetaImpl("test");
    when(namespaceFactory.list()).thenReturn(Collections.singletonList(meta));
    when(clientFactory.create()).thenReturn(kubeClient);
    when(kubeClient.secrets()).thenReturn(secretsMixedOperation);
    when(secretsMixedOperation.inNamespace(eq(meta.getName()))).thenReturn(nonNamespaceOperation);
    ArgumentCaptor<Secret> captor = ArgumentCaptor.forClass(Secret.class);
    PersonalAccessToken token = new PersonalAccessToken("https://bitbucket.com", "cheUser", "username", "userId", "token-name", "tid-24", "token123");
    // when
    personalAccessTokenManager.save(token);
    // then
    verify(nonNamespaceOperation).createOrReplace(captor.capture());
    Secret createdSecret = captor.getValue();
    assertNotNull(createdSecret);
    assertTrue(createdSecret.getMetadata().getName().startsWith(KubernetesPersonalAccessTokenManager.NAME_PATTERN));
    assertEquals(createdSecret.getData().get("token"), Base64.getEncoder().encodeToString(token.getToken().getBytes()));
}
Also used : Secret(io.fabric8.kubernetes.api.model.Secret) KubernetesNamespaceMetaImpl(org.eclipse.che.workspace.infrastructure.kubernetes.api.server.impls.KubernetesNamespaceMetaImpl) PersonalAccessToken(org.eclipse.che.api.factory.server.scm.PersonalAccessToken) KubernetesNamespaceMeta(org.eclipse.che.workspace.infrastructure.kubernetes.api.shared.KubernetesNamespaceMeta) Test(org.testng.annotations.Test)

Example 5 with PersonalAccessToken

use of org.eclipse.che.api.factory.server.scm.PersonalAccessToken in project che-server by eclipse-che.

the class KubernetesPersonalAccessTokenManagerTest method testGetTokenFromNamespaceWithTrailingSlashMismatch.

@Test
public void testGetTokenFromNamespaceWithTrailingSlashMismatch() throws Exception {
    KubernetesNamespaceMeta meta = new KubernetesNamespaceMetaImpl("test");
    when(namespaceFactory.list()).thenReturn(Collections.singletonList(meta));
    KubernetesNamespace kubernetesnamespace = Mockito.mock(KubernetesNamespace.class);
    KubernetesSecrets secrets = Mockito.mock(KubernetesSecrets.class);
    when(namespaceFactory.access(eq(null), eq(meta.getName()))).thenReturn(kubernetesnamespace);
    when(kubernetesnamespace.secrets()).thenReturn(secrets);
    when(scmPersonalAccessTokenFetcher.isValid(any(PersonalAccessToken.class))).thenReturn(true);
    Map<String, String> data1 = Map.of("token", Base64.getEncoder().encodeToString("token1".getBytes(UTF_8)));
    Map<String, String> data2 = Map.of("token", Base64.getEncoder().encodeToString("token2".getBytes(UTF_8)));
    ObjectMeta meta1 = new ObjectMetaBuilder().withAnnotations(Map.of(ANNOTATION_CHE_USERID, "user1", ANNOTATION_SCM_URL, "http://host1.com/")).build();
    ObjectMeta meta2 = new ObjectMetaBuilder().withAnnotations(Map.of(ANNOTATION_CHE_USERID, "user1", ANNOTATION_SCM_URL, "http://host2.com")).build();
    Secret secret1 = new SecretBuilder().withMetadata(meta1).withData(data1).build();
    Secret secret2 = new SecretBuilder().withMetadata(meta2).withData(data2).build();
    when(secrets.get(any(LabelSelector.class))).thenReturn(Arrays.asList(secret1, secret2));
    // when
    PersonalAccessToken token1 = personalAccessTokenManager.get(new SubjectImpl("user", "user1", "t1", false), "http://host1.com").get();
    PersonalAccessToken token2 = personalAccessTokenManager.get(new SubjectImpl("user", "user1", "t1", false), "http://host2.com/").get();
    // then
    assertNotNull(token1);
    assertNotNull(token2);
}
Also used : KubernetesNamespaceMetaImpl(org.eclipse.che.workspace.infrastructure.kubernetes.api.server.impls.KubernetesNamespaceMetaImpl) ObjectMeta(io.fabric8.kubernetes.api.model.ObjectMeta) LabelSelector(io.fabric8.kubernetes.api.model.LabelSelector) ObjectMetaBuilder(io.fabric8.kubernetes.api.model.ObjectMetaBuilder) Secret(io.fabric8.kubernetes.api.model.Secret) SecretBuilder(io.fabric8.kubernetes.api.model.SecretBuilder) KubernetesSecrets(org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesSecrets) PersonalAccessToken(org.eclipse.che.api.factory.server.scm.PersonalAccessToken) KubernetesNamespaceMeta(org.eclipse.che.workspace.infrastructure.kubernetes.api.shared.KubernetesNamespaceMeta) SubjectImpl(org.eclipse.che.commons.subject.SubjectImpl) KubernetesNamespace(org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespace) Test(org.testng.annotations.Test)

Aggregations

PersonalAccessToken (org.eclipse.che.api.factory.server.scm.PersonalAccessToken)54 Test (org.testng.annotations.Test)42 Secret (io.fabric8.kubernetes.api.model.Secret)20 KubernetesNamespaceMeta (org.eclipse.che.workspace.infrastructure.kubernetes.api.shared.KubernetesNamespaceMeta)20 Subject (org.eclipse.che.commons.subject.Subject)16 KubernetesNamespaceMetaImpl (org.eclipse.che.workspace.infrastructure.kubernetes.api.server.impls.KubernetesNamespaceMetaImpl)16 ObjectMeta (io.fabric8.kubernetes.api.model.ObjectMeta)12 ObjectMetaBuilder (io.fabric8.kubernetes.api.model.ObjectMetaBuilder)12 SecretBuilder (io.fabric8.kubernetes.api.model.SecretBuilder)12 SubjectImpl (org.eclipse.che.commons.subject.SubjectImpl)12 LabelSelector (io.fabric8.kubernetes.api.model.LabelSelector)8 OAuthToken (org.eclipse.che.api.auth.shared.dto.OAuthToken)8 BitbucketPersonalAccessToken (org.eclipse.che.api.factory.server.bitbucket.server.BitbucketPersonalAccessToken)8 KubernetesNamespace (org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespace)8 KubernetesSecrets (org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesSecrets)8 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)8 Optional (java.util.Optional)6 ScmBadRequestException (org.eclipse.che.api.factory.server.scm.exception.ScmBadRequestException)6 ScmCommunicationException (org.eclipse.che.api.factory.server.scm.exception.ScmCommunicationException)6 ScmItemNotFoundException (org.eclipse.che.api.factory.server.scm.exception.ScmItemNotFoundException)6