chore: Validate OAuth token secrets on namespace provisioning (#608)

* chore: Validate OAuth token secrets on namespace provisioning

Signed-off-by: Anatolii Bazko <abazko@redhat.com>

---------

Signed-off-by: Anatolii Bazko <abazko@redhat.com>
pull/622/head
Anatolii Bazko 2023-11-15 15:08:48 +01:00 committed by GitHub
parent 92b37d2b6e
commit b5e1e2a4a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 0 deletions

View File

@ -47,6 +47,7 @@ import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.RemoveNames
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.CredentialsSecretConfigurator;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.GitconfigUserDataConfigurator;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.NamespaceConfigurator;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.OAuthTokenSecretsConfigurator;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.PreferencesConfigMapConfigurator;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.SshKeysConfigurator;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.UserPermissionConfigurator;
@ -101,6 +102,7 @@ public class KubernetesInfraModule extends AbstractModule {
Multibinder.newSetBinder(binder(), NamespaceConfigurator.class);
namespaceConfigurators.addBinding().to(UserPermissionConfigurator.class);
namespaceConfigurators.addBinding().to(CredentialsSecretConfigurator.class);
namespaceConfigurators.addBinding().to(OAuthTokenSecretsConfigurator.class);
namespaceConfigurators.addBinding().to(PreferencesConfigMapConfigurator.class);
namespaceConfigurators.addBinding().to(WorkspaceServiceAccountConfigurator.class);
namespaceConfigurators.addBinding().to(UserProfileConfigurator.class);

View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 2012-2023 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenFetcher;
import org.eclipse.che.api.factory.server.scm.PersonalAccessTokenManager;
import org.eclipse.che.api.factory.server.scm.exception.ScmCommunicationException;
import org.eclipse.che.api.factory.server.scm.exception.ScmConfigurationPersistenceException;
import org.eclipse.che.api.factory.server.scm.exception.ScmUnauthorizedException;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.NamespaceResolutionContext;
import org.eclipse.che.commons.env.EnvironmentContext;
import org.eclipse.che.commons.subject.Subject;
import org.eclipse.che.workspace.infrastructure.kubernetes.CheServerKubernetesClientFactory;
/**
* Ensures that OAuth token that are represented by Kubernetes Secrets are valid.
*
* @author Anatolii Bazko
*/
@Singleton
public class OAuthTokenSecretsConfigurator implements NamespaceConfigurator {
private final CheServerKubernetesClientFactory cheServerKubernetesClientFactory;
private final PersonalAccessTokenManager personalAccessTokenManager;
private static final String ANNOTATION_SCM_URL = "che.eclipse.org/scm-url";
private static final String ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME =
"che.eclipse.org/scm-personal-access-token-name";
private static final Map<String, String> SEARCH_LABELS =
ImmutableMap.of(
"app.kubernetes.io/part-of", "che.eclipse.org",
"app.kubernetes.io/component", "scm-personal-access-token");
@Inject
public OAuthTokenSecretsConfigurator(
CheServerKubernetesClientFactory cheServerKubernetesClientFactory,
PersonalAccessTokenManager personalAccessTokenManager) {
this.cheServerKubernetesClientFactory = cheServerKubernetesClientFactory;
this.personalAccessTokenManager = personalAccessTokenManager;
}
@Override
public void configure(NamespaceResolutionContext namespaceResolutionContext, String namespaceName)
throws InfrastructureException {
var client = cheServerKubernetesClientFactory.create();
client.secrets().inNamespace(namespaceName).withLabels(SEARCH_LABELS).list().getItems().stream()
.filter(
s ->
s.getMetadata().getAnnotations() != null
&& s.getMetadata().getAnnotations().containsKey(ANNOTATION_SCM_URL)
&& s.getMetadata()
.getAnnotations()
.containsKey(ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME)
&& s.getMetadata()
.getAnnotations()
.get(ANNOTATION_SCM_PERSONAL_ACCESS_TOKEN_NAME)
.startsWith(PersonalAccessTokenFetcher.OAUTH_2_PREFIX))
.forEach(
s -> {
try {
Subject cheSubject = EnvironmentContext.getCurrent().getSubject();
personalAccessTokenManager.get(
cheSubject, s.getMetadata().getAnnotations().get(ANNOTATION_SCM_URL));
} catch (ScmCommunicationException
| ScmConfigurationPersistenceException
| ScmUnauthorizedException e) {
throw new RuntimeException(e);
}
});
}
}

View File

@ -51,6 +51,7 @@ import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesN
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.CredentialsSecretConfigurator;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.GitconfigUserDataConfigurator;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.NamespaceConfigurator;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.OAuthTokenSecretsConfigurator;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.PreferencesConfigMapConfigurator;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.SshKeysConfigurator;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.UserPermissionConfigurator;
@ -110,6 +111,7 @@ public class OpenShiftInfraModule extends AbstractModule {
namespaceConfigurators.addBinding().to(UserProfileConfigurator.class);
namespaceConfigurators.addBinding().to(UserPreferencesConfigurator.class);
namespaceConfigurators.addBinding().to(CredentialsSecretConfigurator.class);
namespaceConfigurators.addBinding().to(OAuthTokenSecretsConfigurator.class);
namespaceConfigurators.addBinding().to(PreferencesConfigMapConfigurator.class);
namespaceConfigurators.addBinding().to(OpenShiftWorkspaceServiceAccountConfigurator.class);
namespaceConfigurators.addBinding().to(OpenShiftStopWorkspaceRoleConfigurator.class);