Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CODENVY-804 : Use of userManager to get the userId (when injecting ssh keys) #3036

Merged
merged 1 commit into from
Nov 10, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions plugins/plugin-machine/che-plugin-machine-ext-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-ssh</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-user</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-workspace</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

@DynaModule
public class MachineModule extends AbstractModule {

@Override
protected void configure() {
bind(KeysInjector.class).asEagerSingleton();
bind(WorkspaceSshKeys.class).asEagerSingleton();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@

import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.core.model.user.User;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.core.notification.EventSubscriber;
import org.eclipse.che.api.environment.server.CheEnvironmentEngine;
import org.eclipse.che.api.machine.server.spi.Instance;
import org.eclipse.che.api.machine.shared.dto.event.MachineStatusEvent;
import org.eclipse.che.api.ssh.server.SshManager;
import org.eclipse.che.api.ssh.server.model.impl.SshPairImpl;
import org.eclipse.che.api.user.server.UserManager;
import org.eclipse.che.plugin.docker.client.DockerConnector;
import org.eclipse.che.plugin.docker.client.Exec;
import org.eclipse.che.plugin.docker.client.LogMessage;
Expand Down Expand Up @@ -47,18 +49,21 @@ public class KeysInjector {
private final EventService eventService;
private final DockerConnector docker;
private final SshManager sshManager;
private final UserManager userManager;
// TODO replace with WorkspaceManager
private final CheEnvironmentEngine environmentEngine;

@Inject
public KeysInjector(EventService eventService,
DockerConnector docker,
SshManager sshManager,
CheEnvironmentEngine environmentEngine) {
CheEnvironmentEngine environmentEngine,
UserManager userManager) {
this.eventService = eventService;
this.docker = docker;
this.sshManager = sshManager;
this.environmentEngine = environmentEngine;
this.userManager = userManager;
}

@PostConstruct
Expand All @@ -77,8 +82,19 @@ public void onEvent(MachineStatusEvent event) {
}

try {
// get userid
final String userId;
try {
final User user = userManager.getByName(machine.getOwner());
userId = user.getId();
} catch (NotFoundException e) {
LOG.error("User with name {} associated to machine not found", machine.getOwner());
return;
}


// get machine keypairs
List<SshPairImpl> sshPairs = sshManager.getPairs(machine.getOwner(), "machine");
List<SshPairImpl> sshPairs = sshManager.getPairs(userId, "machine");
final List<String> publicMachineKeys = sshPairs.stream()
.filter(sshPair -> sshPair.getPublicKey() != null)
.map(SshPairImpl::getPublicKey)
Expand All @@ -87,7 +103,7 @@ public void onEvent(MachineStatusEvent event) {
// get workspace keypair (if any)
SshPairImpl sshWorkspacePair = null;
try {
sshWorkspacePair = sshManager.getPair(machine.getOwner(), "workspace", event.getWorkspaceId());
sshWorkspacePair = sshManager.getPair(userId, "workspace", event.getWorkspaceId());
} catch (NotFoundException e) {
LOG.debug("No ssh key associated to the workspace", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@
import org.eclipse.che.api.core.ConflictException;
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.core.model.user.User;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.core.notification.EventSubscriber;
import org.eclipse.che.api.ssh.server.SshManager;
import org.eclipse.che.api.user.server.UserManager;
import org.eclipse.che.api.workspace.server.event.WorkspaceCreatedEvent;
import org.eclipse.che.api.workspace.server.event.WorkspaceRemovedEvent;
import org.eclipse.che.commons.env.EnvironmentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -49,6 +50,11 @@ public class WorkspaceSshKeys {
*/
private final SshManager sshManager;

/**
* User manager used to get user from given namespace.
*/
private final UserManager userManager;


/**
* Default injection by using event service and ssh manager.
Expand All @@ -59,9 +65,10 @@ public class WorkspaceSshKeys {
* used to generate/remove default ssh keys
*/
@Inject
public WorkspaceSshKeys(final EventService eventService, final SshManager sshManager) {
public WorkspaceSshKeys(final EventService eventService, final SshManager sshManager, final UserManager userManager) {
this.eventService = eventService;
this.sshManager = sshManager;
this.userManager = userManager;
}

/**
Expand All @@ -72,9 +79,18 @@ public void start() {
eventService.subscribe(new EventSubscriber<WorkspaceCreatedEvent>() {
@Override
public void onEvent(WorkspaceCreatedEvent workspaceCreatedEvent) {
final String userId;
try {
final User user = userManager.getByName(workspaceCreatedEvent.getWorkspace().getNamespace());
userId = user.getId();
} catch (NotFoundException | ServerException e) {
LOG.error("Unable to get owner of the workspace {} with namespace {}", workspaceCreatedEvent.getWorkspace().getId(), workspaceCreatedEvent.getWorkspace().getNamespace());
return;
}

// Register default SSH keypair for this workspace.
try {
sshManager.generatePair(EnvironmentContext.getCurrent().getSubject().getUserId(), "workspace",
sshManager.generatePair(userId, "workspace",
workspaceCreatedEvent.getWorkspace().getId());
} catch (ServerException | ConflictException e) {
// Conflict shouldn't happen as workspace id is new each time.
Expand All @@ -87,9 +103,19 @@ public void onEvent(WorkspaceCreatedEvent workspaceCreatedEvent) {
eventService.subscribe(new EventSubscriber<WorkspaceRemovedEvent>() {
@Override
public void onEvent(WorkspaceRemovedEvent workspaceRemovedEvent) {

final String userId;
try {
final User user = userManager.getByName(workspaceRemovedEvent.getWorkspace().getNamespace());
userId = user.getId();
} catch (NotFoundException | ServerException e) {
LOG.error("Unable to get owner of the workspace {} with namespace {}", workspaceRemovedEvent.getWorkspace().getId(), workspaceRemovedEvent.getWorkspace().getNamespace());
return;
}

// Unregister default SSH keypair for this workspace (if any)
try {
sshManager.removePair(EnvironmentContext.getCurrent().getSubject().getUserId(), "workspace",
sshManager.removePair(userId, "workspace",
workspaceRemovedEvent.getWorkspace().getId());
} catch (NotFoundException e) {
LOG.debug("Do not remove default keypair from workspace {} as it is not existing (workspace ID {})",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.model.machine.MachineRuntimeInfo;
import org.eclipse.che.api.core.model.user.User;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.core.notification.EventSubscriber;
import org.eclipse.che.api.core.util.LineConsumer;
Expand All @@ -20,6 +21,7 @@
import org.eclipse.che.api.machine.shared.dto.event.MachineStatusEvent;
import org.eclipse.che.api.ssh.server.SshManager;
import org.eclipse.che.api.ssh.server.model.impl.SshPairImpl;
import org.eclipse.che.api.user.server.UserManager;
import org.eclipse.che.plugin.docker.client.DockerConnector;
import org.eclipse.che.plugin.docker.client.Exec;
import org.eclipse.che.plugin.docker.client.LogMessage;
Expand Down Expand Up @@ -59,7 +61,8 @@
public class KeysInjectorTest {
private static final String WORKSPACE_ID = "workspace123";
private static final String MACHINE_ID = "machine123";
private static final String OWNER_ID = "user123";
private static final String OWNER_NAME = "user";
private static final String USER_ID = "user123";
private static final String CONTAINER_ID = "container123";
private static final String EXEC_ID = "exec123";

Expand All @@ -80,13 +83,17 @@ public class KeysInjectorTest {
LineConsumer lineConsumer;

@Mock
EventService eventService;
EventService eventService;
@Mock
DockerConnector docker;
DockerConnector docker;
@Mock
CheEnvironmentEngine environmentEngine;
@Mock
SshManager sshManager;
SshManager sshManager;
@Mock
UserManager userManager;
@Mock
User user;

EventSubscriber<MachineStatusEvent> subscriber;

Expand All @@ -100,14 +107,17 @@ public void setUp() throws Exception {
when(machineRuntime.getProperties()).thenReturn(metadataProperties);

when(environmentEngine.getMachine(WORKSPACE_ID, MACHINE_ID)).thenReturn(instance);
when(instance.getOwner()).thenReturn(OWNER_ID);
when(instance.getOwner()).thenReturn(OWNER_NAME);
when(instance.getRuntime()).thenReturn(machineRuntime);
when(instance.getLogger()).thenReturn(lineConsumer);

keysInjector.start();
verify(eventService).subscribe(subscriberCaptor.capture());
subscriber = subscriberCaptor.getValue();

when(userManager.getByName(eq(OWNER_NAME))).thenReturn(user);
when(user.getId()).thenReturn(USER_ID);

when(docker.createExec(any(CreateExecParams.class))).thenReturn(exec);
when(exec.getId()).thenReturn(EXEC_ID);
}
Expand All @@ -128,39 +138,39 @@ public void shouldNotInjectSshKeysWhenThereAreNotAnyPair() throws Exception {
.withWorkspaceId(WORKSPACE_ID));

verify(environmentEngine).getMachine(eq(WORKSPACE_ID), eq(MACHINE_ID));
verify(sshManager).getPairs(eq(OWNER_ID), eq("machine"));
verify(sshManager).getPair(eq(OWNER_ID), eq("workspace"), eq(WORKSPACE_ID));
verify(sshManager).getPairs(eq(USER_ID), eq("machine"));
verify(sshManager).getPair(eq(USER_ID), eq("workspace"), eq(WORKSPACE_ID));
verifyZeroInteractions(docker, environmentEngine, sshManager);
}

@Test
public void shouldNotInjectSshKeysWhenThereAreNotAnyPairWithPublicKey() throws Exception {
when(sshManager.getPairs(anyString(), anyString()))
.thenReturn(Collections.singletonList(new SshPairImpl(OWNER_ID, "machine", "myPair", null, null)));
.thenReturn(Collections.singletonList(new SshPairImpl(USER_ID, "machine", "myPair", null, null)));

subscriber.onEvent(newDto(MachineStatusEvent.class).withEventType(MachineStatusEvent.EventType.RUNNING)
.withMachineId(MACHINE_ID)
.withWorkspaceId(WORKSPACE_ID));

verify(environmentEngine).getMachine(eq(WORKSPACE_ID), eq(MACHINE_ID));
verify(sshManager).getPairs(eq(OWNER_ID), eq("machine"));
verify(sshManager).getPair(eq(OWNER_ID), eq("workspace"), eq(WORKSPACE_ID));
verify(sshManager).getPairs(eq(USER_ID), eq("machine"));
verify(sshManager).getPair(eq(USER_ID), eq("workspace"), eq(WORKSPACE_ID));
verifyZeroInteractions(docker, environmentEngine, sshManager);
}

@Test
public void shouldInjectSshKeysWhenThereAreAnyPairWithNotNullPublicKey() throws Exception {
when(sshManager.getPairs(anyString(), anyString()))
.thenReturn(Arrays.asList(new SshPairImpl(OWNER_ID, "machine", "myPair", "publicKey1", null),
new SshPairImpl(OWNER_ID, "machine", "myPair", "publicKey2", null)));
.thenReturn(Arrays.asList(new SshPairImpl(USER_ID, "machine", "myPair", "publicKey1", null),
new SshPairImpl(USER_ID, "machine", "myPair", "publicKey2", null)));

subscriber.onEvent(newDto(MachineStatusEvent.class).withEventType(MachineStatusEvent.EventType.RUNNING)
.withMachineId(MACHINE_ID)
.withWorkspaceId(WORKSPACE_ID));

verify(environmentEngine).getMachine(eq(WORKSPACE_ID), eq(MACHINE_ID));
verify(sshManager).getPairs(eq(OWNER_ID), eq("machine"));
verify(sshManager).getPair(eq(OWNER_ID), eq("workspace"), eq(WORKSPACE_ID));
verify(sshManager).getPairs(eq(USER_ID), eq("machine"));
verify(sshManager).getPair(eq(USER_ID), eq("workspace"), eq(WORKSPACE_ID));

ArgumentCaptor<CreateExecParams> argumentCaptor = ArgumentCaptor.forClass(CreateExecParams.class);
verify(docker).createExec(argumentCaptor.capture());
Expand All @@ -183,7 +193,7 @@ public void shouldInjectSshKeysWhenThereIsOnlyWorkspaceKey() throws Exception {

// workspace keypair
when(sshManager.getPair(anyString(), eq("workspace"), anyString()))
.thenReturn(new SshPairImpl(OWNER_ID, "workspace", WORKSPACE_ID, "publicKeyWorkspace", null));
.thenReturn(new SshPairImpl(USER_ID, "workspace", WORKSPACE_ID, "publicKeyWorkspace", null));


subscriber.onEvent(newDto(MachineStatusEvent.class).withEventType(MachineStatusEvent.EventType.RUNNING)
Expand All @@ -192,8 +202,8 @@ public void shouldInjectSshKeysWhenThereIsOnlyWorkspaceKey() throws Exception {

verify(environmentEngine).getMachine(eq(WORKSPACE_ID), eq(MACHINE_ID));
// check calls for machine and workspace ssh pairs
verify(sshManager).getPairs(eq(OWNER_ID), eq("machine"));
verify(sshManager).getPair(eq(OWNER_ID), eq("workspace"), eq(WORKSPACE_ID));
verify(sshManager).getPairs(eq(USER_ID), eq("machine"));
verify(sshManager).getPair(eq(USER_ID), eq("workspace"), eq(WORKSPACE_ID));

ArgumentCaptor<CreateExecParams> argumentCaptor = ArgumentCaptor.forClass(CreateExecParams.class);
verify(docker).createExec(argumentCaptor.capture());
Expand All @@ -211,11 +221,11 @@ public void shouldInjectSshKeysWhenThereIsOnlyWorkspaceKey() throws Exception {
public void shouldInjectSshKeysWhenThereIsNoPublicWorkspaceKeyButMachineKeys() throws Exception {
// no machine key pairs
when(sshManager.getPairs(anyString(), eq("machine")))
.thenReturn(Arrays.asList(new SshPairImpl(OWNER_ID, "machine", "myPair", "publicKey1", null)));
.thenReturn(Arrays.asList(new SshPairImpl(USER_ID, "machine", "myPair", "publicKey1", null)));

// workspace keypair without public key
when(sshManager.getPair(anyString(), eq("workspace"), anyString()))
.thenReturn(new SshPairImpl(OWNER_ID, "workspace", WORKSPACE_ID, null, null));
.thenReturn(new SshPairImpl(USER_ID, "workspace", WORKSPACE_ID, null, null));


subscriber.onEvent(newDto(MachineStatusEvent.class).withEventType(MachineStatusEvent.EventType.RUNNING)
Expand All @@ -224,8 +234,8 @@ public void shouldInjectSshKeysWhenThereIsNoPublicWorkspaceKeyButMachineKeys() t

verify(environmentEngine).getMachine(eq(WORKSPACE_ID), eq(MACHINE_ID));
// check calls for machine and workspace ssh pairs
verify(sshManager).getPairs(eq(OWNER_ID), eq("machine"));
verify(sshManager).getPair(eq(OWNER_ID), eq("workspace"), eq(WORKSPACE_ID));
verify(sshManager).getPairs(eq(USER_ID), eq("machine"));
verify(sshManager).getPair(eq(USER_ID), eq("workspace"), eq(WORKSPACE_ID));

ArgumentCaptor<CreateExecParams> argumentCaptor = ArgumentCaptor.forClass(CreateExecParams.class);
verify(docker).createExec(argumentCaptor.capture());
Expand Down Expand Up @@ -256,16 +266,16 @@ public void shouldNotInjectSshKeysWhenThereIsNoWorkspaceKey() throws Exception {

verify(environmentEngine).getMachine(eq(WORKSPACE_ID), eq(MACHINE_ID));
// check calls for machine and workspace ssh pairs
verify(sshManager).getPairs(eq(OWNER_ID), eq("machine"));
verify(sshManager).getPair(eq(OWNER_ID), eq("workspace"), eq(WORKSPACE_ID));
verify(sshManager).getPairs(eq(USER_ID), eq("machine"));
verify(sshManager).getPair(eq(USER_ID), eq("workspace"), eq(WORKSPACE_ID));

verifyZeroInteractions(docker, environmentEngine, sshManager);
}

@Test
public void shouldSendMessageInMachineLoggerWhenSomeErrorOcursOnKeysInjection() throws Exception {
when(sshManager.getPairs(anyString(), anyString()))
.thenReturn(Collections.singletonList(new SshPairImpl(OWNER_ID, "machine", "myPair", "publicKey1", null)));
.thenReturn(Collections.singletonList(new SshPairImpl(USER_ID, "machine", "myPair", "publicKey1", null)));
when(logMessage.getType()).thenReturn(LogMessage.Type.STDERR);
when(logMessage.getContent()).thenReturn("FAILED");

Expand Down
Loading