From 5ef55f5993ec5a258b99a57d0cbe0673b0166ea2 Mon Sep 17 00:00:00 2001 From: Sergii Leshchenko Date: Wed, 11 Oct 2017 11:35:42 +0300 Subject: [PATCH] CHE-6587 Add MachineTokenProvider interface It is implemented in different ways for single and multiuser packaging --- .../assembly-wsmaster-war/pom.xml | 4 - .../che/api/deploy/MachineAuthModule.java | 4 + .../deploy/MultiUserCheWsMasterModule.java | 3 - .../che/api/deploy/CheWsMasterModule.java | 2 + .../server/UserTokenEnvVarProvider.java | 18 +- .../installer/InstallerConfigProvisioner.java | 15 +- .../InstallerConfigProvisionerTest.java | 232 +++++++++++++----- multiuser/infrastructures/openshift/pom.xml | 56 ----- .../MultiuserInstallerConfigProvisioner.java | 51 ---- multiuser/infrastructures/pom.xml | 29 --- .../server/MachineTokenProviderImpl.java | 46 ++++ multiuser/pom.xml | 1 - .../server/hc/ServersReadinessChecker.java | 1 + .../server/token/MachineTokenException.java | 33 +++ .../server/token/MachineTokenProvider.java | 35 +++ 15 files changed, 319 insertions(+), 211 deletions(-) delete mode 100644 multiuser/infrastructures/openshift/pom.xml delete mode 100644 multiuser/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/provision/installer/MultiuserInstallerConfigProvisioner.java delete mode 100644 multiuser/infrastructures/pom.xml create mode 100644 multiuser/machine-auth/che-multiuser-machine-authentication/src/main/java/org/eclipse/che/multiuser/machine/authentication/server/MachineTokenProviderImpl.java create mode 100644 wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/token/MachineTokenException.java create mode 100644 wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/token/MachineTokenProvider.java diff --git a/assembly-multiuser/assembly-wsmaster-war/pom.xml b/assembly-multiuser/assembly-wsmaster-war/pom.xml index d41b1f118b..b28560f4a2 100644 --- a/assembly-multiuser/assembly-wsmaster-war/pom.xml +++ b/assembly-multiuser/assembly-wsmaster-war/pom.xml @@ -103,10 +103,6 @@ org.eclipse.che.multiuser che-multiuser-sql-schema - - org.eclipse.che.multiuser - multiuser-infrastructure-openshift - org.eclipse.che.plugin che-plugin-activity-wsmaster diff --git a/assembly-multiuser/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/MachineAuthModule.java b/assembly-multiuser/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/MachineAuthModule.java index d0b6551d25..2656d9959d 100644 --- a/assembly-multiuser/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/MachineAuthModule.java +++ b/assembly-multiuser/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/MachineAuthModule.java @@ -11,9 +11,11 @@ package org.eclipse.che.api.deploy; import com.google.inject.AbstractModule; +import org.eclipse.che.api.workspace.server.MachineTokenProvider; import org.eclipse.che.commons.auth.token.ChainedTokenExtractor; import org.eclipse.che.commons.auth.token.RequestTokenExtractor; import org.eclipse.che.inject.DynaModule; +import org.eclipse.che.multiuser.machine.authentication.server.MachineTokenProviderImpl; /** * Machine authentication bindings. @@ -32,5 +34,7 @@ public class MachineAuthModule extends AbstractModule { bind(org.eclipse.che.multiuser.machine.authentication.server.MachineTokenRegistry.class); bind(org.eclipse.che.multiuser.machine.authentication.server.MachineSessionInvalidator.class); bind(RequestTokenExtractor.class).to(ChainedTokenExtractor.class); + + bind(MachineTokenProvider.class).to(MachineTokenProviderImpl.class); } } diff --git a/assembly-multiuser/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/MultiUserCheWsMasterModule.java b/assembly-multiuser/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/MultiUserCheWsMasterModule.java index a345c20189..d29c9b7412 100644 --- a/assembly-multiuser/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/MultiUserCheWsMasterModule.java +++ b/assembly-multiuser/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/MultiUserCheWsMasterModule.java @@ -32,8 +32,6 @@ import org.eclipse.che.multiuser.resource.api.ResourceModule; import org.eclipse.che.security.PBKDF2PasswordEncryptor; import org.eclipse.che.security.PasswordEncryptor; import org.eclipse.che.workspace.infrastructure.openshift.OpenShiftInfraModule; -import org.eclipse.che.workspace.infrastructure.openshift.provision.installer.InstallerConfigProvisioner; -import org.eclipse.che.workspace.infrastructure.openshift.provision.installer.MultiuserInstallerConfigProvisioner; @DynaModule public class MultiUserCheWsMasterModule extends AbstractModule { @@ -41,7 +39,6 @@ public class MultiUserCheWsMasterModule extends AbstractModule { @Override protected void configure() { bind(ServerCheckerFactoryImpl.class).to(AuthServerCheckerFactoryImpl.class); - bind(InstallerConfigProvisioner.class).to(MultiuserInstallerConfigProvisioner.class); install(new OpenShiftInfraModule()); bind(TemplateProcessor.class).to(STTemplateProcessorImpl.class); diff --git a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/CheWsMasterModule.java b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/CheWsMasterModule.java index acc03cf471..79b499cfd0 100644 --- a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/CheWsMasterModule.java +++ b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/CheWsMasterModule.java @@ -14,6 +14,7 @@ import com.google.inject.AbstractModule; import com.google.inject.name.Names; import javax.sql.DataSource; import org.eclipse.che.api.user.server.TokenValidator; +import org.eclipse.che.api.workspace.server.token.MachineTokenProvider; import org.eclipse.che.inject.DynaModule; import org.eclipse.che.workspace.infrastructure.docker.DockerInfraModule; import org.eclipse.che.workspace.infrastructure.docker.local.LocalDockerModule; @@ -38,6 +39,7 @@ public class CheWsMasterModule extends AbstractModule { } bind(TokenValidator.class).to(org.eclipse.che.api.local.DummyTokenValidator.class); + bind(MachineTokenProvider.class).to(MachineTokenProvider.EmptyMachineTokenProvider.class); bind(org.eclipse.che.api.workspace.server.stack.StackLoader.class); bind(DataSource.class).toProvider(org.eclipse.che.core.db.h2.H2DataSourceProvider.class); diff --git a/infrastructures/docker/src/main/java/org/eclipse/che/workspace/infrastructure/docker/provisioner/server/UserTokenEnvVarProvider.java b/infrastructures/docker/src/main/java/org/eclipse/che/workspace/infrastructure/docker/provisioner/server/UserTokenEnvVarProvider.java index 190db11e3c..c76dbe95d7 100644 --- a/infrastructures/docker/src/main/java/org/eclipse/che/workspace/infrastructure/docker/provisioner/server/UserTokenEnvVarProvider.java +++ b/infrastructures/docker/src/main/java/org/eclipse/che/workspace/infrastructure/docker/provisioner/server/UserTokenEnvVarProvider.java @@ -12,8 +12,10 @@ package org.eclipse.che.workspace.infrastructure.docker.provisioner.server; import static org.eclipse.che.workspace.infrastructure.docker.DockerMachine.USER_TOKEN; +import javax.inject.Inject; import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity; -import org.eclipse.che.commons.env.EnvironmentContext; +import org.eclipse.che.api.workspace.server.spi.InfrastructureException; +import org.eclipse.che.api.workspace.server.token.MachineTokenProvider; import org.eclipse.che.commons.lang.Pair; /** @@ -21,10 +23,22 @@ import org.eclipse.che.commons.lang.Pair; * access Che master API. * * @author Alexander Garagatyi + * @author Sergii Leshchenko */ public class UserTokenEnvVarProvider implements ServerEnvironmentVariableProvider { + private final MachineTokenProvider machineTokenProvider; + + @Inject + public UserTokenEnvVarProvider(MachineTokenProvider machineTokenProvider) { + this.machineTokenProvider = machineTokenProvider; + } + @Override public Pair get(RuntimeIdentity runtimeIdentity) { - return Pair.of(USER_TOKEN, EnvironmentContext.getCurrent().getSubject().getToken()); + try { + return Pair.of(USER_TOKEN, machineTokenProvider.getToken(runtimeIdentity.getWorkspaceId())); + } catch (InfrastructureException e) { + return null; + } } } diff --git a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/provision/installer/InstallerConfigProvisioner.java b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/provision/installer/InstallerConfigProvisioner.java index ea9b045a27..d2de735bc8 100644 --- a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/provision/installer/InstallerConfigProvisioner.java +++ b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/provision/installer/InstallerConfigProvisioner.java @@ -17,19 +17,17 @@ import static org.slf4j.LoggerFactory.getLogger; import io.fabric8.kubernetes.api.model.Container; import io.fabric8.kubernetes.api.model.EnvVar; import io.fabric8.kubernetes.api.model.Pod; -import java.util.HashMap; import java.util.List; import java.util.Map; import javax.inject.Inject; import javax.inject.Named; -import org.eclipse.che.api.core.model.workspace.config.ServerConfig; import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity; import org.eclipse.che.api.installer.shared.model.Installer; import org.eclipse.che.api.workspace.server.WsAgentMachineFinderUtil; import org.eclipse.che.api.workspace.server.spi.InfrastructureException; import org.eclipse.che.api.workspace.server.spi.InternalEnvironment; import org.eclipse.che.api.workspace.server.spi.InternalMachineConfig; -import org.eclipse.che.workspace.infrastructure.openshift.ServerExposer; +import org.eclipse.che.api.workspace.server.token.MachineTokenProvider; import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment; import org.eclipse.che.workspace.infrastructure.openshift.provision.ConfigurationProvisioner; import org.slf4j.Logger; @@ -51,14 +49,18 @@ import org.slf4j.Logger; * @author Sergii Leshchenko */ public class InstallerConfigProvisioner implements ConfigurationProvisioner { + private static final Logger LOG = getLogger(InstallerConfigProvisioner.class); private static final String ENVIRONMENT_PROPERTY = "environment"; + private final MachineTokenProvider machineTokenProvider; private final String cheServerEndpoint; @Inject - public InstallerConfigProvisioner(@Named("che.api") String cheServerEndpoint) { + public InstallerConfigProvisioner( + MachineTokenProvider machineTokenProvider, @Named("che.api") String cheServerEndpoint) { + this.machineTokenProvider = machineTokenProvider; this.cheServerEndpoint = cheServerEndpoint; } @@ -85,6 +87,11 @@ public class InstallerConfigProvisioner implements ConfigurationProvisioner { // CHE_API is used by installers for agent binary downloading putEnv(container.getEnv(), "CHE_API", cheServerEndpoint); + putEnv( + container.getEnv(), + "USER_TOKEN", + machineTokenProvider.getToken(identity.getWorkspaceId())); + // TODO incorrect place for env variable addition. workspace ID is needed for wsagent server, not installer // WORKSPACE_ID is required only by workspace agent if (devMachineName.equals(machineName)) { diff --git a/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/provision/installer/InstallerConfigProvisionerTest.java b/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/provision/installer/InstallerConfigProvisionerTest.java index c8c81880ce..de2c5afd10 100644 --- a/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/provision/installer/InstallerConfigProvisionerTest.java +++ b/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/provision/installer/InstallerConfigProvisionerTest.java @@ -10,14 +10,11 @@ */ package org.eclipse.che.workspace.infrastructure.openshift.provision.installer; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonList; -import static java.util.Collections.singletonMap; -import static org.mockito.Mockito.atLeast; +import static java.lang.String.format; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; import com.google.common.collect.ImmutableMap; @@ -27,14 +24,18 @@ import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.PodSpec; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; +import org.eclipse.che.api.core.model.workspace.config.ServerConfig; import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity; import org.eclipse.che.api.installer.server.model.impl.InstallerImpl; import org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl; -import org.eclipse.che.api.workspace.server.spi.InfrastructureException; import org.eclipse.che.api.workspace.server.spi.InternalEnvironment; import org.eclipse.che.api.workspace.server.spi.InternalMachineConfig; +import org.eclipse.che.api.workspace.server.token.MachineTokenProvider; import org.eclipse.che.api.workspace.shared.Constants; import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment; import org.mockito.Mock; @@ -47,84 +48,193 @@ import org.testng.annotations.Test; * Tests {@link InstallerConfigProvisioner}. * * @author Anton Korneta + * @author Sergii Leshchenko */ @Listeners(MockitoTestNGListener.class) public class InstallerConfigProvisionerTest { - private static final String CHE_SERVER_ENDPOINT = "localhost:8080"; + private static final String WORKSPACE_ID = "workspace123"; - @Mock private InternalEnvironment environment; - @Mock private OpenShiftEnvironment osEnv; + @Mock private MachineTokenProvider machineTokenProvider; @Mock private RuntimeIdentity runtimeIdentity; private InstallerConfigProvisioner installerConfigProvisioner; @BeforeMethod public void setUp() throws Exception { - installerConfigProvisioner = new InstallerConfigProvisioner(CHE_SERVER_ENDPOINT); + installerConfigProvisioner = + new InstallerConfigProvisioner(machineTokenProvider, CHE_SERVER_ENDPOINT); + + when(runtimeIdentity.getWorkspaceId()).thenReturn(WORKSPACE_ID); } @Test - public void provisionInstallerConfig() throws Exception { - final String podName = "test"; - final Container container = mockContainer("machine"); - final Pod pod = mockPod(podName, singletonList(container)); - when(osEnv.getPods()).thenReturn(ImmutableMap.of(podName, pod)); - final InternalMachineConfig devMachine = mock(InternalMachineConfig.class); - final Map machines = ImmutableMap.of("test/machine", devMachine); + public void provisionWithEnvsFromInstallersAttributes() throws Exception { + //given + final Pod pod = new PodBuilder().setName("test").setContainers("machine").build(); + OpenShiftEnvironment osEnvironment = + OpenShiftEnvironment.builder() + .setPods(ImmutableMap.of(pod.getMetadata().getName(), pod)) + .build(); + + final Map machines = + ImmutableMap.of( + "test/machine", + new MachineConfigBuilder() + .setInstallers( + new InstallerImpl() + .withProperties(ImmutableMap.of("environment", "INSTALLER1=localhost")), + new InstallerImpl() + .withProperties(ImmutableMap.of("environment", "INSTALLER2=agent"))) + .setServer(Constants.SERVER_WS_AGENT_HTTP_REFERENCE, new ServerConfigImpl()) + .build()); + + InternalEnvironment environment = createEnvironment(machines); + + //when + installerConfigProvisioner.provision(environment, osEnvironment, runtimeIdentity); + + //then + Container container = pod.getSpec().getContainers().get(0); + List envs = container.getEnv(); + verifyContainsEnv(envs, "INSTALLER1", "localhost"); + verifyContainsEnv(envs, "INSTALLER2", "agent"); + } + + @Test + public void provisionWithAgentsRequiredEnvs() throws Exception { + //given + when(machineTokenProvider.getToken(WORKSPACE_ID)).thenReturn("superToken"); + + final Pod podWithAgent = new PodBuilder().setName("pod1").setContainers("wsagent").build(); + + final Pod pod = new PodBuilder().setName("pod2").setContainers("machine").build(); + + OpenShiftEnvironment osEnvironment = + OpenShiftEnvironment.builder() + .setPods( + ImmutableMap.of( + podWithAgent.getMetadata().getName(), + podWithAgent, + pod.getMetadata().getName(), + pod)) + .build(); + + final Map machines = + ImmutableMap.of( + "pod1/wsagent", + new MachineConfigBuilder() + .setServer(Constants.SERVER_WS_AGENT_HTTP_REFERENCE, new ServerConfigImpl()) + .build(), + "pod2/machine", + new MachineConfigBuilder() + .setServer(Constants.SERVER_TERMINAL_REFERENCE, new ServerConfigImpl()) + .build()); + + InternalEnvironment environment = createEnvironment(machines); + + //when + installerConfigProvisioner.provision(environment, osEnvironment, runtimeIdentity); + + //then + Container container = podWithAgent.getSpec().getContainers().get(0); + List envs = container.getEnv(); + verifyContainsEnv(envs, "CHE_API", CHE_SERVER_ENDPOINT); + verifyContainsEnv(envs, "USER_TOKEN", "superToken"); + verifyContainsEnv(envs, "CHE_WORKSPACE_ID", WORKSPACE_ID); + + Container container2 = pod.getSpec().getContainers().get(0); + List envs2 = container2.getEnv(); + verifyContainsEnv(envs2, "CHE_API", CHE_SERVER_ENDPOINT); + verifyContainsEnv(envs, "USER_TOKEN", "superToken"); + verifyDoesNotContainEnv(envs2, "CHE_WORKSPACE_ID"); + } + + private InternalEnvironment createEnvironment(Map machines) { + InternalEnvironment environment = mock(InternalEnvironment.class); when(environment.getMachines()).thenReturn(machines); - when(devMachine.getServers()) - .thenReturn(singletonMap(Constants.SERVER_WS_AGENT_HTTP_REFERENCE, new ServerConfigImpl())); - final InstallerImpl installer = mock(InstallerImpl.class); - final List installers = singletonList(installer); - when(devMachine.getInstallers()).thenReturn(installers); - final Map envVars = ImmutableMap.of("environment", "CHE_HOST=localhost"); - when(installer.getProperties()).thenReturn(envVars); - final List envVariables = new ArrayList<>(); - when(container.getEnv()).thenReturn(envVariables); - when(installer.getServers()).thenReturn(emptyMap()); - - installerConfigProvisioner.provision(environment, osEnv, runtimeIdentity); - - verify(osEnv, times(1)).getPods(); - verify(runtimeIdentity, atLeast(1)).getWorkspaceId(); - verify(environment, times(2)).getMachines(); - assertTrue(envVariables.size() == 3); + return environment; } - @Test(expectedExceptions = InfrastructureException.class) - public void throwsInfrastructureExceptionWhenInstallerExceptionOccurs() throws Exception { - final String podName = "test"; - final Pod pod = mockPod(podName, "machine"); - when(osEnv.getPods()).thenReturn(ImmutableMap.of(podName, pod)); - when(environment.getMachines()) - .thenReturn(ImmutableMap.of("test/machine", mock(InternalMachineConfig.class))); + private void verifyDoesNotContainEnv(List envs, String name) { + Optional env = envs.stream().filter(e -> e.getName().equals(name)).findAny(); - installerConfigProvisioner.provision(environment, osEnv, runtimeIdentity); + assertFalse(env.isPresent(), format("Environment variable '%s' found", name)); } - private static Pod mockPod(String podName, List containers) { - final Pod pod = mock(Pod.class); - final ObjectMeta podMeta = mock(ObjectMeta.class); - when(pod.getMetadata()).thenReturn(podMeta); - when(podMeta.getName()).thenReturn(podName); - final PodSpec podSpec = mock(PodSpec.class); - when(pod.getSpec()).thenReturn(podSpec); - when(podSpec.getContainers()).thenReturn(containers); - return pod; + private void verifyContainsEnv(List envs, String name, String expectedValue) { + Optional env = envs.stream().filter(e -> e.getName().equals(name)).findAny(); + + assertTrue(env.isPresent(), format("Expected environment variable '%s' not found", name)); + + String actualValue = env.get().getValue(); + assertEquals( + actualValue, + expectedValue, + format( + "Environment variable '%s' expected with " + "value '%s' but found with '%s'", + name, expectedValue, actualValue)); } - private static Pod mockPod(String podName, String... containerNames) { - final List containers = new ArrayList<>(); - for (String containerName : containerNames) { - containers.add(mockContainer(containerName)); + private static class MachineConfigBuilder { + + private List installers = new ArrayList<>(); + private Map servers = new HashMap<>(); + + MachineConfigBuilder setInstallers(InstallerImpl... installers) { + this.installers = Arrays.asList(installers); + return this; + } + + MachineConfigBuilder setServer(String name, ServerConfig server) { + this.servers.put(name, server); + return this; + } + + InternalMachineConfig build() { + final InternalMachineConfig machineConfig = mock(InternalMachineConfig.class); + when(machineConfig.getInstallers()).thenReturn(installers); + when(machineConfig.getServers()).thenReturn(servers); + return machineConfig; } - return mockPod(podName, containers); } - private static Container mockContainer(String name) { - final Container container = mock(Container.class); - when(container.getName()).thenReturn(name); - return container; + private static class PodBuilder { + + private String name; + private List containersNames; + + PodBuilder setName(String name) { + this.name = name; + return this; + } + + PodBuilder setContainers(String... names) { + this.containersNames = Arrays.asList(names); + return this; + } + + Pod build() { + final Pod pod = mock(Pod.class); + final ObjectMeta podMeta = mock(ObjectMeta.class); + when(pod.getMetadata()).thenReturn(podMeta); + when(podMeta.getName()).thenReturn(name); + + final PodSpec podSpec = mock(PodSpec.class); + when(pod.getSpec()).thenReturn(podSpec); + + final List containers = new ArrayList<>(); + for (String containerName : containersNames) { + final Container container = mock(Container.class); + when(container.getName()).thenReturn(containerName); + when(container.getEnv()).thenReturn(new ArrayList<>()); + + containers.add(container); + } + + when(podSpec.getContainers()).thenReturn(containers); + + return pod; + } } } diff --git a/multiuser/infrastructures/openshift/pom.xml b/multiuser/infrastructures/openshift/pom.xml deleted file mode 100644 index a16370125b..0000000000 --- a/multiuser/infrastructures/openshift/pom.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - 4.0.0 - - che-multiuser-infrastructures-parent - org.eclipse.che.multiuser - 5.19.0-SNAPSHOT - ../pom.xml - - multiuser-infrastructure-openshift - 5.19.0-SNAPSHOT - jar - Che Multiuser OpenShift Infrastructure - - - io.fabric8 - kubernetes-model - - - javax.inject - javax.inject - - - org.eclipse.che - infrastructure-openshift - - - org.eclipse.che.core - che-core-api-core - - - org.eclipse.che.core - che-core-api-model - - - org.eclipse.che.core - che-core-api-workspace - - - org.eclipse.che.multiuser - che-multiuser-machine-authentication - - - diff --git a/multiuser/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/provision/installer/MultiuserInstallerConfigProvisioner.java b/multiuser/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/provision/installer/MultiuserInstallerConfigProvisioner.java deleted file mode 100644 index 192c3a99a9..0000000000 --- a/multiuser/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/provision/installer/MultiuserInstallerConfigProvisioner.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2012-2017 Red Hat, Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ -package org.eclipse.che.workspace.infrastructure.openshift.provision.installer; - -import io.fabric8.kubernetes.api.model.Container; -import javax.inject.Inject; -import javax.inject.Named; -import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity; -import org.eclipse.che.api.workspace.server.spi.InternalMachineConfig; -import org.eclipse.che.commons.env.EnvironmentContext; -import org.eclipse.che.multiuser.machine.authentication.server.MachineTokenRegistry; -import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment; - -/** - * //TODO Fix java doc - * - * @author Sergii Leshchenko - */ -public class MultiuserInstallerConfigProvisioner extends InstallerConfigProvisioner { - - private final MachineTokenRegistry tokenRegistry; - - @Inject - public MultiuserInstallerConfigProvisioner( - @Named("che.api") String cheServerEndpoint, MachineTokenRegistry tokenRegistry) { - super(cheServerEndpoint); - this.tokenRegistry = tokenRegistry; - } - - @Override - protected void doProvisionContainer( - OpenShiftEnvironment osEnv, - Container container, - RuntimeIdentity identity, - String machineName, - InternalMachineConfig machineConf) { - super.doProvisionContainer(osEnv, container, identity, machineName, machineConf); - - String currentUserId = EnvironmentContext.getCurrent().getSubject().getUserId(); - String machineToken = tokenRegistry.generateToken(currentUserId, identity.getWorkspaceId()); - putEnv(container.getEnv(), "USER_TOKEN", machineToken); - } -} diff --git a/multiuser/infrastructures/pom.xml b/multiuser/infrastructures/pom.xml deleted file mode 100644 index 72b51c3d03..0000000000 --- a/multiuser/infrastructures/pom.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - 4.0.0 - - che-multiuser-parent - org.eclipse.che.multiuser - 5.19.0-SNAPSHOT - ../pom.xml - - che-multiuser-infrastructures-parent - 5.19.0-SNAPSHOT - pom - Che Multiuser Infrastructures Parent - - openshift - - diff --git a/multiuser/machine-auth/che-multiuser-machine-authentication/src/main/java/org/eclipse/che/multiuser/machine/authentication/server/MachineTokenProviderImpl.java b/multiuser/machine-auth/che-multiuser-machine-authentication/src/main/java/org/eclipse/che/multiuser/machine/authentication/server/MachineTokenProviderImpl.java new file mode 100644 index 0000000000..2338ba1ab0 --- /dev/null +++ b/multiuser/machine-auth/che-multiuser-machine-authentication/src/main/java/org/eclipse/che/multiuser/machine/authentication/server/MachineTokenProviderImpl.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.multiuser.machine.authentication.server; + +import javax.inject.Inject; +import javax.inject.Singleton; +import org.eclipse.che.api.core.NotFoundException; +import org.eclipse.che.api.workspace.server.token.MachineTokenException; +import org.eclipse.che.api.workspace.server.token.MachineTokenProvider; +import org.eclipse.che.commons.env.EnvironmentContext; + +/** + * Provides machine token from {@link MachineTokenRegistry}. + * + *

Note that {@link MachineTokenRegistry} provides different tokens for different users. Token of + * current user will be provided for agents. + * + * @author Sergii Leshchenko + */ +@Singleton +public class MachineTokenProviderImpl implements MachineTokenProvider { + private final MachineTokenRegistry tokenRegistry; + + @Inject + public MachineTokenProviderImpl(MachineTokenRegistry tokenRegistry) { + this.tokenRegistry = tokenRegistry; + } + + @Override + public String getToken(String workspaceId) throws MachineTokenException { + String currentUserId = EnvironmentContext.getCurrent().getSubject().getUserId(); + try { + return tokenRegistry.getOrCreateToken(currentUserId, workspaceId); + } catch (NotFoundException e) { + throw new MachineTokenException(e.getMessage(), e); + } + } +} diff --git a/multiuser/pom.xml b/multiuser/pom.xml index 59e3949515..b4d1abf416 100644 --- a/multiuser/pom.xml +++ b/multiuser/pom.xml @@ -30,7 +30,6 @@ keycloak machine-auth personal-account - infrastructures integration-tests diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/hc/ServersReadinessChecker.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/hc/ServersReadinessChecker.java index 7ced6faf78..364dff990c 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/hc/ServersReadinessChecker.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/hc/ServersReadinessChecker.java @@ -27,6 +27,7 @@ import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity; import org.eclipse.che.api.core.model.workspace.runtime.Server; import org.eclipse.che.api.workspace.server.spi.InfrastructureException; import org.eclipse.che.api.workspace.server.spi.InternalInfrastructureException; +import org.eclipse.che.api.workspace.server.token.MachineTokenProvider; /** * Checks readiness of servers of a machine. diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/token/MachineTokenException.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/token/MachineTokenException.java new file mode 100644 index 0000000000..cbfdb0f82f --- /dev/null +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/token/MachineTokenException.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.api.workspace.server.token; + +import org.eclipse.che.api.workspace.server.spi.InfrastructureException; + +/** + * An exception thrown by {@link MachineTokenProvider} when an error occurred during token fetching + * operation execution. + * + * @author Sergii Leshchenko + */ +public class MachineTokenException extends InfrastructureException { + public MachineTokenException(String message) { + super(message); + } + + public MachineTokenException(Exception e) { + super(e); + } + + public MachineTokenException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/token/MachineTokenProvider.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/token/MachineTokenProvider.java new file mode 100644 index 0000000000..8b945a3337 --- /dev/null +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/token/MachineTokenProvider.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.api.workspace.server.token; + +/** + * Provides machine token that should be used for access to workspace master from machine. + * + * @author Sergii Leshchenko + */ +public interface MachineTokenProvider { + + /** + * Returns machine token for specified workspace. + * + * @param workspaceId identifier of workspace to fetch token + * @throws MachineTokenException when any exception occurs on token fetching + */ + String getToken(String workspaceId) throws MachineTokenException; + + /** Returns empty string as machine token. */ + class EmptyMachineTokenProvider implements MachineTokenProvider { + @Override + public String getToken(String workspaceId) { + return ""; + } + } +}