feat: Removing dependency on the usr, account, profile db tables

Signed-off-by: Ilya Buziuk <ibuziuk@redhat.com>
pull/416/head
Ilya Buziuk 2022-11-29 14:42:01 +01:00 committed by Ilya Buziuk
parent 0337316203
commit a59cc49a7f
13 changed files with 35 additions and 514 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2021 Red Hat, Inc.
* Copyright (c) 2012-2022 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/
@ -41,10 +41,8 @@ import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.inject.Named;
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.core.model.user.User;
import org.eclipse.che.api.core.model.workspace.Workspace;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.user.server.PreferenceManager;
@ -275,30 +273,21 @@ public class KubernetesNamespaceFactory {
* the context.
*
* @param identity the identity of the workspace runtime
* @param userName the user name
* @return true if the namespace can be created, false if the namespace is expected to already
* exist
* @throws InfrastructureException on failure
*/
protected boolean canCreateNamespace(RuntimeIdentity identity) throws InfrastructureException {
protected boolean canCreateNamespace(RuntimeIdentity identity, String userName)
throws InfrastructureException {
if (!namespaceCreationAllowed) {
return false;
}
// we need to make sure that the provided namespace is indeed the one provided by our
// configuration
User owner;
try {
owner = userManager.getById(identity.getOwnerId());
} catch (NotFoundException | ServerException e) {
throw new InfrastructureException(
"Failed to resolve workspace owner. Cause: " + e.getMessage(), e);
}
String requiredNamespace = identity.getInfrastructureNamespace();
NamespaceResolutionContext resolutionContext =
new NamespaceResolutionContext(
identity.getWorkspaceId(), identity.getOwnerId(), owner.getName());
new NamespaceResolutionContext(identity.getWorkspaceId(), identity.getOwnerId(), userName);
String resolvedDefaultNamespace = evaluateNamespaceName(resolutionContext);
@ -320,14 +309,14 @@ public class KubernetesNamespaceFactory {
KubernetesNamespace namespace = get(identity);
var subject = EnvironmentContext.getCurrent().getSubject();
var userName = subject.getUserName();
NamespaceResolutionContext resolutionCtx =
new NamespaceResolutionContext(
identity.getWorkspaceId(), subject.getUserId(), subject.getUserName());
new NamespaceResolutionContext(identity.getWorkspaceId(), subject.getUserId(), userName);
Map<String, String> namespaceAnnotationsEvaluated =
evaluateAnnotationPlaceholders(resolutionCtx);
namespace.prepare(
canCreateNamespace(identity),
canCreateNamespace(identity, userName),
labelNamespaces ? namespaceLabels : emptyMap(),
annotateNamespaces ? namespaceAnnotationsEvaluated : emptyMap());
@ -515,9 +504,6 @@ public class KubernetesNamespaceFactory {
"Evaluated the namespace for workspace {} using the namespace default to {}",
resolutionCtx.getWorkspaceId(),
namespace);
recordEvaluatedNamespaceName(namespace, resolutionCtx);
return namespace;
}

View File

@ -11,7 +11,6 @@
*/
package org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.Collections.singletonMap;
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.AbstractWorkspaceServiceAccount.GIT_USERDATA_CONFIGMAP_NAME;
@ -21,9 +20,6 @@ import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
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.factory.server.scm.GitUserData;
import org.eclipse.che.api.factory.server.scm.GitUserDataFetcher;
import org.eclipse.che.api.factory.server.scm.exception.ScmCommunicationException;
@ -31,8 +27,6 @@ import org.eclipse.che.api.factory.server.scm.exception.ScmUnauthorizedException
import org.eclipse.che.api.user.server.UserManager;
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.KubernetesClientFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -80,17 +74,6 @@ public class GitconfigUserDataConfigurator implements NamespaceConfigurator {
"true",
"controller.devfile.io/watch-configmap",
"true");
if (gitUserData == null) {
Subject cheSubject = EnvironmentContext.getCurrent().getSubject();
try {
User user = userManager.getById(cheSubject.getUserId());
if (!isNullOrEmpty(user.getName()) && !isNullOrEmpty(user.getEmail())) {
gitUserData = new GitUserData(user.getName(), user.getEmail());
}
} catch (NotFoundException | ServerException e) {
LOG.error(e.getMessage());
}
}
if (gitUserData != null
&& client
.configMaps()

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2021 Red Hat, Inc.
* Copyright (c) 2012-2022 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/
@ -11,22 +11,10 @@
*/
package org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator;
import static org.eclipse.che.workspace.infrastructure.kubernetes.Constants.DEV_WORKSPACE_MOUNT_AS_ANNOTATION;
import static org.eclipse.che.workspace.infrastructure.kubernetes.Constants.DEV_WORKSPACE_MOUNT_LABEL;
import static org.eclipse.che.workspace.infrastructure.kubernetes.Constants.DEV_WORKSPACE_MOUNT_PATH_ANNOTATION;
import com.google.common.annotations.VisibleForTesting;
import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.api.model.SecretBuilder;
import io.fabric8.kubernetes.client.KubernetesClientException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
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.user.server.PreferenceManager;
import org.eclipse.che.api.user.server.UserManager;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
@ -39,6 +27,7 @@ import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesClientFacto
*
* @author Pavol Baran
*/
@Deprecated
@Singleton
public class UserPreferencesConfigurator implements NamespaceConfigurator {
private static final String USER_PREFERENCES_SECRET_NAME = "user-preferences";
@ -59,62 +48,10 @@ public class UserPreferencesConfigurator implements NamespaceConfigurator {
this.preferenceManager = preferenceManager;
}
/** 'user-preferences' secret is obsolete and not used anymore by DevWorkspaces */
@Override
public void configure(NamespaceResolutionContext namespaceResolutionContext, String namespaceName)
throws InfrastructureException {
Secret userPreferencesSecret = preparePreferencesSecret(namespaceResolutionContext);
try {
clientFactory
.create()
.secrets()
.inNamespace(namespaceName)
.createOrReplace(userPreferencesSecret);
} catch (KubernetesClientException e) {
throw new InfrastructureException(
"Error occurred while trying to create user preferences secret.", e);
}
}
private Secret preparePreferencesSecret(NamespaceResolutionContext namespaceResolutionContext)
throws InfrastructureException {
Base64.Encoder enc = Base64.getEncoder();
User user;
Map<String, String> preferences;
try {
user = userManager.getById(namespaceResolutionContext.getUserId());
preferences = preferenceManager.find(user.getId());
} catch (NotFoundException | ServerException e) {
throw new InfrastructureException(
String.format(
"Preferences of user with id:%s cannot be retrieved.",
namespaceResolutionContext.getUserId()),
e);
}
if (preferences == null || preferences.isEmpty()) {
throw new InfrastructureException(
String.format(
"Preferences of user with id:%s are empty. Cannot create user preferences secrets.",
namespaceResolutionContext.getUserId()));
}
Map<String, String> preferencesEncoded = new HashMap<>();
preferences.forEach(
(key, value) ->
preferencesEncoded.put(
normalizePreferenceName(key), enc.encodeToString(value.getBytes())));
return new SecretBuilder()
.addToData(preferencesEncoded)
.withNewMetadata()
.withName(USER_PREFERENCES_SECRET_NAME)
.addToLabels(DEV_WORKSPACE_MOUNT_LABEL, "true")
.addToAnnotations(DEV_WORKSPACE_MOUNT_AS_ANNOTATION, "file")
.addToAnnotations(DEV_WORKSPACE_MOUNT_PATH_ANNOTATION, USER_PREFERENCES_SECRET_MOUNT_PATH)
.endMetadata()
.build();
}
throws InfrastructureException {}
/**
* Some preferences names are not compatible with k8s restrictions on key field in secret. The

View File

@ -24,9 +24,6 @@ import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
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.user.server.UserManager;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.NamespaceResolutionContext;
@ -70,21 +67,15 @@ public class UserProfileConfigurator implements NamespaceConfigurator {
private Secret prepareProfileSecret(NamespaceResolutionContext namespaceResolutionContext)
throws InfrastructureException {
User user;
try {
user = userManager.getById(namespaceResolutionContext.getUserId());
} catch (NotFoundException | ServerException e) {
throw new InfrastructureException(
String.format(
"Could not find current user with id:%s.", namespaceResolutionContext.getUserId()),
e);
}
var userId = namespaceResolutionContext.getUserId();
var userName = namespaceResolutionContext.getUserName();
var userEmail = userName + "@che";
Base64.Encoder enc = Base64.getEncoder();
final Map<String, String> userProfileData = new HashMap<>();
userProfileData.put("id", enc.encodeToString(user.getId().getBytes()));
userProfileData.put("name", enc.encodeToString(user.getName().getBytes()));
userProfileData.put("email", enc.encodeToString(user.getEmail().getBytes()));
userProfileData.put("id", enc.encodeToString(userId.getBytes()));
userProfileData.put("name", enc.encodeToString(userName.getBytes()));
userProfileData.put("email", enc.encodeToString(userEmail.getBytes()));
return new SecretBuilder()
.addToData(userProfileData)

View File

@ -12,8 +12,6 @@
package org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator;
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.AbstractWorkspaceServiceAccount.GIT_USERDATA_CONFIGMAP_NAME;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
@ -25,9 +23,6 @@ import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
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.factory.server.scm.GitUserData;
import org.eclipse.che.api.factory.server.scm.GitUserDataFetcher;
import org.eclipse.che.api.factory.server.scm.exception.ScmCommunicationException;
@ -95,19 +90,6 @@ public class GitconfigUserdataConfiguratorTest {
.get());
}
@Test
public void doNothingWhenGitUserDataAndCheUserAreNull()
throws InfrastructureException, ServerException, NotFoundException {
// when
when(userManager.getById(anyString())).thenThrow(new NotFoundException("not found"));
configurator.configure(namespaceResolutionContext, TEST_NAMESPACE_NAME);
// then - don't create the configmap
var configMaps =
serverMock.getClient().configMaps().inNamespace(TEST_NAMESPACE_NAME).list().getItems();
Assert.assertEquals(configMaps.size(), 0);
}
@Test
public void doNothingWhenSecretAlreadyExists()
throws InfrastructureException, InterruptedException, ScmCommunicationException,
@ -151,30 +133,4 @@ public class GitconfigUserdataConfiguratorTest {
Assert.assertEquals(configMaps.size(), 1);
Assert.assertEquals(configMaps.get(0).getMetadata().getAnnotations().get("already"), "created");
}
@Test
public void createUserdataConfigmapFromCheUserData()
throws InfrastructureException, ServerException, NotFoundException, InterruptedException {
// given
User user = mock(User.class);
when(user.getName()).thenReturn("test name");
when(user.getEmail()).thenReturn("test@email.com");
when(userManager.getById(anyString())).thenReturn(user);
// when
configurator.configure(namespaceResolutionContext, TEST_NAMESPACE_NAME);
// then create a secret
Assert.assertEquals(serverMock.getLastRequest().getMethod(), "POST");
ConfigMap configMap =
serverMock
.getClient()
.configMaps()
.inNamespace(TEST_NAMESPACE_NAME)
.withName(GIT_USERDATA_CONFIGMAP_NAME)
.get();
Assert.assertNotNull(configMap);
Assert.assertTrue(configMap.getData().get("gitconfig").contains("test name"));
Assert.assertTrue(configMap.getData().get("gitconfig").contains("test@email.com"));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2021 Red Hat, Inc.
* Copyright (c) 2012-2022 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/
@ -13,14 +13,10 @@ package org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurat
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.ServerException;
@ -84,25 +80,6 @@ public class UserPreferencesConfiguratorTest {
kubernetesServer.after();
}
@Test
public void shouldCreatePreferencesSecret() throws InfrastructureException {
userPreferencesConfigurator.configure(context, USER_NAMESPACE);
List<Secret> secrets =
kubernetesServer.getClient().secrets().inNamespace(USER_NAMESPACE).list().getItems();
assertEquals(secrets.size(), 1);
assertEquals(secrets.get(0).getMetadata().getName(), "user-preferences");
}
@Test(
expectedExceptions = InfrastructureException.class,
expectedExceptionsMessageRegExp =
"Preferences of user with id:" + USER_ID + " cannot be retrieved.")
public void shouldNotCreateSecretOnException() throws ServerException, InfrastructureException {
when(preferenceManager.find(USER_ID)).thenThrow(new ServerException("test exception"));
userPreferencesConfigurator.configure(context, USER_NAMESPACE);
fail("InfrastructureException should have been thrown.");
}
@Test
public void shouldNormalizePreferenceName() {
assertEquals(

View File

@ -1,100 +0,0 @@
/*
* 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 static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
import java.util.List;
import java.util.Map;
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.user.server.UserManager;
import org.eclipse.che.api.user.server.model.impl.UserImpl;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.api.workspace.server.spi.NamespaceResolutionContext;
import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesClientFactory;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
/**
* Tests for {@link UserProfileConfigurator}.
*
* @author Pavol Baran
*/
@Listeners(MockitoTestNGListener.class)
public class UserProfileConfiguratorTest {
private static final String USER_ID = "user-id";
private static final String USER_NAME = "user-name";
private static final String USER_EMAIL = "user-email";
private static final String USER_NAMESPACE = "user-namespace";
@Mock private KubernetesClientFactory clientFactory;
@Mock private UserManager userManager;
@InjectMocks private UserProfileConfigurator userProfileConfigurator;
private KubernetesServer kubernetesServer;
private NamespaceResolutionContext context;
@BeforeMethod
public void setUp() throws InfrastructureException, NotFoundException, ServerException {
context = new NamespaceResolutionContext(null, USER_ID, USER_NAME);
kubernetesServer = new KubernetesServer(true, true);
kubernetesServer.before();
when(userManager.getById(USER_ID)).thenReturn(new UserImpl(USER_ID, USER_EMAIL, USER_NAME));
when(clientFactory.create()).thenReturn(kubernetesServer.getClient());
}
@AfterMethod
public void cleanUp() {
kubernetesServer.after();
}
@Test
public void shouldCreateProfileSecret() throws InfrastructureException {
userProfileConfigurator.configure(context, USER_NAMESPACE);
List<Secret> secrets =
kubernetesServer.getClient().secrets().inNamespace(USER_NAMESPACE).list().getItems();
assertEquals(secrets.size(), 1);
assertEquals(secrets.get(0).getMetadata().getName(), "user-profile");
Map<String, String> labels = secrets.get(0).getMetadata().getLabels();
String expectedMountLabel = "controller.devfile.io/mount-to-devworkspace";
assertTrue(labels.containsKey(expectedMountLabel));
assertEquals(labels.get(expectedMountLabel), "true");
String expectedWatchLabel = "controller.devfile.io/watch-secret";
assertTrue(labels.containsKey(expectedWatchLabel));
assertEquals(labels.get(expectedWatchLabel), "true");
}
@Test(
expectedExceptions = InfrastructureException.class,
expectedExceptionsMessageRegExp = "Could not find current user with id:" + USER_ID + ".")
public void shouldNotCreateSecretOnException()
throws NotFoundException, ServerException, InfrastructureException {
when(userManager.getById(USER_ID)).thenThrow(new ServerException("test exception"));
userProfileConfigurator.configure(context, USER_NAMESPACE);
fail("InfrastructureException should have been thrown.");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2021 Red Hat, Inc.
* Copyright (c) 2012-2022 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/
@ -106,14 +106,14 @@ public class OpenShiftProjectFactory extends KubernetesNamespaceFactory {
OpenShiftProject osProject = get(identity);
var subject = EnvironmentContext.getCurrent().getSubject();
var userName = subject.getUserName();
NamespaceResolutionContext resolutionCtx =
new NamespaceResolutionContext(
identity.getWorkspaceId(), subject.getUserId(), subject.getUserName());
new NamespaceResolutionContext(identity.getWorkspaceId(), subject.getUserId(), userName);
Map<String, String> namespaceAnnotationsEvaluated =
evaluateAnnotationPlaceholders(resolutionCtx);
osProject.prepare(
canCreateNamespace(identity),
canCreateNamespace(identity, userName),
initWithCheServerSa && !isNullOrEmpty(oAuthIdentityProvider),
labelNamespaces ? namespaceLabels : emptyMap(),
annotateNamespaces ? namespaceAnnotationsEvaluated : emptyMap());

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2021 Red Hat, Inc.
* Copyright (c) 2012-2022 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/
@ -13,18 +13,13 @@ package org.eclipse.che.multiuser.keycloak.server;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertNotEquals;
import static org.testng.AssertJUnit.assertEquals;
import org.eclipse.che.account.api.AccountManager;
import org.eclipse.che.api.core.ConflictException;
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.model.user.User;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.user.server.event.BeforeUserRemovedEvent;
@ -107,80 +102,4 @@ public class KeycloakUserManagerTest {
assertEquals("new@mail.com", user.getEmail());
assertEquals("name", user.getName());
}
@Test
public void shoudCreateNewUserIfHeIsNotFoundByIdOrEmail() throws Exception {
// given
ArgumentCaptor<UserImpl> captor = ArgumentCaptor.forClass(UserImpl.class);
when(userDao.getById(eq("id"))).thenThrow(NotFoundException.class);
when(userDao.getByEmail(eq("user@mail.com"))).thenThrow(NotFoundException.class);
// when
keycloakUserManager.getOrCreateUser("id", "user@mail.com", "name");
// then
verify(userDao, times(2)).getById(eq("id"));
verify(userDao).getByEmail(eq("user@mail.com"));
verify(userDao).create((captor.capture()));
assertEquals("id", captor.getValue().getId());
assertEquals("user@mail.com", captor.getValue().getEmail());
assertEquals("name", captor.getValue().getName());
}
@Test
public void shoudRecreateUserIfHeIsntFoundByIdButFoundByEmail() throws Exception {
// given
UserImpl newUserImpl = new UserImpl("id", "user@mail.com", "name");
UserImpl oldUserImpl = new UserImpl("oldId", "user@mail.com", "name");
ArgumentCaptor<UserImpl> captor = ArgumentCaptor.forClass(UserImpl.class);
when(userDao.getById(eq("id"))).thenThrow(NotFoundException.class);
when(userDao.getByEmail(eq("user@mail.com"))).thenReturn(oldUserImpl);
// when
keycloakUserManager.getOrCreateUser("id", "user@mail.com", "name");
// then
verify(userDao, times(2)).getById(eq("id"));
verify(userDao).getByEmail(eq("user@mail.com"));
verify(userDao).remove(eq(oldUserImpl.getId()));
verify(userDao).create((captor.capture()));
assertEquals(newUserImpl.getId(), captor.getValue().getId());
assertEquals(newUserImpl.getEmail(), captor.getValue().getEmail());
assertEquals(newUserImpl.getName(), captor.getValue().getName());
}
@Test
public void shoudRecreateUserWithDifferentNameIfConflictOccures() throws Exception {
// given
UserImpl newUserImpl = new UserImpl("id", "user@mail.com", "name");
ArgumentCaptor<UserImpl> captor = ArgumentCaptor.forClass(UserImpl.class);
ArgumentCaptor<UserImpl> captor2 = ArgumentCaptor.forClass(UserImpl.class);
when(userDao.getById(eq("id"))).thenThrow(NotFoundException.class);
when(userDao.getByEmail(eq("user@mail.com"))).thenThrow(NotFoundException.class);
doAnswer(
invocation -> {
if (((UserImpl) invocation.getArgument(0)).getName().equals("name")) {
throw new ConflictException("");
}
return newUserImpl;
})
.when(userDao)
.create(any());
// when
keycloakUserManager.getOrCreateUser("id", "user@mail.com", "name");
// then
verify(userDao, times(2)).getById(eq("id"));
verify(userDao).getByEmail(eq("user@mail.com"));
verify(userDao, atLeastOnce()).create((captor.capture()));
assertEquals(newUserImpl.getId(), captor.getValue().getId());
assertEquals(newUserImpl.getEmail(), captor.getValue().getEmail());
assertNotEquals(newUserImpl.getName(), captor.getValue().getName());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* Copyright (c) 2012-2022 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/
@ -29,6 +29,7 @@ import org.eclipse.che.api.core.notification.EventService;
*
* @author Sergii Leschenko
*/
@Deprecated
@Singleton
public class AccountManager {
@ -42,7 +43,7 @@ public class AccountManager {
}
/**
* Creates account.
* Account information is no longer persisted in the database
*
* @param account account to create
* @throws NullPointerException when {@code account} is null
@ -51,7 +52,6 @@ public class AccountManager {
*/
public void create(Account account) throws ConflictException, ServerException {
requireNonNull(account, "Required non-null account");
accountDao.create(new AccountImpl(account));
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* Copyright (c) 2012-2022 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/
@ -31,6 +31,7 @@ import org.eclipse.che.api.user.server.spi.PreferenceDao;
*
* @author Yevhenii Voevodin
*/
@Deprecated
@Singleton
public class PreferenceManager {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2021 Red Hat, Inc.
* Copyright (c) 2012-2022 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/
@ -14,14 +14,12 @@ package org.eclipse.che.api.user.server;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.System.currentTimeMillis;
import static java.util.Collections.emptyList;
import static java.util.Objects.requireNonNull;
import static org.eclipse.che.api.user.server.Constants.ID_LENGTH;
import static org.eclipse.che.api.user.server.Constants.PASSWORD_LENGTH;
import static org.eclipse.che.commons.lang.NameGenerator.generate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import com.google.inject.persist.Transactional;
import java.util.Optional;
@ -38,10 +36,8 @@ import org.eclipse.che.api.core.model.user.Profile;
import org.eclipse.che.api.core.model.user.User;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.user.server.event.BeforeUserRemovedEvent;
import org.eclipse.che.api.user.server.event.PostUserPersistedEvent;
import org.eclipse.che.api.user.server.event.UserCreatedEvent;
import org.eclipse.che.api.user.server.event.UserRemovedEvent;
import org.eclipse.che.api.user.server.model.impl.ProfileImpl;
import org.eclipse.che.api.user.server.model.impl.UserImpl;
import org.eclipse.che.api.user.server.spi.PreferenceDao;
import org.eclipse.che.api.user.server.spi.ProfileDao;
@ -54,6 +50,7 @@ import org.eclipse.che.api.user.server.spi.UserDao;
* @author Yevhenii Voevodin
* @author Anton Korneta
*/
@Deprecated
@Singleton
public class UserManager {
@ -80,7 +77,7 @@ public class UserManager {
}
/**
* Creates new user and his profile.
* Creates new user and his profile. NOTE: The user data is no longer persisted in the database.
*
* @param newUser created user
* @throws NullPointerException when {@code newUser} is null
@ -100,7 +97,6 @@ public class UserManager {
newUser.getName(),
firstNonNull(newUser.getPassword(), generate("", PASSWORD_LENGTH)),
newUser.getAliases());
doCreate(user, isTemporary);
eventService.publish(new UserCreatedEvent(user));
return user;
}
@ -108,14 +104,8 @@ public class UserManager {
@Transactional(rollbackOn = {RuntimeException.class, ApiException.class})
protected void doCreate(UserImpl user, boolean isTemporary)
throws ConflictException, ServerException {
userDao.create(user);
eventService.publish(new PostUserPersistedEvent(new UserImpl(user))).propagateException();
profileDao.create(new ProfileImpl(user.getId()));
preferencesDao.setPreferences(
user.getId(),
ImmutableMap.of(
"temporary", Boolean.toString(isTemporary),
"codenvy:created", Long.toString(currentTimeMillis())));
throw new UnsupportedOperationException(
"'doCreate' method should never be called. User information is no longer persisted in the database.");
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2021 Red Hat, Inc.
* Copyright (c) 2012-2022 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/
@ -12,8 +12,6 @@
package org.eclipse.che.api.user.server;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyMapOf;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.times;
@ -34,9 +32,7 @@ import org.eclipse.che.api.core.model.user.User;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.user.server.event.BeforeUserRemovedEvent;
import org.eclipse.che.api.user.server.event.PostUserPersistedEvent;
import org.eclipse.che.api.user.server.event.UserCreatedEvent;
import org.eclipse.che.api.user.server.event.UserRemovedEvent;
import org.eclipse.che.api.user.server.model.impl.ProfileImpl;
import org.eclipse.che.api.user.server.model.impl.UserImpl;
import org.eclipse.che.api.user.server.spi.PreferenceDao;
import org.eclipse.che.api.user.server.spi.ProfileDao;
@ -85,53 +81,6 @@ public class UserManagerTest {
});
}
@Test
public void shouldCreateAccountAndProfileAndPreferencesOnUserCreation() throws Exception {
final UserImpl user = new UserImpl(null, "test@email.com", "testName", null, null);
manager.create(user, false);
verify(userDao).create(any(UserImpl.class));
verify(profileDao).create(any(ProfileImpl.class));
verify(preferencesDao).setPreferences(anyString(), anyMapOf(String.class, String.class));
}
@Test
public void shouldGeneratePasswordWhenCreatingUserAndItIsMissing() throws Exception {
final User user = new UserImpl(null, "test@email.com", "testName", null, null);
manager.create(user, false);
final ArgumentCaptor<UserImpl> userCaptor = ArgumentCaptor.forClass(UserImpl.class);
verify(userDao).create(userCaptor.capture());
assertNotNull(userCaptor.getValue().getPassword());
}
@Test
public void shouldGenerateIdentifierWhenCreatingUserWithNullId() throws Exception {
final User user = new UserImpl(null, "test@email.com", "testName", null, null);
manager.create(user, false);
final ArgumentCaptor<UserImpl> userCaptor = ArgumentCaptor.forClass(UserImpl.class);
verify(userDao).create(userCaptor.capture());
final String id = userCaptor.getValue().getId();
assertNotNull(id);
}
@Test
public void shouldNotGenerateIdentifierWhenCreatingUserWithNotNullId() throws Exception {
final User user = new UserImpl("identifier", "test@email.com", "testName", null, null);
manager.create(user, false);
final ArgumentCaptor<UserImpl> userCaptor = ArgumentCaptor.forClass(UserImpl.class);
verify(userDao).create(userCaptor.capture());
final String id = userCaptor.getValue().getId();
assertNotNull(id);
assertEquals(id, "identifier");
}
@Test(expectedExceptions = NullPointerException.class)
public void shouldThrowNpeWhenUpdatingUserWithNullEntity() throws Exception {
manager.update(null);
@ -368,74 +317,6 @@ public class UserManagerTest {
firedEvents.getValue() instanceof BeforeUserRemovedEvent, "Not a BeforeUserRemovedEvent");
}
@Test
public void shouldFirePostUserPersistedEventNewUserCreatedAndBeforeCommit() throws Exception {
final UserImpl user =
new UserImpl(
"identifier",
"test@email.com",
"testName",
"password",
Collections.singletonList("alias"));
manager.create(user, false);
ArgumentCaptor<Object> firedEvents = ArgumentCaptor.forClass(Object.class);
verify(eventService, times(2)).publish(firedEvents.capture());
// the first event - PostUserPersistedEvent
// the second event - UserCreatedEvent
Object event = firedEvents.getAllValues().get(0);
assertTrue(event instanceof PostUserPersistedEvent, "Not a PostUserPersistedEvent");
assertEquals(((PostUserPersistedEvent) event).getUser(), user);
}
@Test
public void shouldFireUserCreatedEventOnNewUserCreated() throws Exception {
final UserImpl user =
new UserImpl(
"identifier",
"test@email.com",
"testName",
"password",
Collections.singletonList("alias"));
manager.create(user, false);
ArgumentCaptor<Object> firedEvents = ArgumentCaptor.forClass(Object.class);
verify(eventService, times(2)).publish(firedEvents.capture());
// the first event - PostUserPersistedEvent
// the second event - UserCreatedEvent
Object event = firedEvents.getAllValues().get(1);
assertTrue(event instanceof UserCreatedEvent, "Not a UserCreatedEvent");
assertEquals(((UserCreatedEvent) event).getUser(), user);
}
@Test
public void shouldNotCreteUserWhenSubscriberThrowsExceptionOnCreatingNewUser() throws Exception {
final UserImpl user =
new UserImpl(
"identifier",
"test@email.com",
"testName",
"password",
Collections.singletonList("alias"));
doThrow(new ServerException("error")).when(postUserPersistedEvent).propagateException();
try {
manager.create(user, false);
fail("ServerException expected.");
} catch (ServerException ignored) {
}
ArgumentCaptor<Object> firedEvents = ArgumentCaptor.forClass(Object.class);
verify(eventService, times(1)).publish(firedEvents.capture());
assertTrue(
firedEvents.getValue() instanceof PostUserPersistedEvent, "Not a PostUserPersistedEvent");
}
@Test
public void shouldBeAbleToGetOrCreate_existed() throws Exception {
// given