User structural refactoring
parent
5e0aa31691
commit
d1aa2cfed7
|
|
@ -29,7 +29,7 @@ import org.eclipse.che.api.git.GitUserResolver;
|
|||
import org.eclipse.che.api.project.server.ProjectApiModule;
|
||||
import org.eclipse.che.api.ssh.server.HttpSshServiceClient;
|
||||
import org.eclipse.che.api.ssh.server.SshServiceClient;
|
||||
import org.eclipse.che.api.user.server.dao.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.spi.PreferenceDao;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
import org.eclipse.che.everrest.CheAsynchronousJobPool;
|
||||
import org.eclipse.che.api.git.LocalGitUserResolver;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import com.google.inject.multibindings.Multibinder;
|
|||
import com.google.inject.name.Names;
|
||||
|
||||
import org.eclipse.che.api.machine.shared.Constants;
|
||||
import org.eclipse.che.api.user.server.ProfileService;
|
||||
import org.eclipse.che.inject.DynaModule;
|
||||
import org.everrest.guice.ServiceBindingHelper;
|
||||
|
||||
|
|
@ -30,7 +31,8 @@ public class WsMasterModule extends AbstractModule {
|
|||
bind(org.eclipse.che.api.ssh.server.SshService.class);
|
||||
bind(org.eclipse.che.api.machine.server.recipe.RecipeService.class);
|
||||
bind(org.eclipse.che.api.user.server.UserService.class);
|
||||
bind(org.eclipse.che.api.user.server.UserProfileService.class);
|
||||
bind(org.eclipse.che.api.user.server.ProfileService.class);
|
||||
bind(org.eclipse.che.api.user.server.PreferencesService.class);
|
||||
bind(org.eclipse.che.api.workspace.server.stack.StackLoader.class);
|
||||
bind(org.eclipse.che.api.workspace.server.stack.StackService.class);
|
||||
bind(org.eclipse.che.api.workspace.server.WorkspaceService.class);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.model.user;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Defines the user's profile model.
|
||||
*
|
||||
* <p>User's profile describes an additional user information such as his
|
||||
* job title or company name which is not related to application business logic.
|
||||
* If it is necessary to manage business logic related attributes then
|
||||
* user's preferences should be used instead.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
* @see User
|
||||
*/
|
||||
public interface Profile {
|
||||
|
||||
/**
|
||||
* Returns the identifier of the user {@link User#getId()}
|
||||
* whom this profile belongs to.
|
||||
*/
|
||||
String getUserId();
|
||||
|
||||
/**
|
||||
* Returns the user profile attributes (e.g. job title).
|
||||
*/
|
||||
Map<String, String> getAttributes();
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.core.model.user;
|
||||
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Defines the user model.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public interface User {
|
||||
|
||||
/**
|
||||
* Returns the identifier of the user (e.g. "user0x124567890").
|
||||
* The identifier value is unique and mandatory.
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Returns the user's email (e.g. user@codenvy.com).
|
||||
* The email is unique, mandatory and updatable.
|
||||
*/
|
||||
String getEmail();
|
||||
|
||||
/**
|
||||
* Returns the user's name (e.g. name_example).
|
||||
* The name is unique, mandatory and updatable.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Returns the list of the user's aliases, the aliases are the values
|
||||
* which identify user in the system with third party ids (e.g. if user is registered
|
||||
* within google oauth the aliases list may contain 'google:user_identifier' alias).
|
||||
*
|
||||
* <p>Note that user's {@link #getEmail() email} and {@link #getName() name}
|
||||
* are not a part of the result, and returned list never contains those values.
|
||||
* Also note that returned aliases are unique, so there are no two users
|
||||
* who have the alias in common.
|
||||
*/
|
||||
List<String> getAliases();
|
||||
|
||||
/**
|
||||
* Returns the user's password.
|
||||
* The returned value may be the password placeholder such as 'none' or
|
||||
* even null, depends on the context.
|
||||
*/
|
||||
@Nullable
|
||||
String getPassword();
|
||||
}
|
||||
|
|
@ -18,5 +18,6 @@
|
|||
<source path="machine"/>
|
||||
<source path="project"/>
|
||||
<source path="workspace"/>
|
||||
<source path="user"/>
|
||||
|
||||
</module>
|
||||
|
|
|
|||
|
|
@ -21,10 +21,32 @@
|
|||
<artifactId>che-core-commons-test</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Che Core :: Commons :: Utilities for tests</name>
|
||||
<properties>
|
||||
<findbugs.failonerror>true</findbugs.failonerror>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.commons.test.tck;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Module;
|
||||
|
||||
import org.testng.IModuleFactory;
|
||||
import org.testng.ITestContext;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* Abstract class for those Guice {@link Module modules} which provide
|
||||
* TCK tests components, which will be injected directly into the test class.
|
||||
*
|
||||
* <p>The {@link ServiceLoader} mechanism is used for loading such modules
|
||||
* and for injecting them later. So each module which is TCK module must
|
||||
* provide the implementations list(as described by {@code ServiceLoader} mechanism)
|
||||
* in the file named <i>org.eclipse.che.commons.test.tck.TckModule</i> usually under
|
||||
* <i>test/resources/META-INF/services</i> directory, then the {@link TckModuleFactory}
|
||||
* will recognise and load it.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
* @see TckModuleFactory
|
||||
*/
|
||||
public abstract class TckModule extends AbstractModule {
|
||||
|
||||
/**
|
||||
* It is guaranteed that this field is always present and
|
||||
* can be reused by implementation, the value is equal to the
|
||||
* {@link IModuleFactory#createModule(ITestContext, Class)} first
|
||||
* parameter and will be set by {@link TckModuleFactory} immediately after module
|
||||
* implementation is loaded by {@link ServiceLoader}.
|
||||
*/
|
||||
private ITestContext testContext;
|
||||
|
||||
/** Returns the {@link ITestContext context} of currently executing test suite. */
|
||||
protected ITestContext getTestContext() {
|
||||
return testContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the context of currently executing test suite.
|
||||
* This method designed to be used by {@link TckModuleFactory} for setting
|
||||
* the context before installing modules.
|
||||
*/
|
||||
void setTestContext(ITestContext testContext) {
|
||||
this.testContext = testContext;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.commons.test.tck;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Module;
|
||||
|
||||
import org.testng.IModuleFactory;
|
||||
import org.testng.ITestContext;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* The factory is designed to instantiate {@link TckModule tck modules}
|
||||
* using {@link ServiceLoader} mechanism. The components
|
||||
* provided by those modules will be injected into a test class
|
||||
* whether it's necessary to do so.
|
||||
*
|
||||
* <p>The factory expects at least one implementation of {@code TckModule}
|
||||
* to be configured, if it doesn't find any of the {@code TckModule}
|
||||
* implementations then it will report an appropriate exception
|
||||
* and TckTest will fail(as it requires components to be injected into it).
|
||||
* If it finds more than one {@code TckModule} implementation it will
|
||||
* use all of the found.
|
||||
*
|
||||
* <p>The usage example:
|
||||
* <pre>
|
||||
* package org.eclipse.mycomponent;
|
||||
*
|
||||
* @org.testng.annotations.Guice(moduleFactory = TckModuleFactory.class)
|
||||
* // Good practice to define suiteName for TCK tests as it makes easier
|
||||
* // to implement logic related to certain tests in ITestNGListener implementations
|
||||
* @org.testng.annotations.Test(suiteName = "MySuite")
|
||||
* class SubjectTest {
|
||||
*
|
||||
* @javax.inject.Inject
|
||||
* private Component1 component1.
|
||||
* @javax.inject.Inject
|
||||
* private Component2 component2;
|
||||
*
|
||||
* @org.testng.annotations.Test
|
||||
* public void test() {
|
||||
* // use components
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* class MyTckModule extends TckModule {
|
||||
* public void configure() {
|
||||
* bind(Component1.class).to(...);
|
||||
* bind(Component2.class).toInstance(new Component2(() -> testContext.getAttribute("server_url").toString()));
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Allows to add pre/post test actions like db server start/stop
|
||||
* class DBServerListener implements ITestListener {
|
||||
* // ...
|
||||
* public void onStart(ITestContext context) {
|
||||
* String url = dbServer.start();
|
||||
* context.setAttribute("server_url", url)l
|
||||
* }
|
||||
*
|
||||
* public void onFinish(ITestContext context) {
|
||||
* dbServer.stop();
|
||||
* }
|
||||
* // ...
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>Configuring:
|
||||
* <pre>
|
||||
* <i>META-INF/services/org.eclipse.che.commons.test.tck.TckModule</i>
|
||||
* org.eclipse.mycomponent.MyTckModule
|
||||
*
|
||||
* <i>META-INF/services/org.testng.ITestNGListener</i>
|
||||
* org.eclipse.mycomponent.DBServerListener
|
||||
* </pre>
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
* @see org.testng.annotations.Guice
|
||||
* @see IModuleFactory
|
||||
*/
|
||||
public class TckModuleFactory implements IModuleFactory {
|
||||
|
||||
@Override
|
||||
public Module createModule(ITestContext context, Class<?> testClass) {
|
||||
final Iterator<TckModule> moduleIterator = ServiceLoader.load(TckModule.class).iterator();
|
||||
if (!moduleIterator.hasNext()) {
|
||||
throw new IllegalStateException(format("Couldn't find a TckModule configuration. " +
|
||||
"You probably forgot to configure resources/META-INF/services/%s, or even " +
|
||||
"provide an implementation of the TckModule which is required by the tck test class %s",
|
||||
TckModule.class.getName(),
|
||||
testClass.getName()));
|
||||
}
|
||||
return new CompoundModule(context, moduleIterator);
|
||||
}
|
||||
|
||||
private static class CompoundModule extends AbstractModule {
|
||||
private final ITestContext testContext;
|
||||
private final Iterator<TckModule> moduleIterator;
|
||||
|
||||
private CompoundModule(ITestContext testContext, Iterator<TckModule> moduleIterator) {
|
||||
this.testContext = testContext;
|
||||
this.moduleIterator = moduleIterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(ITestContext.class).toInstance(testContext);
|
||||
while (moduleIterator.hasNext()) {
|
||||
final TckModule module = moduleIterator.next();
|
||||
module.setTestContext(testContext);
|
||||
install(module);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.commons.test.tck.repository;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* The interface which allows to create TCK tests for DAO interfaces
|
||||
* by providing operations for creating/removing batch of elements.
|
||||
* The interface is designed to work with entities, which means
|
||||
* that entity marshaling and unmarshalling to/from db objects must be
|
||||
* tested by implementation separately.
|
||||
*
|
||||
* @param <T>
|
||||
* the type of the object managed by the repository
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public interface TckRepository<T> {
|
||||
|
||||
/**
|
||||
* Creates all the given {@code entities} in the storage.
|
||||
*
|
||||
* <p>Note that implementation must fail if it is impossible to
|
||||
* create any of the given entities.
|
||||
*
|
||||
* @param entities
|
||||
* elements to create
|
||||
* @throws TckRepositoryException
|
||||
* when any error occurs during the storing
|
||||
*/
|
||||
void createAll(Collection<? extends T> entities) throws TckRepositoryException;
|
||||
|
||||
/**
|
||||
* Clears the storage.
|
||||
*
|
||||
* <p>Note that implementation must fail if it is impossible to
|
||||
* remove all the entities.
|
||||
*
|
||||
* @throws TckRepositoryException
|
||||
* when any error occurs during the clearing
|
||||
*/
|
||||
void removeAll() throws TckRepositoryException;
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.commons.test.tck.repository;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Thrown when any error occurs during {@link TckRepository#createAll(Collection)}
|
||||
* or {@link TckRepository#removeAll()} invocation. Usually wraps exceptions
|
||||
* occurred during the storing/removing.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class TckRepositoryException extends Exception {
|
||||
|
||||
public TckRepositoryException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public TckRepositoryException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.commons.test.tck;
|
||||
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.ITestListener;
|
||||
import org.testng.ITestResult;
|
||||
|
||||
/**
|
||||
* Listener representing fake db server url injection for testing "attributes sharing"
|
||||
* using {@link ITestContext} test suite instance.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class DBServerListener implements ITestListener {
|
||||
|
||||
public static final String DB_SERVER_URL_ATTRIBUTE_NAME = "db_server_url";
|
||||
public static final String DB_SERVER_URL = "localhost:12345";
|
||||
|
||||
@Override
|
||||
public void onStart(ITestContext context) {
|
||||
context.setAttribute(DB_SERVER_URL_ATTRIBUTE_NAME, DB_SERVER_URL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish(ITestContext context) {}
|
||||
|
||||
@Override
|
||||
public void onTestStart(ITestResult result) {}
|
||||
|
||||
@Override
|
||||
public void onTestSuccess(ITestResult result) {}
|
||||
|
||||
@Override
|
||||
public void onTestFailure(ITestResult result) {}
|
||||
|
||||
@Override
|
||||
public void onTestSkipped(ITestResult result) {}
|
||||
|
||||
@Override
|
||||
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.commons.test.tck;
|
||||
|
||||
import org.eclipse.che.commons.test.tck.repository.TckRepository;
|
||||
import org.testng.annotations.Guice;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* Tests for {@code org.eclipse.che.commons.test.tck.*} package.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Guice(moduleFactory = TckModuleFactory.class)
|
||||
public class TckComponentsTest {
|
||||
|
||||
@Inject
|
||||
private TckRepository<Entity> tckRepository;
|
||||
|
||||
@Inject
|
||||
private DBUrlProvider dbUrlProvider;
|
||||
|
||||
@Test
|
||||
public void testComponentsAreInjected() {
|
||||
assertNotNull(tckRepository, "TckRepository is not injected");
|
||||
assertNotNull(dbUrlProvider, "DBUrlProvider is not injected");
|
||||
assertEquals(dbUrlProvider.getUrl(), DBServerListener.DB_SERVER_URL, "Value is set to ITestContext");
|
||||
}
|
||||
|
||||
public interface Entity {}
|
||||
|
||||
public interface DBUrlProvider {
|
||||
String getUrl();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.commons.test.tck;
|
||||
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
import org.eclipse.che.commons.test.tck.TckComponentsTest.Entity;
|
||||
import org.eclipse.che.commons.test.tck.repository.TckRepository;
|
||||
import org.eclipse.che.commons.test.tck.repository.TckRepositoryException;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class TestModule1 extends TckModule {
|
||||
|
||||
@Override
|
||||
public void configure() {
|
||||
bind(new TypeLiteral<TckRepository<Entity>>() {}).toInstance(new TckRepository<Entity>() {
|
||||
@Override
|
||||
public void createAll(Collection<? extends Entity> entities) throws TckRepositoryException {}
|
||||
|
||||
@Override
|
||||
public void removeAll() throws TckRepositoryException {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -8,25 +8,19 @@
|
|||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.shared.model;
|
||||
package org.eclipse.che.commons.test.tck;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.eclipse.che.commons.test.tck.TckComponentsTest.DBUrlProvider;
|
||||
|
||||
import static org.eclipse.che.commons.test.tck.DBServerListener.DB_SERVER_URL_ATTRIBUTE_NAME;
|
||||
|
||||
/**
|
||||
* @author gazarenkov
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public interface Membership {
|
||||
public class TestModule2 extends TckModule {
|
||||
|
||||
String getScope();
|
||||
|
||||
List<String> getRoles();
|
||||
|
||||
String getUserId();
|
||||
|
||||
String getUserName();
|
||||
|
||||
String getSubjectId();
|
||||
|
||||
Map<String, String> getSubjectProperties();
|
||||
@Override
|
||||
public void configure() {
|
||||
bind(DBUrlProvider.class).toInstance(() -> getTestContext().getAttribute(DB_SERVER_URL_ATTRIBUTE_NAME).toString());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
org.eclipse.che.commons.test.tck.TestModule1
|
||||
org.eclipse.che.commons.test.tck.TestModule2
|
||||
|
|
@ -0,0 +1 @@
|
|||
org.eclipse.che.commons.test.tck.DBServerListener
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.ide.api.user;
|
||||
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* GWT client for preferences service;
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public interface PreferencesServiceClient {
|
||||
|
||||
/**
|
||||
* Updates user's preferences using the merge strategy.
|
||||
*
|
||||
* @param prefsToUpdate
|
||||
* preferences update
|
||||
* @return a promise that resolves all the user's preferences, or rejects with an error
|
||||
*/
|
||||
Promise<Map<String, String>> updatePreferences(@NotNull Map<String, String> prefsToUpdate);
|
||||
|
||||
/**
|
||||
* Gets user preferences.
|
||||
*
|
||||
* @return a promise that resolves preferences, or rejects with an error
|
||||
*/
|
||||
Promise<Map<String, String>> getPreferences();
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.ide.api.user;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.ide.json.JsonHelper;
|
||||
import org.eclipse.che.ide.rest.AsyncRequestFactory;
|
||||
import org.eclipse.che.ide.rest.RestContext;
|
||||
import org.eclipse.che.ide.rest.StringMapUnmarshaller;
|
||||
import org.eclipse.che.ide.ui.loaders.request.LoaderFactory;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.eclipse.che.ide.MimeType.APPLICATION_JSON;
|
||||
import static org.eclipse.che.ide.rest.HTTPHeader.ACCEPT;
|
||||
import static org.eclipse.che.ide.rest.HTTPHeader.CONTENT_TYPE;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link PreferencesServiceClient}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class PreferencesServiceClientImpl implements PreferencesServiceClient {
|
||||
|
||||
private final String PREFERENCES_PATH;
|
||||
private final LoaderFactory loaderFactory;
|
||||
private final AsyncRequestFactory asyncRequestFactory;
|
||||
|
||||
@Inject
|
||||
protected PreferencesServiceClientImpl(@RestContext String restContext,
|
||||
LoaderFactory loaderFactory,
|
||||
AsyncRequestFactory asyncRequestFactory) {
|
||||
this.loaderFactory = loaderFactory;
|
||||
this.asyncRequestFactory = asyncRequestFactory;
|
||||
PREFERENCES_PATH = restContext + "/preferences";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<Map<String, String>> getPreferences() {
|
||||
return asyncRequestFactory.createGetRequest(PREFERENCES_PATH)
|
||||
.header(ACCEPT, APPLICATION_JSON)
|
||||
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||
.loader(loaderFactory.newLoader("Getting user's preferences..."))
|
||||
.send(new StringMapUnmarshaller());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<Map<String, String>> updatePreferences(Map<String, String> update) {
|
||||
final String data = JsonHelper.toJson(update);
|
||||
return asyncRequestFactory.createPutRequest(PREFERENCES_PATH, null)
|
||||
.header(ACCEPT, APPLICATION_JSON)
|
||||
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||
.data(data)
|
||||
.loader(loaderFactory.newLoader("Updating user's preferences..."))
|
||||
.send(new StringMapUnmarshaller());
|
||||
}
|
||||
}
|
||||
|
|
@ -20,9 +20,9 @@ export class AddRegistryController {
|
|||
* Default constructor.
|
||||
* @ngInject for Dependency injection
|
||||
*/
|
||||
constructor($mdDialog, cheProfile, cheNotification) {
|
||||
constructor($mdDialog, chePreferences, cheNotification) {
|
||||
this.$mdDialog = $mdDialog;
|
||||
this.cheProfile = cheProfile;
|
||||
this.chePreferences = chePreferences;
|
||||
this.cheNotification = cheNotification;
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ export class AddRegistryController {
|
|||
return;
|
||||
}
|
||||
|
||||
let promise = this.cheProfile.addRegistry(this.registryUrl, this.registryUserName, this.registryUserPassword);
|
||||
let promise = this.chePreferences.addRegistry(this.registryUrl, this.registryUserName, this.registryUserPassword);
|
||||
|
||||
promise.then(() => {
|
||||
this.$mdDialog.hide();
|
||||
|
|
|
|||
|
|
@ -22,16 +22,16 @@ export class DockerRegistryListController {
|
|||
* Default constructor that is using resource
|
||||
* @ngInject for Dependency injection
|
||||
*/
|
||||
constructor($mdDialog, $document, cheProfile, cheNotification) {
|
||||
constructor($mdDialog, $document, chePreferences, cheNotification) {
|
||||
this.$mdDialog = $mdDialog;
|
||||
this.$document = $document;
|
||||
this.cheProfile = cheProfile;
|
||||
this.chePreferences = chePreferences;
|
||||
this.cheNotification = cheNotification;
|
||||
|
||||
this.registries = cheProfile.getRegistries();
|
||||
this.registries = chePreferences.getRegistries();
|
||||
this.isLoading = true;
|
||||
|
||||
let promise = cheProfile.fetchPreferences();
|
||||
let promise = chePreferences.fetchPreferences();
|
||||
promise.then(() => {
|
||||
this.isLoading = false;
|
||||
}, (error) => {
|
||||
|
|
@ -91,7 +91,7 @@ export class DockerRegistryListController {
|
|||
.targetEvent(event);
|
||||
this.$mdDialog.show(confirm).then(() => {
|
||||
this.isLoading = true;
|
||||
let promise = this.cheProfile.removeRegistry(registry.url);
|
||||
let promise = this.chePreferences.removeRegistry(registry.url);
|
||||
promise.then(() => {
|
||||
this.isLoading = false;
|
||||
}, (error) => {
|
||||
|
|
|
|||
|
|
@ -40,13 +40,13 @@ let initModule = angular.module('userDashboard', ['ngAnimate', 'ngCookies', 'ngT
|
|||
initModule.config(['$routeProvider', ($routeProvider) => {
|
||||
$routeProvider.accessWhen = (path, route) => {
|
||||
route.resolve || (route.resolve = {});
|
||||
route.resolve.app = ['cheBranding', '$q', 'cheProfile', (cheBranding, $q, cheProfile) => {
|
||||
route.resolve.app = ['cheBranding', '$q', 'chePreferences', (cheBranding, $q, chePreferences) => {
|
||||
var deferred = $q.defer();
|
||||
let profilePreferences = cheProfile.getPreferences();
|
||||
if (profilePreferences && profilePreferences.$resolved) {
|
||||
let preferences = chePreferences.getPreferences();
|
||||
if (preferences && preferences.$resolved) {
|
||||
deferred.resolve();
|
||||
} else {
|
||||
profilePreferences.$promise.then(() => {
|
||||
preferences.$promise.then(() => {
|
||||
deferred.resolve();
|
||||
}, (error) => {
|
||||
deferred.reject(error);
|
||||
|
|
@ -61,13 +61,13 @@ initModule.config(['$routeProvider', ($routeProvider) => {
|
|||
|
||||
$routeProvider.accessOtherWise = (route) => {
|
||||
route.resolve || (route.resolve = {});
|
||||
route.resolve.app = ['$q', 'cheProfile', ($q, cheProfile) => {
|
||||
route.resolve.app = ['$q', 'chePreferences', ($q, chePreferences) => {
|
||||
var deferred = $q.defer();
|
||||
let profilePreferences = cheProfile.getPreferences();
|
||||
if (profilePreferences && profilePreferences.$resolved) {
|
||||
let preferences = chePreferences.getPreferences();
|
||||
if (preferences && preferences.$resolved) {
|
||||
deferred.resolve();
|
||||
} else {
|
||||
profilePreferences.$promise.then(() => {
|
||||
preferences.$promise.then(() => {
|
||||
deferred.resolve();
|
||||
}, (error) => {
|
||||
deferred.reject(error);
|
||||
|
|
|
|||
|
|
@ -26,11 +26,11 @@ export class CheNavBarCtrl {
|
|||
this.links = [{href: '#/create-workspace', name: 'New Workspace'}];
|
||||
|
||||
this.profile = cheAPI.getProfile().getProfile();
|
||||
if (this.profile.attributes) {
|
||||
this.email = this.profile.attributes.email;
|
||||
if (this.profile.email) {
|
||||
this.email = this.profile.email;
|
||||
} else {
|
||||
this.profile.$promise.then(() => {
|
||||
this.email = this.profile.attributes.email ? this.profile.attributes.email : 'N/A ';
|
||||
this.email = this.profile.email ? this.profile.email : 'N/A ';
|
||||
}, () => {
|
||||
this.email = 'N/A ';
|
||||
});
|
||||
|
|
|
|||
|
|
@ -49,9 +49,9 @@ export class ListProjectsCtrl {
|
|||
}
|
||||
});
|
||||
|
||||
let profilePreferences = cheAPI.getProfile().getPreferences();
|
||||
let preferences = cheAPI.getPreferences().getPreferences();
|
||||
|
||||
this.profileCreationDate = profilePreferences['che:created'];
|
||||
this.profileCreationDate = preferences['che:created'];
|
||||
|
||||
this.menuOptions = [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ export class WorkspaceDetailsProjectsCtrl {
|
|||
this.namespace = $route.current.params.namespace;
|
||||
this.workspaceName = $route.current.params.workspaceName;
|
||||
|
||||
let profilePreferences = cheAPI.getProfile().getPreferences();
|
||||
let preferences = cheAPI.getPreferences().getPreferences();
|
||||
|
||||
this.profileCreationDate = profilePreferences['che:created'];
|
||||
this.profileCreationDate = preferences['che:created'];
|
||||
|
||||
if (!this.cheWorkspace.getWorkspacesById().get(this.workspaceId)) {
|
||||
let promise = this.cheWorkspace.fetchWorkspaceDetails(this.workspaceId);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ export class CheProfileBuilder {
|
|||
* @returns {CheProfileBuilder}
|
||||
*/
|
||||
withEmail(email) {
|
||||
return this.withAttribute('email', email);
|
||||
this.profile.email = email;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import {CheRecipeTemplate} from './che-recipe-template.factory';
|
|||
import {CheStack} from './che-stack.factory';
|
||||
import {CheWebsocket} from './che-websocket.factory';
|
||||
import {CheProfile} from './che-profile.factory';
|
||||
import {ChePreferences} from './che-preferences.factory';
|
||||
import {CheService} from './che-service.factory';
|
||||
import {CheSvn} from './che-svn.factory';
|
||||
import {CheHttpBackend} from './test/che-http-backend';
|
||||
|
|
@ -35,6 +36,7 @@ export class ApiConfig {
|
|||
register.factory('cheWorkspace', CheWorkspace);
|
||||
register.factory('cheProjectTemplate', CheProjectTemplate);
|
||||
register.factory('cheProfile', CheProfile);
|
||||
register.factory('chePreferences', ChePreferences);
|
||||
register.factory('cheWebsocket', CheWebsocket);
|
||||
register.factory('cheRecipe', CheRecipe);
|
||||
register.factory('cheRecipeTemplate', CheRecipeTemplate);
|
||||
|
|
|
|||
|
|
@ -22,10 +22,11 @@ export class CheAPI {
|
|||
* Default constructor that is using resource
|
||||
* @ngInject for Dependency injection
|
||||
*/
|
||||
constructor(cheWorkspace, cheProfile, cheProjectTemplate, cheWebsocket, cheSvn, cheService,
|
||||
constructor(cheWorkspace, cheProfile, chePreferences, cheProjectTemplate, cheWebsocket, cheSvn, cheService,
|
||||
cheAdminPlugins, cheAdminService, cheRecipe, cheRecipeTemplate, cheStack, cheOAuthProvider) {
|
||||
this.cheWorkspace = cheWorkspace;
|
||||
this.cheProfile = cheProfile;
|
||||
this.chePreferences = chePreferences;
|
||||
this.cheProjectTemplate = cheProjectTemplate;
|
||||
this.cheWebsocket = cheWebsocket;
|
||||
this.cheSvn = cheSvn;
|
||||
|
|
@ -63,6 +64,14 @@ export class CheAPI {
|
|||
return this.cheProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Che Preferences API
|
||||
* @returns {ChePreferences|*}
|
||||
*/
|
||||
getPreferences() {
|
||||
return this.chePreferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Che Project Template API
|
||||
* @returns {CheProjectTemplate|*}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* This class is handling the preferences API retrieval
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
export class ChePreferences {
|
||||
|
||||
/**
|
||||
* Default constructor that is using resource
|
||||
* @ngInject for Dependency injection
|
||||
*/
|
||||
constructor($resource, $http, $window) {
|
||||
this.$window = $window;
|
||||
|
||||
// keep resource
|
||||
this.$resource = $resource;
|
||||
|
||||
// http is used for sending data with DELETE method (angular is not sending any data by default with DELETE)
|
||||
this.$http = $http;
|
||||
|
||||
// remote call
|
||||
this.remotePreferencesAPI = this.$resource('/api/preferences', {}, {
|
||||
getPreferences: {method: 'GET', url: '/api/preferences'},
|
||||
updatePreferences: {method: 'POST', url: '/api/preferences'}
|
||||
});
|
||||
|
||||
// fetch the preferences when we're initialized
|
||||
this.fetchPreferences();
|
||||
|
||||
|
||||
//registry array
|
||||
this.registries = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the preferences
|
||||
* @return preferences
|
||||
*/
|
||||
getPreferences() {
|
||||
return this.preferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the preferences
|
||||
* @param properties
|
||||
*/
|
||||
updatePreferences(properties) {
|
||||
angular.extend(this.preferences, properties);
|
||||
return this.preferences.$save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove preferences properties
|
||||
* @param properties (list of keys)
|
||||
*/
|
||||
removePreferences(properties) {
|
||||
// delete method doesn't send body when it is defined in $resources
|
||||
// that's why direct $http call is used.
|
||||
this.$http({
|
||||
url: '/api/preferences',
|
||||
method: 'DELETE',
|
||||
headers: {'Content-Type': 'application/json;charset=utf-8'},
|
||||
data: properties}).then(resp => {
|
||||
this.fetchPreferences();
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the preferences data
|
||||
*/
|
||||
fetchPreferences() {
|
||||
let preferences = this.remotePreferencesAPI.getPreferences();
|
||||
// if we don't yet have data
|
||||
if (!this.preferences) {
|
||||
// set preferences for using promise in controllers during first request
|
||||
this.preferences = preferences;
|
||||
}
|
||||
|
||||
let preferencesPromise = this.preferences.$promise;
|
||||
|
||||
preferencesPromise.then((preferences) => {
|
||||
// update preferences data if we have new value
|
||||
this.preferences = preferences;
|
||||
});
|
||||
|
||||
return preferencesPromise;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the registries
|
||||
* @return registries
|
||||
*/
|
||||
getRegistries() {
|
||||
return this.registries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a registry
|
||||
* @param registryUrl
|
||||
* @param userName
|
||||
* @param userEmail
|
||||
* @param userPassword
|
||||
* @returns {*} the promise
|
||||
*/
|
||||
addRegistry(registryUrl, userName, userPassword) {
|
||||
let credentials = {};
|
||||
credentials[registryUrl] = {
|
||||
username: userName,
|
||||
password: userPassword
|
||||
};
|
||||
|
||||
if (this.preferences.dockerCredentials) {
|
||||
let remoteCredentialsJson = this.$window.atob(this.preferences.dockerCredentials);
|
||||
let remoteCredentials = angular.fromJson(remoteCredentialsJson);
|
||||
if (remoteCredentials[registryUrl]) {
|
||||
delete remoteCredentials[registryUrl];
|
||||
}
|
||||
angular.extend(credentials, remoteCredentials);
|
||||
}
|
||||
|
||||
let credentialsBase64 = this.$window.btoa(angular.toJson(credentials));
|
||||
let preferences = {dockerCredentials: credentialsBase64};
|
||||
let promise = this.updatePreferences(preferences);
|
||||
|
||||
promise.then((preferences) => {
|
||||
this.preferences = preferences;
|
||||
this._updateRegistries(preferences);
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the registry by its URL
|
||||
* @param registryUrl
|
||||
* @returns {*} the promise
|
||||
*/
|
||||
removeRegistry(registryUrl) {
|
||||
let credentialsJson = this.$window.atob(this.preferences.dockerCredentials);
|
||||
let credentials = angular.fromJson(credentialsJson);
|
||||
|
||||
delete credentials[registryUrl];
|
||||
|
||||
let credentialsBase64 = this.$window.btoa(angular.toJson(credentials));
|
||||
let preferences = {dockerCredentials: credentialsBase64};
|
||||
|
||||
let promise = this.updatePreferences(preferences);
|
||||
|
||||
promise.then((preferences) => {
|
||||
this.preferences = preferences;
|
||||
this._updateRegistries(preferences);
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update registry array from preferences
|
||||
* @param preferences
|
||||
*/
|
||||
_updateRegistries(preferences) {
|
||||
this.registries.length = 0;
|
||||
if (preferences.dockerCredentials) {
|
||||
let credentialsJson = this.$window.atob(preferences.dockerCredentials);
|
||||
let credentials = angular.fromJson(credentialsJson);
|
||||
|
||||
for (var key in credentials) {
|
||||
let credential = {
|
||||
url: key,
|
||||
username: credentials[key].username,
|
||||
password: credentials[key].password
|
||||
};
|
||||
this.registries.push(credential);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Test of the ChePreferences
|
||||
*/
|
||||
describe('ChePreferences', function () {
|
||||
|
||||
/**
|
||||
* Preferences Factory for the test
|
||||
*/
|
||||
var factory;
|
||||
|
||||
/**
|
||||
* API builder.
|
||||
*/
|
||||
var apiBuilder;
|
||||
|
||||
/**
|
||||
* Backend for handling http operations
|
||||
*/
|
||||
var httpBackend;
|
||||
|
||||
/**
|
||||
* che backend
|
||||
*/
|
||||
var cheBackend;
|
||||
|
||||
/**
|
||||
* setup module
|
||||
*/
|
||||
beforeEach(angular.mock.module('userDashboard'));
|
||||
|
||||
/**
|
||||
* Inject factory and http backend
|
||||
*/
|
||||
beforeEach(inject(function (chePreferences, cheAPIBuilder, cheHttpBackend) {
|
||||
factory = chePreferences;
|
||||
apiBuilder = cheAPIBuilder;
|
||||
cheBackend = cheHttpBackend;
|
||||
httpBackend = cheHttpBackend.getHttpBackend();
|
||||
}));
|
||||
|
||||
/**
|
||||
* Check assertion after the test
|
||||
*/
|
||||
afterEach(function () {
|
||||
httpBackend.verifyNoOutstandingExpectation();
|
||||
httpBackend.verifyNoOutstandingRequest();
|
||||
});
|
||||
|
||||
/**
|
||||
* Check that we're able to fetch preferences
|
||||
*/
|
||||
it('Fetch preferences', function () {
|
||||
// providing request
|
||||
// add default preferences on Http backend
|
||||
let defaultPreferences = { pref1 : "value1", pref2 : "value2"};
|
||||
cheBackend.addDefaultPreferences(defaultPreferences);
|
||||
|
||||
// setup backend
|
||||
cheBackend.setup();
|
||||
|
||||
// fetch preferences
|
||||
factory.fetchPreferences();
|
||||
|
||||
// expecting GETs
|
||||
httpBackend.expectGET('/api/preferences');
|
||||
|
||||
// flush command
|
||||
httpBackend.flush();
|
||||
|
||||
// now, check preferences
|
||||
let preferences = factory.getPreferences();
|
||||
|
||||
expect(preferences["pref1"]).toEqual("value1");
|
||||
expect(preferences["pref2"]).toEqual("value2");
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Check that we're able to update preferences
|
||||
*/
|
||||
it('Update preferences', function () {
|
||||
let defaultPreferences = { pref1 : "value1" };
|
||||
|
||||
// setup backend
|
||||
cheBackend.setup();
|
||||
cheBackend.setPreferences(defaultPreferences);
|
||||
|
||||
// fetch preferences
|
||||
factory.updatePreferences(defaultPreferences);
|
||||
|
||||
// expecting POST
|
||||
httpBackend.expectPOST('/api/preferences');
|
||||
|
||||
// flush command
|
||||
httpBackend.flush();
|
||||
|
||||
// now, check preferences
|
||||
let preferences = factory.getPreferences();
|
||||
|
||||
expect(preferences["pref1"]).toEqual("value1");
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Check that we're able to delete preferences
|
||||
*/
|
||||
it('Remove preferences', function () {
|
||||
|
||||
let defaultPreferences = { pref1 : "value1", pref2 : "value2" };
|
||||
cheBackend.addDefaultPreferences(defaultPreferences);
|
||||
|
||||
// setup backend
|
||||
cheBackend.setup();
|
||||
|
||||
// r
|
||||
factory.removePreferences(["pref1"]);
|
||||
|
||||
// expecting POST
|
||||
httpBackend.expectDELETE('/api/preferences');
|
||||
|
||||
// flush command
|
||||
httpBackend.flush();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
@ -21,9 +21,8 @@ export class CheProfile {
|
|||
* Default constructor that is using resource
|
||||
* @ngInject for Dependency injection
|
||||
*/
|
||||
constructor($resource, $http, $window) {
|
||||
constructor($resource, $http) {
|
||||
this.$resource = $resource;
|
||||
this.$window = $window;
|
||||
|
||||
// http is used for sending data with DELETE method (angular is not sending any data by default with DELETE)
|
||||
this.$http = $http;
|
||||
|
|
@ -31,22 +30,13 @@ export class CheProfile {
|
|||
// remote call
|
||||
this.remoteProfileAPI = this.$resource('/api/profile', {}, {
|
||||
getById: {method: 'GET', url: '/api/profile/:userId'},
|
||||
setAttributes: {method: 'POST', url: '/api/profile'}
|
||||
setAttributes: {method: 'PUT', url: '/api/profile/attributes'}
|
||||
});
|
||||
|
||||
// remote call for preferences
|
||||
this.remoteProfilePreferencesAPI = this.$resource('/api/profile/prefs');
|
||||
|
||||
this.profileIdMap = new Map();
|
||||
|
||||
// fetch the profile when we're initialized
|
||||
this.fetchProfile();
|
||||
|
||||
// fetch the profilePreferences when we're initialized
|
||||
this.fetchPreferences();
|
||||
|
||||
//registry array
|
||||
this.registries = [];
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -58,129 +48,6 @@ export class CheProfile {
|
|||
return this.profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the preferences
|
||||
* @return preferences
|
||||
*/
|
||||
getPreferences() {
|
||||
return this.profilePreferences;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the preferences
|
||||
* @param properties
|
||||
* @returns {*} the promise
|
||||
*/
|
||||
updatePreferences(properties) {
|
||||
angular.extend(this.profilePreferences, properties);
|
||||
return this.profilePreferences.$save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the registries
|
||||
* @return registries
|
||||
*/
|
||||
getRegistries() {
|
||||
return this.registries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a registry
|
||||
* @param registryUrl
|
||||
* @param userName
|
||||
* @param userEmail
|
||||
* @param userPassword
|
||||
* @returns {*} the promise
|
||||
*/
|
||||
addRegistry(registryUrl, userName, userPassword) {
|
||||
let credentials = {};
|
||||
credentials[registryUrl] = {
|
||||
username: userName,
|
||||
password: userPassword
|
||||
};
|
||||
|
||||
if (this.profilePreferences.dockerCredentials) {
|
||||
let remoteCredentialsJson = this.$window.atob(this.profilePreferences.dockerCredentials);
|
||||
let remoteCredentials = angular.fromJson(remoteCredentialsJson);
|
||||
if (remoteCredentials[registryUrl]) {
|
||||
delete remoteCredentials[registryUrl];
|
||||
}
|
||||
angular.extend(credentials, remoteCredentials);
|
||||
}
|
||||
|
||||
let credentialsBase64 = this.$window.btoa(angular.toJson(credentials));
|
||||
let preferences = {dockerCredentials: credentialsBase64};
|
||||
let promise = this.updatePreferences(preferences);
|
||||
|
||||
promise.then((profilePreferences) => {
|
||||
this.profilePreferences = profilePreferences;
|
||||
this._updateRegistries(profilePreferences);
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the registry by its URL
|
||||
* @param registryUrl
|
||||
* @returns {*} the promise
|
||||
*/
|
||||
removeRegistry(registryUrl) {
|
||||
let credentialsJson = this.$window.atob(this.profilePreferences.dockerCredentials);
|
||||
let credentials = angular.fromJson(credentialsJson);
|
||||
|
||||
delete credentials[registryUrl];
|
||||
|
||||
let credentialsBase64 = this.$window.btoa(angular.toJson(credentials));
|
||||
let preferences = {dockerCredentials: credentialsBase64};
|
||||
|
||||
let promise = this.updatePreferences(preferences);
|
||||
|
||||
promise.then((profilePreferences) => {
|
||||
this.profilePreferences = profilePreferences;
|
||||
this._updateRegistries(profilePreferences);
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update registry array from profile preferences
|
||||
* @param profilePreferences
|
||||
*/
|
||||
_updateRegistries(profilePreferences) {
|
||||
this.registries.length = 0;
|
||||
if (profilePreferences.dockerCredentials) {
|
||||
let credentialsJson = this.$window.atob(profilePreferences.dockerCredentials);
|
||||
let credentials = angular.fromJson(credentialsJson);
|
||||
|
||||
for (var key in credentials) {
|
||||
let credential = {
|
||||
url: key,
|
||||
username: credentials[key].username,
|
||||
password: credentials[key].password
|
||||
};
|
||||
this.registries.push(credential);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove preferences properties
|
||||
* @param properties (list of keys)
|
||||
*/
|
||||
removePreferences(properties) {
|
||||
this.$http({
|
||||
url: '/api/profile/prefs',
|
||||
method: 'DELETE',
|
||||
headers: {'Content-Type': 'application/json;charset=utf-8'},
|
||||
data: properties
|
||||
});
|
||||
this.fetchPreferences();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full name if it possible
|
||||
* @returns {string} full name
|
||||
|
|
@ -223,28 +90,6 @@ export class CheProfile {
|
|||
return profilePromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the preferences data
|
||||
*/
|
||||
fetchPreferences() {
|
||||
let profilePreferences = this.remoteProfilePreferencesAPI.get();
|
||||
// if we don't yet have data
|
||||
if (!this.profilePreferences) {
|
||||
// set profilePreferences for using promise in controllers during first request
|
||||
this.profilePreferences = profilePreferences;
|
||||
}
|
||||
|
||||
let profilePrefsPromise = this.profilePreferences.$promise;
|
||||
|
||||
profilePrefsPromise.then((profilePreferences) => {
|
||||
// update profilePreferences data if we have new value
|
||||
this.profilePreferences = profilePreferences;
|
||||
this._updateRegistries(profilePreferences);
|
||||
});
|
||||
|
||||
return profilePrefsPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the profile attributes data
|
||||
* @param attributes
|
||||
|
|
|
|||
|
|
@ -82,8 +82,6 @@ describe('CheProfile', function () {
|
|||
|
||||
// expecting GETs
|
||||
httpBackend.expectGET('/api/profile');
|
||||
httpBackend.expectGET('/api/profile/prefs');
|
||||
|
||||
// flush command
|
||||
httpBackend.flush();
|
||||
|
||||
|
|
@ -92,7 +90,7 @@ describe('CheProfile', function () {
|
|||
|
||||
// check id, email, firstName and lastName in profile attributes
|
||||
expect(profile.id).toEqual(profileId);
|
||||
expect(profile.attributes.email).toEqual(email);
|
||||
expect(profile.email).toEqual(email);
|
||||
expect(profile.attributes.firstName).toEqual(firstName);
|
||||
expect(profile.attributes.lastName).toEqual(lastName);
|
||||
}
|
||||
|
|
@ -112,8 +110,8 @@ describe('CheProfile', function () {
|
|||
// fetch profile
|
||||
factory.setAttributes(testAttributes);
|
||||
|
||||
// expecting a POST
|
||||
httpBackend.expectPOST('/api/profile');
|
||||
// expecting a PUT
|
||||
httpBackend.expectPUT('/api/profile/attributes');
|
||||
|
||||
// flush command
|
||||
httpBackend.flush();
|
||||
|
|
|
|||
|
|
@ -61,12 +61,15 @@ export class CheHttpBackend {
|
|||
|
||||
//profiles
|
||||
this.httpBackend.when('GET', '/api/profile').respond(this.defaultProfile);
|
||||
this.httpBackend.when('GET', '/api/profile/prefs').respond(this.defaultProfilePrefs);
|
||||
var profileKeys = this.profilesMap.keys();
|
||||
for (let key of profileKeys) {
|
||||
this.httpBackend.when('GET', '/api/profile/' + key).respond(this.profilesMap.get(key));
|
||||
}
|
||||
|
||||
//preferences
|
||||
this.httpBackend.when('GET', '/api/preferences').respond(this.defaultPreferences);
|
||||
this.httpBackend.when('DELETE', '/api/preferences').respond();
|
||||
|
||||
/// project details
|
||||
var projectDetailsKeys = this.projectDetailsMap.keys();
|
||||
for (let projectKey of projectDetailsKeys) {
|
||||
|
|
@ -177,6 +180,23 @@ export class CheHttpBackend {
|
|||
this.defaultProfile = profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given preferences
|
||||
* @param preferences
|
||||
*/
|
||||
addDefaultPreferences(preferences) {
|
||||
this.defaultPreferences = preferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given preferences
|
||||
* @param preferences
|
||||
*/
|
||||
setPreferences(preferences) {
|
||||
this.httpBackend.when('POST', '/api/preferences').respond(preferences);
|
||||
this.defaultPreferences = preferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given profile
|
||||
* @param profile
|
||||
|
|
@ -191,7 +211,7 @@ export class CheHttpBackend {
|
|||
* @param attributes
|
||||
*/
|
||||
setAttributes(attributes) {
|
||||
this.httpBackend.when('POST', '/api/profile').respond(attributes);
|
||||
this.httpBackend.when('PUT', '/api/profile/attributes').respond(attributes);
|
||||
this.defaultProfile.attributes = attributes;
|
||||
}
|
||||
|
||||
|
|
@ -312,4 +332,3 @@ export class CheHttpBackend {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,18 +23,18 @@ export class CheLearnMoreCtrl {
|
|||
* Default constructor that is using resource
|
||||
* @ngInject for Dependency injection
|
||||
*/
|
||||
constructor($scope, $element, $attrs, $compile, cheProfile) {
|
||||
constructor($scope, $element, $attrs, $compile, chePreferences) {
|
||||
this.items = [];
|
||||
|
||||
this.WIDGET_PREFERENCES_PREFIX = 'learn-widget-';
|
||||
|
||||
this.cheProfile = cheProfile;
|
||||
this.chePreferences = chePreferences;
|
||||
|
||||
// current index is first one
|
||||
this.currentIndex = 0;
|
||||
|
||||
|
||||
let preferences = this.cheProfile.getPreferences();
|
||||
let preferences = this.chePreferences.getPreferences();
|
||||
let promise = preferences.$promise;
|
||||
|
||||
promise.then(() => {
|
||||
|
|
@ -87,7 +87,7 @@ export class CheLearnMoreCtrl {
|
|||
let checkKey = this.WIDGET_PREFERENCES_PREFIX + key;
|
||||
var properties = {};
|
||||
properties[checkKey] = value;
|
||||
this.cheProfile.updatePreferences(properties);
|
||||
this.chePreferences.updatePreferences(properties);
|
||||
|
||||
// also update icon state
|
||||
this.stateIcons[key] = value;
|
||||
|
|
@ -104,7 +104,7 @@ export class CheLearnMoreCtrl {
|
|||
// check if key is stored in preferences
|
||||
// if there,
|
||||
if (key) {
|
||||
let preferences = this.cheProfile.getPreferences();
|
||||
let preferences = this.chePreferences.getPreferences();
|
||||
let promise = preferences.$promise;
|
||||
|
||||
promise.then(() => {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.che.ide.api.app;
|
||||
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDescriptor;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDto;
|
||||
|
||||
import com.google.inject.Singleton;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -22,17 +23,17 @@ import java.util.Map;
|
|||
@Singleton
|
||||
public class CurrentUser {
|
||||
|
||||
private ProfileDescriptor profileDescriptor;
|
||||
private ProfileDto profileDescriptor;
|
||||
private Map<String, String> preferences;
|
||||
|
||||
public CurrentUser() {
|
||||
}
|
||||
|
||||
public CurrentUser(ProfileDescriptor profileDescriptor) {
|
||||
public CurrentUser(ProfileDto profileDescriptor) {
|
||||
this(profileDescriptor, null);
|
||||
}
|
||||
|
||||
public CurrentUser(ProfileDescriptor profileDescriptor, Map<String, String> preferences) {
|
||||
public CurrentUser(ProfileDto profileDescriptor, Map<String, String> preferences) {
|
||||
this.profileDescriptor = profileDescriptor;
|
||||
this.preferences = preferences;
|
||||
}
|
||||
|
|
@ -42,11 +43,11 @@ public class CurrentUser {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
public ProfileDescriptor getProfile() {
|
||||
public ProfileDto getProfile() {
|
||||
return profileDescriptor;
|
||||
}
|
||||
|
||||
public void setProfile(ProfileDescriptor profileDescriptor) {
|
||||
public void setProfile(ProfileDto profileDescriptor) {
|
||||
this.profileDescriptor = profileDescriptor;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.ide.api.user;
|
||||
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* GWT client for preferences service;
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public interface PreferencesServiceClient {
|
||||
|
||||
/**
|
||||
* Updates user's preferences using the merge strategy.
|
||||
*
|
||||
* @param prefsToUpdate
|
||||
* preferences update
|
||||
* @return a promise that resolves all the user's preferences, or rejects with an error
|
||||
*/
|
||||
Promise<Map<String, String>> updatePreferences(@NotNull Map<String, String> prefsToUpdate);
|
||||
|
||||
/**
|
||||
* Gets user preferences.
|
||||
*
|
||||
* @return a promise that resolves preferences, or rejects with an error
|
||||
*/
|
||||
Promise<Map<String, String>> getPreferences();
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.ide.api.user;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.ide.json.JsonHelper;
|
||||
import org.eclipse.che.ide.rest.AsyncRequestFactory;
|
||||
import org.eclipse.che.ide.rest.RestContext;
|
||||
import org.eclipse.che.ide.rest.StringMapUnmarshaller;
|
||||
import org.eclipse.che.ide.ui.loaders.request.LoaderFactory;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.eclipse.che.ide.MimeType.APPLICATION_JSON;
|
||||
import static org.eclipse.che.ide.rest.HTTPHeader.ACCEPT;
|
||||
import static org.eclipse.che.ide.rest.HTTPHeader.CONTENT_TYPE;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link PreferencesServiceClient}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class PreferencesServiceClientImpl implements PreferencesServiceClient {
|
||||
|
||||
private final String PREFERENCES_PATH;
|
||||
private final LoaderFactory loaderFactory;
|
||||
private final AsyncRequestFactory asyncRequestFactory;
|
||||
|
||||
@Inject
|
||||
protected PreferencesServiceClientImpl(@RestContext String restContext,
|
||||
LoaderFactory loaderFactory,
|
||||
AsyncRequestFactory asyncRequestFactory) {
|
||||
this.loaderFactory = loaderFactory;
|
||||
this.asyncRequestFactory = asyncRequestFactory;
|
||||
PREFERENCES_PATH = restContext + "/preferences";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<Map<String, String>> getPreferences() {
|
||||
return asyncRequestFactory.createGetRequest(PREFERENCES_PATH)
|
||||
.header(ACCEPT, APPLICATION_JSON)
|
||||
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||
.loader(loaderFactory.newLoader("Getting user's preferences..."))
|
||||
.send(new StringMapUnmarshaller());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<Map<String, String>> updatePreferences(Map<String, String> update) {
|
||||
final String data = JsonHelper.toJson(update);
|
||||
return asyncRequestFactory.createPutRequest(PREFERENCES_PATH, null)
|
||||
.header(ACCEPT, APPLICATION_JSON)
|
||||
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||
.data(data)
|
||||
.loader(loaderFactory.newLoader("Updating user's preferences..."))
|
||||
.send(new StringMapUnmarshaller());
|
||||
}
|
||||
}
|
||||
|
|
@ -10,8 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.che.ide.api.user;
|
||||
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDescriptor;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDto;
|
||||
import org.eclipse.che.ide.rest.AsyncRequestCallback;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
|
@ -29,7 +28,7 @@ public interface UserProfileServiceClient {
|
|||
*
|
||||
* @param callback
|
||||
*/
|
||||
void getCurrentProfile(AsyncRequestCallback<ProfileDescriptor> callback);
|
||||
void getCurrentProfile(AsyncRequestCallback<ProfileDto> callback);
|
||||
|
||||
/**
|
||||
* Update current user's profile.
|
||||
|
|
@ -38,7 +37,7 @@ public interface UserProfileServiceClient {
|
|||
* attributes to update
|
||||
* @param callback
|
||||
*/
|
||||
void updateCurrentProfile(@NotNull Map<String, String> updates, AsyncRequestCallback<ProfileDescriptor> callback);
|
||||
void updateCurrentProfile(@NotNull Map<String, String> updates, AsyncRequestCallback<ProfileDto> callback);
|
||||
|
||||
/**
|
||||
* Get profile by id.
|
||||
|
|
@ -47,26 +46,8 @@ public interface UserProfileServiceClient {
|
|||
* profile's id
|
||||
* @param callback
|
||||
*/
|
||||
void getProfileById(@NotNull String id, AsyncRequestCallback<ProfileDescriptor> callback);
|
||||
void getProfileById(@NotNull String id, AsyncRequestCallback<ProfileDto> callback);
|
||||
|
||||
/**
|
||||
* Get user preferences
|
||||
*
|
||||
* @param callback
|
||||
* which contains some action with user preferences
|
||||
* @deprecated use {@link #getPreferences()}
|
||||
*/
|
||||
@Deprecated
|
||||
void getPreferences(AsyncRequestCallback<Map<String, String>> callback);
|
||||
|
||||
/**
|
||||
* Get user preferences
|
||||
*
|
||||
* @return the promise which either uses preferences for some actions or rejects with an error
|
||||
*/
|
||||
Promise<Map<String, String>> getPreferences();
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Update profile.
|
||||
|
|
@ -77,25 +58,5 @@ public interface UserProfileServiceClient {
|
|||
* attributes to update
|
||||
* @param callback
|
||||
*/
|
||||
void updateProfile(@NotNull String id, Map<String, String> updates, AsyncRequestCallback<ProfileDescriptor> callback);
|
||||
|
||||
/**
|
||||
* Update preferences.
|
||||
*
|
||||
* @param prefsToUpdate
|
||||
* preferences to update
|
||||
* @param callback
|
||||
* which contains some action with user preferences
|
||||
* @deprecated use {@link #updatePreferences(Map)}
|
||||
*/
|
||||
@Deprecated
|
||||
void updatePreferences(@NotNull Map<String, String> prefsToUpdate, AsyncRequestCallback<Map<String, String>> callback);
|
||||
|
||||
/**
|
||||
* Update preferences.
|
||||
*
|
||||
* @param prefsToUpdate
|
||||
* @return promise which either uses preferences for some actions or rejects with an error
|
||||
*/
|
||||
Promise<Map<String, String>> updatePreferences(@NotNull Map<String, String> prefsToUpdate);
|
||||
void updateProfile(@NotNull String id, Map<String, String> updates, AsyncRequestCallback<ProfileDto> callback);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ package org.eclipse.che.ide.api.user;
|
|||
import com.google.inject.Inject;
|
||||
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDescriptor;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDto;
|
||||
import org.eclipse.che.ide.json.JsonHelper;
|
||||
import org.eclipse.che.ide.rest.AsyncRequestCallback;
|
||||
import org.eclipse.che.ide.rest.AsyncRequestFactory;
|
||||
|
|
@ -35,7 +35,6 @@ import static org.eclipse.che.ide.rest.HTTPHeader.CONTENT_TYPE;
|
|||
*/
|
||||
public class UserProfileServiceClientImpl implements UserProfileServiceClient {
|
||||
private final String PROFILE;
|
||||
private final String PREFS;
|
||||
private final LoaderFactory loaderFactory;
|
||||
private final AsyncRequestFactory asyncRequestFactory;
|
||||
|
||||
|
|
@ -46,12 +45,11 @@ public class UserProfileServiceClientImpl implements UserProfileServiceClient {
|
|||
this.loaderFactory = loaderFactory;
|
||||
this.asyncRequestFactory = asyncRequestFactory;
|
||||
PROFILE = restContext + "/profile/";
|
||||
PREFS = PROFILE + "prefs";
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void getCurrentProfile(AsyncRequestCallback<ProfileDescriptor> callback) {
|
||||
public void getCurrentProfile(AsyncRequestCallback<ProfileDto> callback) {
|
||||
asyncRequestFactory.createGetRequest(PROFILE)
|
||||
.header(ACCEPT, APPLICATION_JSON)
|
||||
.loader(loaderFactory.newLoader("Retrieving current user's profile..."))
|
||||
|
|
@ -60,7 +58,7 @@ public class UserProfileServiceClientImpl implements UserProfileServiceClient {
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void updateCurrentProfile(@NotNull Map<String, String> updates, AsyncRequestCallback<ProfileDescriptor> callback) {
|
||||
public void updateCurrentProfile(@NotNull Map<String, String> updates, AsyncRequestCallback<ProfileDto> callback) {
|
||||
asyncRequestFactory.createPostRequest(PROFILE, null)
|
||||
.header(ACCEPT, APPLICATION_JSON)
|
||||
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||
|
|
@ -71,7 +69,7 @@ public class UserProfileServiceClientImpl implements UserProfileServiceClient {
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void getProfileById(@NotNull String id, AsyncRequestCallback<ProfileDescriptor> callback) {
|
||||
public void getProfileById(@NotNull String id, AsyncRequestCallback<ProfileDto> callback) {
|
||||
String requestUrl = PROFILE + id;
|
||||
|
||||
asyncRequestFactory.createGetRequest(requestUrl)
|
||||
|
|
@ -80,27 +78,9 @@ public class UserProfileServiceClientImpl implements UserProfileServiceClient {
|
|||
.send(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPreferences(AsyncRequestCallback<Map<String, String>> callback) {
|
||||
asyncRequestFactory.createGetRequest(PREFS)
|
||||
.header(ACCEPT, APPLICATION_JSON)
|
||||
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||
.loader(loaderFactory.newLoader("Getting user's preferences..."))
|
||||
.send(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Promise<Map<String, String>> getPreferences() {
|
||||
return asyncRequestFactory.createGetRequest(PREFS)
|
||||
.header(ACCEPT, APPLICATION_JSON)
|
||||
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||
.loader(loaderFactory.newLoader("Getting user's preferences..."))
|
||||
.send(new StringMapUnmarshaller());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void updateProfile(@NotNull String id, Map<String, String> updates, AsyncRequestCallback<ProfileDescriptor> callback) {
|
||||
public void updateProfile(@NotNull String id, Map<String, String> updates, AsyncRequestCallback<ProfileDto> callback) {
|
||||
String requestUrl = PROFILE + id;
|
||||
|
||||
asyncRequestFactory.createPostRequest(requestUrl, null)
|
||||
|
|
@ -110,28 +90,4 @@ public class UserProfileServiceClientImpl implements UserProfileServiceClient {
|
|||
.loader(loaderFactory.newLoader("Updating user's profile..."))
|
||||
.send(callback);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void updatePreferences(@NotNull Map<String, String> update, AsyncRequestCallback<Map<String, String>> callback) {
|
||||
final String data = JsonHelper.toJson(update);
|
||||
asyncRequestFactory.createPostRequest(PREFS, null)
|
||||
.header(ACCEPT, APPLICATION_JSON)
|
||||
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||
.data(data)
|
||||
.loader(loaderFactory.newLoader("Updating user's preferences..."))
|
||||
.send(callback);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public Promise<Map<String, String>> updatePreferences(@NotNull Map<String, String> update) {
|
||||
final String data = JsonHelper.toJson(update);
|
||||
return asyncRequestFactory.createPostRequest(PREFS, null)
|
||||
.header(ACCEPT, APPLICATION_JSON)
|
||||
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||
.data(data)
|
||||
.loader(loaderFactory.newLoader("Updating user's preferences..."))
|
||||
.send(new StringMapUnmarshaller());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.che.ide.api.user;
|
||||
|
||||
import org.eclipse.che.api.user.shared.dto.UserDescriptor;
|
||||
import org.eclipse.che.api.user.shared.dto.UserDto;
|
||||
import org.eclipse.che.ide.rest.AsyncRequestCallback;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
|
@ -31,14 +31,14 @@ public interface UserServiceClient {
|
|||
* if <code>true</code> - is temporary user
|
||||
* @param callback
|
||||
*/
|
||||
void createUser(@NotNull String token, boolean isTemporary, AsyncRequestCallback<UserDescriptor> callback);
|
||||
void createUser(@NotNull String token, boolean isTemporary, AsyncRequestCallback<UserDto> callback);
|
||||
|
||||
/**
|
||||
* Get current user's information.
|
||||
*
|
||||
* @param callback
|
||||
*/
|
||||
void getCurrentUser(AsyncRequestCallback<UserDescriptor> callback);
|
||||
void getCurrentUser(AsyncRequestCallback<UserDto> callback);
|
||||
|
||||
/**
|
||||
* Update user's password.
|
||||
|
|
@ -56,7 +56,7 @@ public interface UserServiceClient {
|
|||
* user's id
|
||||
* @param callback
|
||||
*/
|
||||
void getUserById(@NotNull String id, AsyncRequestCallback<UserDescriptor> callback);
|
||||
void getUserById(@NotNull String id, AsyncRequestCallback<UserDto> callback);
|
||||
|
||||
/**
|
||||
* Get user's information by its alias.
|
||||
|
|
@ -65,7 +65,7 @@ public interface UserServiceClient {
|
|||
* user's alias
|
||||
* @param callback
|
||||
*/
|
||||
void getUserByAlias(@NotNull String alias, AsyncRequestCallback<UserDescriptor> callback);
|
||||
void getUserByAlias(@NotNull String alias, AsyncRequestCallback<UserDto> callback);
|
||||
|
||||
/**
|
||||
* Remove user.
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ package org.eclipse.che.ide.api.user;
|
|||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.eclipse.che.api.user.shared.dto.UserDescriptor;
|
||||
import org.eclipse.che.api.user.shared.dto.UserDto;
|
||||
import org.eclipse.che.ide.MimeType;
|
||||
import org.eclipse.che.ide.rest.AsyncRequestCallback;
|
||||
import org.eclipse.che.ide.rest.AsyncRequestFactory;
|
||||
|
|
@ -52,7 +52,7 @@ public class UserServiceClientImpl implements UserServiceClient {
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void createUser(@NotNull String token, boolean isTemporary, AsyncRequestCallback<UserDescriptor> callback) {
|
||||
public void createUser(@NotNull String token, boolean isTemporary, AsyncRequestCallback<UserDto> callback) {
|
||||
StringBuilder requestUrl = new StringBuilder(CREATE);
|
||||
requestUrl.append("?token=").append(token).append("&temporary=").append(isTemporary);
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ public class UserServiceClientImpl implements UserServiceClient {
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void getCurrentUser(AsyncRequestCallback<UserDescriptor> callback) {
|
||||
public void getCurrentUser(AsyncRequestCallback<UserDto> callback) {
|
||||
|
||||
asyncRequestFactory.createGetRequest(USER)
|
||||
.header(ACCEPT, MimeType.APPLICATION_JSON)
|
||||
|
|
@ -86,7 +86,7 @@ public class UserServiceClientImpl implements UserServiceClient {
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void getUserById(@NotNull String id, AsyncRequestCallback<UserDescriptor> callback) {
|
||||
public void getUserById(@NotNull String id, AsyncRequestCallback<UserDto> callback) {
|
||||
String requestUrl = USER + id;
|
||||
|
||||
asyncRequestFactory.createGetRequest(requestUrl)
|
||||
|
|
@ -97,7 +97,7 @@ public class UserServiceClientImpl implements UserServiceClient {
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void getUserByAlias(@NotNull String alias, AsyncRequestCallback<UserDescriptor> callback) {
|
||||
public void getUserByAlias(@NotNull String alias, AsyncRequestCallback<UserDto> callback) {
|
||||
String requestUrl = FIND + "?alias=" + alias;
|
||||
|
||||
asyncRequestFactory.createGetRequest(requestUrl)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ import org.eclipse.che.ide.api.project.ProjectTypeServiceClient;
|
|||
import org.eclipse.che.ide.api.project.ProjectTypeServiceClientImpl;
|
||||
import org.eclipse.che.ide.api.ssh.SshServiceClient;
|
||||
import org.eclipse.che.ide.api.ssh.SshServiceClientImpl;
|
||||
import org.eclipse.che.ide.api.user.PreferencesServiceClient;
|
||||
import org.eclipse.che.ide.api.user.PreferencesServiceClientImpl;
|
||||
import org.eclipse.che.ide.api.user.UserProfileServiceClient;
|
||||
import org.eclipse.che.ide.api.user.UserProfileServiceClientImpl;
|
||||
import org.eclipse.che.ide.api.user.UserServiceClient;
|
||||
|
|
@ -333,6 +335,7 @@ public class CoreGinModule extends AbstractGinModule {
|
|||
private void configurePlatformApiGwtClients() {
|
||||
bind(UserServiceClient.class).to(UserServiceClientImpl.class).in(Singleton.class);
|
||||
bind(UserProfileServiceClient.class).to(UserProfileServiceClientImpl.class).in(Singleton.class);
|
||||
bind(PreferencesServiceClient.class).to(PreferencesServiceClientImpl.class).in(Singleton.class);
|
||||
bind(GitServiceClient.class).to(GitServiceClientImpl.class).in(Singleton.class);
|
||||
bind(OAuthServiceClient.class).to(OAuthServiceClientImpl.class).in(Singleton.class);
|
||||
bind(FactoryServiceClient.class).to(FactoryServiceClientImpl.class).in(Singleton.class);
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.che.ide.core;
|
||||
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDto;
|
||||
import org.eclipse.che.ide.api.user.UserProfileServiceClient;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDescriptor;
|
||||
import org.eclipse.che.ide.api.app.CurrentUser;
|
||||
import org.eclipse.che.ide.api.component.Component;
|
||||
import org.eclipse.che.ide.rest.AsyncRequestCallback;
|
||||
|
|
@ -40,10 +40,10 @@ public class ProfileComponent implements Component {
|
|||
|
||||
@Override
|
||||
public void start(final Callback<Component, Exception> callback) {
|
||||
AsyncRequestCallback<ProfileDescriptor> asyncRequestCallback = new AsyncRequestCallback<ProfileDescriptor>(
|
||||
dtoUnmarshallerFactory.newUnmarshaller(ProfileDescriptor.class)) {
|
||||
AsyncRequestCallback<ProfileDto> asyncRequestCallback = new AsyncRequestCallback<ProfileDto>(
|
||||
dtoUnmarshallerFactory.newUnmarshaller(ProfileDto.class)) {
|
||||
@Override
|
||||
protected void onSuccess(final ProfileDescriptor profile) {
|
||||
protected void onSuccess(final ProfileDto profile) {
|
||||
currentUser.setProfile(profile);
|
||||
callback.onSuccess(ProfileComponent.this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import org.eclipse.che.api.promises.client.Function;
|
|||
import org.eclipse.che.api.promises.client.FunctionException;
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.api.promises.client.js.Promises;
|
||||
import org.eclipse.che.ide.api.user.UserProfileServiceClient;
|
||||
import org.eclipse.che.ide.api.user.PreferencesServiceClient;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.ide.api.preferences.PreferencesManager;
|
||||
|
||||
|
|
@ -31,22 +31,22 @@ import java.util.Map;
|
|||
*/
|
||||
@Singleton
|
||||
public class PreferencesManagerImpl implements PreferencesManager {
|
||||
private final UserProfileServiceClient userProfileService;
|
||||
private final Map<String, String> changedPreferences;
|
||||
private final Map<String, String> changedPreferences;
|
||||
private final PreferencesServiceClient preferencesService;
|
||||
|
||||
private Map<String, String> persistedPreferences;
|
||||
|
||||
/**
|
||||
* Create preferences manager
|
||||
*
|
||||
* @param userProfileService
|
||||
* @param preferencesService
|
||||
* user preference service client
|
||||
*/
|
||||
@Inject
|
||||
protected PreferencesManagerImpl(UserProfileServiceClient userProfileService) {
|
||||
protected PreferencesManagerImpl(PreferencesServiceClient preferencesService) {
|
||||
this.persistedPreferences = new HashMap<>();
|
||||
this.changedPreferences = new HashMap<>();
|
||||
this.userProfileService = userProfileService;
|
||||
this.preferencesService = preferencesService;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
|
|
@ -72,9 +72,9 @@ public class PreferencesManagerImpl implements PreferencesManager {
|
|||
return Promises.resolve(null);
|
||||
}
|
||||
|
||||
return userProfileService.updatePreferences(changedPreferences).thenPromise(new Function<Map<String,String>, Promise<Void>>() {
|
||||
return preferencesService.updatePreferences(changedPreferences).thenPromise(new Function<Map<String, String>, Promise<Void>>() {
|
||||
@Override
|
||||
public Promise<Void> apply(Map<String,String> result) throws FunctionException {
|
||||
public Promise<Void> apply(Map<String, String> result) throws FunctionException {
|
||||
persistedPreferences.putAll(changedPreferences);
|
||||
changedPreferences.clear();
|
||||
return Promises.resolve(null);
|
||||
|
|
@ -85,7 +85,7 @@ public class PreferencesManagerImpl implements PreferencesManager {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public Promise<Map<String, String>> loadPreferences() {
|
||||
return userProfileService.getPreferences().then(new Function<Map<String, String>, Map<String, String>>() {
|
||||
return preferencesService.getPreferences().then(new Function<Map<String, String>, Map<String, String>>() {
|
||||
@Override
|
||||
public Map<String, String> apply(Map<String, String> preferences) throws FunctionException {
|
||||
persistedPreferences = preferences;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ package org.eclipse.che.plugin.docker.client;
|
|||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import org.eclipse.che.api.user.server.dao.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.PreferenceManager;
|
||||
import org.eclipse.che.commons.annotation.Nullable;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
|
|
@ -35,11 +35,11 @@ public class UserSpecificDockerRegistryCredentialsProvider {
|
|||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UserSpecificDockerRegistryCredentialsProvider.class);
|
||||
|
||||
private PreferenceDao preferenceDao;
|
||||
private PreferenceManager preferenceManager;
|
||||
|
||||
@Inject
|
||||
public UserSpecificDockerRegistryCredentialsProvider(PreferenceDao preferenceDao) {
|
||||
this.preferenceDao = preferenceDao;
|
||||
public UserSpecificDockerRegistryCredentialsProvider(PreferenceManager preferenceManager) {
|
||||
this.preferenceManager = preferenceManager;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -52,11 +52,11 @@ public class UserSpecificDockerRegistryCredentialsProvider {
|
|||
@Nullable
|
||||
public AuthConfigs getCredentials() {
|
||||
try {
|
||||
String encodedCredentials = preferenceDao.getPreferences(EnvironmentContext.getCurrent()
|
||||
.getSubject()
|
||||
.getUserId(),
|
||||
DOCKER_REGISTRY_CREDENTIALS_KEY)
|
||||
.get(DOCKER_REGISTRY_CREDENTIALS_KEY);
|
||||
String encodedCredentials = preferenceManager.find(EnvironmentContext.getCurrent()
|
||||
.getSubject()
|
||||
.getUserId(),
|
||||
DOCKER_REGISTRY_CREDENTIALS_KEY)
|
||||
.get(DOCKER_REGISTRY_CREDENTIALS_KEY);
|
||||
String credentials = encodedCredentials != null ? new String(Base64.getDecoder().decode(encodedCredentials), "UTF-8") : "{}";
|
||||
|
||||
return DtoFactory.newDto(AuthConfigs.class).withConfigs(
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
package org.eclipse.che.plugin.docker.client;
|
||||
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.user.server.dao.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.PreferenceManager;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
|
|
@ -41,13 +41,13 @@ public class UserSpecificDockerRegistryCredentialsProviderTest {
|
|||
private static final String DOCKER_REGISTRY_CREDENTIALS_KEY = "dockerCredentials";
|
||||
|
||||
@Mock
|
||||
private PreferenceDao preferenceDao;
|
||||
private PreferenceManager preferenceManager;
|
||||
|
||||
private UserSpecificDockerRegistryCredentialsProvider dockerCredentials;
|
||||
|
||||
@BeforeClass
|
||||
private void before() {
|
||||
dockerCredentials = new UserSpecificDockerRegistryCredentialsProvider(preferenceDao);
|
||||
dockerCredentials = new UserSpecificDockerRegistryCredentialsProvider(preferenceManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -101,7 +101,7 @@ public class UserSpecificDockerRegistryCredentialsProviderTest {
|
|||
preferences.put(DOCKER_REGISTRY_CREDENTIALS_KEY, base64encodedCredentials);
|
||||
|
||||
EnvironmentContext.getCurrent().setSubject(new SubjectImpl("name", "id", "token1234", false));
|
||||
when(preferenceDao.getPreferences(anyObject(), anyObject())).thenReturn(preferences);
|
||||
when(preferenceManager.find(anyObject(), anyObject())).thenReturn(preferences);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import org.eclipse.che.api.machine.server.MachineInstanceProviders;
|
|||
import org.eclipse.che.api.machine.server.MachineManager;
|
||||
import org.eclipse.che.api.machine.server.MachineRegistry;
|
||||
import org.eclipse.che.api.machine.server.MachineService;
|
||||
import org.eclipse.che.api.machine.server.dao.SnapshotDao;
|
||||
import org.eclipse.che.api.machine.server.spi.SnapshotDao;
|
||||
import org.eclipse.che.api.machine.server.exception.MachineException;
|
||||
import org.eclipse.che.api.machine.server.spi.impl.SnapshotImpl;
|
||||
import org.eclipse.che.api.machine.server.model.impl.MachineImpl;
|
||||
|
|
@ -128,7 +128,7 @@ public class ServiceTest {
|
|||
.withHostConfig(new HostConfig().withPortBindings(
|
||||
singletonMap("5000/tcp", new PortBinding[]{new PortBinding().withHostPort("5000")})));
|
||||
|
||||
registryContainerId = docker.createContainer(containerConfig, null).getId();
|
||||
registryContainerId = docker.createContainer(containerConfig, null).getUserId();
|
||||
|
||||
docker.startContainer(registryContainerId, null);
|
||||
}
|
||||
|
|
@ -192,7 +192,7 @@ public class ServiceTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
public String getUserId() {
|
||||
return USER;
|
||||
}
|
||||
|
||||
|
|
@ -208,7 +208,7 @@ public class ServiceTest {
|
|||
@AfterMethod
|
||||
public void tearDown() throws Exception {
|
||||
for (MachineStateImpl machine : new ArrayList<>(machineManager.getMachinesStates())) {
|
||||
machineManager.destroy(machine.getId(), false);
|
||||
machineManager.destroy(machine.getUserId(), false);
|
||||
}
|
||||
EnvironmentContext.reset();
|
||||
}
|
||||
|
|
@ -224,7 +224,7 @@ public class ServiceTest {
|
|||
.withType("Dockerfile")
|
||||
.withScript("FROM ubuntu\nCMD tail -f /dev/null\n")));
|
||||
|
||||
waitMachineIsRunning(machine.getId());
|
||||
waitMachineIsRunning(machine.getUserId());
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "saveSnapshotTest", enabled = false)
|
||||
|
|
@ -242,27 +242,27 @@ public class ServiceTest {
|
|||
final MachineStateDescriptor machine = machineService
|
||||
.createMachineFromSnapshot(newDto(SnapshotMachineCreationMetadata.class).withSnapshotId(SNAPSHOT_ID));
|
||||
|
||||
waitMachineIsRunning(machine.getId());
|
||||
waitMachineIsRunning(machine.getUserId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMachineTest() throws Exception {
|
||||
final MachineImpl machine = createMachineAndWaitRunningState();
|
||||
|
||||
final MachineDescriptor machineById = machineService.getMachineById(machine.getId());
|
||||
final MachineDescriptor machineById = machineService.getMachineById(machine.getUserId());
|
||||
|
||||
assertEquals(machineById.getId(), machine.getId());
|
||||
assertEquals(machineById.getUserId(), machine.getUserId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMachinesTest() throws Exception {
|
||||
Set<String> expected = new HashSet<>();
|
||||
expected.add(createMachineAndWaitRunningState().getId());
|
||||
expected.add(createMachineAndWaitRunningState().getId());
|
||||
expected.add(createMachineAndWaitRunningState().getUserId());
|
||||
expected.add(createMachineAndWaitRunningState().getUserId());
|
||||
|
||||
Set<String> actual = machineManager.getMachinesStates()
|
||||
.stream()
|
||||
.map(MachineImpl::getId)
|
||||
.map(MachineImpl::getUserId)
|
||||
.collect(Collectors.toSet());
|
||||
assertEquals(actual, expected);
|
||||
}
|
||||
|
|
@ -271,14 +271,14 @@ public class ServiceTest {
|
|||
public void destroyMachineTest() throws Exception {
|
||||
final MachineImpl machine = createMachineAndWaitRunningState();
|
||||
|
||||
machineService.destroyMachine(machine.getId());
|
||||
machineService.destroyMachine(machine.getUserId());
|
||||
|
||||
assertEquals(machineService.getMachineStateById(machine.getId()).getStatus(), MachineStatus.DESTROYING);
|
||||
assertEquals(machineService.getMachineStateById(machine.getUserId()).getStatus(), MachineStatus.DESTROYING);
|
||||
|
||||
int counter = 0;
|
||||
while (++counter < 1000) {
|
||||
try {
|
||||
machineManager.getMachine(machine.getId());
|
||||
machineManager.getMachine(machine.getUserId());
|
||||
} catch (NotFoundException e) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -293,7 +293,7 @@ public class ServiceTest {
|
|||
|
||||
// use machine manager instead of machine service because it returns future with snapshot
|
||||
// that allows check operation result
|
||||
final SnapshotImpl snapshot = machineManager.save(machine.getId(), USER, "test description");
|
||||
final SnapshotImpl snapshot = machineManager.save(machine.getUserId(), USER, "test description");
|
||||
|
||||
for (int i = 0; snapshot.getInstanceKey() == null && i < 10; ++i) {
|
||||
Thread.sleep(500);
|
||||
|
|
@ -337,13 +337,13 @@ public class ServiceTest {
|
|||
final MachineImpl machine = createMachineAndWaitRunningState();
|
||||
|
||||
String commandInMachine = "echo \"command in machine\" && tail -f /dev/null";
|
||||
machineService.executeCommandInMachine(machine.getId(),
|
||||
machineService.executeCommandInMachine(machine.getUserId(),
|
||||
DtoFactory.newDto(CommandDto.class).withCommandLine(commandInMachine),
|
||||
null);
|
||||
|
||||
Thread.sleep(500);
|
||||
|
||||
final List<MachineProcessDto> processes = machineService.getProcesses(machine.getId());
|
||||
final List<MachineProcessDto> processes = machineService.getProcesses(machine.getUserId());
|
||||
assertEquals(processes.size(), 1);
|
||||
assertEquals(processes.get(0).getCommandLine(), commandInMachine);
|
||||
}
|
||||
|
|
@ -357,12 +357,12 @@ public class ServiceTest {
|
|||
commands.add("sleep 10000");
|
||||
|
||||
for (String command : commands) {
|
||||
machineService.executeCommandInMachine(machine.getId(), DtoFactory.newDto(CommandDto.class).withCommandLine(command), null);
|
||||
machineService.executeCommandInMachine(machine.getUserId(), DtoFactory.newDto(CommandDto.class).withCommandLine(command), null);
|
||||
}
|
||||
|
||||
Thread.sleep(500);
|
||||
|
||||
final List<MachineProcessDto> processes = machineService.getProcesses(machine.getId());
|
||||
final List<MachineProcessDto> processes = machineService.getProcesses(machine.getUserId());
|
||||
assertEquals(processes.size(), 2);
|
||||
Set<String> actualCommandLines = new HashSet<>(2);
|
||||
for (MachineProcessDto process : processes) {
|
||||
|
|
@ -377,19 +377,19 @@ public class ServiceTest {
|
|||
final MachineImpl machine = createMachineAndWaitRunningState();
|
||||
|
||||
String commandInMachine = "echo \"command in machine\" && tail -f /dev/null";
|
||||
machineService.executeCommandInMachine(machine.getId(),
|
||||
machineService.executeCommandInMachine(machine.getUserId(),
|
||||
DtoFactory.newDto(CommandDto.class).withCommandLine(commandInMachine),
|
||||
null);
|
||||
|
||||
Thread.sleep(500);
|
||||
|
||||
final List<MachineProcessDto> processes = machineService.getProcesses(machine.getId());
|
||||
final List<MachineProcessDto> processes = machineService.getProcesses(machine.getUserId());
|
||||
assertEquals(processes.size(), 1);
|
||||
assertEquals(processes.get(0).getCommandLine(), commandInMachine);
|
||||
|
||||
machineService.stopProcess(machine.getId(), processes.get(0).getPid());
|
||||
machineService.stopProcess(machine.getUserId(), processes.get(0).getPid());
|
||||
|
||||
assertTrue(machineService.getProcesses(machine.getId()).isEmpty());
|
||||
assertTrue(machineService.getProcesses(machine.getUserId()).isEmpty());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NotFoundException.class, expectedExceptionsMessageRegExp = "Process with pid .* not found")
|
||||
|
|
@ -397,17 +397,17 @@ public class ServiceTest {
|
|||
final MachineImpl machine = createMachineAndWaitRunningState();
|
||||
|
||||
String commandInMachine = "echo \"command in machine\" && tail -f /dev/null";
|
||||
machineService.executeCommandInMachine(machine.getId(),
|
||||
machineService.executeCommandInMachine(machine.getUserId(),
|
||||
DtoFactory.newDto(CommandDto.class).withCommandLine(commandInMachine),
|
||||
null);
|
||||
|
||||
Thread.sleep(500);
|
||||
|
||||
final List<MachineProcessDto> processes = machineService.getProcesses(machine.getId());
|
||||
final List<MachineProcessDto> processes = machineService.getProcesses(machine.getUserId());
|
||||
assertEquals(processes.size(), 1);
|
||||
assertEquals(processes.get(0).getCommandLine(), commandInMachine);
|
||||
|
||||
machineService.stopProcess(machine.getId(), processes.get(0).getPid() + 100);
|
||||
machineService.stopProcess(machine.getUserId(), processes.get(0).getPid() + 100);
|
||||
}
|
||||
|
||||
private MachineImpl createMachineAndWaitRunningState() throws Exception {
|
||||
|
|
@ -423,7 +423,7 @@ public class ServiceTest {
|
|||
.withDev(false)
|
||||
.withDisplayName("displayName" + System.currentTimeMillis())
|
||||
, false);
|
||||
waitMachineIsRunning(machine.getId());
|
||||
waitMachineIsRunning(machine.getUserId());
|
||||
return machine;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ public class GitHubAuthenticatorImpl implements OAuth2Authenticator, OAuthCallba
|
|||
private void generateSshKeys(final OAuthStatus authStatus) {
|
||||
final SshKeyUploader githubKeyUploader = registry.getUploader(GITHUB_HOST);
|
||||
if (githubKeyUploader != null) {
|
||||
String userId = appContext.getCurrentUser().getProfile().getId();
|
||||
String userId = appContext.getCurrentUser().getProfile().getUserId();
|
||||
githubKeyUploader.uploadKey(userId, new AsyncCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ import com.google.gwtmockito.GwtMockitoTestRunner;
|
|||
import org.eclipse.che.api.promises.client.Operation;
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.api.ssh.shared.dto.SshPairDto;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDescriptor;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.ide.api.app.CurrentUser;
|
||||
import org.eclipse.che.ide.api.dialogs.ConfirmCallback;
|
||||
|
|
@ -141,14 +142,14 @@ public class GitHubAuthenticatorImplTest {
|
|||
SshKeyUploader sshKeyUploader = mock(SshKeyUploader.class);
|
||||
|
||||
CurrentUser user = mock(CurrentUser.class);
|
||||
ProfileDescriptor profile = mock(ProfileDescriptor.class);
|
||||
ProfileDto profile = mock(ProfileDto.class);
|
||||
when(view.isGenerateKeysSelected()).thenReturn(true);
|
||||
|
||||
when(registry.getUploader(GITHUB_HOST)).thenReturn(sshKeyUploader);
|
||||
|
||||
when(appContext.getCurrentUser()).thenReturn(user);
|
||||
when(user.getProfile()).thenReturn(profile);
|
||||
when(profile.getId()).thenReturn(userId);
|
||||
when(profile.getUserId()).thenReturn(userId);
|
||||
|
||||
gitHubAuthenticator.onAuthenticated(authStatus);
|
||||
|
||||
|
|
@ -164,11 +165,11 @@ public class GitHubAuthenticatorImplTest {
|
|||
OAuthStatus authStatus = mock(OAuthStatus.class);
|
||||
|
||||
CurrentUser user = mock(CurrentUser.class);
|
||||
ProfileDescriptor profile = mock(ProfileDescriptor.class);
|
||||
ProfileDto profile = mock(ProfileDto.class);
|
||||
when(view.isGenerateKeysSelected()).thenReturn(false);
|
||||
when(appContext.getCurrentUser()).thenReturn(user);
|
||||
when(user.getProfile()).thenReturn(profile);
|
||||
when(profile.getId()).thenReturn(userId);
|
||||
when(profile.getUserId()).thenReturn(userId);
|
||||
|
||||
gitHubAuthenticator.authenticate(null, getCallBack());
|
||||
gitHubAuthenticator.onAuthenticated(authStatus);
|
||||
|
|
@ -184,13 +185,13 @@ public class GitHubAuthenticatorImplTest {
|
|||
SshKeyUploader keyProvider = mock(SshKeyUploader.class);
|
||||
|
||||
CurrentUser user = mock(CurrentUser.class);
|
||||
ProfileDescriptor profile = mock(ProfileDescriptor.class);
|
||||
ProfileDto profile = mock(ProfileDto.class);
|
||||
when(view.isGenerateKeysSelected()).thenReturn(true);
|
||||
when(registry.getUploader(GITHUB_HOST)).thenReturn(keyProvider);
|
||||
|
||||
when(appContext.getCurrentUser()).thenReturn(user);
|
||||
when(user.getProfile()).thenReturn(profile);
|
||||
when(profile.getId()).thenReturn(userId);
|
||||
when(profile.getUserId()).thenReturn(userId);
|
||||
|
||||
gitHubAuthenticator.authenticate(null, getCallBack());
|
||||
gitHubAuthenticator.onAuthenticated(authStatus);
|
||||
|
|
@ -213,14 +214,14 @@ public class GitHubAuthenticatorImplTest {
|
|||
SshKeyUploader keyProvider = mock(SshKeyUploader.class);
|
||||
|
||||
CurrentUser user = mock(CurrentUser.class);
|
||||
ProfileDescriptor profile = mock(ProfileDescriptor.class);
|
||||
ProfileDto profile = mock(ProfileDto.class);
|
||||
MessageDialog messageDialog = mock(MessageDialog.class);
|
||||
when(view.isGenerateKeysSelected()).thenReturn(true);
|
||||
when(registry.getUploader(GITHUB_HOST)).thenReturn(keyProvider);
|
||||
|
||||
when(appContext.getCurrentUser()).thenReturn(user);
|
||||
when(user.getProfile()).thenReturn(profile);
|
||||
when(profile.getId()).thenReturn(userId);
|
||||
when(profile.getUserId()).thenReturn(userId);
|
||||
when(dialogFactory.createMessageDialog(anyString(), anyString(), Matchers.<ConfirmCallback>anyObject())).thenReturn(messageDialog);
|
||||
|
||||
gitHubAuthenticator.authenticate(null, getCallBack());
|
||||
|
|
@ -248,14 +249,14 @@ public class GitHubAuthenticatorImplTest {
|
|||
SshKeyUploader keyUploader = mock(SshKeyUploader.class);
|
||||
|
||||
CurrentUser user = mock(CurrentUser.class);
|
||||
ProfileDescriptor profile = mock(ProfileDescriptor.class);
|
||||
ProfileDto profile = mock(ProfileDto.class);
|
||||
MessageDialog messageDialog = mock(MessageDialog.class);
|
||||
when(view.isGenerateKeysSelected()).thenReturn(true);
|
||||
when(registry.getUploader(GITHUB_HOST)).thenReturn(keyUploader);
|
||||
|
||||
when(appContext.getCurrentUser()).thenReturn(user);
|
||||
when(user.getProfile()).thenReturn(profile);
|
||||
when(profile.getId()).thenReturn(userId);
|
||||
when(profile.getUserId()).thenReturn(userId);
|
||||
when(dialogFactory.createMessageDialog(anyString(), anyString(), Matchers.<ConfirmCallback>anyObject())).thenReturn(messageDialog);
|
||||
when(pair.getName()).thenReturn(GITHUB_HOST);
|
||||
when(pair.getService()).thenReturn(SshKeyManagerPresenter.VCS_SSH_SERVICE);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ import org.eclipse.che.api.project.shared.dto.ProjectImporterDescriptor;
|
|||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.api.promises.client.PromiseError;
|
||||
import org.eclipse.che.ide.api.user.UserServiceClient;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDescriptor;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.SourceStorageDto;
|
||||
import org.eclipse.che.ide.api.app.AppContext;
|
||||
import org.eclipse.che.ide.api.app.CurrentUser;
|
||||
import org.eclipse.che.ide.api.notification.NotificationManager;
|
||||
|
|
@ -500,11 +502,11 @@ public class GithubImporterPagePresenterTest {
|
|||
public void onLoadRepoClickedWhenAuthorizeIsFailed() throws Exception {
|
||||
String userId = "userId";
|
||||
CurrentUser user = mock(CurrentUser.class);
|
||||
ProfileDescriptor profile = mock(ProfileDescriptor.class);
|
||||
ProfileDto profile = mock(ProfileDto.class);
|
||||
|
||||
when(appContext.getCurrentUser()).thenReturn(user);
|
||||
when(user.getProfile()).thenReturn(profile);
|
||||
when(profile.getId()).thenReturn(userId);
|
||||
when(profile.getUserId()).thenReturn(userId);
|
||||
|
||||
|
||||
final Throwable exception = mock(UnauthorizedException.class);
|
||||
|
|
@ -553,12 +555,12 @@ public class GithubImporterPagePresenterTest {
|
|||
final Throwable exception = mock(UnauthorizedException.class);
|
||||
String userId = "userId";
|
||||
CurrentUser user = mock(CurrentUser.class);
|
||||
ProfileDescriptor profile = mock(ProfileDescriptor.class);
|
||||
ProfileDto profile = mock(ProfileDto.class);
|
||||
doReturn(exception).when(promiseError).getCause();
|
||||
|
||||
when(appContext.getCurrentUser()).thenReturn(user);
|
||||
when(user.getProfile()).thenReturn(profile);
|
||||
when(profile.getId()).thenReturn(userId);
|
||||
when(profile.getUserId()).thenReturn(userId);
|
||||
|
||||
presenter.onLoadRepoClicked();
|
||||
|
||||
|
|
|
|||
|
|
@ -53,9 +53,9 @@ public interface IWorkingSet extends /*IPersistableElement,*/ IAdaptable {
|
|||
* Currently, this is one of the icons specified in the extensions
|
||||
* of the org.eclipse.ui.workingSets extension point.
|
||||
* The extension is identified using the value returned by
|
||||
* <code>getId()</code>.
|
||||
* <code>getUserId()</code>.
|
||||
* Returns <code>null</code> if no icon has been specified in the
|
||||
* extension or if <code>getId()</code> returns <code>null</code>.
|
||||
* extension or if <code>getUserId()</code> returns <code>null</code>.
|
||||
*
|
||||
* @return the working set icon or <code>null</code>.
|
||||
* @since 2.1
|
||||
|
|
@ -69,9 +69,9 @@ public interface IWorkingSet extends /*IPersistableElement,*/ IAdaptable {
|
|||
* Currently, this is one of the icons specified in the extensions
|
||||
* of the org.eclipse.ui.workingSets extension point.
|
||||
* The extension is identified using the value returned by
|
||||
* <code>getId()</code>.
|
||||
* <code>getUserId()</code>.
|
||||
* Returns <code>null</code> if no icon has been specified in the
|
||||
* extension or if <code>getId()</code> returns <code>null</code>.
|
||||
* extension or if <code>getUserId()</code> returns <code>null</code>.
|
||||
*
|
||||
* @return the working set icon or <code>null</code>.
|
||||
* @since 3.3
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ import com.google.inject.Inject;
|
|||
import org.eclipse.che.api.promises.client.Operation;
|
||||
import org.eclipse.che.api.promises.client.OperationException;
|
||||
import org.eclipse.che.api.promises.client.PromiseError;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDto;
|
||||
import org.eclipse.che.ide.api.user.UserProfileServiceClient;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDescriptor;
|
||||
import org.eclipse.che.ide.api.workspace.WorkspaceServiceClient;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceDto;
|
||||
import org.eclipse.che.ide.extension.machine.client.machine.Machine;
|
||||
|
|
@ -66,11 +66,11 @@ public class MachineInfoPresenter implements TabPresenter {
|
|||
*/
|
||||
public void update(@NotNull Machine machine) {
|
||||
|
||||
Unmarshallable<ProfileDescriptor> profileUnMarshaller = unmarshallerFactory.newUnmarshaller(ProfileDescriptor.class);
|
||||
Unmarshallable<ProfileDto> profileUnMarshaller = unmarshallerFactory.newUnmarshaller(ProfileDto.class);
|
||||
|
||||
userProfile.getCurrentProfile(new AsyncRequestCallback<ProfileDescriptor>(profileUnMarshaller) {
|
||||
userProfile.getCurrentProfile(new AsyncRequestCallback<ProfileDto>(profileUnMarshaller) {
|
||||
@Override
|
||||
protected void onSuccess(ProfileDescriptor result) {
|
||||
protected void onSuccess(ProfileDto result) {
|
||||
Map<String, String> attributes = result.getAttributes();
|
||||
|
||||
String firstName = attributes.get(FIRST_NAME_KEY);
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ package org.eclipse.che.ide.extension.machine.client.perspective.widgets.machine
|
|||
import com.google.gwt.user.client.ui.AcceptsOneWidget;
|
||||
|
||||
import org.eclipse.che.api.promises.client.Promise;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDto;
|
||||
import org.eclipse.che.ide.api.user.UserProfileServiceClient;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDescriptor;
|
||||
import org.eclipse.che.ide.api.workspace.WorkspaceServiceClient;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceDto;
|
||||
|
|
@ -62,22 +62,22 @@ public class MachineInfoPresenterTest {
|
|||
|
||||
//additional mocks
|
||||
@Mock
|
||||
private Machine machine;
|
||||
private Machine machine;
|
||||
@Mock
|
||||
private AcceptsOneWidget container;
|
||||
private AcceptsOneWidget container;
|
||||
@Mock
|
||||
private Unmarshallable<ProfileDescriptor> profileUnmarshaller;
|
||||
private Unmarshallable<ProfileDto> profileUnmarshaller;
|
||||
@Mock
|
||||
private Unmarshallable<WorkspaceDto> wsUnmarshaller;
|
||||
private Unmarshallable<WorkspaceDto> wsUnmarshaller;
|
||||
@Mock
|
||||
private ProfileDescriptor profileDescriptor;
|
||||
private ProfileDto profileDescriptor;
|
||||
@Mock
|
||||
private WorkspaceDto wsDescriptor;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private Promise<WorkspaceDto> promise;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<AsyncRequestCallback<ProfileDescriptor>> profileCaptor;
|
||||
private ArgumentCaptor<AsyncRequestCallback<ProfileDto>> profileCaptor;
|
||||
@Captor
|
||||
private ArgumentCaptor<AsyncRequestCallback<WorkspaceDto>> wsCaptor;
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ public class MachineInfoPresenterTest {
|
|||
public void setUp() {
|
||||
when(machine.getWorkspaceId()).thenReturn(SOME_TEXT);
|
||||
|
||||
when(unmarshallerFactory.newUnmarshaller(ProfileDescriptor.class)).thenReturn(profileUnmarshaller);
|
||||
when(unmarshallerFactory.newUnmarshaller(ProfileDto.class)).thenReturn(profileUnmarshaller);
|
||||
when(unmarshallerFactory.newUnmarshaller(WorkspaceDto.class)).thenReturn(wsUnmarshaller);
|
||||
}
|
||||
|
||||
|
|
@ -98,9 +98,9 @@ public class MachineInfoPresenterTest {
|
|||
|
||||
presenter.update(machine);
|
||||
|
||||
verify(unmarshallerFactory).newUnmarshaller(ProfileDescriptor.class);
|
||||
verify(unmarshallerFactory).newUnmarshaller(ProfileDto.class);
|
||||
|
||||
verify(userProfile).getCurrentProfile(Matchers.<AsyncRequestCallback<ProfileDescriptor>>anyObject());
|
||||
verify(userProfile).getCurrentProfile(Matchers.<AsyncRequestCallback<ProfileDto>>anyObject());
|
||||
verify(machine).getWorkspaceId();
|
||||
verify(wsService).getWorkspace(eq(SOME_TEXT));
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ public class MachineInfoPresenterTest {
|
|||
presenter.update(machine);
|
||||
|
||||
verify(userProfile).getCurrentProfile(profileCaptor.capture());
|
||||
AsyncRequestCallback<ProfileDescriptor> callback = profileCaptor.getValue();
|
||||
AsyncRequestCallback<ProfileDto> callback = profileCaptor.getValue();
|
||||
|
||||
//noinspection NonJREEmulationClassesInClientCode
|
||||
Method method = callback.getClass().getDeclaredMethod("onSuccess", Object.class);
|
||||
|
|
@ -144,7 +144,7 @@ public class MachineInfoPresenterTest {
|
|||
presenter.update(machine);
|
||||
|
||||
verify(userProfile).getCurrentProfile(profileCaptor.capture());
|
||||
AsyncRequestCallback<ProfileDescriptor> callback = profileCaptor.getValue();
|
||||
AsyncRequestCallback<ProfileDto> callback = profileCaptor.getValue();
|
||||
|
||||
//noinspection NonJREEmulationClassesInClientCode
|
||||
Method method = callback.getClass().getDeclaredMethod("onSuccess", Object.class);
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ public class SshKeyManagerPresenter extends AbstractPreferencePagePresenter impl
|
|||
CurrentUser user = appContext.getCurrentUser();
|
||||
final SshKeyUploader githubUploader = registry.getUploaders().get(GITHUB_HOST);
|
||||
if (user != null && githubUploader != null) {
|
||||
githubUploader.uploadKey(user.getProfile().getId(), new AsyncCallback<Void>() {
|
||||
githubUploader.uploadKey(user.getProfile().getUserId(), new AsyncCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
refreshKeys();
|
||||
|
|
|
|||
|
|
@ -10,9 +10,8 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.che.plugin.svn.server.credentials;
|
||||
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.user.server.dao.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.spi.PreferenceDao;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
|
||||
|
|
@ -45,7 +44,7 @@ public class CurrentUserPreferencesAccessImpl implements CurrentUserPreferencesA
|
|||
content.put(key, value);
|
||||
try {
|
||||
this.preferencesDao.setPreferences(currentSubject.getUserId(), content);
|
||||
} catch (final ServerException | NotFoundException e) {
|
||||
} catch (final ServerException e) {
|
||||
throw new PreferencesAccessException(e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import org.eclipse.che.api.project.server.FolderEntry;
|
|||
import org.eclipse.che.api.project.server.importer.ProjectImporter;
|
||||
import org.eclipse.che.api.project.server.type.ProjectTypeDef;
|
||||
import org.eclipse.che.api.project.server.type.ValueProviderFactory;
|
||||
import org.eclipse.che.api.user.server.dao.UserProfileDao;
|
||||
import org.eclipse.che.api.user.server.spi.ProfileDao;
|
||||
import org.eclipse.che.api.vfs.VirtualFile;
|
||||
import org.eclipse.che.api.vfs.VirtualFileSystem;
|
||||
import org.eclipse.che.commons.lang.NameGenerator;
|
||||
|
|
@ -47,7 +47,8 @@ import static org.mockito.Mockito.when;
|
|||
public class SubversionProjectImporterTest {
|
||||
|
||||
@Mock
|
||||
private UserProfileDao userProfileDao;
|
||||
private ProfileDao userProfileDao;
|
||||
|
||||
@Mock
|
||||
private CredentialsProvider credentialsProvider;
|
||||
@Mock
|
||||
|
|
@ -73,7 +74,7 @@ public class SubversionProjectImporterTest {
|
|||
.to(SubversionValueProviderFactory.class);
|
||||
|
||||
bind(SshKeyProvider.class).toInstance(sshKeyProvider);
|
||||
bind(UserProfileDao.class).toInstance(userProfileDao);
|
||||
bind(ProfileDao.class).toInstance(userProfileDao);
|
||||
bind(CredentialsProvider.class).toInstance(credentialsProvider);
|
||||
bind(RepositoryUrlProvider.class).toInstance(repositoryUrlProvider);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ import com.google.common.io.Files;
|
|||
|
||||
import org.eclipse.che.api.core.util.LineConsumer;
|
||||
import org.eclipse.che.api.core.util.LineConsumerFactory;
|
||||
import org.eclipse.che.api.user.server.dao.Profile;
|
||||
import org.eclipse.che.api.user.server.dao.UserProfileDao;
|
||||
import org.eclipse.che.api.user.server.model.impl.ProfileImpl;
|
||||
import org.eclipse.che.api.user.server.spi.ProfileDao;
|
||||
import org.eclipse.che.api.vfs.VirtualFileSystem;
|
||||
import org.eclipse.che.api.vfs.VirtualFileSystemProvider;
|
||||
import org.eclipse.che.api.vfs.impl.file.LocalVirtualFileSystemProvider;
|
||||
|
|
@ -163,7 +163,7 @@ public class TestUtils {
|
|||
* @throws Exception
|
||||
* if anything goes wrong
|
||||
*/
|
||||
public static void createTestUser(final UserProfileDao userProfileDao) throws Exception {
|
||||
public static void createTestUser(final ProfileDao userProfileDao) throws Exception {
|
||||
// set current user
|
||||
EnvironmentContext.getCurrent().setSubject(new SubjectImpl("codenvy", "codenvy", null, false));
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ public class TestUtils {
|
|||
profileAttributes.put("email", "che@eclipse.org");
|
||||
|
||||
Mockito.when(userProfileDao.getById("codenvy"))
|
||||
.thenReturn(new Profile().withId("codenvy").withUserId("codenvy").withAttributes(profileAttributes));
|
||||
.thenReturn(new ProfileImpl("codenvy", profileAttributes));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
6
pom.xml
6
pom.xml
|
|
@ -186,6 +186,12 @@
|
|||
<artifactId>che-core-api-ssh-shared</artifactId>
|
||||
<version>${che.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-user</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-user</artifactId>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ package org.eclipse.che.api.git;
|
|||
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.git.shared.GitUser;
|
||||
import org.eclipse.che.api.user.server.dao.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.spi.PreferenceDao;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import org.eclipse.che.api.project.shared.dto.ItemReference;
|
|||
import org.eclipse.che.api.project.shared.dto.MoveOptions;
|
||||
import org.eclipse.che.api.project.shared.dto.SourceEstimation;
|
||||
import org.eclipse.che.api.project.shared.dto.TreeElement;
|
||||
import org.eclipse.che.api.user.server.dao.UserDao;
|
||||
import org.eclipse.che.api.user.server.spi.UserDao;
|
||||
import org.eclipse.che.api.vfs.VirtualFile;
|
||||
import org.eclipse.che.api.vfs.VirtualFileSystem;
|
||||
import org.eclipse.che.api.vfs.impl.file.DefaultFileWatcherNotificationHandler;
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ import org.eclipse.che.api.core.NotFoundException;
|
|||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.UnauthorizedException;
|
||||
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
|
||||
import org.eclipse.che.api.user.server.UserProfileService;
|
||||
import org.eclipse.che.api.user.server.dao.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.spi.PreferenceDao;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
|
@ -44,12 +43,12 @@ public class RemotePreferenceDao implements PreferenceDao {
|
|||
|
||||
@Inject
|
||||
public RemotePreferenceDao(@Named("api.endpoint") String apiUrl, HttpJsonRequestFactory requestFactory) {
|
||||
this.prefsUrl = apiUrl + "/profile/prefs";
|
||||
this.prefsUrl = apiUrl + "/preferences";
|
||||
this.requestFactory = requestFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreferences(String userId, Map<String, String> preferences) throws ServerException, NotFoundException {
|
||||
public void setPreferences(String userId, Map<String, String> preferences) throws ServerException {
|
||||
requireNonNull(preferences, "Required non-null preferences");
|
||||
checkUserId(requireNonNull(userId, "Required non-null user id"));
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -11,10 +11,9 @@
|
|||
package org.eclipse.che;
|
||||
|
||||
import org.eclipse.che.api.core.rest.DefaultHttpJsonRequestFactory;
|
||||
import org.eclipse.che.api.user.server.UserProfileService;
|
||||
import org.eclipse.che.api.user.server.dao.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.dao.UserDao;
|
||||
import org.eclipse.che.api.user.server.dao.UserProfileDao;
|
||||
import org.eclipse.che.api.user.server.PreferenceManager;
|
||||
import org.eclipse.che.api.user.server.PreferencesService;
|
||||
import org.eclipse.che.api.user.server.ProfileService;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
|
|
@ -41,7 +40,7 @@ import static org.mockito.Mockito.verify;
|
|||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Tests that {@link RemotePreferenceDao} uses correct methods of {@link UserProfileService}.
|
||||
* Tests that {@link RemotePreferenceDao} uses correct methods of {@link ProfileService}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
|
|
@ -53,16 +52,10 @@ public class RemotePreferenceDaoCompatibilityTest {
|
|||
private static final Subject TEST_SUBJECT = new SubjectImpl("name", "id", "token", false);
|
||||
|
||||
@Mock
|
||||
private PreferenceDao preferenceDaoMock;
|
||||
|
||||
@Mock
|
||||
private UserDao userDao;
|
||||
|
||||
@Mock
|
||||
private UserProfileDao userProfileDao;
|
||||
private PreferenceManager preferenceManager;
|
||||
|
||||
@InjectMocks
|
||||
private UserProfileService profileService;
|
||||
private PreferencesService preferenceService;
|
||||
|
||||
@BeforeMethod
|
||||
private void setUp() {
|
||||
|
|
@ -77,7 +70,7 @@ public class RemotePreferenceDaoCompatibilityTest {
|
|||
|
||||
remoteDao.getPreferences(TEST_SUBJECT.getUserId());
|
||||
|
||||
verify(preferenceDaoMock).getPreferences(TEST_SUBJECT.getUserId());
|
||||
verify(preferenceManager).find(TEST_SUBJECT.getUserId());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -86,7 +79,7 @@ public class RemotePreferenceDaoCompatibilityTest {
|
|||
|
||||
remoteDao.getPreferences(TEST_SUBJECT.getUserId(), "filter");
|
||||
|
||||
verify(preferenceDaoMock).getPreferences(TEST_SUBJECT.getUserId(), "filter");
|
||||
verify(preferenceManager).find(TEST_SUBJECT.getUserId(), "filter");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -96,7 +89,7 @@ public class RemotePreferenceDaoCompatibilityTest {
|
|||
|
||||
remoteDao.setPreferences(TEST_SUBJECT.getUserId(), prefs);
|
||||
|
||||
verify(preferenceDaoMock).setPreferences(TEST_SUBJECT.getUserId(), prefs);
|
||||
verify(preferenceManager).save(TEST_SUBJECT.getUserId(), prefs);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -105,7 +98,7 @@ public class RemotePreferenceDaoCompatibilityTest {
|
|||
|
||||
remoteDao.remove(TEST_SUBJECT.getUserId());
|
||||
|
||||
verify(preferenceDaoMock).remove(TEST_SUBJECT.getUserId());
|
||||
verify(preferenceManager).remove(TEST_SUBJECT.getUserId());
|
||||
}
|
||||
|
||||
@Filter
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import org.eclipse.che.api.factory.server.builder.FactoryBuilder;
|
|||
import org.eclipse.che.api.factory.server.snippet.SnippetGenerator;
|
||||
import org.eclipse.che.api.factory.shared.dto.Author;
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.user.server.dao.UserDao;
|
||||
import org.eclipse.che.api.user.server.spi.UserDao;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceManager;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ package org.eclipse.che.api.factory.server.impl;
|
|||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.factory.server.FactoryAcceptValidator;
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.user.server.dao.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.spi.PreferenceDao;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import org.eclipse.che.api.factory.shared.dto.Ide;
|
|||
import org.eclipse.che.api.factory.shared.dto.OnAppLoaded;
|
||||
import org.eclipse.che.api.factory.shared.dto.OnProjectsLoaded;
|
||||
import org.eclipse.che.api.factory.shared.dto.Policies;
|
||||
import org.eclipse.che.api.user.server.dao.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.spi.PreferenceDao;
|
||||
import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
|
@ -30,7 +30,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.google.common.base.Strings.emptyToNull;
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static java.lang.Boolean.parseBoolean;
|
||||
import static java.lang.String.format;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import org.eclipse.che.api.core.ForbiddenException;
|
|||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.factory.server.FactoryCreateValidator;
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.user.server.dao.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.spi.PreferenceDao;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceValidator;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ import org.eclipse.che.api.factory.shared.dto.Button;
|
|||
import org.eclipse.che.api.factory.shared.dto.ButtonAttributes;
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.machine.shared.dto.CommandDto;
|
||||
import org.eclipse.che.api.user.server.dao.User;
|
||||
import org.eclipse.che.api.user.server.dao.UserDao;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.api.user.server.spi.UserDao;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceManager;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
|
||||
|
|
@ -161,7 +161,11 @@ public class FactoryServiceTest {
|
|||
factoryBuilder = spy(new FactoryBuilder(new SourceStorageParametersValidator()));
|
||||
doNothing().when(factoryBuilder).checkValid(any(Factory.class));
|
||||
when(factoryParametersResolverHolder.getFactoryParametersResolvers()).thenReturn(factoryParametersResolvers);
|
||||
when(userDao.getById(anyString())).thenReturn(new User().withName(JettyHttpServer.ADMIN_USER_NAME));
|
||||
when(userDao.getById(anyString())).thenReturn(new UserImpl(null,
|
||||
null,
|
||||
JettyHttpServer.ADMIN_USER_NAME,
|
||||
null,
|
||||
null));
|
||||
factoryService = new FactoryService(factoryStore,
|
||||
createValidator,
|
||||
acceptValidator,
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ import org.eclipse.che.api.factory.shared.dto.OnAppClosed;
|
|||
import org.eclipse.che.api.factory.shared.dto.OnAppLoaded;
|
||||
import org.eclipse.che.api.factory.shared.dto.OnProjectsLoaded;
|
||||
import org.eclipse.che.api.factory.shared.dto.Policies;
|
||||
import org.eclipse.che.api.user.server.dao.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.dao.User;
|
||||
import org.eclipse.che.api.user.server.dao.UserDao;
|
||||
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.UserDao;
|
||||
import org.eclipse.che.api.workspace.shared.dto.ProjectConfigDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.SourceStorageDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.WorkspaceConfigDto;
|
||||
|
|
@ -86,7 +86,7 @@ public class FactoryBaseValidatorTest {
|
|||
.withCreator(newDto(Author.class)
|
||||
.withUserId("userid"));
|
||||
|
||||
User user = new User().withId("userid");
|
||||
UserImpl user = new UserImpl("userid");
|
||||
|
||||
when(userDao.getById("userid")).thenReturn(user);
|
||||
validator = new TesterFactoryBaseValidator(preferenceDao);
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ package org.eclipse.che.api.factory.server.impl;
|
|||
import org.eclipse.che.api.core.ApiException;
|
||||
import org.eclipse.che.api.core.model.workspace.WorkspaceConfig;
|
||||
import org.eclipse.che.api.factory.shared.dto.Factory;
|
||||
import org.eclipse.che.api.user.server.dao.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.dao.UserDao;
|
||||
import org.eclipse.che.api.user.server.spi.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.spi.UserDao;
|
||||
import org.eclipse.che.api.workspace.server.WorkspaceValidator;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.che.api.factory.server.impl;
|
||||
|
||||
import org.eclipse.che.api.user.server.dao.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.spi.PreferenceDao;
|
||||
|
||||
/**
|
||||
* @author Sergii Kabashniuk
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-dto</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-model</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<resources>
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.shared.dto;
|
||||
|
||||
import org.eclipse.che.api.user.shared.model.Membership;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author andrew00x
|
||||
*/
|
||||
@DTO
|
||||
public interface MembershipDto extends Membership {
|
||||
|
||||
@Override
|
||||
String getUserId();
|
||||
|
||||
void setUserId(String id);
|
||||
|
||||
MembershipDto withUserId(String id);
|
||||
|
||||
@Override
|
||||
String getScope();
|
||||
|
||||
@Override
|
||||
String getUserName();
|
||||
|
||||
@Override
|
||||
String getSubjectId();
|
||||
|
||||
@Override
|
||||
Map<String, String> getSubjectProperties();
|
||||
|
||||
@Override
|
||||
List<String> getRoles();
|
||||
|
||||
void setRoles(List<String> roles);
|
||||
|
||||
MembershipDto withRoles(List<String> roles);
|
||||
}
|
||||
|
|
@ -10,43 +10,47 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.shared.dto;
|
||||
|
||||
import org.eclipse.che.api.core.model.user.Profile;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.Link;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author andrew00x
|
||||
* This object used for transporting profile data to/from client.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
* @see Profile
|
||||
* @see DtoFactory
|
||||
*/
|
||||
@DTO
|
||||
public interface ProfileDescriptor {
|
||||
|
||||
void setId(String id);
|
||||
|
||||
@ApiModelProperty("Profile ID")
|
||||
String getId();
|
||||
|
||||
ProfileDescriptor withId(String id);
|
||||
|
||||
@ApiModelProperty("User ID")
|
||||
String getUserId();
|
||||
public interface ProfileDto extends Profile {
|
||||
|
||||
void setUserId(String id);
|
||||
|
||||
ProfileDescriptor withUserId(String id);
|
||||
@ApiModelProperty("Profile ID")
|
||||
String getUserId();
|
||||
|
||||
ProfileDto withUserId(String id);
|
||||
|
||||
@ApiModelProperty("Profile attributes")
|
||||
Map<String, String> getAttributes();
|
||||
|
||||
void setAttributes(Map<String, String> attributes);
|
||||
|
||||
ProfileDescriptor withAttributes(Map<String, String> attributes);
|
||||
ProfileDto withAttributes(Map<String, String> attributes);
|
||||
|
||||
List<Link> getLinks();
|
||||
|
||||
void setLinks(List<Link> links);
|
||||
|
||||
ProfileDescriptor withLinks(List<Link> links);
|
||||
ProfileDto withLinks(List<Link> links);
|
||||
|
||||
String getEmail();
|
||||
|
||||
ProfileDto withEmail(String email);
|
||||
}
|
||||
|
|
@ -10,56 +10,62 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.shared.dto;
|
||||
|
||||
import org.eclipse.che.api.core.model.user.User;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.Link;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author andrew00x
|
||||
* This object used for transporting user data to/from client.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
* @see User
|
||||
* @see DtoFactory
|
||||
*/
|
||||
@DTO
|
||||
public interface UserDescriptor {
|
||||
public interface UserDto extends User {
|
||||
@ApiModelProperty("User ID")
|
||||
String getId();
|
||||
|
||||
void setId(String id);
|
||||
|
||||
UserDescriptor withId(String id);
|
||||
|
||||
UserDto withId(String id);
|
||||
|
||||
@ApiModelProperty("User alias which is used for oAuth")
|
||||
List<String> getAliases();
|
||||
|
||||
void setAliases(List<String> aliases);
|
||||
|
||||
UserDescriptor withAliases(List<String> aliases);
|
||||
UserDto withAliases(List<String> aliases);
|
||||
|
||||
@ApiModelProperty("User email")
|
||||
String getEmail();
|
||||
|
||||
void setEmail(String email);
|
||||
|
||||
UserDescriptor withEmail(String email);
|
||||
UserDto withEmail(String email);
|
||||
|
||||
@ApiModelProperty("User name")
|
||||
String getName();
|
||||
|
||||
void setName(String name);
|
||||
|
||||
UserDescriptor withName(String name);
|
||||
UserDto withName(String name);
|
||||
|
||||
@ApiModelProperty("User password")
|
||||
String getPassword();
|
||||
|
||||
void setPassword(String password);
|
||||
|
||||
UserDescriptor withPassword(String password);
|
||||
UserDto withPassword(String password);
|
||||
|
||||
List<Link> getLinks();
|
||||
|
||||
void setLinks(List<Link> links);
|
||||
|
||||
UserDescriptor withLinks(List<Link> links);
|
||||
UserDto withLinks(List<Link> links);
|
||||
}
|
||||
|
|
@ -48,6 +48,10 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-dto</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-model</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-user-shared</artifactId>
|
||||
|
|
@ -56,10 +60,19 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-lang</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jayway.restassured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
|
|
@ -99,4 +112,35 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- Skip tests -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/spi/tck/*.*</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Create the test jar -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/spi/tck/*.*</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -11,30 +11,32 @@
|
|||
package org.eclipse.che.api.user.server;
|
||||
|
||||
/**
|
||||
* Constants for User API and UserProfile API
|
||||
* Constants for User/Profile/Preferences API.
|
||||
*
|
||||
* @author Eugene Voevodin
|
||||
* @author Yevhenii Voevodin
|
||||
* @author Max Shaposhnik
|
||||
*/
|
||||
public final class Constants {
|
||||
|
||||
public static final String LINK_REL_GET_CURRENT_USER_PROFILE = "current user profile";
|
||||
public static final String LINK_REL_UPDATE_CURRENT_USER_PROFILE = "update current user profile";
|
||||
public static final String LINK_REL_GET_USER_PROFILE_BY_ID = "user profile by id";
|
||||
public static final String LINK_REL_UPDATE_USER_PROFILE_BY_ID = "update user profile by id";
|
||||
public static final String LINK_REL_INROLE = "in role";
|
||||
public static final String LINK_REL_CREATE_USER = "create user";
|
||||
public static final String LINK_REL_GET_CURRENT_USER = "get current";
|
||||
public static final String LINK_REL_UPDATE_PASSWORD = "update password";
|
||||
public static final String LINK_REL_REMOVE_PREFERENCES = "remove preferences";
|
||||
public static final String LINK_REL_REMOVE_ATTRIBUTES = "remove attributes";
|
||||
public static final String LINK_REL_GET_USER_BY_ID = "get user by id";
|
||||
public static final String LINK_REL_GET_USER_BY_EMAIL = "get user by email";
|
||||
public static final String LINK_REL_REMOVE_USER_BY_ID = "remove user by id";
|
||||
public static final String LINK_REL_UPDATE_PREFERENCES = "update prefs";
|
||||
public static final int ID_LENGTH = 16;
|
||||
public static final int PASSWORD_LENGTH = 10;
|
||||
/** Profile link relationships. */
|
||||
public static final String LINK_REL_CURRENT_PROFILE = "current_profile";
|
||||
public static final String LINK_REL_CURRENT_PROFILE_ATTRIBUTES = "current_profile.attributes";
|
||||
public static final String LINK_REL_PROFILE = "profile";
|
||||
public static final String LINK_REL_PROFILE_ATTRIBUTES = "profile.attributes";
|
||||
|
||||
private Constants() {
|
||||
}
|
||||
/** User links relationships. */
|
||||
public static final String LINK_REL_USER = "user";
|
||||
public static final String LINK_REL_CURRENT_USER = "current_user";
|
||||
public static final String LINK_REL_CURRENT_USER_PASSWORD = "current_user.password";
|
||||
public static final String LINK_REL_CURRENT_USER_SETTINGS = "current_user.settings";
|
||||
|
||||
/** Preferences links relationships. */
|
||||
public static final String LINK_REL_PREFERENCES = "preferences";
|
||||
|
||||
public static final String LINK_REL_SELF = "self";
|
||||
|
||||
public static final int ID_LENGTH = 16;
|
||||
public static final int PASSWORD_LENGTH = 10;
|
||||
|
||||
private Constants() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server;
|
||||
|
||||
import org.eclipse.che.api.user.server.dao.User;
|
||||
import org.eclipse.che.api.user.shared.dto.UserDescriptor;
|
||||
import org.eclipse.che.api.core.model.user.User;
|
||||
import org.eclipse.che.api.user.shared.dto.UserDto;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
|
||||
/**
|
||||
|
|
@ -22,10 +22,10 @@ import org.eclipse.che.dto.server.DtoFactory;
|
|||
public final class DtoConverter {
|
||||
|
||||
/**
|
||||
* Converts {@link User} to {@link UserDescriptor}.
|
||||
* Converts {@link User} to {@link UserDto}.
|
||||
*/
|
||||
public static UserDescriptor toDescriptor(User user) {
|
||||
return DtoFactory.getInstance().createDto(UserDescriptor.class)
|
||||
public static UserDto asDto(User user) {
|
||||
return DtoFactory.getInstance().createDto(UserDto.class)
|
||||
.withId(user.getId())
|
||||
.withEmail(user.getEmail())
|
||||
.withName(user.getName())
|
||||
|
|
|
|||
|
|
@ -0,0 +1,176 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server;
|
||||
|
||||
import com.google.common.util.concurrent.Striped;
|
||||
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.user.server.spi.PreferenceDao;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Preferences manager layer, simplifies preferences service by
|
||||
* taking all the business logic out from the service and making that logic easily
|
||||
* reusable throughout the system.
|
||||
*
|
||||
* <p>The manager doesn't perform any bean validations and it
|
||||
* is expected that all the incoming objects are valid, nevertheless
|
||||
* this exactly the right place for performing business validations.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Singleton
|
||||
public class PreferenceManager {
|
||||
|
||||
private static final Striped<Lock> UPDATE_REENTRANT_LOCKS = Striped.lazyWeakLock(32);
|
||||
|
||||
@Inject
|
||||
private PreferenceDao preferenceDao;
|
||||
|
||||
/**
|
||||
* Associates the given {@code preferences} with the given {@code userId}.
|
||||
*
|
||||
* <p>Note that this method will override all the existing properties
|
||||
* for the user with id {@code userId}.
|
||||
*
|
||||
* @param userId
|
||||
* the user id whom the {@code preferences} belong to
|
||||
* @param preferences
|
||||
* the preferences to associate with the {@code userId}
|
||||
* @throws NullPointerException
|
||||
* when either {@code userId} or {@code preferences} is null
|
||||
* @throws ServerException
|
||||
* when any error occurs
|
||||
*/
|
||||
public void save(String userId, Map<String, String> preferences) throws ServerException {
|
||||
requireNonNull(userId, "Required non-null user id");
|
||||
requireNonNull(preferences, "Required non-null preferences");
|
||||
preferenceDao.setPreferences(userId, preferences);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the preferences of the user by merging given {@code preferences}
|
||||
* with the existing preferences. If user doesn't have any preferences
|
||||
* then the given {@code preferences} will be associated with the user.
|
||||
*
|
||||
* @param userId
|
||||
* the user whose preferences should be updated
|
||||
* @param preferences
|
||||
* preferences update
|
||||
* @return all the user's preferences including the update
|
||||
* @throws NullPointerException
|
||||
* when either {@code userId} or {@code preferences} is null
|
||||
* @throws ServerException
|
||||
* when any error occurs
|
||||
*/
|
||||
public Map<String, String> update(String userId, Map<String, String> preferences) throws ServerException {
|
||||
requireNonNull(userId, "Required non-null user id");
|
||||
requireNonNull(preferences, "Required non-null preferences");
|
||||
// Holding reference to prevent garbage collection
|
||||
// this reentrantLock helps to avoid race-conditions when parallel updates are applied
|
||||
final Lock reentrantLock = UPDATE_REENTRANT_LOCKS.get(userId);
|
||||
reentrantLock.lock();
|
||||
try {
|
||||
final Map<String, String> found = preferenceDao.getPreferences(userId);
|
||||
found.putAll(preferences);
|
||||
preferenceDao.setPreferences(userId, found);
|
||||
return found;
|
||||
} finally {
|
||||
reentrantLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds user's preferences.
|
||||
*
|
||||
* @param userId
|
||||
* user id to find preferences
|
||||
* @return found preferences or empty map, if there are no preferences related to user
|
||||
* @throws NullPointerException
|
||||
* when {@code userId} is null
|
||||
* @throws ServerException
|
||||
* when any error occurs
|
||||
*/
|
||||
public Map<String, String> find(String userId) throws ServerException {
|
||||
requireNonNull(userId, "Required non-null user id");
|
||||
return preferenceDao.getPreferences(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds user's preferences.
|
||||
*
|
||||
* @param userId
|
||||
* user id to find preferences
|
||||
* @param keyFilter
|
||||
* regex which is used to filter preferences by keys, so
|
||||
* result contains only the user's preferences that match {@code keyFilter} regex
|
||||
* @return found preferences filtered by {@code keyFilter} or an empty map
|
||||
* if there are no preferences related to user
|
||||
* @throws NullPointerException
|
||||
* when {@code userId} is null
|
||||
* @throws ServerException
|
||||
* when any error occurs
|
||||
*/
|
||||
public Map<String, String> find(String userId, String keyFilter) throws ServerException {
|
||||
requireNonNull(userId, "Required non-null user id");
|
||||
return preferenceDao.getPreferences(userId, keyFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes(clears) user's preferences.
|
||||
*
|
||||
* @param userId
|
||||
* the id of the user to remove preferences
|
||||
* @throws NullPointerException
|
||||
* when {@code userId} is null
|
||||
* @throws ServerException
|
||||
* when any error occurs
|
||||
*/
|
||||
public void remove(String userId) throws ServerException {
|
||||
requireNonNull(userId, "Required non-null user id");
|
||||
preferenceDao.remove(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the preferences with the given {@code names}.
|
||||
*
|
||||
* @param userId
|
||||
* the id of the user to remove preferences
|
||||
* @param names
|
||||
* the names to remove
|
||||
* @throws NullPointerException
|
||||
* when either {@code userId} or {@code names} is null
|
||||
* @throws ServerException
|
||||
* when any error occurs
|
||||
*/
|
||||
public void remove(String userId, List<String> names) throws ServerException {
|
||||
requireNonNull(userId, "Required non-null user id");
|
||||
requireNonNull(names, "Required non-null preference names");
|
||||
// Holding reference to prevent garbage collection
|
||||
// this reentrantLock helps to avoid race-conditions when parallel updates are applied
|
||||
final Lock reentrantLock = UPDATE_REENTRANT_LOCKS.get(userId);
|
||||
reentrantLock.lock();
|
||||
try {
|
||||
final Map<String, String> preferences = preferenceDao.getPreferences(userId);
|
||||
names.forEach(preferences::remove);
|
||||
preferenceDao.setPreferences(userId, preferences);
|
||||
} finally {
|
||||
reentrantLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.rest.Service;
|
||||
import org.eclipse.che.api.core.rest.annotations.GenerateLink;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_PREFERENCES;
|
||||
|
||||
/**
|
||||
* Preferences REST API.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Path("/preferences")
|
||||
@Api(value = "/preferences", description = "Preferences REST API")
|
||||
public class PreferencesService extends Service {
|
||||
|
||||
@Inject
|
||||
private PreferenceManager preferenceManager;
|
||||
|
||||
@GET
|
||||
@Produces(APPLICATION_JSON)
|
||||
@GenerateLink(rel = LINK_REL_PREFERENCES)
|
||||
@ApiOperation(value = "Gets preferences of logged in user",
|
||||
notes = "If not all the preferences needed then 'filter' may be used, " +
|
||||
"basically it is regex for filtering preferences by names")
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "Preferences successfully fetched"),
|
||||
@ApiResponse(code = 500, message = "Internal Server Error")})
|
||||
public Map<String, String> find(@ApiParam("Regex for filtering preferences by names, e.g. '.*github.*' " +
|
||||
"will return all the preferences which name contains github")
|
||||
@QueryParam("filter")
|
||||
String filter) throws ServerException {
|
||||
if (filter == null) {
|
||||
return preferenceManager.find(userId());
|
||||
}
|
||||
return preferenceManager.find(userId(), filter);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes(APPLICATION_JSON)
|
||||
@GenerateLink(rel = LINK_REL_PREFERENCES)
|
||||
@ApiOperation(value = "Saves preferences of logged in user",
|
||||
notes = "All the existing user's preferences will be override by this method")
|
||||
@ApiResponses({@ApiResponse(code = 204, message = "Preferences successfully saved"),
|
||||
@ApiResponse(code = 400, message = "Request doesn't contain new preferences"),
|
||||
@ApiResponse(code = 500, message = "Couldn't save preferences due to internal server error")})
|
||||
public void save(Map<String, String> preferences) throws BadRequestException, ServerException {
|
||||
if (preferences == null) {
|
||||
throw new BadRequestException("Required non-null new preferences");
|
||||
}
|
||||
preferenceManager.save(userId(), preferences);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Consumes(APPLICATION_JSON)
|
||||
@Produces(APPLICATION_JSON)
|
||||
@GenerateLink(rel = LINK_REL_PREFERENCES)
|
||||
@ApiOperation(value = "Updates preferences of logged in user",
|
||||
notes = "The merge strategy is used for update, which means that " +
|
||||
"existing preferences with keys equal to update preference keys will " +
|
||||
"be replaces with new values, and new preferences will be added")
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "Preferences successfully updated, response contains " +
|
||||
"all the user preferences"),
|
||||
@ApiResponse(code = 400, message = "Request doesn't contain preferences update"),
|
||||
@ApiResponse(code = 500, message = "Couldn't update preferences due to internal server error")})
|
||||
public Map<String, String> update(Map<String, String> preferences) throws ServerException, BadRequestException {
|
||||
if (preferences == null) {
|
||||
throw new BadRequestException("Required non-null preferences update");
|
||||
}
|
||||
return preferenceManager.update(userId(), preferences);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Consumes(APPLICATION_JSON)
|
||||
@GenerateLink(rel = LINK_REL_PREFERENCES)
|
||||
@ApiOperation(value = "Remove preferences of logged in user.",
|
||||
notes = "If names are not specified, then all the user's preferences will be removed, " +
|
||||
"otherwise only the preferences which names are listed")
|
||||
@ApiResponses({@ApiResponse(code = 204, message = "Preferences successfully removed"),
|
||||
@ApiResponse(code = 500, message = "Couldn't remove preferences due to internal server error")})
|
||||
public void removePreferences(@ApiParam("Preferences to remove") List<String> names) throws ServerException {
|
||||
if (names == null || names.isEmpty()) {
|
||||
preferenceManager.remove(userId());
|
||||
} else {
|
||||
preferenceManager.remove(userId(), names);
|
||||
}
|
||||
}
|
||||
|
||||
private static String userId() {
|
||||
return EnvironmentContext.getCurrent().getSubject().getUserId();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server;
|
||||
|
||||
import org.eclipse.che.api.core.rest.ServiceContext;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.Link;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDto;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static org.eclipse.che.api.core.util.LinksHelper.createLink;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_CURRENT_PROFILE;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_CURRENT_PROFILE_ATTRIBUTES;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_PROFILE_ATTRIBUTES;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_SELF;
|
||||
|
||||
/**
|
||||
* Creates and injects links to the {@link ProfileDto} object.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Singleton
|
||||
public class ProfileLinksInjector {
|
||||
|
||||
public ProfileDto injectLinks(ProfileDto profileDto, ServiceContext serviceContext) {
|
||||
final UriBuilder uriBuilder = serviceContext.getServiceUriBuilder();
|
||||
final List<Link> links = new ArrayList<>(5);
|
||||
links.add(createLink(HttpMethod.GET,
|
||||
uriBuilder.clone()
|
||||
.path(ProfileService.class, "getCurrent")
|
||||
.build()
|
||||
.toString(),
|
||||
null,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_CURRENT_PROFILE));
|
||||
links.add(createLink(HttpMethod.GET,
|
||||
uriBuilder.clone()
|
||||
.path(ProfileService.class, "getById")
|
||||
.build(profileDto.getUserId())
|
||||
.toString(),
|
||||
null,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_SELF));
|
||||
links.add(createLink(HttpMethod.PUT,
|
||||
uriBuilder.clone()
|
||||
.path(ProfileService.class, "updateAttributes")
|
||||
.build()
|
||||
.toString(),
|
||||
APPLICATION_JSON,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_CURRENT_PROFILE_ATTRIBUTES));
|
||||
links.add(createLink(HttpMethod.DELETE,
|
||||
uriBuilder.clone()
|
||||
.path(ProfileService.class, "removeAttributes")
|
||||
.build(profileDto.getUserId())
|
||||
.toString(),
|
||||
APPLICATION_JSON,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_CURRENT_PROFILE_ATTRIBUTES));
|
||||
links.add(createLink(HttpMethod.PUT,
|
||||
uriBuilder.clone()
|
||||
.path(ProfileService.class, "updateAttributesById")
|
||||
.build(profileDto.getUserId())
|
||||
.toString(),
|
||||
APPLICATION_JSON,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_PROFILE_ATTRIBUTES));
|
||||
return profileDto.withLinks(links);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server;
|
||||
|
||||
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.Profile;
|
||||
import org.eclipse.che.api.core.model.user.User;
|
||||
import org.eclipse.che.api.user.server.model.impl.ProfileImpl;
|
||||
import org.eclipse.che.api.user.server.spi.ProfileDao;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Preferences manager layer, simplifies prefernces service by
|
||||
* taking all the business logic out from the service and making that logic
|
||||
* easily reusable throughout the system.
|
||||
*
|
||||
* <p>The manager doesn't perform any bean validations and it
|
||||
* is expected that all the incoming objects are valid, nevertheless
|
||||
* this exactly the right place for performing business validations.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Singleton
|
||||
public class ProfileManager {
|
||||
|
||||
@Inject
|
||||
private ProfileDao profileDao;
|
||||
|
||||
/**
|
||||
* Finds the profile related to the user with given {@code userId}.
|
||||
*
|
||||
* @param userId
|
||||
* the id to search the user's profile
|
||||
* @return found profile
|
||||
* @throws NullPointerException
|
||||
* when {@code userId} is null
|
||||
* @throws NotFoundException
|
||||
* when there is no profile for the user with the id {@code userId}
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
public Profile getById(String userId) throws NotFoundException, ServerException {
|
||||
requireNonNull(userId, "Required non-null user id");
|
||||
return profileDao.getById(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new user's profile .
|
||||
*
|
||||
* @param profile
|
||||
* new profile
|
||||
* @throws NullPointerException
|
||||
* when profile is null
|
||||
* @throws ConflictException
|
||||
* when profile for the user {@code profile.getUserId()} already exists
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
public void create(Profile profile) throws ServerException, ConflictException {
|
||||
requireNonNull(profile, "Required non-null profile");
|
||||
profileDao.create(new ProfileImpl(profile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates current profile using replace strategy.
|
||||
*
|
||||
* <p>Note that {@link Profile#getEmail()} can't be updated using this method
|
||||
* as it is mirrored from the {@link User#getEmail()}.
|
||||
*
|
||||
* @param profile
|
||||
* profile update
|
||||
* @throws NullPointerException
|
||||
* when {@code profile} is null
|
||||
* @throws NotFoundException
|
||||
* when there is no profile for the user with the id {@code profile.getUserId()}
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
public void update(Profile profile) throws NotFoundException, ServerException {
|
||||
requireNonNull(profile, "Required non-null profile");
|
||||
profileDao.update(new ProfileImpl(profile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the user's profile.
|
||||
*
|
||||
* <p>Note that this method won't throw any exception when
|
||||
* user doesn't have the corresponding profile.
|
||||
*
|
||||
* @param userId
|
||||
* the id of the user, whose profile should be removed
|
||||
* @throws NullPointerException
|
||||
* when {@code id} is null
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
public void remove(String userId) throws ServerException {
|
||||
requireNonNull(userId, "Required non-null user id");
|
||||
profileDao.remove(userId);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server;
|
||||
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.model.user.Profile;
|
||||
import org.eclipse.che.api.core.model.user.User;
|
||||
import org.eclipse.che.api.core.rest.Service;
|
||||
import org.eclipse.che.api.core.rest.annotations.GenerateLink;
|
||||
import org.eclipse.che.api.user.server.model.impl.ProfileImpl;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDto;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.SecurityContext;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_CURRENT_PROFILE;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_CURRENT_PROFILE_ATTRIBUTES;
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
|
||||
/**
|
||||
* Profile REST API.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Api(value = "/profile", description = "Profile REST API")
|
||||
@Path("/profile")
|
||||
public class ProfileService extends Service {
|
||||
|
||||
@Inject
|
||||
private ProfileManager profileManager;
|
||||
@Inject
|
||||
private UserManager userManager;
|
||||
@Inject
|
||||
private ProfileLinksInjector linksInjector;
|
||||
@Context
|
||||
private SecurityContext context;
|
||||
|
||||
@GET
|
||||
@Produces(APPLICATION_JSON)
|
||||
@GenerateLink(rel = LINK_REL_CURRENT_PROFILE)
|
||||
@ApiOperation("Get profile of the logged in user")
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "The response contains requested profile entity"),
|
||||
@ApiResponse(code = 404, message = "Currently logged in user doesn't have profile"),
|
||||
@ApiResponse(code = 500, message = "Couldn't retrieve profile due to internal server error")})
|
||||
public ProfileDto getCurrent() throws ServerException, NotFoundException {
|
||||
final ProfileImpl profile = new ProfileImpl(profileManager.getById(userId()));
|
||||
return linksInjector.injectLinks(asDto(profile, userManager.getById(profile.getUserId())), getServiceContext());
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
@Produces(APPLICATION_JSON)
|
||||
@GenerateLink(rel = LINK_REL_CURRENT_PROFILE)
|
||||
@ApiOperation("Get profile by user's id")
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "The response contains requested profile entity"),
|
||||
@ApiResponse(code = 404, message = "Profile for the user with requested identifier doesn't exist"),
|
||||
@ApiResponse(code = 500, message = "Couldn't retrieve profile due to internal server error")})
|
||||
public ProfileDto getById(@ApiParam("User identifier")
|
||||
@PathParam("id")
|
||||
String userId) throws NotFoundException, ServerException {
|
||||
return linksInjector.injectLinks(asDto(profileManager.getById(userId), userManager.getById(userId)), getServiceContext());
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/attributes")
|
||||
@Consumes(APPLICATION_JSON)
|
||||
@Produces(APPLICATION_JSON)
|
||||
@ApiOperation(value = "Update the profile attributes of the user with requested identifier",
|
||||
notes = "The replace strategy is used for the update, so all the existing profile " +
|
||||
"attributes will be override by the profile update")
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "The profile successfully updated and the response contains " +
|
||||
"newly updated profile entity"),
|
||||
@ApiResponse(code = 404, message = "When profile for the user with requested identifier doesn't exist"),
|
||||
@ApiResponse(code = 500, message = "Couldn't retrieve profile due to internal server error")})
|
||||
public ProfileDto updateAttributesById(@ApiParam("Id of the user")
|
||||
@PathParam("id")
|
||||
String userId,
|
||||
@ApiParam("New profile attributes")
|
||||
Map<String, String> updates) throws NotFoundException,
|
||||
ServerException,
|
||||
BadRequestException {
|
||||
if (updates == null) {
|
||||
throw new BadRequestException("Update attributes required");
|
||||
}
|
||||
final ProfileImpl profile = new ProfileImpl(profileManager.getById(userId));
|
||||
profile.setAttributes(updates);
|
||||
profileManager.update(profile);
|
||||
return linksInjector.injectLinks(asDto(profile, userManager.getById(userId)), getServiceContext());
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/attributes")
|
||||
@Consumes(APPLICATION_JSON)
|
||||
@Produces(APPLICATION_JSON)
|
||||
@GenerateLink(rel = LINK_REL_CURRENT_PROFILE_ATTRIBUTES)
|
||||
@ApiOperation(value = "Update the profile attributes of the currently logged in user",
|
||||
notes = "The replace strategy is used for the update, so all the existing profile " +
|
||||
"attributes will be override with incoming values")
|
||||
public ProfileDto updateAttributes(@ApiParam("New profile attributes")
|
||||
Map<String, String> updates) throws NotFoundException,
|
||||
ServerException,
|
||||
BadRequestException {
|
||||
if (updates == null) {
|
||||
throw new BadRequestException("Update attributes required");
|
||||
}
|
||||
final ProfileImpl profile = new ProfileImpl(profileManager.getById(userId()));
|
||||
profile.setAttributes(updates);
|
||||
profileManager.update(profile);
|
||||
return linksInjector.injectLinks(asDto(profile, userManager.getById(profile.getUserId())), getServiceContext());
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("/attributes")
|
||||
@GenerateLink(rel = LINK_REL_CURRENT_PROFILE_ATTRIBUTES)
|
||||
@Consumes(APPLICATION_JSON)
|
||||
@ApiOperation(value = "Remove profile attributes which names are equal to given",
|
||||
notes = "If names list is not send, all the attributes will be removed, " +
|
||||
"if there are no attributes which names equal to some of the given names, " +
|
||||
"then those names are skipped.")
|
||||
@ApiResponses({@ApiResponse(code = 204, message = "Attributes successfully removed"),
|
||||
@ApiResponse(code = 500, message = "Couldn't remove attributes due to internal server error")})
|
||||
public void removeAttributes(@ApiParam("The names of the profile attributes to remove")
|
||||
List<String> names) throws NotFoundException, ServerException {
|
||||
final Profile profile = profileManager.getById(userId());
|
||||
final Map<String, String> attributes = profile.getAttributes();
|
||||
if (names == null) {
|
||||
attributes.clear();
|
||||
} else {
|
||||
names.forEach(attributes::remove);
|
||||
}
|
||||
profileManager.update(profile);
|
||||
}
|
||||
|
||||
private static ProfileDto asDto(Profile profile, User user) {
|
||||
return DtoFactory.newDto(ProfileDto.class)
|
||||
.withUserId(profile.getUserId())
|
||||
.withEmail(user.getEmail())
|
||||
.withAttributes(profile.getAttributes());
|
||||
}
|
||||
|
||||
private static String userId() {
|
||||
return EnvironmentContext.getCurrent().getSubject().getUserId();
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
package org.eclipse.che.api.user.server;
|
||||
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.user.server.dao.User;
|
||||
import org.eclipse.che.api.core.model.user.User;
|
||||
|
||||
/**
|
||||
* Validates token.
|
||||
|
|
@ -22,7 +22,7 @@ import org.eclipse.che.api.user.server.dao.User;
|
|||
public interface TokenValidator {
|
||||
|
||||
/**
|
||||
* Validates {@param token}
|
||||
* Validates {@code token}.
|
||||
*
|
||||
* @return user email
|
||||
* @throws ConflictException
|
||||
|
|
|
|||
|
|
@ -13,96 +13,88 @@ package org.eclipse.che.api.user.server;
|
|||
import org.eclipse.che.api.core.rest.ServiceContext;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.Link;
|
||||
import org.eclipse.che.api.core.util.LinksHelper;
|
||||
import org.eclipse.che.api.user.shared.dto.UserDescriptor;
|
||||
import org.eclipse.che.api.user.shared.dto.UserDto;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import java.util.LinkedList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED;
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_GET_CURRENT_USER;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_GET_CURRENT_USER_PROFILE;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_GET_USER_BY_EMAIL;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_GET_USER_BY_ID;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_GET_USER_PROFILE_BY_ID;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_REMOVE_USER_BY_ID;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_UPDATE_PASSWORD;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_CURRENT_USER;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_CURRENT_USER_PASSWORD;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_CURRENT_USER_SETTINGS;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_PREFERENCES;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_PROFILE;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_SELF;
|
||||
|
||||
/**
|
||||
* Helps to inject {@link UserService} related links.
|
||||
*
|
||||
* @author Anatoliy Bazko
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public final class LinksInjector {
|
||||
@Singleton
|
||||
public class UserLinksInjector {
|
||||
|
||||
public static UserDescriptor injectLinks(UserDescriptor userDescriptor, ServiceContext serviceContext) {
|
||||
public UserDto injectLinks(UserDto userDto, ServiceContext serviceContext) {
|
||||
final UriBuilder uriBuilder = serviceContext.getBaseUriBuilder();
|
||||
final List<Link> links = new LinkedList<>();
|
||||
final List<Link> links = new ArrayList<>(6);
|
||||
links.add(LinksHelper.createLink(HttpMethod.GET,
|
||||
uriBuilder.clone().path(UserProfileService.class)
|
||||
.path(UserProfileService.class, "getCurrent")
|
||||
.build()
|
||||
uriBuilder.clone()
|
||||
.path(UserService.class)
|
||||
.path(UserService.class, "getById")
|
||||
.build(userDto.getId())
|
||||
.toString(),
|
||||
null,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_GET_CURRENT_USER_PROFILE));
|
||||
LINK_REL_SELF));
|
||||
links.add(LinksHelper.createLink(HttpMethod.GET,
|
||||
uriBuilder.clone().path(UserService.class)
|
||||
uriBuilder.clone()
|
||||
.path(UserService.class)
|
||||
.path(UserService.class, "getCurrent")
|
||||
.build()
|
||||
.toString(),
|
||||
null,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_GET_CURRENT_USER));
|
||||
LINK_REL_CURRENT_USER));
|
||||
links.add(LinksHelper.createLink(HttpMethod.POST,
|
||||
uriBuilder.clone().path(UserService.class)
|
||||
uriBuilder.clone()
|
||||
.path(UserService.class)
|
||||
.path(UserService.class, "updatePassword")
|
||||
.build()
|
||||
.toString(),
|
||||
APPLICATION_FORM_URLENCODED,
|
||||
null,
|
||||
LINK_REL_UPDATE_PASSWORD));
|
||||
|
||||
LINK_REL_CURRENT_USER_PASSWORD));
|
||||
links.add(LinksHelper.createLink(HttpMethod.GET,
|
||||
uriBuilder.clone().path(UserService.class)
|
||||
.path(UserService.class, "getById")
|
||||
.build(userDescriptor.getId())
|
||||
uriBuilder.clone()
|
||||
.path(ProfileService.class)
|
||||
.path(ProfileService.class, "getById")
|
||||
.build(userDto.getId())
|
||||
.toString(),
|
||||
null,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_GET_USER_BY_ID));
|
||||
LINK_REL_PROFILE));
|
||||
links.add(LinksHelper.createLink(HttpMethod.GET,
|
||||
uriBuilder.clone().path(UserProfileService.class)
|
||||
.path(UserProfileService.class, "getById")
|
||||
.build(userDescriptor.getId())
|
||||
uriBuilder.clone()
|
||||
.path(UserService.class)
|
||||
.path(UserService.class, "getSettings")
|
||||
.build()
|
||||
.toString(),
|
||||
null,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_GET_USER_PROFILE_BY_ID));
|
||||
if (userDescriptor.getEmail() != null) {
|
||||
links.add(LinksHelper.createLink(HttpMethod.GET,
|
||||
uriBuilder.clone().path(UserService.class)
|
||||
.path(UserService.class, "getByAlias")
|
||||
.queryParam("email", userDescriptor.getEmail())
|
||||
.build()
|
||||
.toString(),
|
||||
null,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_GET_USER_BY_EMAIL));
|
||||
}
|
||||
links.add(LinksHelper.createLink(HttpMethod.DELETE,
|
||||
uriBuilder.clone().path(UserService.class)
|
||||
.path(UserService.class, "remove")
|
||||
.build(userDescriptor.getId())
|
||||
LINK_REL_CURRENT_USER_SETTINGS));
|
||||
links.add(LinksHelper.createLink(HttpMethod.GET,
|
||||
uriBuilder.clone().path(PreferencesService.class)
|
||||
.path(PreferencesService.class, "find")
|
||||
.build()
|
||||
.toString(),
|
||||
null,
|
||||
null,
|
||||
LINK_REL_REMOVE_USER_BY_ID));
|
||||
|
||||
return userDescriptor.withLinks(links);
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_PREFERENCES));
|
||||
return userDto.withLinks(links);
|
||||
}
|
||||
|
||||
private LinksInjector() {}
|
||||
}
|
||||
|
|
@ -10,167 +10,218 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
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.user.server.dao.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.dao.Profile;
|
||||
import org.eclipse.che.api.user.server.dao.User;
|
||||
import org.eclipse.che.api.user.server.dao.UserDao;
|
||||
import org.eclipse.che.api.user.server.dao.UserProfileDao;
|
||||
import org.eclipse.che.api.core.model.user.Profile;
|
||||
import org.eclipse.che.api.core.model.user.User;
|
||||
import org.eclipse.che.api.user.server.model.impl.ProfileImpl;
|
||||
import org.eclipse.che.api.user.server.spi.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.spi.ProfileDao;
|
||||
import org.eclipse.che.api.user.server.spi.UserDao;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
import static java.lang.String.format;
|
||||
import static java.lang.System.currentTimeMillis;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Facade for User related operations.
|
||||
* Facade for {@link User} and {@link Profile} related operations.
|
||||
*
|
||||
* @author Max Shaposhnik (mshaposhnik@codenvy.com)
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Singleton
|
||||
public class UserManager {
|
||||
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UserManager.class);
|
||||
|
||||
private final UserDao userDao;
|
||||
private final UserProfileDao profileDao;
|
||||
private final PreferenceDao preferenceDao;
|
||||
private final Set<String> reservedNames;
|
||||
private final UserDao userDao;
|
||||
private final ProfileDao profileDao;
|
||||
private final PreferenceDao preferencesDao;
|
||||
private final Set<String> reservedNames;
|
||||
|
||||
@Inject
|
||||
public UserManager(UserDao userDao,
|
||||
UserProfileDao profileDao,
|
||||
PreferenceDao preferenceDao,
|
||||
ProfileDao profileDao,
|
||||
PreferenceDao preferencesDao,
|
||||
@Named("user.reserved_names") String[] reservedNames) {
|
||||
this.userDao = userDao;
|
||||
this.profileDao = profileDao;
|
||||
this.preferenceDao = preferenceDao;
|
||||
this.preferencesDao = preferencesDao;
|
||||
this.reservedNames = Sets.newHashSet(reservedNames);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates new user.
|
||||
* Creates new user and his profile.
|
||||
*
|
||||
* @param user
|
||||
* POJO representation of user entity
|
||||
* @param newUser
|
||||
* created user
|
||||
* @throws NullPointerException
|
||||
* when {@code newUser} is null
|
||||
* @throws ConflictException
|
||||
* when given user cannot be created
|
||||
* when user with such name/email/alias already exists
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
public void create(User user, boolean isTemporary) throws ConflictException, ServerException {
|
||||
if (reservedNames.contains(user.getName().toLowerCase())) {
|
||||
throw new ConflictException(String.format("Username \"%s\" is reserved", user.getName()));
|
||||
public User create(User newUser, boolean isTemporary) throws ConflictException, ServerException {
|
||||
requireNonNull(newUser, "Required non-null user");
|
||||
if (reservedNames.contains(newUser.getName().toLowerCase())) {
|
||||
throw new ConflictException(String.format("Username '%s' is reserved", newUser.getName()));
|
||||
}
|
||||
user.withId(generate("user", ID_LENGTH))
|
||||
.withPassword(firstNonNull(user.getPassword(), generate("", PASSWORD_LENGTH)));
|
||||
userDao.create(user);
|
||||
|
||||
profileDao.create(new Profile(user.getId()));
|
||||
|
||||
final Map<String, String> preferences = new HashMap<>(4);
|
||||
preferences.put("temporary", Boolean.toString(isTemporary));
|
||||
preferences.put("codenvy:created", Long.toString(System.currentTimeMillis()));
|
||||
final UserImpl user = new UserImpl(generate("user", ID_LENGTH),
|
||||
newUser.getEmail(),
|
||||
newUser.getName(),
|
||||
firstNonNull(newUser.getPassword(), generate("", PASSWORD_LENGTH)),
|
||||
newUser.getAliases());
|
||||
try {
|
||||
preferenceDao.setPreferences(user.getId(), preferences);
|
||||
} catch (NotFoundException e) {
|
||||
LOG.warn(format("Cannot set creation time preferences for user %s.", user.getId()), e);
|
||||
userDao.create(user);
|
||||
profileDao.create(new ProfileImpl(user.getId()));
|
||||
preferencesDao.setPreferences(user.getId(), ImmutableMap.of("temporary", Boolean.toString(isTemporary),
|
||||
"codenvy:created", Long.toString(currentTimeMillis())));
|
||||
} catch (ConflictException | ServerException x) {
|
||||
// optimistic rollback(won't remove profile if userDao.remove failed)
|
||||
// remove operation is not-found-safe so if any exception
|
||||
// during the either user or profile creation occurs remove all entities
|
||||
// NOTE: this logic must be replaced with transaction management
|
||||
try {
|
||||
userDao.remove(user.getId());
|
||||
profileDao.remove(user.getId());
|
||||
preferencesDao.remove(user.getId());
|
||||
} catch (ConflictException | ServerException rollbackEx) {
|
||||
LOG.error(format("An attempt to clean up resources due to user creation failure was unsuccessful." +
|
||||
"Now the system may be in inconsistent state. " +
|
||||
"User with id '%s' must not exist",
|
||||
user.getId()),
|
||||
rollbackEx);
|
||||
}
|
||||
throw x;
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates user by replacing an existing user entity with a new one.
|
||||
*
|
||||
* @param user
|
||||
* user update
|
||||
* @throws NullPointerException
|
||||
* when {@code user} is null
|
||||
* @throws NotFoundException
|
||||
* when user with id {@code user.getId()} is not found
|
||||
* @throws ConflictException
|
||||
* when user's new alias/email/name is not unique
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
public void update(User user) throws NotFoundException, ServerException, ConflictException {
|
||||
requireNonNull(user, "Required non-null user");
|
||||
userDao.update(new UserImpl(user));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets user from persistent layer by his identifier
|
||||
* Finds user by given {@code id}.
|
||||
*
|
||||
* @param id
|
||||
* user identifier
|
||||
* @return user POJO
|
||||
* @return user instance
|
||||
* @throws NullPointerException
|
||||
* when {@code id} is null
|
||||
* @throws NotFoundException
|
||||
* when user doesn't exist
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
public User getById(String id) throws NotFoundException, ServerException {
|
||||
requireNonNull(id, "Required non-null id");
|
||||
return userDao.getById(id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates already present in persistent layer user.
|
||||
*
|
||||
* @param user
|
||||
* POJO representation of user entity
|
||||
* @throws NotFoundException
|
||||
* when user is not found
|
||||
* @throws ConflictException
|
||||
* when given user cannot be updated
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*
|
||||
*/
|
||||
public void update(User user) throws NotFoundException, ServerException, ConflictException {
|
||||
userDao.update(user);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets user from persistent layer by any of his aliases
|
||||
* Finds user by given {@code alias}.
|
||||
*
|
||||
* @param alias
|
||||
* user name or alias
|
||||
* @return user POJO
|
||||
* user alias
|
||||
* @return user instance
|
||||
* @throws NullPointerException
|
||||
* when {@code alias} is null
|
||||
* @throws NotFoundException
|
||||
* when user doesn't exist
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
public User getByAlias(String alias) throws NotFoundException, ServerException {
|
||||
requireNonNull(alias, "Required non-null alias");
|
||||
return userDao.getByAlias(alias);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets user from persistent layer by his username
|
||||
* Finds user by given {@code name}.
|
||||
*
|
||||
* @param userName
|
||||
* @param name
|
||||
* user name
|
||||
* @return user POJO
|
||||
* @return user instance
|
||||
* @throws NullPointerException
|
||||
* when {@code name} is null
|
||||
* @throws NotFoundException
|
||||
* when user doesn't exist
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
public User getByName(String userName) throws NotFoundException, ServerException {
|
||||
return userDao.getByName(userName);
|
||||
public User getByName(String name) throws NotFoundException, ServerException {
|
||||
requireNonNull(name, "Required non-null name");
|
||||
return userDao.getByName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds user by given {@code email}.
|
||||
*
|
||||
* @param email
|
||||
* user email
|
||||
* @return user instance
|
||||
* @throws NullPointerException
|
||||
* when {@code email} is null
|
||||
* @throws NotFoundException
|
||||
* when user doesn't exist
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
public User getByEmail(String email) throws NotFoundException, ServerException {
|
||||
requireNonNull(email, "Required non-null email");
|
||||
return userDao.getByEmail(email);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes user from persistent layer by his identifier.
|
||||
* Removes user and his dependencies by given {@code id}.
|
||||
*
|
||||
* @param id
|
||||
* user identifier
|
||||
* @throws NullPointerException
|
||||
* when {@code id} is null
|
||||
* @throws ConflictException
|
||||
* when given user cannot be deleted
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
public void remove(String id) throws NotFoundException, ServerException, ConflictException {
|
||||
public void remove(String id) throws ServerException, ConflictException {
|
||||
requireNonNull(id, "Required non-null id");
|
||||
profileDao.remove(id);
|
||||
preferencesDao.remove(id);
|
||||
userDao.remove(id);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,442 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server;
|
||||
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
|
||||
import com.google.common.util.concurrent.Striped;
|
||||
|
||||
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.rest.Service;
|
||||
import org.eclipse.che.api.core.rest.annotations.Description;
|
||||
import org.eclipse.che.api.core.rest.annotations.GenerateLink;
|
||||
import org.eclipse.che.api.core.rest.annotations.Required;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.Link;
|
||||
import org.eclipse.che.api.core.util.LinksHelper;
|
||||
import org.eclipse.che.api.user.server.dao.PreferenceDao;
|
||||
import org.eclipse.che.api.user.server.dao.Profile;
|
||||
import org.eclipse.che.api.user.server.dao.User;
|
||||
import org.eclipse.che.api.user.server.dao.UserDao;
|
||||
import org.eclipse.che.api.user.server.dao.UserProfileDao;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDescriptor;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
import static com.google.common.base.Strings.nullToEmpty;
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_GET_CURRENT_USER_PROFILE;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_GET_USER_PROFILE_BY_ID;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_REMOVE_ATTRIBUTES;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_REMOVE_PREFERENCES;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_UPDATE_CURRENT_USER_PROFILE;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_UPDATE_PREFERENCES;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_UPDATE_USER_PROFILE_BY_ID;
|
||||
|
||||
/**
|
||||
* User Profile API
|
||||
*
|
||||
* @author Eugene Voevodin
|
||||
* @author Max Shaposhnik
|
||||
*/
|
||||
@Api(value = "/profile",
|
||||
description = "User profile manager")
|
||||
@Path("/profile")
|
||||
public class UserProfileService extends Service {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UserProfileService.class);
|
||||
|
||||
// Assuming 1000 concurrent users at most trying to update their preferences (if more they will wait for another user to finish).
|
||||
// Using the lazy weak version of Striped so the locks will be created on demand and not eagerly, and garbage collected when not needed anymore.
|
||||
private static final Striped<Lock> preferencesUpdateLocksByUser = Striped.lazyWeakLock(1000);
|
||||
|
||||
private final UserProfileDao profileDao;
|
||||
private final UserDao userDao;
|
||||
private final PreferenceDao preferenceDao;
|
||||
|
||||
@Inject
|
||||
public UserProfileService(UserProfileDao profileDao, PreferenceDao preferenceDao, UserDao userDao) {
|
||||
this.profileDao = profileDao;
|
||||
this.userDao = userDao;
|
||||
this.preferenceDao = preferenceDao;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns {@link ProfileDescriptor} for current user profile.</p>
|
||||
* <p>By default user email will be added to attributes with key <i>'email'</i>.</p>
|
||||
*
|
||||
* @return descriptor of profile
|
||||
* @throws ServerException
|
||||
* when some error occurred while retrieving/updating profile
|
||||
* @see ProfileDescriptor
|
||||
* @see #updateCurrent(Map)
|
||||
*/
|
||||
@ApiOperation(value = "Get user profile",
|
||||
notes = "Get user profile details.",
|
||||
response = ProfileDescriptor.class)
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(code = 200, message = "OK"),
|
||||
@ApiResponse(code = 404, message = "Not Found"),
|
||||
@ApiResponse(code = 500, message = "Internal Server Error")})
|
||||
@GET
|
||||
@GenerateLink(rel = LINK_REL_GET_CURRENT_USER_PROFILE)
|
||||
@Produces(APPLICATION_JSON)
|
||||
public ProfileDescriptor getCurrent() throws NotFoundException, ServerException {
|
||||
final User user = userDao.getById(currentUser().getUserId());
|
||||
final Profile profile = profileDao.getById(user.getId());
|
||||
profile.getAttributes().put("email", user.getEmail());
|
||||
return toDescriptor(profile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns preferences for current user
|
||||
*/
|
||||
@ApiOperation(value = "Get user preferences",
|
||||
notes = "Get user preferences, like SSH keys, recently opened project and files. It is possible " +
|
||||
"to use a filter, e.g. CodenvyAppState or ssh.key.public.github.com to get the last opened project " +
|
||||
"or a public part of GitHub SSH key (if any)",
|
||||
response = ProfileDescriptor.class)
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(code = 200, message = "OK"),
|
||||
@ApiResponse(code = 500, message = "Internal Server Error")})
|
||||
@GET
|
||||
@Path("/prefs")
|
||||
@Produces(APPLICATION_JSON)
|
||||
public Map<String, String> getPreferences(@ApiParam(value = "Filer")
|
||||
@QueryParam("filter") String filter) throws ServerException {
|
||||
if (filter != null) {
|
||||
return preferenceDao.getPreferences(currentUser().getUserId(), filter);
|
||||
}
|
||||
return preferenceDao.getPreferences(currentUser().getUserId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates attributes of current user profile.
|
||||
*
|
||||
* @param updates
|
||||
* attributes to update
|
||||
* @return descriptor of updated profile
|
||||
* @throws ServerException
|
||||
* when some error occurred while retrieving/persisting profile
|
||||
* @see ProfileDescriptor
|
||||
*/
|
||||
|
||||
@POST
|
||||
@GenerateLink(rel = LINK_REL_UPDATE_CURRENT_USER_PROFILE)
|
||||
@Consumes(APPLICATION_JSON)
|
||||
@Produces(APPLICATION_JSON)
|
||||
public ProfileDescriptor updateCurrent(@Description("attributes to update") Map<String, String> updates)
|
||||
throws NotFoundException, ServerException, ConflictException {
|
||||
if (updates == null || updates.isEmpty()) {
|
||||
throw new ConflictException("Attributes to update required");
|
||||
}
|
||||
final User user = userDao.getById(currentUser().getUserId());
|
||||
final Profile profile = profileDao.getById(user.getId());
|
||||
profile.getAttributes().putAll(updates);
|
||||
profileDao.update(profile);
|
||||
logEventUserUpdateProfile(user, profile.getAttributes());
|
||||
return toDescriptor(profile);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates attributes of certain profile.
|
||||
*
|
||||
* @param profileId
|
||||
* profile identifier
|
||||
* @param updates
|
||||
* attributes to update
|
||||
* @return descriptor of updated profile
|
||||
* @throws NotFoundException
|
||||
* when profile with given identifier doesn't exist
|
||||
* @throws ServerException
|
||||
* when some error occurred while retrieving/updating profile
|
||||
* @see ProfileDescriptor
|
||||
* @see #getById(String)
|
||||
*/
|
||||
|
||||
@POST
|
||||
@Path("/{id}")
|
||||
@Consumes(APPLICATION_JSON)
|
||||
@Produces(APPLICATION_JSON)
|
||||
public ProfileDescriptor update(@PathParam("id") String profileId,
|
||||
Map<String, String> updates) throws NotFoundException, ServerException, ConflictException {
|
||||
if (updates == null || updates.isEmpty()) {
|
||||
throw new ConflictException("Attributes to update required");
|
||||
}
|
||||
final Profile profile = profileDao.getById(profileId);
|
||||
profile.getAttributes().putAll(updates);
|
||||
profileDao.update(profile);
|
||||
final User user = userDao.getById(profile.getUserId());
|
||||
logEventUserUpdateProfile(user, profile.getAttributes());
|
||||
return toDescriptor(profile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for profile with given identifier and {@link ProfileDescriptor} if found.
|
||||
*
|
||||
* @param profileId
|
||||
* profile identifier
|
||||
* @return descriptor of found profile
|
||||
* @throws NotFoundException
|
||||
* when profile with given identifier doesn't exist
|
||||
* @throws ServerException
|
||||
* when some error occurred while retrieving user or profile
|
||||
* @see ProfileDescriptor
|
||||
* @see #getById(String)
|
||||
*/
|
||||
@ApiOperation(value = "Get profile of a specific user",
|
||||
notes = "Get profile of a specific user",
|
||||
response = ProfileDescriptor.class)
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(code = 200, message = "OK"),
|
||||
@ApiResponse(code = 404, message = "Not Found"),
|
||||
@ApiResponse(code = 500, message = "Internal Server Error")})
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
@Produces(APPLICATION_JSON)
|
||||
public ProfileDescriptor getById(@ApiParam(value = " ID")
|
||||
@PathParam("id")
|
||||
String profileId) throws NotFoundException, ServerException {
|
||||
final Profile profile = profileDao.getById(profileId);
|
||||
final User user = userDao.getById(profile.getUserId());
|
||||
profile.getAttributes().put("email", user.getEmail());
|
||||
return toDescriptor(profile);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Updates preferences of current user profile.</p>
|
||||
*
|
||||
* @param update
|
||||
* update preferences
|
||||
* @return descriptor of updated profile
|
||||
* @throws ServerException
|
||||
* when some error occurred while retrieving/updating profile
|
||||
* @throws ConflictException
|
||||
* when update is {@code null} or <i>empty</i>
|
||||
* @see ProfileDescriptor
|
||||
* @see #updateCurrent(Map)
|
||||
*/
|
||||
@POST
|
||||
@Path("/prefs")
|
||||
@GenerateLink(rel = LINK_REL_UPDATE_PREFERENCES)
|
||||
@Consumes(APPLICATION_JSON)
|
||||
@Produces(APPLICATION_JSON)
|
||||
public Map<String, String> updatePreferences(@Required Map<String, String> update) throws NotFoundException,
|
||||
ServerException,
|
||||
ConflictException {
|
||||
if (update == null || update.isEmpty()) {
|
||||
throw new ConflictException("Preferences to update required");
|
||||
}
|
||||
|
||||
String userId = currentUser().getUserId();
|
||||
// Keep the lock in a variable so it isn't garbage collected while in use
|
||||
Lock lock = preferencesUpdateLocksByUser.get(userId);
|
||||
lock.lock();
|
||||
try {
|
||||
final Map<String, String> preferences = preferenceDao.getPreferences(userId);
|
||||
preferences.putAll(update);
|
||||
preferenceDao.setPreferences(currentUser().getUserId(), preferences);
|
||||
return preferences;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes attributes with given names from current user profile.
|
||||
* If names are {@code null} - all attributes will be removed
|
||||
*
|
||||
* @param attrNames
|
||||
* attributes names to remove
|
||||
* @throws ConflictException
|
||||
* when given list of attributes names is {@code null}
|
||||
* @throws ServerException
|
||||
* when some error occurred while retrieving/updating profile
|
||||
*/
|
||||
@ApiOperation(value = "Remove attributes of a current user",
|
||||
notes = "Remove attributes of a current user",
|
||||
position = 6)
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(code = 204, message = "OK"),
|
||||
@ApiResponse(code = 404, message = "Not Found"),
|
||||
@ApiResponse(code = 409, message = "Attributes names required"),
|
||||
@ApiResponse(code = 500, message = "Internal Server Error")})
|
||||
@DELETE
|
||||
@Path("/attributes")
|
||||
@GenerateLink(rel = LINK_REL_REMOVE_ATTRIBUTES)
|
||||
@Consumes(APPLICATION_JSON)
|
||||
public void removeAttributes(@ApiParam(value = "Attributes", required = true)
|
||||
@Required
|
||||
@Description("Attributes names to remove")
|
||||
List<String> attrNames) throws NotFoundException, ServerException, ConflictException {
|
||||
final Profile currentProfile = profileDao.getById(currentUser().getUserId());
|
||||
if (attrNames == null) {
|
||||
currentProfile.getAttributes().clear();
|
||||
} else {
|
||||
for (String attributeName : attrNames) {
|
||||
currentProfile.getAttributes().remove(attributeName);
|
||||
}
|
||||
}
|
||||
profileDao.update(currentProfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes preferences with given name from current user profile.
|
||||
* If names are {@code null} - all preferences will be removed
|
||||
*
|
||||
* @param names
|
||||
* preferences names to remove
|
||||
* @throws ServerException
|
||||
* when some error occurred while retrieving/updating profile
|
||||
* @see #removeAttributes(List)
|
||||
*/
|
||||
@ApiOperation(value = "Remove profile references of a current user",
|
||||
notes = "Remove profile references of a current user",
|
||||
position = 7)
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(code = 204, message = "OK"),
|
||||
@ApiResponse(code = 404, message = "Not Found"),
|
||||
@ApiResponse(code = 409, message = "Preferences names required"),
|
||||
@ApiResponse(code = 500, message = "Internal Server Error")})
|
||||
@DELETE
|
||||
@Path("/prefs")
|
||||
@GenerateLink(rel = LINK_REL_REMOVE_PREFERENCES)
|
||||
@Consumes(APPLICATION_JSON)
|
||||
public void removePreferences(@ApiParam(value = "Preferences to remove", required = true)
|
||||
@Required
|
||||
List<String> names) throws ServerException, NotFoundException {
|
||||
String userId = currentUser().getUserId();
|
||||
if (names == null) {
|
||||
preferenceDao.remove(userId);
|
||||
} else {
|
||||
// Keep the lock in a variable so it isn't garbage collected while in use
|
||||
Lock lock = preferencesUpdateLocksByUser.get(userId);
|
||||
lock.lock();
|
||||
try {
|
||||
final Map<String, String> preferences = preferenceDao.getPreferences(userId);
|
||||
for (String name : names) {
|
||||
preferences.remove(name);
|
||||
}
|
||||
preferenceDao.setPreferences(userId, preferences);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts {@link Profile} to {@link ProfileDescriptor}
|
||||
*/
|
||||
/* package-private used in tests*/ProfileDescriptor toDescriptor(Profile profile) {
|
||||
final UriBuilder uriBuilder = getServiceContext().getServiceUriBuilder();
|
||||
final List<Link> links = new LinkedList<>();
|
||||
links.add(LinksHelper.createLink(HttpMethod.GET,
|
||||
uriBuilder.clone()
|
||||
.path(getClass(), "getCurrent")
|
||||
.build()
|
||||
.toString(),
|
||||
null,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_GET_CURRENT_USER_PROFILE));
|
||||
links.add(LinksHelper.createLink(HttpMethod.GET,
|
||||
uriBuilder.clone()
|
||||
.path(getClass(), "getById")
|
||||
.build(profile.getId())
|
||||
.toString(),
|
||||
null,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_GET_USER_PROFILE_BY_ID));
|
||||
links.add(LinksHelper.createLink(HttpMethod.POST,
|
||||
uriBuilder.clone()
|
||||
.path(getClass(), "updateCurrent")
|
||||
.build()
|
||||
.toString(),
|
||||
APPLICATION_JSON,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_UPDATE_CURRENT_USER_PROFILE));
|
||||
links.add(LinksHelper.createLink(HttpMethod.POST,
|
||||
uriBuilder.clone()
|
||||
.path(getClass(), "updatePreferences")
|
||||
.build()
|
||||
.toString(),
|
||||
APPLICATION_JSON,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_UPDATE_PREFERENCES));
|
||||
links.add(LinksHelper.createLink(HttpMethod.GET,
|
||||
uriBuilder.clone()
|
||||
.path(getClass(), "getById")
|
||||
.build(profile.getId())
|
||||
.toString(),
|
||||
null,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_GET_USER_PROFILE_BY_ID));
|
||||
links.add(LinksHelper.createLink(HttpMethod.POST,
|
||||
uriBuilder.clone()
|
||||
.path(getClass(), "update")
|
||||
.build(profile.getId())
|
||||
.toString(),
|
||||
APPLICATION_JSON,
|
||||
APPLICATION_JSON,
|
||||
LINK_REL_UPDATE_USER_PROFILE_BY_ID));
|
||||
return DtoFactory.newDto(ProfileDescriptor.class)
|
||||
.withId(profile.getId())
|
||||
.withUserId(profile.getUserId())
|
||||
.withAttributes(profile.getAttributes())
|
||||
.withLinks(links);
|
||||
}
|
||||
|
||||
private Subject currentUser() {
|
||||
return EnvironmentContext.getCurrent().getSubject();
|
||||
}
|
||||
|
||||
private void logEventUserUpdateProfile(User user, Map<String, String> attributes) {
|
||||
final Set<String> emails = new HashSet<>(user.getAliases());
|
||||
emails.add(user.getEmail());
|
||||
|
||||
LOG.info("EVENT#user-update-profile# USER#{}# FIRSTNAME#{}# LASTNAME#{}# COMPANY#{}# PHONE#{}# JOBTITLE#{}# EMAILS#{}# USER-ID#{}#",
|
||||
user.getEmail(),
|
||||
nullToEmpty(attributes.get("firstName")),
|
||||
nullToEmpty(attributes.get("lastName")),
|
||||
nullToEmpty(attributes.get("employer")),
|
||||
nullToEmpty(attributes.get("phone")),
|
||||
nullToEmpty(attributes.get("jobtitle")),
|
||||
user.getAliases(),
|
||||
user.getId());
|
||||
}
|
||||
}
|
||||
|
|
@ -20,15 +20,14 @@ import com.google.common.collect.ImmutableMap;
|
|||
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.UnauthorizedException;
|
||||
import org.eclipse.che.api.core.model.user.User;
|
||||
import org.eclipse.che.api.core.rest.Service;
|
||||
import org.eclipse.che.api.core.rest.annotations.GenerateLink;
|
||||
import org.eclipse.che.api.core.rest.annotations.Required;
|
||||
import org.eclipse.che.api.user.server.dao.User;
|
||||
import org.eclipse.che.api.user.shared.dto.UserDescriptor;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
import org.eclipse.che.api.user.shared.dto.UserDto;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
|
@ -46,301 +45,162 @@ import javax.ws.rs.QueryParam;
|
|||
import javax.ws.rs.core.Response;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED;
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static javax.ws.rs.core.Response.Status.CREATED;
|
||||
import static javax.ws.rs.core.Response.status;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_CREATE_USER;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_GET_CURRENT_USER;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_GET_USER_BY_EMAIL;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_GET_USER_BY_ID;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_REMOVE_USER_BY_ID;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_UPDATE_PASSWORD;
|
||||
import static org.eclipse.che.api.user.server.DtoConverter.toDescriptor;
|
||||
import static org.eclipse.che.api.user.server.LinksInjector.injectLinks;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_CURRENT_USER;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_CURRENT_USER_PASSWORD;
|
||||
import static org.eclipse.che.api.user.server.Constants.LINK_REL_USER;
|
||||
import static org.eclipse.che.api.user.server.DtoConverter.asDto;
|
||||
|
||||
/**
|
||||
* Provides REST API for user management
|
||||
* User REST API.
|
||||
*
|
||||
* @author Eugene Voevodin
|
||||
* @author Yevhenii Voevodin
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
@Api(value = "/user", description = "User manager")
|
||||
@Path("/user")
|
||||
@Api(value = "/user", description = "User REST API")
|
||||
public class UserService extends Service {
|
||||
public static final String USER_SELF_CREATION_ALLOWED = "user.self.creation.allowed";
|
||||
|
||||
private final UserManager userManager;
|
||||
private final TokenValidator tokenValidator;
|
||||
private final UserNameValidator userNameValidator;
|
||||
private final UserLinksInjector linksInjector;
|
||||
private final UserValidator userValidator;
|
||||
private final boolean userSelfCreationAllowed;
|
||||
|
||||
@Inject
|
||||
public UserService(UserManager userManager,
|
||||
TokenValidator tokenValidator,
|
||||
UserNameValidator userNameValidator,
|
||||
UserValidator userNameValidator,
|
||||
UserLinksInjector linksInjector,
|
||||
@Named(USER_SELF_CREATION_ALLOWED) boolean userSelfCreationAllowed) {
|
||||
this.userManager = userManager;
|
||||
this.linksInjector = linksInjector;
|
||||
this.tokenValidator = tokenValidator;
|
||||
this.userNameValidator = userNameValidator;
|
||||
this.userValidator = userNameValidator;
|
||||
this.userSelfCreationAllowed = userSelfCreationAllowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new user and profile.
|
||||
*
|
||||
* <p>User will be created from {@code token} parameter or from {@code userDescriptor}
|
||||
* when {@code token} is null
|
||||
*
|
||||
* @param token
|
||||
* authentication token
|
||||
* @param isTemporary
|
||||
* if it is {@code true} creates temporary user
|
||||
* @return entity of created user
|
||||
* @throws ForbiddenException
|
||||
* when the user is not the system admin, or self creation is disabled
|
||||
* @throws BadRequestException
|
||||
* when {@code userDescriptor} is invalid
|
||||
* @throws UnauthorizedException
|
||||
* when token is null
|
||||
* @throws ConflictException
|
||||
* when token is not valid
|
||||
* @throws ServerException
|
||||
* when some error occurred while persisting user or user profile
|
||||
* @see UserDescriptor
|
||||
* @see #getCurrent()
|
||||
* @see #updatePassword(String)
|
||||
* @see #getById(String)
|
||||
* @see #getByAlias(String)
|
||||
* @see #remove(String)
|
||||
*/
|
||||
@POST
|
||||
@Path("/create")
|
||||
@Consumes(APPLICATION_JSON)
|
||||
@Produces(APPLICATION_JSON)
|
||||
@GenerateLink(rel = LINK_REL_CREATE_USER)
|
||||
@ApiOperation(value = "Create a new user",
|
||||
notes = "Create a new user in the system. There are two ways to create a user: " +
|
||||
"through a regular registration workflow when auth token is sent to user's mailbox" +
|
||||
"and directly with predefined name and password. ",
|
||||
response = UserDescriptor.class)
|
||||
@ApiResponses({@ApiResponse(code = 201, message = "Created"),
|
||||
@GenerateLink(rel = LINK_REL_USER)
|
||||
@ApiOperation(value = "Create a new user", response = UserDto.class)
|
||||
@ApiResponses({@ApiResponse(code = 201, message = "User successfully created, response contains created entity"),
|
||||
@ApiResponse(code = 400, message = "Missed required parameters, parameters are not valid"),
|
||||
@ApiResponse(code = 401, message = "Missed token parameter"),
|
||||
@ApiResponse(code = 403, message = "Invalid or missing request parameters"),
|
||||
@ApiResponse(code = 409, message = "Invalid token"),
|
||||
@ApiResponse(code = 500, message = "Internal Server Error")})
|
||||
public Response create(@ApiParam(value = "New user")
|
||||
UserDescriptor userDescriptor,
|
||||
@ApiParam(value = "Authentication token")
|
||||
@ApiResponse(code = 500, message = "Couldn't create user due to internal server error")})
|
||||
public Response create(@ApiParam("New user")
|
||||
UserDto userDto,
|
||||
@ApiParam("Authentication token")
|
||||
@QueryParam("token")
|
||||
String token,
|
||||
@ApiParam(value = "User type")
|
||||
@ApiParam("User type")
|
||||
@QueryParam("temporary")
|
||||
@DefaultValue("false")
|
||||
Boolean isTemporary) throws ForbiddenException,
|
||||
BadRequestException,
|
||||
Boolean isTemporary) throws BadRequestException,
|
||||
UnauthorizedException,
|
||||
ConflictException,
|
||||
ServerException,
|
||||
NotFoundException {
|
||||
final User user = isNullOrEmpty(token) ? fromEntity(userDescriptor) : fromToken(token);
|
||||
if (!userNameValidator.isValidUserName(user.getName())) {
|
||||
throw new BadRequestException("Username must contain only letters and digits");
|
||||
}
|
||||
userManager.create(user, isTemporary);
|
||||
return status(CREATED).entity(injectLinks(toDescriptor(user), getServiceContext())).build();
|
||||
ServerException {
|
||||
final User newUser = token == null ? userDto : tokenValidator.validateToken(token);
|
||||
userValidator.checkUser(newUser);
|
||||
return Response.status(CREATED)
|
||||
.entity(linksInjector.injectLinks(asDto(userManager.create(newUser, isTemporary)), getServiceContext()))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link UserDescriptor} of current user.
|
||||
*
|
||||
* @return entity of current user.
|
||||
* @throws NotFoundException
|
||||
* when current user not found
|
||||
* @throws ServerException
|
||||
* when some error occurred while retrieving current user
|
||||
*/
|
||||
@GET
|
||||
@GenerateLink(rel = LINK_REL_GET_CURRENT_USER)
|
||||
@Produces(APPLICATION_JSON)
|
||||
@ApiOperation(value = "Get current user",
|
||||
notes = "Get user currently logged in the system",
|
||||
response = UserDescriptor.class,
|
||||
position = 2)
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK"),
|
||||
@ApiResponse(code = 404, message = "Not Found"),
|
||||
@ApiResponse(code = 500, message = "Internal Server Error")})
|
||||
public UserDescriptor getCurrent() throws NotFoundException, ServerException {
|
||||
final User user = userManager.getById(currentUserId());
|
||||
return injectLinks(toDescriptor(user), getServiceContext());
|
||||
@GenerateLink(rel = LINK_REL_CURRENT_USER)
|
||||
@ApiOperation("Get logged in user")
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "The response contains currently logged in user entity"),
|
||||
@ApiResponse(code = 500, message = "Couldn't get user due to internal server error")})
|
||||
public UserDto getCurrent() throws NotFoundException, ServerException {
|
||||
final User user = userManager.getById(userId());
|
||||
return linksInjector.injectLinks(asDto(user), getServiceContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates current user password.
|
||||
*
|
||||
* @param password
|
||||
* new user password
|
||||
* @throws NotFoundException
|
||||
* when current user not found
|
||||
* @throws BadRequestException
|
||||
* when given password is invalid
|
||||
* @throws ServerException
|
||||
* when some error occurred while updating profile
|
||||
* @see UserDescriptor
|
||||
*/
|
||||
@POST
|
||||
@Path("/password")
|
||||
@GenerateLink(rel = LINK_REL_UPDATE_PASSWORD)
|
||||
@Consumes(APPLICATION_FORM_URLENCODED)
|
||||
@ApiOperation(value = "Update password",
|
||||
notes = "Update current password")
|
||||
@ApiResponses({@ApiResponse(code = 204, message = "OK"),
|
||||
@ApiResponse(code = 400, message = "Invalid password"),
|
||||
@ApiResponse(code = 404, message = "Not Found"),
|
||||
@ApiResponse(code = 500, message = "Internal Server Error")})
|
||||
@GenerateLink(rel = LINK_REL_CURRENT_USER_PASSWORD)
|
||||
@ApiOperation(value = "Update password of logged in user",
|
||||
notes = "Password must contain at least 8 characters, " +
|
||||
"passport must contain letters and digits")
|
||||
@ApiResponses({@ApiResponse(code = 204, message = "Password successfully updated"),
|
||||
@ApiResponse(code = 400, message = "Incoming password is invalid value." +
|
||||
"Valid password must contain at least 8 character " +
|
||||
"which are letters and digits"),
|
||||
@ApiResponse(code = 500, message = "Couldn't update password due to internal server error")})
|
||||
public void updatePassword(@ApiParam(value = "New password", required = true)
|
||||
@FormParam("password")
|
||||
String password) throws NotFoundException,
|
||||
BadRequestException,
|
||||
ServerException,
|
||||
ConflictException {
|
||||
userValidator.checkPassword(password);
|
||||
|
||||
checkPassword(password);
|
||||
|
||||
final User user = userManager.getById(currentUserId());
|
||||
final UserImpl user = new UserImpl(userManager.getById(userId()));
|
||||
user.setPassword(password);
|
||||
userManager.update(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns status <b>200</b> and {@link UserDescriptor} built from user with given {@code id}
|
||||
* or status <b>404</b> when user with given {@code id} was not found.
|
||||
*
|
||||
* @param id
|
||||
* identifier to search user
|
||||
* @return entity of found user
|
||||
* @throws NotFoundException
|
||||
* when user with given identifier doesn't exist
|
||||
* @throws ServerException
|
||||
* when some error occurred while retrieving user
|
||||
* @see UserDescriptor
|
||||
* @see #getByAlias(String)
|
||||
*/
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
@GenerateLink(rel = LINK_REL_GET_USER_BY_ID)
|
||||
@Produces(APPLICATION_JSON)
|
||||
@ApiOperation(value = "Get user by ID",
|
||||
notes = "Get user by its ID in the system",
|
||||
response = UserDescriptor.class)
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK"),
|
||||
@ApiResponse(code = 404, message = "Not Found"),
|
||||
@ApiResponse(code = 500, message = "Internal Server Error")})
|
||||
public UserDescriptor getById(@ApiParam(value = "User ID") @PathParam("id") String id) throws NotFoundException,
|
||||
ServerException {
|
||||
@GenerateLink(rel = LINK_REL_USER)
|
||||
@ApiOperation("Get user by identifier")
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "The response contains requested user entity"),
|
||||
@ApiResponse(code = 404, message = "User with requested identifier not found"),
|
||||
@ApiResponse(code = 500, message = "Impossible to get user due to internal server error")})
|
||||
public UserDto getById(@ApiParam("User identifier")
|
||||
@PathParam("id")
|
||||
String id) throws NotFoundException, ServerException {
|
||||
final User user = userManager.getById(id);
|
||||
return injectLinks(toDescriptor(user), getServiceContext());
|
||||
return linksInjector.injectLinks(asDto(user), getServiceContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns status <b>200</b> and {@link UserDescriptor} built from user with given {@code alias}
|
||||
* or status <b>404</b> when user with given {@code alias} was not found.
|
||||
*
|
||||
* @param alias
|
||||
* alias to search user
|
||||
* @return entity of found user
|
||||
* @throws NotFoundException
|
||||
* when user with given alias doesn't exist
|
||||
* @throws ServerException
|
||||
* when some error occurred while retrieving user
|
||||
* @throws BadRequestException
|
||||
* when alias parameter is missing
|
||||
* @see UserDescriptor
|
||||
* @see #getById(String)
|
||||
* @see #remove(String)
|
||||
*/
|
||||
@GET
|
||||
@Path("/find")
|
||||
@GenerateLink(rel = LINK_REL_GET_USER_BY_EMAIL)
|
||||
@Produces(APPLICATION_JSON)
|
||||
@ApiOperation(value = "Get user by alias",
|
||||
notes = "Get user by alias",
|
||||
response = UserDescriptor.class)
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK"),
|
||||
@ApiResponse(code = 400, message = "Missed alias parameter"),
|
||||
@ApiResponse(code = 404, message = "Not Found"),
|
||||
@ApiResponse(code = 500, message = "Internal Server Error")})
|
||||
public UserDescriptor getByAlias(@ApiParam(value = "User alias", required = true)
|
||||
@QueryParam("alias")
|
||||
@Required String alias) throws NotFoundException,
|
||||
ServerException,
|
||||
BadRequestException {
|
||||
if (alias == null) {
|
||||
throw new BadRequestException("Missed parameter alias");
|
||||
@GenerateLink(rel = LINK_REL_USER)
|
||||
@ApiOperation("Get user by email or name")
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "The response contains requested user entity"),
|
||||
@ApiResponse(code = 404, message = "User with requested email/name not found"),
|
||||
@ApiResponse(code = 500, message = "Impossible to get user due to internal server error")})
|
||||
public UserDto find(@ApiParam("User email, if it is set then name shouldn't be")
|
||||
@QueryParam("email")
|
||||
String email,
|
||||
@ApiParam("User name, if is is set then email shouldn't be")
|
||||
@QueryParam("name")
|
||||
String name) throws NotFoundException,
|
||||
ServerException,
|
||||
BadRequestException {
|
||||
if (email == null && name == null) {
|
||||
throw new BadRequestException("Missed user's email or name");
|
||||
}
|
||||
final User user = userManager.getByAlias(alias);
|
||||
return injectLinks(toDescriptor(user), getServiceContext());
|
||||
if (email != null && name != null) {
|
||||
throw new BadRequestException("Expected either user's email or name, while both values received");
|
||||
}
|
||||
final User user = name == null ? userManager.getByEmail(email) : userManager.getByName(name);
|
||||
return linksInjector.injectLinks(asDto(user), getServiceContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes user with given identifier.
|
||||
*
|
||||
* @param id
|
||||
* identifier to remove user
|
||||
* @throws NotFoundException
|
||||
* when user with given identifier doesn't exist
|
||||
* @throws ServerException
|
||||
* when some error occurred while removing user
|
||||
* @throws ConflictException
|
||||
* when some error occurred while removing user
|
||||
*/
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
@GenerateLink(rel = LINK_REL_REMOVE_USER_BY_ID)
|
||||
@ApiOperation(value = "Delete user",
|
||||
notes = "Delete a user from the system")
|
||||
@ApiResponses({@ApiResponse(code = 204, message = "Deleted"),
|
||||
@ApiResponse(code = 404, message = "Not Found"),
|
||||
@ApiResponse(code = 409, message = "Impossible to remove user"),
|
||||
@ApiResponse(code = 500, message = "Internal Server Error")})
|
||||
public void remove(@ApiParam(value = "User ID") @PathParam("id") String id) throws NotFoundException,
|
||||
ServerException,
|
||||
ConflictException {
|
||||
@GenerateLink(rel = LINK_REL_USER)
|
||||
@ApiOperation("Delete user")
|
||||
@ApiResponses({@ApiResponse(code = 204, message = "User successfully removed"),
|
||||
@ApiResponse(code = 409, message = "Couldn't remove user due to conflict(e.g. it has related entities)"),
|
||||
@ApiResponse(code = 500, message = "Couldn't remove user due to internal server error")})
|
||||
public void remove(@ApiParam("User identifier")
|
||||
@PathParam("id")
|
||||
String id) throws ServerException, ConflictException {
|
||||
userManager.remove(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user by name.
|
||||
*
|
||||
* @param name
|
||||
* user name
|
||||
* @return found user
|
||||
* @throws NotFoundException
|
||||
* when user with given name doesn't exist
|
||||
* @throws ServerException
|
||||
* when some error occurred while retrieving user
|
||||
*/
|
||||
@GET
|
||||
@Path("/name/{name}")
|
||||
@GenerateLink(rel = "get user by name")
|
||||
@Produces(APPLICATION_JSON)
|
||||
@ApiOperation(value = "Get user by name",
|
||||
notes = "Get user by its name in the system")
|
||||
@ApiResponses({@ApiResponse(code = 200, message = "OK"),
|
||||
@ApiResponse(code = 404, message = "Not Found"),
|
||||
@ApiResponse(code = 500, message = "Internal Server Error")})
|
||||
public UserDescriptor getByName(@ApiParam(value = "User email")
|
||||
@PathParam("name")
|
||||
String name) throws NotFoundException, ServerException {
|
||||
final User user = userManager.getByName(name);
|
||||
return injectLinks(toDescriptor(user), getServiceContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get setting of user service
|
||||
*/
|
||||
@GET
|
||||
@Path("/settings")
|
||||
@Produces(APPLICATION_JSON)
|
||||
|
|
@ -348,64 +208,7 @@ public class UserService extends Service {
|
|||
return ImmutableMap.of(USER_SELF_CREATION_ALLOWED, Boolean.toString(userSelfCreationAllowed));
|
||||
}
|
||||
|
||||
private User fromEntity(UserDescriptor userDescriptor) throws BadRequestException {
|
||||
if (userDescriptor == null) {
|
||||
throw new BadRequestException("User Descriptor required");
|
||||
}
|
||||
if (isNullOrEmpty(userDescriptor.getName())) {
|
||||
throw new BadRequestException("User name required");
|
||||
}
|
||||
if (isNullOrEmpty(userDescriptor.getEmail())) {
|
||||
throw new BadRequestException("User email required");
|
||||
}
|
||||
final User user = new User().withName(userDescriptor.getName())
|
||||
.withEmail(userDescriptor.getEmail());
|
||||
if (userDescriptor.getPassword() != null) {
|
||||
checkPassword(userDescriptor.getPassword());
|
||||
user.setPassword(userDescriptor.getPassword());
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
private User fromToken(String token) throws UnauthorizedException, ConflictException {
|
||||
return tokenValidator.validateToken(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks user password conforms some rules:
|
||||
* <ul>
|
||||
* <li> Not null
|
||||
* <li> Must be at least 8 character length
|
||||
* <li> Must contain at least one letter and one digit
|
||||
* </ul>
|
||||
*
|
||||
* @param password
|
||||
* user's password
|
||||
* @throws BadRequestException
|
||||
* when password violates any rule
|
||||
*/
|
||||
private void checkPassword(String password) throws BadRequestException {
|
||||
if (password == null) {
|
||||
throw new BadRequestException("Password required");
|
||||
}
|
||||
if (password.length() < 8) {
|
||||
throw new BadRequestException("Password should contain at least 8 characters");
|
||||
}
|
||||
int numOfLetters = 0;
|
||||
int numOfDigits = 0;
|
||||
for (char passwordChar : password.toCharArray()) {
|
||||
if (Character.isDigit(passwordChar)) {
|
||||
numOfDigits++;
|
||||
} else if (Character.isLetter(passwordChar)) {
|
||||
numOfLetters++;
|
||||
}
|
||||
}
|
||||
if (numOfDigits == 0 || numOfLetters == 0) {
|
||||
throw new BadRequestException("Password should contain letters and digits");
|
||||
}
|
||||
}
|
||||
|
||||
private String currentUserId() {
|
||||
private static String userId() {
|
||||
return EnvironmentContext.getCurrent().getSubject().getUserId();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server;
|
||||
|
||||
import org.eclipse.che.api.core.BadRequestException;
|
||||
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.commons.lang.NameGenerator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
@ -19,13 +21,17 @@ import org.slf4j.LoggerFactory;
|
|||
import javax.inject.Inject;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
|
||||
// TODO extract normalization code from the validator as it is not related to the validation at all
|
||||
/**
|
||||
* Utils for username validation and normalization.
|
||||
*
|
||||
* @author Mihail Kuznyetsov
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class UserNameValidator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UserNameValidator.class);
|
||||
public class UserValidator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UserValidator.class);
|
||||
|
||||
private static final Pattern ILLEGAL_USERNAME_CHARACTERS = Pattern.compile("[^a-zA-Z0-9]");
|
||||
private static final Pattern VALID_USERNAME = Pattern.compile("^[a-zA-Z0-9]*");
|
||||
|
|
@ -33,19 +39,74 @@ public class UserNameValidator {
|
|||
private final UserManager userManager;
|
||||
|
||||
@Inject
|
||||
public UserNameValidator (UserManager userManager) {
|
||||
public UserValidator(UserManager userManager) {
|
||||
this.userManager = userManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether given user is valid.
|
||||
*
|
||||
* @param user
|
||||
* user to check
|
||||
* @throws BadRequestException
|
||||
* when user is not valid
|
||||
*/
|
||||
public void checkUser(User user) throws BadRequestException {
|
||||
if (user == null) {
|
||||
throw new BadRequestException("User required");
|
||||
}
|
||||
if (isNullOrEmpty(user.getName())) {
|
||||
throw new BadRequestException("User name required");
|
||||
}
|
||||
if (!isValidName(user.getName())) {
|
||||
throw new BadRequestException("Username must contain only letters and digits");
|
||||
}
|
||||
if (isNullOrEmpty(user.getEmail())) {
|
||||
throw new BadRequestException("User email required");
|
||||
}
|
||||
if (user.getPassword() != null) {
|
||||
checkPassword(user.getPassword());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether password is ok.
|
||||
*
|
||||
* @param password
|
||||
* password to check
|
||||
* @throws BadRequestException
|
||||
* when password is not valid
|
||||
*/
|
||||
public void checkPassword(String password) throws BadRequestException {
|
||||
if (password == null) {
|
||||
throw new BadRequestException("Password required");
|
||||
}
|
||||
if (password.length() < 8) {
|
||||
throw new BadRequestException("Password should contain at least 8 characters");
|
||||
}
|
||||
int numOfLetters = 0;
|
||||
int numOfDigits = 0;
|
||||
for (char passwordChar : password.toCharArray()) {
|
||||
if (Character.isDigit(passwordChar)) {
|
||||
numOfDigits++;
|
||||
} else if (Character.isLetter(passwordChar)) {
|
||||
numOfLetters++;
|
||||
}
|
||||
}
|
||||
if (numOfDigits == 0 || numOfLetters == 0) {
|
||||
throw new BadRequestException("Password should contain letters and digits");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate name, if it doesn't contain illegal characters
|
||||
*
|
||||
* @param name
|
||||
* username
|
||||
* username
|
||||
* @return true if valid name, false otherwise
|
||||
*/
|
||||
public boolean isValidUserName(String name) {
|
||||
return VALID_USERNAME.matcher(name).matches();
|
||||
public boolean isValidName(String name) {
|
||||
return name != null && VALID_USERNAME.matcher(name).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -54,7 +115,7 @@ public class UserNameValidator {
|
|||
* Also ensures username is unique, if not, adds digits to it's end.
|
||||
*
|
||||
* @param name
|
||||
* username
|
||||
* username
|
||||
* @return username without illegal characters
|
||||
*/
|
||||
public String normalizeUserName(String name) throws ServerException {
|
||||
|
|
@ -67,7 +128,7 @@ public class UserNameValidator {
|
|||
candidate = normalized.isEmpty() ? NameGenerator.generate("username", 4) : normalized + String.valueOf(i++);
|
||||
}
|
||||
} catch (ServerException e) {
|
||||
LOG.warn("Error occured during username normalization", e);
|
||||
LOG.warn("Error occurred during username normalization", e);
|
||||
throw e;
|
||||
}
|
||||
return candidate;
|
||||
|
|
@ -78,8 +139,6 @@ public class UserNameValidator {
|
|||
userManager.getByName(username);
|
||||
} catch (NotFoundException e) {
|
||||
return false;
|
||||
} catch (ServerException e) {
|
||||
throw e;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server.dao;
|
||||
|
||||
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.UnauthorizedException;
|
||||
|
||||
/**
|
||||
* DAO interface offers means to perform CRUD operations with {@link User} data. The implementation is not
|
||||
* required to be responsible for persistent layer data dto integrity. It simply transfers data from one layer to another, so if
|
||||
* you're going to call any of implemented methods it is considered that all needed verifications are already done. <p>
|
||||
* <strong>Note:</strong> This particularly does not mean that method call will not make any inconsistency, but this
|
||||
* mean that such kind of inconsistencies are expected by design and may be treated further. </p>
|
||||
*/
|
||||
public interface UserDao {
|
||||
|
||||
/**
|
||||
* Authenticate user.
|
||||
*
|
||||
* @param alias
|
||||
* user name or alias
|
||||
* @param password
|
||||
* password
|
||||
* @return user id when authentication success
|
||||
* @throws UnauthorizedException
|
||||
* when authentication failed or no such user exists
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*
|
||||
*/
|
||||
String authenticate(String alias, String password) throws UnauthorizedException, ServerException;
|
||||
|
||||
/**
|
||||
* Adds user to persistent layer.
|
||||
*
|
||||
* @param user
|
||||
* - POJO representation of user entity
|
||||
* @throws ConflictException
|
||||
* when given user cannot be created
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
void create(User user) throws ConflictException, ServerException;
|
||||
|
||||
/**
|
||||
* Updates already present in persistent layer user.
|
||||
*
|
||||
* @param user
|
||||
* POJO representation of user entity
|
||||
* @throws NotFoundException
|
||||
* when user is not found
|
||||
* @throws ConflictException
|
||||
* when given user cannot be updated
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*
|
||||
*/
|
||||
void update(User user) throws NotFoundException, ServerException, ConflictException;
|
||||
|
||||
/**
|
||||
* Removes user from persistent layer by his identifier.
|
||||
*
|
||||
* @param id
|
||||
* user identifier
|
||||
* @throws ConflictException
|
||||
* when given user cannot be deleted
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
void remove(String id) throws NotFoundException, ServerException, ConflictException;
|
||||
|
||||
/**
|
||||
* Gets user from persistent layer by any of his aliases
|
||||
*
|
||||
* @param alias
|
||||
* user name or alias
|
||||
* @return user POJO
|
||||
* @throws NotFoundException
|
||||
* when user doesn't exist
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
User getByAlias(String alias) throws NotFoundException, ServerException;
|
||||
|
||||
/**
|
||||
* Gets user from persistent layer by his identifier
|
||||
*
|
||||
* @param id
|
||||
* user identifier
|
||||
* @return user POJO
|
||||
* @throws NotFoundException
|
||||
* when user doesn't exist
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
User getById(String id) throws NotFoundException, ServerException;
|
||||
|
||||
/**
|
||||
* Gets user from persistent layer by his username
|
||||
*
|
||||
* @param userName
|
||||
* user name
|
||||
* @return user POJO
|
||||
* @throws NotFoundException
|
||||
* when user doesn't exist
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
User getByName(String userName) throws NotFoundException, ServerException;
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server.dao;
|
||||
|
||||
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
|
||||
/**
|
||||
* DAO interface offers means to perform CRUD operations with {@link Profile} data.
|
||||
*
|
||||
* @author Eugene Voevodin
|
||||
* @author Max Shaposhnik
|
||||
*/
|
||||
public interface UserProfileDao {
|
||||
|
||||
/**
|
||||
* Adds profile to persistent layer.
|
||||
*
|
||||
* @param profile
|
||||
* profile to setPreferences
|
||||
*/
|
||||
void create(Profile profile) throws ConflictException, ServerException;
|
||||
|
||||
/**
|
||||
* Updates already present in persistent layer profile.
|
||||
*
|
||||
* @param profile
|
||||
* profile to update
|
||||
*/
|
||||
void update(Profile profile) throws NotFoundException, ServerException;
|
||||
|
||||
/**
|
||||
* Removes profile from persistent layer.
|
||||
*
|
||||
* @param id
|
||||
* profile identifier
|
||||
*/
|
||||
void remove(String id) throws NotFoundException, ServerException;
|
||||
|
||||
/**
|
||||
* Gets profile from persistent layer.
|
||||
*
|
||||
* @param id
|
||||
* profile identifier
|
||||
* @return profile with given {@code id}
|
||||
* @throws org.eclipse.che.api.core.NotFoundException
|
||||
* when profile doesn't exist
|
||||
*/
|
||||
Profile getById(String id) throws NotFoundException, ServerException;
|
||||
}
|
||||
|
|
@ -8,57 +8,48 @@
|
|||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server.dao;
|
||||
package org.eclipse.che.api.user.server.model.impl;
|
||||
|
||||
import org.eclipse.che.api.core.model.user.Profile;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Eugene Voevodin
|
||||
* Data object for the {@link Profile}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class Profile {
|
||||
public class ProfileImpl implements Profile {
|
||||
|
||||
private String id;
|
||||
private String userId;
|
||||
private Map<String, String> attributes;
|
||||
|
||||
public Profile() {}
|
||||
|
||||
public Profile(String id) {
|
||||
public ProfileImpl(String id) {
|
||||
this.id = id;
|
||||
this.userId = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
public ProfileImpl(String id, Map<String, String> attributes) {
|
||||
this.id = id;
|
||||
if (attributes != null) {
|
||||
this.attributes = new HashMap<>(attributes);
|
||||
}
|
||||
}
|
||||
|
||||
public ProfileImpl(Profile profile) {
|
||||
this(profile.getUserId(), profile.getAttributes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Profile withId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Profile withUserId(String userId) {
|
||||
this.userId = userId;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAttributes() {
|
||||
if (attributes == null) {
|
||||
attributes = new HashMap<>();
|
||||
this.attributes = new HashMap<>();
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
|
@ -67,31 +58,31 @@ public class Profile {
|
|||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public Profile withAttributes(Map<String, String> attributes) {
|
||||
this.attributes = attributes;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof Profile)) {
|
||||
if (!(obj instanceof ProfileImpl)) {
|
||||
return false;
|
||||
}
|
||||
final Profile other = (Profile)obj;
|
||||
return Objects.equals(id, other.id) &&
|
||||
Objects.equals(userId, other.userId) &&
|
||||
Objects.equals(getAttributes(), other.getAttributes());
|
||||
final ProfileImpl that = (ProfileImpl)obj;
|
||||
return Objects.equals(id, that.id) && getAttributes().equals(that.getAttributes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 31 * hash + Objects.hashCode(id);
|
||||
hash = 31 * hash + Objects.hashCode(userId);
|
||||
hash = 31 * hash + Objects.hashCode(attributes);
|
||||
hash = 31 * hash + getAttributes().hashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ProfileImpl{" +
|
||||
"id='" + id + '\'' +
|
||||
", attributes=" + attributes +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
@ -8,16 +8,21 @@
|
|||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server.dao;
|
||||
package org.eclipse.che.api.user.server.model.impl;
|
||||
|
||||
import org.eclipse.che.api.core.model.user.User;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Eugene Voevodin
|
||||
* Data object for the {@link User}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class User {
|
||||
public class UserImpl implements User {
|
||||
|
||||
private String id;
|
||||
private String email;
|
||||
|
|
@ -25,19 +30,69 @@ public class User {
|
|||
private String password;
|
||||
private List<String> aliases;
|
||||
|
||||
public UserImpl(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public UserImpl(String id, String email, String name) {
|
||||
this.id = id;
|
||||
this.email = email;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public UserImpl(String id,
|
||||
String email,
|
||||
String name,
|
||||
String password,
|
||||
Collection<String> aliases) {
|
||||
this(id, email, name);
|
||||
this.password = password;
|
||||
if (aliases != null) {
|
||||
this.aliases = new ArrayList<>(aliases);
|
||||
}
|
||||
}
|
||||
|
||||
public UserImpl(User user) {
|
||||
this(user.getId(),
|
||||
user.getEmail(),
|
||||
user.getName(),
|
||||
user.getPassword(),
|
||||
user.getAliases());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
@Override
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public User withId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAliases() {
|
||||
if (aliases == null) {
|
||||
aliases = new ArrayList<>();
|
||||
|
|
@ -49,64 +104,20 @@ public class User {
|
|||
this.aliases = aliases;
|
||||
}
|
||||
|
||||
public User withAliases(List<String> aliases) {
|
||||
this.aliases = aliases;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public User withEmail(String email) {
|
||||
this.email = email;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public User withPassword(String password) {
|
||||
this.password = password;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public User withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof User)) {
|
||||
if (!(obj instanceof UserImpl)) {
|
||||
return false;
|
||||
}
|
||||
final User other = (User)obj;
|
||||
return Objects.equals(id, other.id) &&
|
||||
Objects.equals(email, other.email) &&
|
||||
Objects.equals(password, other.password) &&
|
||||
Objects.equals(name, other.name) &&
|
||||
getAliases().equals(other.getAliases());
|
||||
final UserImpl that = (UserImpl)obj;
|
||||
return Objects.equals(id, that.id)
|
||||
&& Objects.equals(email, that.email)
|
||||
&& Objects.equals(name, that.name)
|
||||
&& Objects.equals(password, that.password)
|
||||
&& getAliases().equals(that.getAliases());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -114,9 +125,20 @@ public class User {
|
|||
int hash = 7;
|
||||
hash = 31 * hash + Objects.hashCode(id);
|
||||
hash = 31 * hash + Objects.hashCode(email);
|
||||
hash = 31 * hash + Objects.hashCode(password);
|
||||
hash = 31 * hash + Objects.hashCode(name);
|
||||
hash = 31 * hash + Objects.hashCode(password);
|
||||
hash = 31 * hash + getAliases().hashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UserImpl{" +
|
||||
"id='" + id + '\'' +
|
||||
", email='" + email + '\'' +
|
||||
", name='" + name + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", aliases=" + aliases +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
@ -8,9 +8,8 @@
|
|||
* Contributors:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server.dao;
|
||||
package org.eclipse.che.api.user.server.spi;
|
||||
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
|
||||
import java.util.Map;
|
||||
|
|
@ -31,12 +30,10 @@ public interface PreferenceDao {
|
|||
* new preferences, if preferences are empty - removes user preferences
|
||||
* @throws NullPointerException
|
||||
* when preferences or userId is null
|
||||
* @throws NotFoundException
|
||||
* when user with given identifier doesn't exist
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
void setPreferences(String userId, Map<String, String> preferences) throws ServerException, NotFoundException;
|
||||
void setPreferences(String userId, Map<String, String> preferences) throws ServerException;
|
||||
|
||||
/**
|
||||
* Gets user preferences.
|
||||
|
|
@ -45,7 +42,7 @@ public interface PreferenceDao {
|
|||
* <pre>{@code
|
||||
* Map<String, String> prefs = dao.getPreferences("user123");
|
||||
* prefs.put("key", "secret");
|
||||
* dao.setPreferences("user123", prefs);
|
||||
* spi.setPreferences("user123", prefs);
|
||||
* }</pre>
|
||||
*
|
||||
* @param userId
|
||||
|
|
@ -63,7 +60,7 @@ public interface PreferenceDao {
|
|||
*
|
||||
* <p>Note that this method must always return upgradable map, thus it may be used as:
|
||||
* <pre>{@code
|
||||
* Map<String, String> prefs = dao.getPreferences("user123", ".*key.*");
|
||||
* Map<String, String> prefs = spi.getPreferences("user123", ".*key.*");
|
||||
* prefs.put("new-key", "secret");
|
||||
* prefs.setPreferences("user123", prefs);
|
||||
* }</pre>
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server.spi;
|
||||
|
||||
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.Profile;
|
||||
import org.eclipse.che.api.core.model.user.User;
|
||||
import org.eclipse.che.api.user.server.model.impl.ProfileImpl;
|
||||
|
||||
/**
|
||||
* Data access object contract for {@link Profile}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public interface ProfileDao {
|
||||
|
||||
/**
|
||||
* Creates user profile.
|
||||
*
|
||||
* @param profile
|
||||
* new profile
|
||||
* @throws NullPointerException
|
||||
* when {@code profile} is null
|
||||
* @throws ServerException
|
||||
* when any error occurs
|
||||
* @throws ConflictException
|
||||
* when profile for user {@code profile.getUserId()} already exists
|
||||
*/
|
||||
void create(ProfileImpl profile) throws ServerException, ConflictException;
|
||||
|
||||
/**
|
||||
* Updates profile by replacing an existing entity with a new one.
|
||||
*
|
||||
* @param profile
|
||||
* profile update
|
||||
* @throws NullPointerException
|
||||
* when {@code profile} is null
|
||||
* @throws NotFoundException
|
||||
* when profile with such id doesn't exist
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
void update(ProfileImpl profile) throws NotFoundException, ServerException;
|
||||
|
||||
/**
|
||||
* Removes profile.
|
||||
*
|
||||
* @param id
|
||||
* profile identifier
|
||||
* @throws NullPointerException
|
||||
* when {@code id} is null
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
void remove(String id) throws ServerException;
|
||||
|
||||
/**
|
||||
* Finds profile by its id.
|
||||
*
|
||||
* <p>Due to {@link Profile#getEmail()} and {@link Profile#getUserId()} definition
|
||||
* returned profile must contain profile owner's {@link User#getEmail() email}
|
||||
* and {@link User#getId()} identifier.
|
||||
*
|
||||
* @param id
|
||||
* profile identifier
|
||||
* @return profile with given {@code id}
|
||||
* @throws NullPointerException
|
||||
* when {@code id} is null
|
||||
* @throws NotFoundException
|
||||
* when profile with such {@code id} doesn't exist
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
ProfileImpl getById(String id) throws NotFoundException, ServerException;
|
||||
}
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server.spi;
|
||||
|
||||
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.UnauthorizedException;
|
||||
import org.eclipse.che.api.user.server.model.impl.UserImpl;
|
||||
|
||||
/**
|
||||
* Defines data access object contract for {@link UserImpl}.
|
||||
*
|
||||
* <p>The implementation is not required to be responsible for persistent layer
|
||||
* data dto integrity. It simply transfers data from one layer to another,
|
||||
* so if you're going to call any of implemented methods it is considered
|
||||
* that all needed verifications are already done.
|
||||
*
|
||||
* <p><strong>Note:</strong> This particularly does not mean that
|
||||
* method call will not make any inconsistency, but this mean that
|
||||
* such kind of inconsistencies are expected by design and may be treated further.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public interface UserDao {
|
||||
|
||||
/**
|
||||
* // TODO remove this method from spi
|
||||
* Authenticates user.
|
||||
*
|
||||
* @param emailOrAliasOrName
|
||||
* one of the user identifiers such as email/name/alias
|
||||
* @param password
|
||||
* password
|
||||
* @return user identifier
|
||||
* @throws NullPointerException
|
||||
* when either {@code emailOrAliasOrName} or {@code password} is null
|
||||
* @throws UnauthorizedException
|
||||
* when user with such {@code aliasOrName} and {@code password} doesn't exist
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
String authenticate(String emailOrAliasOrName, String password) throws UnauthorizedException, ServerException;
|
||||
|
||||
/**
|
||||
* Creates a new user.
|
||||
*
|
||||
* @param user
|
||||
* user to create
|
||||
* @throws NullPointerException
|
||||
* when {@code user} is null
|
||||
* @throws ConflictException
|
||||
* when user with such id/alias/email/name already exists
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
void create(UserImpl user) throws ConflictException, ServerException;
|
||||
|
||||
/**
|
||||
* Updates user by replacing an existing entity with a new one.
|
||||
*
|
||||
* @param user
|
||||
* user to update
|
||||
* @throws NullPointerException
|
||||
* when {@code user} is null
|
||||
* @throws NotFoundException
|
||||
* when user with id {@code user.getId()} doesn't exist
|
||||
* @throws ConflictException
|
||||
* when any of the id/alias/email/name updated with a value
|
||||
* which is not unique
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
void update(UserImpl user) throws NotFoundException, ServerException, ConflictException;
|
||||
|
||||
/**
|
||||
* Removes user.
|
||||
*
|
||||
* <p>It is up to implementation to do cascade removing of dependent data or
|
||||
* to forbid removing at all.
|
||||
*
|
||||
* <p>Note that this method doesn't throw any exception when
|
||||
* user doesn't exist.
|
||||
*
|
||||
* @param id
|
||||
* user identifier
|
||||
* @throws NullPointerException
|
||||
* when {@code id} is null
|
||||
* @throws ConflictException
|
||||
* when given user cannot be deleted
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
void remove(String id) throws ServerException, ConflictException;
|
||||
|
||||
/**
|
||||
* Finds user by his alias.
|
||||
*
|
||||
* <p>This method doesn't work for user's email or name.
|
||||
* If it is necessary to get user by name use {@link #getByName(String)} method instead.
|
||||
*
|
||||
* @param alias
|
||||
* user name or alias
|
||||
* @return user instance, never null
|
||||
* @throws NullPointerException
|
||||
* when {@code alias} is null
|
||||
* @throws NotFoundException
|
||||
* when user with given {@code alias} doesn't exist
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
UserImpl getByAlias(String alias) throws NotFoundException, ServerException;
|
||||
|
||||
/**
|
||||
* Finds user by his identifier.
|
||||
*
|
||||
* @param id
|
||||
* user identifier
|
||||
* @return user instance, never null
|
||||
* @throws NullPointerException
|
||||
* when {@code id} is null
|
||||
* @throws NotFoundException
|
||||
* when user with given {@code id} doesn't exist
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
UserImpl getById(String id) throws NotFoundException, ServerException;
|
||||
|
||||
/**
|
||||
* Finds user by his name.
|
||||
*
|
||||
* @param name
|
||||
* user name
|
||||
* @return user instance, never null
|
||||
* @throws NullPointerException
|
||||
* when {@code name} is null
|
||||
* @throws NotFoundException
|
||||
* when user with such {@code name} doesn't exist
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
UserImpl getByName(String name) throws NotFoundException, ServerException;
|
||||
|
||||
/**
|
||||
* Finds user by his email.
|
||||
*
|
||||
* @param email
|
||||
* user email
|
||||
* @return user instance, never null
|
||||
* @throws NullPointerException
|
||||
* when {@code email} is null
|
||||
* @throws NotFoundException
|
||||
* when user with such {@code email} doesn't exist
|
||||
* @throws ServerException
|
||||
* when any other error occurs
|
||||
*/
|
||||
UserImpl getByEmail(String email) throws NotFoundException, ServerException;
|
||||
}
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import org.eclipse.che.api.user.server.spi.PreferenceDao;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Tests for {@link PreferenceManager}.
|
||||
*
|
||||
* @author Yevhenii Voevodin.
|
||||
*/
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class PreferenceManagerTest {
|
||||
|
||||
@Mock
|
||||
private PreferenceDao preferenceDao;
|
||||
|
||||
@InjectMocks
|
||||
private PreferenceManager preferenceManager;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<Map<String, String>> preferencesCaptor;
|
||||
|
||||
@Test
|
||||
public void shouldUseMergeStrategyForPreferencesUpdate() throws Exception {
|
||||
// Preparing preferences
|
||||
final Map<String, String> existingPreferences = new HashMap<>();
|
||||
existingPreferences.put("pKey1", "pValue1");
|
||||
existingPreferences.put("pKey2", "pValue2");
|
||||
existingPreferences.put("pKey3", "pValue3");
|
||||
existingPreferences.put("pKey4", "pValue4");
|
||||
when(preferenceDao.getPreferences(any())).thenReturn(existingPreferences);
|
||||
|
||||
// Updating preferences
|
||||
final Map<String, String> newPreferences = new HashMap<>();
|
||||
newPreferences.put("pKey5", "pValue5");
|
||||
newPreferences.put("pKey1", "new-value");
|
||||
preferenceManager.update("user123", newPreferences);
|
||||
|
||||
// Checking
|
||||
verify(preferenceDao).setPreferences(anyString(), preferencesCaptor.capture());
|
||||
assertEquals(preferencesCaptor.getValue(), ImmutableMap.of("pKey1", "new-value",
|
||||
"pKey2", "pValue2",
|
||||
"pKey3", "pValue3",
|
||||
"pKey4", "pValue4",
|
||||
"pKey5", "pValue5"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveSpecifiedPreferences() throws Exception {
|
||||
// Preparing preferences
|
||||
final Map<String, String> existingPreferences = new HashMap<>();
|
||||
existingPreferences.put("pKey1", "pValue1");
|
||||
existingPreferences.put("pKey2", "pValue2");
|
||||
existingPreferences.put("pKey3", "pValue3");
|
||||
existingPreferences.put("pKey4", "pValue4");
|
||||
when(preferenceDao.getPreferences(any())).thenReturn(existingPreferences);
|
||||
|
||||
// Removing
|
||||
preferenceManager.remove("user123", asList("pKey1", "pKey5", "odd-pref-name"));
|
||||
|
||||
// Checking
|
||||
verify(preferenceDao).setPreferences(anyString(), preferencesCaptor.capture());
|
||||
assertEquals(preferencesCaptor.getValue(), ImmutableMap.of("pKey2", "pValue2",
|
||||
"pKey3", "pValue3",
|
||||
"pKey4", "pValue4"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetPreferencesByUser() throws Exception {
|
||||
final Map<String, String> preferences = ImmutableMap.of("name", "value");
|
||||
when(preferenceDao.getPreferences("user123")).thenReturn(preferences);
|
||||
|
||||
assertEquals(preferenceManager.find("user123"), preferences);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetPreferencesByUserAndFilter() throws Exception {
|
||||
final Map<String, String> preferences = ImmutableMap.of("name", "value");
|
||||
when(preferenceDao.getPreferences("user123", "name.*")).thenReturn(preferences);
|
||||
|
||||
assertEquals(preferenceManager.find("user123", "name.*"), preferences);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void getPreferencesShouldThrowNpeWhenUserIdIsNull() throws Exception {
|
||||
preferenceManager.find(null);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void getPreferencesByUserAndFilterShouldThrowNpeWhenUserIdIsNull() throws Exception {
|
||||
preferenceManager.find(null, "name.*");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenRemovingPreferencesAndUserIdIsNull() throws Exception {
|
||||
preferenceManager.remove(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveUserPreferences() throws Exception {
|
||||
preferenceManager.remove("user123");
|
||||
|
||||
verify(preferenceDao).remove("user123");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenSavePreferencesWithNullUser() throws Exception {
|
||||
preferenceManager.save(null, Collections.emptyMap());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenSavePreferencesWithNullPreferences() throws Exception {
|
||||
preferenceManager.save("user123", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSavePreferences() throws Exception {
|
||||
preferenceManager.save("user123", Collections.emptyMap());
|
||||
|
||||
verify(preferenceDao).setPreferences("user123", Collections.emptyMap());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.jayway.restassured.response.Response;
|
||||
|
||||
import org.eclipse.che.api.core.rest.ApiExceptionMapper;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
import org.everrest.assured.EverrestJetty;
|
||||
import org.everrest.core.Filter;
|
||||
import org.everrest.core.GenericContainerRequest;
|
||||
import org.everrest.core.RequestFilter;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static com.jayway.restassured.RestAssured.given;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.everrest.assured.JettyHttpServer.ADMIN_USER_NAME;
|
||||
import static org.everrest.assured.JettyHttpServer.ADMIN_USER_PASSWORD;
|
||||
import static org.everrest.assured.JettyHttpServer.SECURE_PATH;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Tests for {@link PreferencesService}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Listeners({EverrestJetty.class, MockitoTestNGListener.class})
|
||||
public class PreferencesServiceTest {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final ApiExceptionMapper MAPPER = new ApiExceptionMapper();
|
||||
@SuppressWarnings("unused")
|
||||
private static final EnvironmentFilter FILTER = new EnvironmentFilter();
|
||||
private static final Subject SUBJECT = new SubjectImpl("user", "user123", "token", false);
|
||||
|
||||
@Mock(answer = Answers.RETURNS_MOCKS)
|
||||
private PreferenceManager preferenceManager;
|
||||
|
||||
@InjectMocks
|
||||
private PreferencesService preferencesService;
|
||||
|
||||
@Test
|
||||
public void shouldFindPreferences() throws Exception {
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/preferences");
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
verify(preferenceManager).find(SUBJECT.getUserId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindPreferencesAndFilter() throws Exception {
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/preferences?filter=.*github.*");
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
verify(preferenceManager).find(SUBJECT.getUserId(), ".*github.*");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSavePreferences() throws Exception {
|
||||
final Map<String, String> preferences = ImmutableMap.of("pref1", "value1",
|
||||
"pref2", "value2",
|
||||
"pref3", "value3");
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.body(preferences)
|
||||
.when()
|
||||
.post(SECURE_PATH + "/preferences");
|
||||
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verify(preferenceManager).save(SUBJECT.getUserId(), preferences);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotSavePreferencesWhenNothingSent() throws Exception {
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.when()
|
||||
.post(SECURE_PATH + "/preferences");
|
||||
|
||||
assertEquals(response.getStatusCode(), 400);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdatePreferences() throws Exception {
|
||||
final Map<String, String> preferences = ImmutableMap.of("pref1", "value1",
|
||||
"pref2", "value2",
|
||||
"pref3", "value3");
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.body(preferences)
|
||||
.when()
|
||||
.put(SECURE_PATH + "/preferences");
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
verify(preferenceManager).update(SUBJECT.getUserId(), preferences);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotUpdatePreferencesWhenNothingSent() throws Exception {
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.when()
|
||||
.put(SECURE_PATH + "/preferences");
|
||||
|
||||
assertEquals(response.getStatusCode(), 400);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveSpecifiedPreferences() throws Exception {
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.body(asList("pref1", "pref2"))
|
||||
.when()
|
||||
.delete(SECURE_PATH + "/preferences");
|
||||
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verify(preferenceManager).remove(SUBJECT.getUserId(), asList("pref1", "pref2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveAllPreferencesIfNothingSent() throws Exception {
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.contentType("application/json")
|
||||
.when()
|
||||
.delete(SECURE_PATH + "/preferences");
|
||||
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verify(preferenceManager).remove(SUBJECT.getUserId());
|
||||
}
|
||||
|
||||
@Filter
|
||||
public static class EnvironmentFilter implements RequestFilter {
|
||||
public void doFilter(GenericContainerRequest request) {
|
||||
EnvironmentContext.getCurrent().setSubject(SUBJECT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import org.eclipse.che.api.core.rest.ServiceContext;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDto;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.everrest.core.impl.uri.UriBuilderImpl;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Tests for {@link ProfileLinksInjector}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class ProfileLinksInjectorTest {
|
||||
|
||||
@Mock
|
||||
private ServiceContext serviceContext;
|
||||
|
||||
@InjectMocks
|
||||
private ProfileLinksInjector linksInjector;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUpContext() {
|
||||
final UriBuilderImpl uriBuilder = new UriBuilderImpl();
|
||||
uriBuilder.uri("http://localhost:8080");
|
||||
when(serviceContext.getServiceUriBuilder()).thenReturn(uriBuilder);
|
||||
when(serviceContext.getBaseUriBuilder()).thenReturn(uriBuilder);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldInjectProfileLinks() throws Exception {
|
||||
final ProfileDto profileDto = DtoFactory.newDto(ProfileDto.class)
|
||||
.withUserId("user123")
|
||||
.withEmail("user@codenvy.com");
|
||||
|
||||
linksInjector.injectLinks(profileDto, serviceContext);
|
||||
|
||||
// [rel, method] pairs links
|
||||
final Set<Pair<String, String>> links = profileDto.getLinks()
|
||||
.stream()
|
||||
.map(link -> Pair.of(link.getMethod(), link.getRel()))
|
||||
.collect(Collectors.toSet());
|
||||
final Set<Pair<String, String>> expectedLinks
|
||||
= new HashSet<>(asList(Pair.of("GET", Constants.LINK_REL_SELF),
|
||||
Pair.of("GET", Constants.LINK_REL_CURRENT_PROFILE),
|
||||
Pair.of("PUT", Constants.LINK_REL_PROFILE_ATTRIBUTES),
|
||||
Pair.of("PUT", Constants.LINK_REL_CURRENT_PROFILE_ATTRIBUTES),
|
||||
Pair.of("DELETE", Constants.LINK_REL_CURRENT_PROFILE_ATTRIBUTES)));
|
||||
|
||||
assertEquals(links, expectedLinks, "Difference " + Sets.symmetricDifference(links, expectedLinks) + "\n");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server;
|
||||
|
||||
import org.eclipse.che.api.user.server.model.impl.ProfileImpl;
|
||||
import org.eclipse.che.api.user.server.spi.ProfileDao;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Tests for {@link ProfileManager}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class ProfileManagerTest {
|
||||
|
||||
@Mock
|
||||
private ProfileDao profileDao;
|
||||
|
||||
@InjectMocks
|
||||
private ProfileManager profileManager;
|
||||
|
||||
@Test
|
||||
public void shouldGetProfileById() throws Exception {
|
||||
final ProfileImpl profile = new ProfileImpl("user123");
|
||||
when(profileDao.getById(profile.getUserId())).thenReturn(profile);
|
||||
|
||||
assertEquals(profile, profileManager.getById(profile.getUserId()));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenGettingProfileByNullId() throws Exception {
|
||||
profileManager.getById(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateProfile() throws Exception {
|
||||
final ProfileImpl profile = new ProfileImpl("user123");
|
||||
|
||||
profileManager.create(profile);
|
||||
|
||||
final ArgumentCaptor<ProfileImpl> captor = ArgumentCaptor.forClass(ProfileImpl.class);
|
||||
verify(profileDao).create(captor.capture());
|
||||
assertEquals(captor.getValue(), profile);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenCreatingNullProfile() throws Exception {
|
||||
profileManager.create(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdateProfile() throws Exception {
|
||||
final ProfileImpl profile = new ProfileImpl("user123");
|
||||
|
||||
profileManager.update(profile);
|
||||
|
||||
final ArgumentCaptor<ProfileImpl> captor = ArgumentCaptor.forClass(ProfileImpl.class);
|
||||
verify(profileDao).update(captor.capture());
|
||||
assertEquals(captor.getValue(), profile);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenUpdatingNull() throws Exception {
|
||||
profileManager.update(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveProfile() throws Exception {
|
||||
profileManager.remove("user123");
|
||||
|
||||
verify(profileDao).remove("user123");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void shouldThrowNpeWhenRemovingNull() throws Exception {
|
||||
profileManager.remove(null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.jayway.restassured.response.Response;
|
||||
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.model.user.Profile;
|
||||
import org.eclipse.che.api.core.rest.ApiExceptionMapper;
|
||||
import org.eclipse.che.api.user.server.model.impl.ProfileImpl;
|
||||
import org.eclipse.che.api.user.shared.dto.ProfileDto;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.commons.subject.Subject;
|
||||
import org.eclipse.che.commons.subject.SubjectImpl;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.everrest.assured.EverrestJetty;
|
||||
import org.everrest.core.Filter;
|
||||
import org.everrest.core.GenericContainerRequest;
|
||||
import org.everrest.core.RequestFilter;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static com.jayway.restassured.RestAssured.given;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.everrest.assured.JettyHttpServer.ADMIN_USER_NAME;
|
||||
import static org.everrest.assured.JettyHttpServer.ADMIN_USER_PASSWORD;
|
||||
import static org.everrest.assured.JettyHttpServer.SECURE_PATH;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests for {@link ProfileService}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Listeners({EverrestJetty.class, MockitoTestNGListener.class})
|
||||
public class ProfileServiceTest {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final ApiExceptionMapper MAPPER = new ApiExceptionMapper();
|
||||
@SuppressWarnings("unused")
|
||||
private static final EnvironmentFilter FILTER = new EnvironmentFilter();
|
||||
private static final Subject SUBJECT = new SubjectImpl("user", "user123", "token", false);
|
||||
|
||||
@Mock(answer = Answers.RETURNS_MOCKS)
|
||||
private ProfileManager profileManager;
|
||||
|
||||
@Mock
|
||||
private ProfileLinksInjector linksInjector;
|
||||
|
||||
@Mock(answer = Answers.RETURNS_MOCKS)
|
||||
private UserManager userManager;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<Profile> profileCaptor;
|
||||
|
||||
@InjectMocks
|
||||
private ProfileService profileService;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws NotFoundException, ServerException {
|
||||
when(linksInjector.injectLinks(any(), any())).thenAnswer(inv -> inv.getArguments()[0]);
|
||||
|
||||
when(profileManager.getById(SUBJECT.getUserId())).thenReturn(new ProfileImpl(SUBJECT.getUserId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetCurrentProfile() throws Exception {
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/profile");
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
final ProfileDto profileDto = unwrapDto(response, ProfileDto.class);
|
||||
assertEquals(profileDto.getUserId(), SUBJECT.getUserId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetProfileById() throws Exception {
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/profile/" + SUBJECT.getUserId());
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
final ProfileDto profileDto = unwrapDto(response, ProfileDto.class);
|
||||
assertEquals(profileDto.getUserId(), SUBJECT.getUserId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToUpdateCurrentProfileAttributes() throws Exception {
|
||||
final ImmutableMap<String, String> attributes = ImmutableMap.of("attr1", "value1",
|
||||
"attr2", "value2",
|
||||
"attr3", "value3");
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.contentType("application/json")
|
||||
.body(attributes)
|
||||
.put(SECURE_PATH + "/profile/attributes");
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
verify(profileManager).update(profileCaptor.capture());
|
||||
final Profile profile = profileCaptor.getValue();
|
||||
assertEquals(profile.getAttributes(), attributes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotUpdateCurrentProfileAttributesIfNothingSent() throws Exception {
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.contentType("application/json")
|
||||
.put(SECURE_PATH + "/profile/attributes");
|
||||
|
||||
assertEquals(response.getStatusCode(), 400);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToUpdateAttributesOfSpecifiedProfile() throws Exception {
|
||||
final ImmutableMap<String, String> attributes = ImmutableMap.of("attr1", "value1",
|
||||
"attr2", "value2",
|
||||
"attr3", "value3");
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.contentType("application/json")
|
||||
.body(attributes)
|
||||
.put(SECURE_PATH + "/profile/" + SUBJECT.getUserId() + "/attributes/");
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
verify(profileManager).update(profileCaptor.capture());
|
||||
final Profile profile = profileCaptor.getValue();
|
||||
assertEquals(profile.getAttributes(), attributes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotUpdateSpecifiedProfileAttributesIfNothingSent() throws Exception {
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.contentType("application/json")
|
||||
.put(SECURE_PATH + "/profile/" + SUBJECT.getUserId() + "/attributes/");
|
||||
|
||||
assertEquals(response.getStatusCode(), 400);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToRemoveSpecifiedAttributes() throws Exception {
|
||||
when(profileManager.getById(SUBJECT.getUserId()))
|
||||
.thenReturn(new ProfileImpl(SUBJECT.getUserId(),
|
||||
ImmutableMap.of("attr1", "value1",
|
||||
"attr2", "value2",
|
||||
"attr3", "value3")));
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.contentType("application/json")
|
||||
.body(asList("attr1", "attr3"))
|
||||
.delete(SECURE_PATH + "/profile/attributes");
|
||||
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verify(profileManager).update(profileCaptor.capture());
|
||||
final Profile profile = profileCaptor.getValue();
|
||||
assertEquals(profile.getAttributes(), ImmutableMap.of("attr2", "value2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveAllAttributeIfNoSpecified() throws Exception {
|
||||
when(profileManager.getById(SUBJECT.getUserId()))
|
||||
.thenReturn(new ProfileImpl(SUBJECT.getUserId(),
|
||||
ImmutableMap.of("attr1", "value1",
|
||||
"attr2", "value2",
|
||||
"attr3", "value3")));
|
||||
final Response response = given().auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.contentType("application/json")
|
||||
.delete(SECURE_PATH + "/profile/attributes");
|
||||
|
||||
assertEquals(response.getStatusCode(), 204);
|
||||
verify(profileManager).update(profileCaptor.capture());
|
||||
final Profile profile = profileCaptor.getValue();
|
||||
assertTrue(profile.getAttributes().isEmpty());
|
||||
}
|
||||
|
||||
@Filter
|
||||
public static class EnvironmentFilter implements RequestFilter {
|
||||
public void doFilter(GenericContainerRequest request) {
|
||||
EnvironmentContext.getCurrent().setSubject(SUBJECT);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> T unwrapDto(Response response, Class<T> dtoClass) {
|
||||
return DtoFactory.getInstance().createDtoFromJson(response.body().print(), dtoClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012-2016 Codenvy, S.A.
|
||||
* 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:
|
||||
* Codenvy, S.A. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.che.api.user.server;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import org.eclipse.che.api.core.rest.ServiceContext;
|
||||
import org.eclipse.che.api.user.shared.dto.UserDto;
|
||||
import org.eclipse.che.commons.lang.Pair;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.everrest.core.impl.uri.UriBuilderImpl;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Tests for {@link UserLinksInjector}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class UserLinksInjectorTest {
|
||||
|
||||
@Mock
|
||||
private ServiceContext serviceContext;
|
||||
|
||||
@InjectMocks
|
||||
private UserLinksInjector linksInjector;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUpContext() {
|
||||
final UriBuilderImpl uriBuilder = new UriBuilderImpl();
|
||||
uriBuilder.uri("http://localhost:8080");
|
||||
when(serviceContext.getServiceUriBuilder()).thenReturn(uriBuilder);
|
||||
when(serviceContext.getBaseUriBuilder()).thenReturn(uriBuilder);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldInjectLinks() throws Exception {
|
||||
final UserDto userDto = DtoFactory.newDto(UserDto.class)
|
||||
.withId("user123")
|
||||
.withEmail("user@codenvy.com")
|
||||
.withName("user");
|
||||
|
||||
linksInjector.injectLinks(userDto, serviceContext);
|
||||
|
||||
// [rel, method] pairs links
|
||||
final Set<Pair<String, String>> links = userDto.getLinks()
|
||||
.stream()
|
||||
.map(link -> Pair.of(link.getMethod(), link.getRel()))
|
||||
.collect(Collectors.toSet());
|
||||
final Set<Pair<String, String>> expectedLinks
|
||||
= new HashSet<>(asList(Pair.of("GET", Constants.LINK_REL_SELF),
|
||||
Pair.of("GET", Constants.LINK_REL_CURRENT_USER),
|
||||
Pair.of("GET", Constants.LINK_REL_PROFILE),
|
||||
Pair.of("GET", Constants.LINK_REL_CURRENT_USER_SETTINGS),
|
||||
Pair.of("GET", Constants.LINK_REL_PREFERENCES),
|
||||
Pair.of("POST", Constants.LINK_REL_CURRENT_USER_PASSWORD)));
|
||||
|
||||
assertEquals(links, expectedLinks, "Difference " + Sets.symmetricDifference(links, expectedLinks) + "\n");
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue