TSK-1706: Implementation of the new UserService (#1692)
This commit is contained in:
parent
1d23aeecc0
commit
1e3f90509d
|
@ -13,6 +13,7 @@ public final class SampleDataProvider {
|
|||
static final String TEST_CLASSIFICATION = "/sql/test-data/classification.sql";
|
||||
static final String TEST_OBJECT_REFERENCE = "/sql/test-data/object-reference.sql";
|
||||
static final String TEST_ATTACHMENT = "/sql/test-data/attachment.sql";
|
||||
static final String TEST_USER = "/sql/test-data/user.sql";
|
||||
static final String TEST_TASK_HISTORY_EVENT = "/sql/test-data/task-history-event.sql";
|
||||
static final String TEST_WORKBASKET_HISTORY_EVENT = "/sql/test-data/workbasket-history-event.sql";
|
||||
static final String TEST_CLASSIFICATION_HISTORY_EVENT =
|
||||
|
@ -31,6 +32,7 @@ public final class SampleDataProvider {
|
|||
private static final String SAMPLE_CLASSIFICATION = "/sql/sample-data/classification.sql";
|
||||
private static final String SAMPLE_OBJECT_REFERENCE = "/sql/sample-data/object-reference.sql";
|
||||
private static final String SAMPLE_ATTACHMENT = "/sql/sample-data/attachment.sql";
|
||||
private static final String SAMPLE_USER = "/sql/sample-data/user.sql";
|
||||
|
||||
private SampleDataProvider() {}
|
||||
|
||||
|
@ -44,7 +46,8 @@ public final class SampleDataProvider {
|
|||
SAMPLE_ATTACHMENT,
|
||||
SAMPLE_WORKBASKET_ACCESS_LIST,
|
||||
SAMPLE_OBJECT_REFERENCE,
|
||||
SAMPLE_TASK_HISTORY_EVENT);
|
||||
SAMPLE_TASK_HISTORY_EVENT,
|
||||
SAMPLE_USER);
|
||||
}
|
||||
|
||||
static Stream<String> getScriptsToClearDatabase() {
|
||||
|
@ -67,7 +70,8 @@ public final class SampleDataProvider {
|
|||
TEST_WORKBASKET_ACCESS_LIST,
|
||||
TEST_DISTRIBUTION_TARGETS,
|
||||
TEST_OBJECT_REFERENCE,
|
||||
TEST_ATTACHMENT);
|
||||
TEST_ATTACHMENT,
|
||||
TEST_USER);
|
||||
}
|
||||
|
||||
static Stream<String> getMonitorDataScripts() {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
-- USER_INFO TABLE (USER_ID , FIRST_NAME , LASTNAME , FULL_NAME , LONG_NAME , E_MAIL , PHONE , MOBILE_PHONE , ORG_LEVEL_4 , ORG_LEVEL_3 , ORG_LEVEL_2 , ORG_LEVEL_1 , DATA
|
||||
INSERT INTO USER_INFO VALUES('teamlead-1' , 'Titus' , 'Toll' , 'Toll, Titus' , 'Toll, Titus - (teamlead-1)' , 'titus.toll@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , 'xy' );
|
||||
INSERT INTO USER_INFO VALUES('user-1-1' , 'Max' , 'Mustermann' , 'Mustermann, Max' , 'Mustermann, Max - (user-1-1)' , 'max.mustermann@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-1-2' , 'Elena' , 'Eifrig' , 'Eifrig, Elena' , 'Eifrig, Elena - (user-1-2)' , 'elena.eifrig@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-1-3' , 'Elena' , 'Faul' , 'Faul, Elena' , 'Faul, Elena - (user-1-3)' , 'elena.faul@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-1' , 'Simone' , 'Müller' , 'Müller, Simone' , 'Müller, Simone - (user-2-1)' , 'simone.müller@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-2' , 'Tim' , 'Schläfrig' , 'Schläfrig, Tim' , 'Schläfrig, Tim - (user-2-2)' , 'tim.schläfrig@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-3' , 'Thomas' , 'Bach' , 'Bach, Thomas' , 'Bach, Thomas - (user-2-3)' , 'thomas.bach@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-4' , 'Rolf' , 'Wieland' , 'Wieland, Rolf' , 'Wieland, Rolf - (user-2-4)' , 'rolf.wieland@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-5' , 'Heike' , 'Schmidt' , 'Schmidt, Heike' , 'Schmidt, Heike - (user-2-5)' , 'heike.schmidt@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-6' , 'Kurt' , 'Maier' , 'Maier, Kurt' , 'Maier, Kurt - (user-2-6)' , 'kurt.maier@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-7' , 'Wiebke' , 'Meyer' , 'Meyer, Wiebke' , 'Meyer, Wiebke - (user-2-7)' , 'wiebke.meyer@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-9' , 'Nathalie' , 'Fuchs' , 'Fuchs, Nathalie' , 'Fuchs, Nathalie - (user-2-9)' , 'nathalie.fuchs@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-10' , 'Johannes' , 'Renz' , 'Renz, Johannes' , 'Renz, Johannes - (user-2-10)' , 'johannes.renz@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-11' , 'Max' , 'Renz' , 'Renz, Max' , 'Renz, Max - (user-2-11)' , 'max.renz@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
|
@ -0,0 +1,15 @@
|
|||
-- USER_INFO TABLE (USER_ID , FIRST_NAME , LASTNAME , FULL_NAME , LONG_NAME , E_MAIL , PHONE , MOBILE_PHONE , ORG_LEVEL_4 , ORG_LEVEL_3 , ORG_LEVEL_2 , ORG_LEVEL_1 , DATA
|
||||
INSERT INTO USER_INFO VALUES('teamlead-1' , 'Titus' , 'Toll' , 'Toll, Titus' , 'Toll, Titus - (teamlead-1)' , 'titus.toll@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , 'xy' );
|
||||
INSERT INTO USER_INFO VALUES('user-1-1' , 'Max' , 'Mustermann' , 'Mustermann, Max' , 'Mustermann, Max - (user-1-1)' , 'max.mustermann@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-1-2' , 'Elena' , 'Eifrig' , 'Eifrig, Elena' , 'Eifrig, Elena - (user-1-2)' , 'elena.eifrig@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-1-3' , 'Elena' , 'Faul' , 'Faul, Elena' , 'Faul, Elena - (user-1-3)' , 'elena.faul@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-1' , 'Simone' , 'Müller' , 'Müller, Simone' , 'Müller, Simone - (user-2-1)' , 'simone.müller@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-2' , 'Tim' , 'Schläfrig' , 'Schläfrig, Tim' , 'Schläfrig, Tim - (user-2-2)' , 'tim.schläfrig@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-3' , 'Thomas' , 'Bach' , 'Bach, Thomas' , 'Bach, Thomas - (user-2-3)' , 'thomas.bach@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-4' , 'Rolf' , 'Wieland' , 'Wieland, Rolf' , 'Wieland, Rolf - (user-2-4)' , 'rolf.wieland@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-5' , 'Heike' , 'Schmidt' , 'Schmidt, Heike' , 'Schmidt, Heike - (user-2-5)' , 'heike.schmidt@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-6' , 'Kurt' , 'Maier' , 'Maier, Kurt' , 'Maier, Kurt - (user-2-6)' , 'kurt.maier@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-7' , 'Wiebke' , 'Meyer' , 'Meyer, Wiebke' , 'Meyer, Wiebke - (user-2-7)' , 'wiebke.meyer@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-9' , 'Nathalie' , 'Fuchs' , 'Fuchs, Nathalie' , 'Fuchs, Nathalie - (user-2-9)' , 'nathalie.fuchs@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-10' , 'Johannes' , 'Renz' , 'Renz, Johannes' , 'Renz, Johannes - (user-2-10)' , 'johannes.renz@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
||||
INSERT INTO USER_INFO VALUES('user-2-11' , 'Max' , 'Renz' , 'Renz, Max' , 'Renz, Max - (user-2-11)' , 'max.renz@web.de' , '040-2951854' , '015637683197' , 'Novatec' , 'BPM' , 'Human Workflow' , 'TASKANA' , '' );
|
|
@ -308,6 +308,20 @@ ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 2
|
|||
cn: Johannes Renz
|
||||
userPassword: user-2-10
|
||||
|
||||
dn: uid=das_ist_eine_sehr_sehr_sehr_sehr_sehr_lange_user_id,cn=users,OU=Test,O=TASKANA
|
||||
objectclass: inetorgperson
|
||||
objectclass: organizationalperson
|
||||
objectclass: person
|
||||
objectclass: top
|
||||
givenName: Max
|
||||
description: desc
|
||||
memberOf: cn=Organisationseinheit KSC 2,cn=Organisationseinheit KSC,cn=organisation,OU=Test,O=TASKANA
|
||||
uid: das_ist_eine_sehr_sehr_sehr_sehr_sehr_lange_user_id
|
||||
sn: Renz
|
||||
ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 2
|
||||
cn: Max Renz
|
||||
userPassword: user-2-11
|
||||
|
||||
########################
|
||||
# Users Domäne B
|
||||
########################
|
||||
|
|
|
@ -304,7 +304,7 @@ CREATE TABLE CLASSIFICATION_HISTORY_EVENT
|
|||
PRIMARY KEY (ID)
|
||||
);
|
||||
|
||||
|
||||
-- USER can not be taken as table name because it is a reserved keyword.
|
||||
CREATE TABLE USER_INFO (
|
||||
USER_ID VARCHAR(32) NOT NULL,
|
||||
FIRST_NAME VARCHAR(32) NULL,
|
||||
|
|
|
@ -9,6 +9,7 @@ import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
|||
import pro.taskana.common.api.security.CurrentUserContext;
|
||||
import pro.taskana.monitor.api.MonitorService;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.user.api.UserService;
|
||||
import pro.taskana.workbasket.api.WorkbasketService;
|
||||
|
||||
/** The TaskanaEngine represents an overall set of all needed services. */
|
||||
|
@ -49,6 +50,8 @@ public interface TaskanaEngine {
|
|||
*/
|
||||
JobService getJobService();
|
||||
|
||||
UserService getUserService();
|
||||
|
||||
/**
|
||||
* The Taskana configuration.
|
||||
*
|
||||
|
|
|
@ -61,6 +61,9 @@ import pro.taskana.task.internal.TaskCommentMapper;
|
|||
import pro.taskana.task.internal.TaskMapper;
|
||||
import pro.taskana.task.internal.TaskQueryMapper;
|
||||
import pro.taskana.task.internal.TaskServiceImpl;
|
||||
import pro.taskana.user.api.UserService;
|
||||
import pro.taskana.user.internal.UserMapper;
|
||||
import pro.taskana.user.internal.UserServiceImpl;
|
||||
import pro.taskana.workbasket.api.WorkbasketService;
|
||||
import pro.taskana.workbasket.internal.DistributionTargetMapper;
|
||||
import pro.taskana.workbasket.internal.WorkbasketAccessMapper;
|
||||
|
@ -153,6 +156,12 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
|||
return new JobServiceImpl(internalTaskanaEngineImpl, sessionManager.getMapper(JobMapper.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserService getUserService() {
|
||||
return new UserServiceImpl(
|
||||
internalTaskanaEngineImpl, sessionManager.getMapper(UserMapper.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskanaEngineConfiguration getConfiguration() {
|
||||
return this.taskanaEngineConfiguration;
|
||||
|
@ -311,6 +320,7 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
|||
configuration.addMapper(ClassificationQueryMapper.class);
|
||||
configuration.addMapper(AttachmentMapper.class);
|
||||
configuration.addMapper(JobMapper.class);
|
||||
configuration.addMapper(UserMapper.class);
|
||||
SqlSessionFactory localSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
|
||||
return SqlSessionManager.newInstance(localSessionFactory);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
package pro.taskana.user.api;
|
||||
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.user.api.exceptions.UserAlreadyExistException;
|
||||
import pro.taskana.user.api.exceptions.UserNotFoundException;
|
||||
import pro.taskana.user.api.models.User;
|
||||
|
||||
/** The UserService manages all operations concerning {@linkplain User Users}. */
|
||||
public interface UserService {
|
||||
|
||||
/**
|
||||
* Returns a new {@linkplain User} with all fields being empty.
|
||||
*
|
||||
* <p>It will be only generated but not yet inserted until method {@linkplain
|
||||
* UserService#createUser(User)} is called.
|
||||
*
|
||||
* @return the new {@linkplain User}
|
||||
*/
|
||||
User newUser();
|
||||
|
||||
/**
|
||||
* Gets a {@linkplain User}.
|
||||
*
|
||||
* <p>If a {@linkplain User} with the specified {@linkplain User#getId() id} is existing in the
|
||||
* database, it is returned.
|
||||
*
|
||||
* @param id the {@linkplain User#getId() id} of the {@linkplain User} to be retrieved
|
||||
* @return the retrieved {@linkplain User}
|
||||
* @throws UserNotFoundException if there does not exist a {@linkplain User} with the specified
|
||||
* {@linkplain User#getId() id} inside the database
|
||||
*/
|
||||
User getUser(String id) throws UserNotFoundException;
|
||||
|
||||
/**
|
||||
* Creates a new {@linkplain User}.
|
||||
*
|
||||
* <p>If all checks have passed the specified {@linkplain User} will be inserted into the
|
||||
* database. The {@linkplain User#getId() id} of the {@linkplain User} must be set and should be
|
||||
* unique, such that no other {@linkplain User} with same {@linkplain User#getId() id} is already
|
||||
* existing in the database. The {@linkplain User#getFirstName() first name} and the {@linkplain
|
||||
* User#getLastName() last name} must not be null. The fields for the {@linkplain
|
||||
* User#getFullName() full name} and the {@linkplain User#getLongName() long name} are set
|
||||
* according to following rules:
|
||||
*
|
||||
* <ul>
|
||||
* <li><b>fullName</b> = lastName, firstName
|
||||
* <li><b>longName</b> = lastName, firstName - (id)
|
||||
* </ul>
|
||||
*
|
||||
* @param userToCreate the {@linkplain User} which should be inserted
|
||||
* @return the inserted {@linkplain User}
|
||||
* @throws InvalidArgumentException if some fields are not set properly
|
||||
* @throws NotAuthorizedException if the current user is not admin or business-admin
|
||||
* @throws UserAlreadyExistException if there already exists a {@linkplain User} with the
|
||||
* specified {@linkplain User#getId() id} inside the database
|
||||
*/
|
||||
User createUser(User userToCreate)
|
||||
throws InvalidArgumentException, NotAuthorizedException, UserAlreadyExistException;
|
||||
|
||||
/**
|
||||
* Updates an existing {@linkplain User}.
|
||||
*
|
||||
* <p>If a {@linkplain User} with the specified {@linkplain User#getId() id} exists in the
|
||||
* database and if the current user is allowed to perform the operation, the {@linkplain User}
|
||||
* gets updated according to the set fields of the passed object.
|
||||
*
|
||||
* @param userToUpdate the {@linkplain User} which should be updated
|
||||
* @return the updated {@linkplain User}
|
||||
* @throws NotAuthorizedException if the current user is not admin or business-admin
|
||||
* @throws UserNotFoundException if there does not exist a {@linkplain User} with the specified
|
||||
* {@linkplain User#getId() id} inside the database
|
||||
*/
|
||||
User updateUser(User userToUpdate) throws UserNotFoundException, NotAuthorizedException;
|
||||
|
||||
/**
|
||||
* Deletes a {@linkplain User}.
|
||||
*
|
||||
* <p>If a {@linkplain User} with the specified {@linkplain User#getId() id} exists in the
|
||||
* database and if the current user is allowed to perform the operation, the {@linkplain User}
|
||||
* gets deleted.
|
||||
*
|
||||
* @param id the {@linkplain User#getId() id} of the {@linkplain User} which should be deleted
|
||||
* @throws NotAuthorizedException if the current user is not admin or business-admin
|
||||
* @throws UserNotFoundException if there does not exist a {@linkplain User} with the specified
|
||||
* {@linkplain User#getId() id} inside the database
|
||||
*/
|
||||
void deleteUser(String id) throws UserNotFoundException, NotAuthorizedException;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package pro.taskana.user.api.exceptions;
|
||||
|
||||
import pro.taskana.common.api.exceptions.ErrorCode;
|
||||
import pro.taskana.common.api.exceptions.TaskanaException;
|
||||
import pro.taskana.common.internal.util.MapCreator;
|
||||
import pro.taskana.user.api.models.User;
|
||||
|
||||
/**
|
||||
* This exception is thrown when a {@linkplain User} was tried to be created with an {@linkplain
|
||||
* User#getId() id} already existing.
|
||||
*/
|
||||
public class UserAlreadyExistException extends TaskanaException {
|
||||
public static final String ERROR_KEY = "USER_ALREADY_EXISTS";
|
||||
private final String userId;
|
||||
|
||||
public UserAlreadyExistException(String userId) {
|
||||
super(
|
||||
String.format("User with id '%s' already exists.", userId),
|
||||
ErrorCode.of(ERROR_KEY, MapCreator.of("userId", userId)));
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package pro.taskana.user.api.exceptions;
|
||||
|
||||
import pro.taskana.common.api.exceptions.ErrorCode;
|
||||
import pro.taskana.common.api.exceptions.NotFoundException;
|
||||
import pro.taskana.common.internal.util.MapCreator;
|
||||
import pro.taskana.user.api.models.User;
|
||||
|
||||
/**
|
||||
* This exception is thrown when a specific {@linkplain User} referenced by its {@linkplain
|
||||
* User#getId() id} is not in the database.
|
||||
*/
|
||||
public class UserNotFoundException extends NotFoundException {
|
||||
public static final String ERROR_KEY = "USER_NOT_FOUND";
|
||||
private final String userId;
|
||||
|
||||
public UserNotFoundException(String userId) {
|
||||
super(
|
||||
String.format("User with id '%s' was not found.", userId),
|
||||
ErrorCode.of(ERROR_KEY, MapCreator.of("userId", userId)));
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,190 @@
|
|||
package pro.taskana.user.api.models;
|
||||
|
||||
/** The User holds some relevant information about the TASKANA users. */
|
||||
public interface User {
|
||||
|
||||
/**
|
||||
* Gets the id of the User.
|
||||
*
|
||||
* @return userId
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Sets the id of the User.
|
||||
*
|
||||
* @param id the id of the User
|
||||
*/
|
||||
void setId(String id);
|
||||
|
||||
/**
|
||||
* Gets the first name of the User.
|
||||
*
|
||||
* @return firstName
|
||||
*/
|
||||
String getFirstName();
|
||||
|
||||
/**
|
||||
* Sets the first name of the User.
|
||||
*
|
||||
* @param firstName the first name of the User
|
||||
*/
|
||||
void setFirstName(String firstName);
|
||||
|
||||
/**
|
||||
* Gets the last name of the User.
|
||||
*
|
||||
* @return lastName
|
||||
*/
|
||||
String getLastName();
|
||||
|
||||
/**
|
||||
* Sets the last name of the User.
|
||||
*
|
||||
* @param lastName the last name of the User
|
||||
*/
|
||||
void setLastName(String lastName);
|
||||
|
||||
/**
|
||||
* Gets the full name of the User.
|
||||
*
|
||||
* @return fullName
|
||||
*/
|
||||
String getFullName();
|
||||
|
||||
/**
|
||||
* Sets the full name of the User.
|
||||
*
|
||||
* @param fullName the full name of the User
|
||||
*/
|
||||
void setFullName(String fullName);
|
||||
|
||||
/**
|
||||
* Gets the long name of the User.
|
||||
*
|
||||
* @return longName
|
||||
*/
|
||||
String getLongName();
|
||||
|
||||
/**
|
||||
* Sets the long name of the User.
|
||||
*
|
||||
* @param longName the long name of the User
|
||||
*/
|
||||
void setLongName(String longName);
|
||||
|
||||
/**
|
||||
* Gets the email address of the User.
|
||||
*
|
||||
* @return email
|
||||
*/
|
||||
String getEmail();
|
||||
|
||||
/**
|
||||
* Sets the email address of the User.
|
||||
*
|
||||
* @param email the email address of the User
|
||||
*/
|
||||
void setEmail(String email);
|
||||
|
||||
/**
|
||||
* Gets the phone number of the User.
|
||||
*
|
||||
* @return phone
|
||||
*/
|
||||
String getPhone();
|
||||
|
||||
/**
|
||||
* Sets the phone number of the User.
|
||||
*
|
||||
* @param phone the phone number of the User
|
||||
*/
|
||||
void setPhone(String phone);
|
||||
|
||||
/**
|
||||
* Gets the mobile phone number of the User.
|
||||
*
|
||||
* @return mobilePhone
|
||||
*/
|
||||
String getMobilePhone();
|
||||
|
||||
/**
|
||||
* Sets the mobile phone number of the User.
|
||||
*
|
||||
* @param mobilePhone the mobile phone number of the User
|
||||
*/
|
||||
void setMobilePhone(String mobilePhone);
|
||||
|
||||
/**
|
||||
* Gets the orgLevel4 of the User.
|
||||
*
|
||||
* @return orgLevel4
|
||||
*/
|
||||
String getOrgLevel4();
|
||||
|
||||
/**
|
||||
* Sets the fourth organization level of the User.
|
||||
*
|
||||
* @param orgLevel4 the fourth organization level of the User
|
||||
*/
|
||||
void setOrgLevel4(String orgLevel4);
|
||||
|
||||
/**
|
||||
* Gets the orgLevel3 of the User.
|
||||
*
|
||||
* @return orgLevel3
|
||||
*/
|
||||
String getOrgLevel3();
|
||||
|
||||
/**
|
||||
* Sets the third organization level of the User.
|
||||
*
|
||||
* @param orgLevel3 the third organization level of the User
|
||||
*/
|
||||
void setOrgLevel3(String orgLevel3);
|
||||
|
||||
/**
|
||||
* Gets the orgLevel2 of the User.
|
||||
*
|
||||
* @return orgLevel2
|
||||
*/
|
||||
String getOrgLevel2();
|
||||
|
||||
/**
|
||||
* Sets the second organization level of the User.
|
||||
*
|
||||
* @param orgLevel2 the second organization level of the User
|
||||
*/
|
||||
void setOrgLevel2(String orgLevel2);
|
||||
|
||||
/**
|
||||
* Gets the orgLevel1 of the User.
|
||||
*
|
||||
* @return orgLevel1
|
||||
*/
|
||||
String getOrgLevel1();
|
||||
|
||||
/**
|
||||
* Sets the first organization level of the User.
|
||||
*
|
||||
* @param orgLevel1 the first organization level of the User
|
||||
*/
|
||||
void setOrgLevel1(String orgLevel1);
|
||||
|
||||
/**
|
||||
* Gets the data of the User.
|
||||
*
|
||||
* @return data
|
||||
*/
|
||||
String getData();
|
||||
|
||||
/**
|
||||
* Sets the data of the User.
|
||||
*
|
||||
* @param data the data of the User
|
||||
*/
|
||||
void setData(String data);
|
||||
|
||||
User copy();
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package pro.taskana.user.internal;
|
||||
|
||||
import org.apache.ibatis.annotations.DeleteProvider;
|
||||
import org.apache.ibatis.annotations.InsertProvider;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Result;
|
||||
import org.apache.ibatis.annotations.SelectProvider;
|
||||
import org.apache.ibatis.annotations.UpdateProvider;
|
||||
|
||||
import pro.taskana.user.internal.models.UserImpl;
|
||||
|
||||
public interface UserMapper {
|
||||
@SelectProvider(type = UserMapperSqlProvider.class, method = "findById")
|
||||
@Result(property = "id", column = "USER_ID")
|
||||
@Result(property = "firstName", column = "FIRST_NAME")
|
||||
@Result(property = "lastName", column = "LASTNAME")
|
||||
@Result(property = "fullName", column = "FULL_NAME")
|
||||
@Result(property = "longName", column = "LONG_NAME")
|
||||
@Result(property = "email", column = "E_MAIL")
|
||||
@Result(property = "phone", column = "PHONE")
|
||||
@Result(property = "mobilePhone", column = "MOBILE_PHONE")
|
||||
@Result(property = "orgLevel4", column = "ORG_LEVEL_4")
|
||||
@Result(property = "orgLevel3", column = "ORG_LEVEL_3")
|
||||
@Result(property = "orgLevel2", column = "ORG_LEVEL_2")
|
||||
@Result(property = "orgLevel1", column = "ORG_LEVEL_1")
|
||||
@Result(property = "data", column = "DATA")
|
||||
UserImpl findById(@Param("id") String id);
|
||||
|
||||
@InsertProvider(type = UserMapperSqlProvider.class, method = "insert")
|
||||
void insert(UserImpl user);
|
||||
|
||||
@UpdateProvider(type = UserMapperSqlProvider.class, method = "update")
|
||||
void update(UserImpl user);
|
||||
|
||||
@DeleteProvider(type = UserMapperSqlProvider.class, method = "delete")
|
||||
void delete(String id);
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package pro.taskana.user.internal;
|
||||
|
||||
import static pro.taskana.common.internal.util.SqlProviderUtil.CLOSING_SCRIPT_TAG;
|
||||
import static pro.taskana.common.internal.util.SqlProviderUtil.DB2_WITH_UR;
|
||||
import static pro.taskana.common.internal.util.SqlProviderUtil.OPENING_SCRIPT_TAG;
|
||||
|
||||
public class UserMapperSqlProvider {
|
||||
private static final String USER_INFO = "USER_INFO ";
|
||||
private static final String USER_INFO_COLUMNS =
|
||||
"USER_ID, FIRST_NAME, LASTNAME, FULL_NAME, LONG_NAME, E_MAIL, PHONE, MOBILE_PHONE, "
|
||||
+ "ORG_LEVEL_4, ORG_LEVEL_3, ORG_LEVEL_2, ORG_LEVEL_1, DATA ";
|
||||
private static final String USER_INFO_VALUES =
|
||||
"#{id}, #{firstName}, #{lastName}, #{fullName}, #{longName}, #{email}, #{phone}, "
|
||||
+ "#{mobilePhone}, #{orgLevel4}, #{orgLevel3}, #{orgLevel2}, #{orgLevel1}, #{data} ";
|
||||
private static final String WHERE_USER_ID = "WHERE USER_ID = #{id} ";
|
||||
|
||||
private UserMapperSqlProvider() {}
|
||||
|
||||
public static String findById() {
|
||||
return OPENING_SCRIPT_TAG
|
||||
+ "SELECT "
|
||||
+ USER_INFO_COLUMNS
|
||||
+ "FROM "
|
||||
+ USER_INFO
|
||||
+ WHERE_USER_ID
|
||||
+ DB2_WITH_UR
|
||||
+ CLOSING_SCRIPT_TAG;
|
||||
}
|
||||
|
||||
public static String insert() {
|
||||
return "INSERT INTO "
|
||||
+ USER_INFO
|
||||
+ "( "
|
||||
+ USER_INFO_COLUMNS
|
||||
+ ") VALUES("
|
||||
+ USER_INFO_VALUES
|
||||
+ ")";
|
||||
}
|
||||
|
||||
public static String update() {
|
||||
return "UPDATE "
|
||||
+ USER_INFO
|
||||
+ "SET FIRST_NAME = #{firstName}, "
|
||||
+ "LASTNAME = #{lastName}, FULL_NAME = #{fullName}, LONG_NAME = #{longName}, "
|
||||
+ "E_MAIL = #{email}, PHONE = #{phone}, MOBILE_PHONE = #{mobilePhone}, "
|
||||
+ "ORG_LEVEL_4 = #{orgLevel4}, ORG_LEVEL_3 = #{orgLevel3}, "
|
||||
+ "ORG_LEVEL_2 = #{orgLevel2}, ORG_LEVEL_1 = #{orgLevel1}, DATA = #{data} "
|
||||
+ WHERE_USER_ID;
|
||||
}
|
||||
|
||||
public static String delete() {
|
||||
return "DELETE FROM " + USER_INFO + WHERE_USER_ID;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
package pro.taskana.user.internal;
|
||||
|
||||
import org.apache.ibatis.exceptions.PersistenceException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import pro.taskana.common.api.TaskanaRole;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||
import pro.taskana.user.api.UserService;
|
||||
import pro.taskana.user.api.exceptions.UserAlreadyExistException;
|
||||
import pro.taskana.user.api.exceptions.UserNotFoundException;
|
||||
import pro.taskana.user.api.models.User;
|
||||
import pro.taskana.user.internal.models.UserImpl;
|
||||
|
||||
public class UserServiceImpl implements UserService {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);
|
||||
|
||||
private final InternalTaskanaEngine taskanaEngine;
|
||||
private final UserMapper userMapper;
|
||||
|
||||
public UserServiceImpl(InternalTaskanaEngine taskanaEngine, UserMapper userMapper) {
|
||||
this.taskanaEngine = taskanaEngine;
|
||||
this.userMapper = userMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User newUser() {
|
||||
return new UserImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser(String id) throws UserNotFoundException {
|
||||
User user = taskanaEngine.executeInDatabaseConnection(() -> userMapper.findById(id));
|
||||
if (user == null) {
|
||||
throw new UserNotFoundException(id);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User createUser(User userToCreate)
|
||||
throws InvalidArgumentException, NotAuthorizedException, UserAlreadyExistException {
|
||||
taskanaEngine.getEngine().checkRoleMembership(TaskanaRole.BUSINESS_ADMIN, TaskanaRole.ADMIN);
|
||||
validateAndPopulateFields(userToCreate);
|
||||
insertIntoDatabase(userToCreate);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Method createUser() created User '{}'.", userToCreate);
|
||||
}
|
||||
|
||||
return userToCreate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User updateUser(User userToUpdate) throws UserNotFoundException, NotAuthorizedException {
|
||||
taskanaEngine.getEngine().checkRoleMembership(TaskanaRole.BUSINESS_ADMIN, TaskanaRole.ADMIN);
|
||||
getUser(userToUpdate.getId());
|
||||
|
||||
taskanaEngine.executeInDatabaseConnection(() -> userMapper.update((UserImpl) userToUpdate));
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Method updateUser() updated User '{}'.", userToUpdate);
|
||||
}
|
||||
|
||||
return userToUpdate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteUser(String id) throws UserNotFoundException, NotAuthorizedException {
|
||||
taskanaEngine.getEngine().checkRoleMembership(TaskanaRole.BUSINESS_ADMIN, TaskanaRole.ADMIN);
|
||||
getUser(id);
|
||||
|
||||
taskanaEngine.executeInDatabaseConnection(() -> userMapper.delete(id));
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Method deleteUser() deleted User with id '{}'.", id);
|
||||
}
|
||||
}
|
||||
|
||||
private void insertIntoDatabase(User userToCreate) throws UserAlreadyExistException {
|
||||
try {
|
||||
taskanaEngine.openConnection();
|
||||
userMapper.insert((UserImpl) userToCreate);
|
||||
} catch (PersistenceException e) {
|
||||
throw new UserAlreadyExistException(userToCreate.getId());
|
||||
} finally {
|
||||
taskanaEngine.returnConnection();
|
||||
}
|
||||
}
|
||||
|
||||
private void validateAndPopulateFields(User userToCreate) throws InvalidArgumentException {
|
||||
if (userToCreate.getId() == null || userToCreate.getId().isEmpty()) {
|
||||
throw new InvalidArgumentException("UserId must not be empty when creating User.");
|
||||
}
|
||||
if (userToCreate.getFirstName() == null || userToCreate.getLastName() == null) {
|
||||
throw new InvalidArgumentException("First and last name of User must be set or empty.");
|
||||
}
|
||||
|
||||
if (userToCreate.getFullName() == null || userToCreate.getFullName().isEmpty()) {
|
||||
userToCreate.setFullName(userToCreate.getLastName() + ", " + userToCreate.getFirstName());
|
||||
}
|
||||
if (userToCreate.getLongName() == null || userToCreate.getLongName().isEmpty()) {
|
||||
userToCreate.setLongName(userToCreate.getFullName() + " - (" + userToCreate.getId() + ")");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,250 @@
|
|||
package pro.taskana.user.internal.models;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import pro.taskana.user.api.models.User;
|
||||
|
||||
public class UserImpl implements User {
|
||||
private String id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String fullName;
|
||||
private String longName;
|
||||
private String email;
|
||||
private String phone;
|
||||
private String mobilePhone;
|
||||
private String orgLevel4;
|
||||
private String orgLevel3;
|
||||
private String orgLevel2;
|
||||
private String orgLevel1;
|
||||
private String data;
|
||||
|
||||
public UserImpl() {}
|
||||
|
||||
protected UserImpl(UserImpl copyFrom) {
|
||||
this.id = copyFrom.id;
|
||||
this.firstName = copyFrom.firstName;
|
||||
this.lastName = copyFrom.lastName;
|
||||
this.fullName = copyFrom.fullName;
|
||||
this.longName = copyFrom.longName;
|
||||
this.email = copyFrom.email;
|
||||
this.phone = copyFrom.phone;
|
||||
this.mobilePhone = copyFrom.mobilePhone;
|
||||
this.orgLevel4 = copyFrom.orgLevel4;
|
||||
this.orgLevel3 = copyFrom.orgLevel3;
|
||||
this.orgLevel2 = copyFrom.orgLevel2;
|
||||
this.orgLevel1 = copyFrom.orgLevel1;
|
||||
this.data = copyFrom.data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFullName(String fullName) {
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLongName() {
|
||||
return longName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLongName(String longName) {
|
||||
this.longName = longName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMobilePhone() {
|
||||
return mobilePhone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMobilePhone(String mobilePhone) {
|
||||
this.mobilePhone = mobilePhone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOrgLevel4() {
|
||||
return orgLevel4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrgLevel4(String orgLevel4) {
|
||||
this.orgLevel4 = orgLevel4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOrgLevel3() {
|
||||
return orgLevel3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrgLevel3(String orgLevel3) {
|
||||
this.orgLevel3 = orgLevel3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOrgLevel2() {
|
||||
return orgLevel2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrgLevel2(String orgLevel2) {
|
||||
this.orgLevel2 = orgLevel2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOrgLevel1() {
|
||||
return orgLevel1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrgLevel1(String orgLevel1) {
|
||||
this.orgLevel1 = orgLevel1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserImpl copy() {
|
||||
return new UserImpl(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(
|
||||
id,
|
||||
firstName,
|
||||
lastName,
|
||||
fullName,
|
||||
longName,
|
||||
email,
|
||||
phone,
|
||||
mobilePhone,
|
||||
orgLevel4,
|
||||
orgLevel3,
|
||||
orgLevel2,
|
||||
orgLevel1,
|
||||
data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
UserImpl other = (UserImpl) obj;
|
||||
return Objects.equals(id, other.id)
|
||||
&& Objects.equals(firstName, other.firstName)
|
||||
&& Objects.equals(lastName, other.lastName)
|
||||
&& Objects.equals(fullName, other.fullName)
|
||||
&& Objects.equals(longName, other.longName)
|
||||
&& Objects.equals(email, other.email)
|
||||
&& Objects.equals(phone, other.phone)
|
||||
&& Objects.equals(mobilePhone, other.mobilePhone)
|
||||
&& Objects.equals(orgLevel4, other.orgLevel4)
|
||||
&& Objects.equals(orgLevel3, other.orgLevel3)
|
||||
&& Objects.equals(orgLevel2, other.orgLevel2)
|
||||
&& Objects.equals(orgLevel1, other.orgLevel1)
|
||||
&& Objects.equals(data, other.data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UserImpl [id="
|
||||
+ id
|
||||
+ ", firstName="
|
||||
+ firstName
|
||||
+ ", lastname="
|
||||
+ lastName
|
||||
+ ", fullName="
|
||||
+ fullName
|
||||
+ ", longName="
|
||||
+ longName
|
||||
+ ", email="
|
||||
+ email
|
||||
+ ", phone="
|
||||
+ phone
|
||||
+ ", mobilePhone="
|
||||
+ mobilePhone
|
||||
+ ", orgLevel4="
|
||||
+ orgLevel4
|
||||
+ ", orgLevel3="
|
||||
+ orgLevel3
|
||||
+ ", orgLevel2="
|
||||
+ orgLevel2
|
||||
+ ", orgLevel1="
|
||||
+ orgLevel1
|
||||
+ ", data="
|
||||
+ data
|
||||
+ "]";
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@ import pro.taskana.common.internal.TaskanaEngineImpl;
|
|||
import pro.taskana.sampledata.SampleDataGenerator;
|
||||
import pro.taskana.task.api.models.Attachment;
|
||||
import pro.taskana.task.api.models.ObjectReference;
|
||||
import pro.taskana.user.api.models.User;
|
||||
|
||||
/** Base class for all acceptance tests. */
|
||||
public abstract class AbstractAccTest {
|
||||
|
@ -88,7 +89,7 @@ public abstract class AbstractAccTest {
|
|||
.collect(Collectors.toMap("Property_"::concat, "Property Value of Property_"::concat));
|
||||
}
|
||||
|
||||
protected Attachment createAttachment(
|
||||
protected Attachment createExampleAttachment(
|
||||
String classificationKey,
|
||||
ObjectReference objRef,
|
||||
String channel,
|
||||
|
@ -112,6 +113,25 @@ public abstract class AbstractAccTest {
|
|||
return attachment;
|
||||
}
|
||||
|
||||
protected User createExampleUser(String id) {
|
||||
User user = taskanaEngine.getUserService().newUser();
|
||||
user.setId(id);
|
||||
user.setFirstName("Hans");
|
||||
user.setLastName("Georg");
|
||||
user.setFullName("Georg, Hans");
|
||||
user.setLongName("Georg, Hans - (user-10-20)");
|
||||
user.setEmail("hans.georg@web.com");
|
||||
user.setPhone("1234");
|
||||
user.setMobilePhone("01574275632");
|
||||
user.setOrgLevel4("level4");
|
||||
user.setOrgLevel3("level3");
|
||||
user.setOrgLevel2("level2");
|
||||
user.setOrgLevel1("level1");
|
||||
user.setData("ab");
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
protected TimeInterval toDaysInterval() {
|
||||
Instant begin =
|
||||
ZonedDateTime.of(LocalDate.now(ZoneId.of("UTC")), LocalTime.MIN, ZoneId.of("UTC"))
|
||||
|
|
|
@ -66,6 +66,10 @@ class ArchitectureTest {
|
|||
"pro.taskana.monitor.internal",
|
||||
"pro.taskana.task.api",
|
||||
"pro.taskana.task.internal",
|
||||
"pro.taskana.user.api",
|
||||
"pro.taskana.user.api.exceptions",
|
||||
"pro.taskana.user.api.models",
|
||||
"pro.taskana.user.internal",
|
||||
"pro.taskana.workbasket.api",
|
||||
"pro.taskana.workbasket.internal",
|
||||
"pro.taskana.spi.routing.api",
|
||||
|
|
|
@ -72,7 +72,7 @@ class UpdateObjectsUseUtcTimeStampsAccTest extends AbstractAccTest {
|
|||
newTask.setDescription("Description of test task");
|
||||
newTask.setNote("My note");
|
||||
newTask.addAttachment(
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT",
|
||||
createObjectReference(
|
||||
"COMPANY_A",
|
||||
|
|
|
@ -308,7 +308,7 @@ class CreateTaskAccTest extends AbstractAccTest {
|
|||
newTask.setClassificationKey("L12010");
|
||||
Map<String, String> customAttributesForCreate = createSimpleCustomPropertyMap(27);
|
||||
newTask.addAttachment(
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT",
|
||||
createObjectReference(
|
||||
"COMPANY_A",
|
||||
|
@ -387,7 +387,7 @@ class CreateTaskAccTest extends AbstractAccTest {
|
|||
newTask.setPrimaryObjRef(
|
||||
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
|
||||
newTask.addAttachment(
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT",
|
||||
createObjectReference(
|
||||
"COMPANY_A",
|
||||
|
@ -399,7 +399,7 @@ class CreateTaskAccTest extends AbstractAccTest {
|
|||
laterInstant,
|
||||
createSimpleCustomPropertyMap(3)));
|
||||
newTask.addAttachment(
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT",
|
||||
createObjectReference(
|
||||
"COMPANY_A",
|
||||
|
@ -441,7 +441,7 @@ class CreateTaskAccTest extends AbstractAccTest {
|
|||
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
|
||||
|
||||
newTask.addAttachment(
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT", // prio 99, SL P2000D
|
||||
createObjectReference(
|
||||
"COMPANY_A",
|
||||
|
@ -453,7 +453,7 @@ class CreateTaskAccTest extends AbstractAccTest {
|
|||
Instant.parse("2018-01-15T00:00:00Z"),
|
||||
createSimpleCustomPropertyMap(3)));
|
||||
newTask.addAttachment(
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"L1060", // prio 1, SL P1D
|
||||
createObjectReference(
|
||||
"COMPANY_A",
|
||||
|
@ -507,7 +507,7 @@ class CreateTaskAccTest extends AbstractAccTest {
|
|||
};
|
||||
|
||||
testCreateTask.accept(
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT",
|
||||
null,
|
||||
"E-MAIL",
|
||||
|
@ -515,7 +515,7 @@ class CreateTaskAccTest extends AbstractAccTest {
|
|||
createSimpleCustomPropertyMap(3)));
|
||||
|
||||
testCreateTask.accept(
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT",
|
||||
createObjectReference("COMPANY_A", "SYSTEM_B", "INSTANCE_B", "ArchiveId", null),
|
||||
"E-MAIL",
|
||||
|
@ -523,7 +523,7 @@ class CreateTaskAccTest extends AbstractAccTest {
|
|||
createSimpleCustomPropertyMap(3)));
|
||||
|
||||
testCreateTask.accept(
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT",
|
||||
createObjectReference(
|
||||
"COMPANY_A",
|
||||
|
@ -536,7 +536,7 @@ class CreateTaskAccTest extends AbstractAccTest {
|
|||
createSimpleCustomPropertyMap(3)));
|
||||
|
||||
testCreateTask.accept(
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT",
|
||||
createObjectReference(
|
||||
null,
|
||||
|
@ -632,7 +632,8 @@ class CreateTaskAccTest extends AbstractAccTest {
|
|||
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", null));
|
||||
testCreateTask.accept(
|
||||
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", null, "1234567"));
|
||||
testCreateTask.accept(createObjectReference(null, "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
|
||||
testCreateTask.accept(
|
||||
createObjectReference(null, "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
|
@ -671,7 +672,7 @@ class CreateTaskAccTest extends AbstractAccTest {
|
|||
newTask.setDescription("Description of test task");
|
||||
newTask.setNote("My note");
|
||||
newTask.addAttachment(
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT",
|
||||
createObjectReference(
|
||||
"COMPANY_A",
|
||||
|
|
|
@ -169,7 +169,7 @@ class QueryTasksAccTest extends AbstractAccTest {
|
|||
void testQueryForAttachmentInSummary() throws Exception {
|
||||
|
||||
Attachment attachment =
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT", // priority 99, SL P2000D
|
||||
createObjectReference(
|
||||
"COMPANY_A",
|
||||
|
|
|
@ -53,7 +53,7 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
|
|||
"TKI:000000000000000000000000000000000000"); // class T2000, prio 1, SL P1D
|
||||
task.setClassificationKey("T2000");
|
||||
attachment =
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT", // prio 99, SL P2000D
|
||||
createObjectReference(
|
||||
"COMPANY_A",
|
||||
|
@ -113,7 +113,7 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
|
|||
void should_UpdateTaskReceived_When_AddingTwoAttachments() throws Exception {
|
||||
task.addAttachment(attachment);
|
||||
Attachment attachment2 =
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"L10303",
|
||||
createObjectReference(
|
||||
"COMPANY_B",
|
||||
|
@ -336,7 +336,7 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
|
|||
task.addAttachment(attachment);
|
||||
|
||||
Attachment attachment2 =
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"L10303", // prio 101, SL PT7H
|
||||
createObjectReference(
|
||||
"COMPANY_B",
|
||||
|
@ -408,7 +408,7 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
|
|||
assertThat(task.getAttachments()).isEmpty();
|
||||
task.addAttachment(attachment);
|
||||
Attachment attachment2 =
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT",
|
||||
createObjectReference(
|
||||
"COMPANY_B",
|
||||
|
@ -427,7 +427,7 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
|
|||
.isEqualTo("DOCTYPE_DEFAULT");
|
||||
|
||||
Attachment attachment3 =
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT",
|
||||
createObjectReference(
|
||||
"COMPANY_C",
|
||||
|
@ -470,7 +470,7 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
|
|||
createObjectReference("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567"));
|
||||
|
||||
newTask.addAttachment(
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT", // prio 99, SL P2000D
|
||||
createObjectReference(
|
||||
"COMPANY_A",
|
||||
|
@ -482,7 +482,7 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
|
|||
Instant.parse("2018-01-15T00:00:00Z"),
|
||||
createSimpleCustomPropertyMap(3)));
|
||||
newTask.addAttachment(
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"L1060", // prio 1, SL P1D
|
||||
createObjectReference(
|
||||
"COMPANY_A",
|
||||
|
@ -529,7 +529,7 @@ class UpdateTaskAttachmentsAccTest extends AbstractAccTest {
|
|||
taskService.getTask(
|
||||
"TKI:000000000000000000000000000000000000"); // class T2000, prio 1, SL P1D
|
||||
attachment =
|
||||
createAttachment(
|
||||
createExampleAttachment(
|
||||
"DOCTYPE_DEFAULT", // prio 99, SL P2000D
|
||||
createObjectReference(
|
||||
"COMPANY_A",
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
package acceptance.user;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import acceptance.AbstractAccTest;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.stream.Stream;
|
||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||
import org.junit.jupiter.api.DynamicTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestFactory;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.function.ThrowingConsumer;
|
||||
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.MismatchedRoleException;
|
||||
import pro.taskana.common.test.security.JaasExtension;
|
||||
import pro.taskana.common.test.security.WithAccessId;
|
||||
import pro.taskana.user.api.UserService;
|
||||
import pro.taskana.user.api.exceptions.UserAlreadyExistException;
|
||||
import pro.taskana.user.api.exceptions.UserNotFoundException;
|
||||
import pro.taskana.user.api.models.User;
|
||||
|
||||
/** Acceptance test which tests the functionality of the UserService. */
|
||||
@ExtendWith(JaasExtension.class)
|
||||
class UserServiceAccTest extends AbstractAccTest {
|
||||
private static final UserService USER_SERVICE = taskanaEngine.getUserService();
|
||||
|
||||
@WithAccessId(user = "user-1-2")
|
||||
@Test
|
||||
void should_ReturnUserWithAllFields_When_IdExisting() throws Exception {
|
||||
User user = USER_SERVICE.getUser("teamlead-1");
|
||||
|
||||
assertThat(user.getFirstName()).isEqualTo("Titus");
|
||||
assertThat(user.getLastName()).isEqualTo("Toll");
|
||||
assertThat(user.getFullName()).isEqualTo("Toll, Titus");
|
||||
assertThat(user.getLongName()).isEqualTo("Toll, Titus - (teamlead-1)");
|
||||
assertThat(user.getEmail()).isEqualTo("titus.toll@web.de");
|
||||
assertThat(user.getPhone()).isEqualTo("040-2951854");
|
||||
assertThat(user.getMobilePhone()).isEqualTo("015637683197");
|
||||
assertThat(user.getOrgLevel4()).isEqualTo("Novatec");
|
||||
assertThat(user.getOrgLevel3()).isEqualTo("BPM");
|
||||
assertThat(user.getOrgLevel2()).isEqualTo("Human Workflow");
|
||||
assertThat(user.getOrgLevel1()).isEqualTo("TASKANA");
|
||||
assertThat(user.getData()).isEqualTo("xy");
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-2")
|
||||
@Test
|
||||
void should_ThrowUserNotFoundException_When_TryingToGetUserWithNonExistingId() {
|
||||
ThrowingCallable callable = () -> USER_SERVICE.getUser("NOT_EXISTING");
|
||||
assertThatThrownBy(callable)
|
||||
.isInstanceOf(UserNotFoundException.class)
|
||||
.hasMessage("User with id 'NOT_EXISTING' was not found.");
|
||||
}
|
||||
|
||||
@WithAccessId(user = "admin")
|
||||
@Test
|
||||
void should_InsertUserInDatabase_When_CreatingUser() throws Exception {
|
||||
User userToCreate = createExampleUser("user-10-20");
|
||||
|
||||
USER_SERVICE.createUser(userToCreate);
|
||||
User userInDatabse = USER_SERVICE.getUser(userToCreate.getId());
|
||||
|
||||
assertThat(userToCreate)
|
||||
.hasNoNullFieldsOrProperties()
|
||||
.isNotSameAs(userInDatabse)
|
||||
.isEqualTo(userInDatabse);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "admin")
|
||||
@Test
|
||||
void should_SetTheLongAndFullNameAccordingToRules_When_CreatingUserWithThoseFieldsEmpty()
|
||||
throws Exception {
|
||||
User userToCreate = createExampleUser("user-10-21");
|
||||
userToCreate.setLongName(null);
|
||||
userToCreate.setFullName(null);
|
||||
|
||||
String fullName = userToCreate.getLastName() + ", " + userToCreate.getFirstName();
|
||||
String longName =
|
||||
userToCreate.getLastName()
|
||||
+ ", "
|
||||
+ userToCreate.getFirstName()
|
||||
+ " - ("
|
||||
+ userToCreate.getId()
|
||||
+ ")";
|
||||
|
||||
User createdUser = USER_SERVICE.createUser(userToCreate);
|
||||
assertThat(createdUser.getLongName()).isEqualTo(longName);
|
||||
assertThat(createdUser.getFullName()).isEqualTo(fullName);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "admin")
|
||||
@Test
|
||||
void should_ThrowInvalidArgumentException_When_TryingToCreateUserWithFirstOrLastNameNull()
|
||||
throws Exception {
|
||||
User userToCreate = createExampleUser("user-10-20");
|
||||
userToCreate.setFirstName(null);
|
||||
|
||||
ThrowingCallable callable = () -> USER_SERVICE.createUser(userToCreate);
|
||||
assertThatThrownBy(callable)
|
||||
.isInstanceOf(InvalidArgumentException.class)
|
||||
.hasMessage("First and last name of User must be set or empty.");
|
||||
|
||||
userToCreate.setFirstName("xy");
|
||||
userToCreate.setLastName(null);
|
||||
callable = () -> USER_SERVICE.createUser(userToCreate);
|
||||
assertThatThrownBy(callable).isInstanceOf(InvalidArgumentException.class);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "admin")
|
||||
@TestFactory
|
||||
Stream<DynamicTest> should_ThrowInvalidArgumentException_When_TryingToCreateUserWithNotSetId()
|
||||
throws Exception {
|
||||
Iterator<String> iterator = Arrays.asList("", null).iterator();
|
||||
|
||||
ThrowingConsumer<String> test =
|
||||
userId -> {
|
||||
User userToCreate = createExampleUser("user-10-20");
|
||||
userToCreate.setId(userId);
|
||||
ThrowingCallable callable = () -> USER_SERVICE.createUser(userToCreate);
|
||||
assertThatThrownBy(callable)
|
||||
.isInstanceOf(InvalidArgumentException.class)
|
||||
.hasMessage("UserId must not be empty when creating User.");
|
||||
};
|
||||
|
||||
return DynamicTest.stream(iterator, c -> "for " + c, test);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "admin")
|
||||
@Test
|
||||
void should_ThrowUserAlreadyExistException_When_TryingToCreateUserWithExistingId() {
|
||||
User userToCreate = createExampleUser("teamlead-1"); // existing userId
|
||||
|
||||
ThrowingCallable callable = () -> USER_SERVICE.createUser(userToCreate);
|
||||
assertThatThrownBy(callable)
|
||||
.isInstanceOf(UserAlreadyExistException.class)
|
||||
.hasMessage("User with id 'teamlead-1' already exists.");
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-2")
|
||||
@Test
|
||||
void should_ThrowNotAuthorizedException_When_TryingToCreateUserWithoutAdminRole() {
|
||||
User userToCreate = createExampleUser("user-10-22");
|
||||
|
||||
ThrowingCallable callable = () -> USER_SERVICE.createUser(userToCreate);
|
||||
assertThatThrownBy(callable)
|
||||
.isInstanceOf(MismatchedRoleException.class)
|
||||
.hasMessage(
|
||||
"Not authorized. The current user 'user-1-2' is not member of role(s) "
|
||||
+ "'[BUSINESS_ADMIN, ADMIN]'.");
|
||||
}
|
||||
|
||||
@WithAccessId(user = "admin")
|
||||
@Test
|
||||
void should_UpdateUserInDatabase_When_IdExisting() throws Exception {
|
||||
User userToUpdate = createExampleUser("teamlead-1"); // existing userId
|
||||
|
||||
USER_SERVICE.updateUser(userToUpdate);
|
||||
User userInDatabase = USER_SERVICE.getUser("teamlead-1");
|
||||
|
||||
assertThat(userToUpdate)
|
||||
.hasNoNullFieldsOrProperties()
|
||||
.isNotSameAs(userInDatabase)
|
||||
.isEqualTo(userInDatabase);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "admin")
|
||||
@Test
|
||||
void should_ThrowUserNotFoundException_When_TryingToUpdateUserWithNonExistingId() {
|
||||
User userToUpdate = createExampleUser("NOT_EXISTING");
|
||||
|
||||
ThrowingCallable callable = () -> USER_SERVICE.updateUser(userToUpdate);
|
||||
assertThatThrownBy(callable)
|
||||
.isInstanceOf(UserNotFoundException.class)
|
||||
.hasMessage("User with id 'NOT_EXISTING' was not found.");
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-2")
|
||||
@Test
|
||||
void should_ThrowNotAuthorizedException_When_TryingToUpdateUserWithNoAdminRole() {
|
||||
User userToUpdate = createExampleUser("teamlead-1"); // existing userId
|
||||
|
||||
ThrowingCallable callable = () -> USER_SERVICE.updateUser(userToUpdate);
|
||||
assertThatThrownBy(callable)
|
||||
.isInstanceOf(MismatchedRoleException.class)
|
||||
.hasMessage(
|
||||
"Not authorized. The current user 'user-1-2' is not member of role(s) "
|
||||
+ "'[BUSINESS_ADMIN, ADMIN]'.");
|
||||
}
|
||||
|
||||
@WithAccessId(user = "admin")
|
||||
@Test
|
||||
void should_DeleteUserFromDatabase_When_IdExisting() throws Exception {
|
||||
String id = "teamlead-1";
|
||||
USER_SERVICE.getUser(id); // User existing
|
||||
|
||||
USER_SERVICE.deleteUser(id);
|
||||
ThrowingCallable callable = () -> USER_SERVICE.getUser(id); // User deleted
|
||||
assertThatThrownBy(callable).isInstanceOf(UserNotFoundException.class);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "admin")
|
||||
@Test
|
||||
void should_ThrowUserNotFoundException_When_TryingToDeleteUserWithNonExistingId() {
|
||||
ThrowingCallable callable = () -> USER_SERVICE.deleteUser("NOT_EXISTING");
|
||||
assertThatThrownBy(callable)
|
||||
.isInstanceOf(UserNotFoundException.class)
|
||||
.hasMessage("User with id 'NOT_EXISTING' was not found.");
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-2")
|
||||
@Test
|
||||
void should_ThrowNotAuthorizedException_When_TryingToDeleteUserWithNoAdminRole() {
|
||||
ThrowingCallable callable = () -> USER_SERVICE.deleteUser("teamlead-1");
|
||||
assertThatThrownBy(callable)
|
||||
.isInstanceOf(MismatchedRoleException.class)
|
||||
.hasMessage(
|
||||
"Not authorized. The current user 'user-1-2' is not member of role(s) "
|
||||
+ "'[BUSINESS_ADMIN, ADMIN]'.");
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ import pro.taskana.SpringTaskanaEngineConfiguration;
|
|||
import pro.taskana.classification.api.ClassificationService;
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.user.api.UserService;
|
||||
import pro.taskana.workbasket.api.WorkbasketService;
|
||||
|
||||
/** Class to set /load configuration for Taskana Library. */
|
||||
|
@ -73,6 +74,11 @@ public class TaskanaConfig {
|
|||
return taskanaEngine.getClassificationService();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public UserService userService(TaskanaEngine taskanaEngine) {
|
||||
return taskanaEngine.getUserService();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ExampleBootstrap exampleBootstrap() {
|
||||
return new ExampleBootstrap();
|
||||
|
|
|
@ -42,12 +42,14 @@ Additionally, an optional set of message variables, containing some technical in
|
|||
| *404 NOT_FOUND* | TASK_NOT_FOUND | taskId
|
||||
| *404 NOT_FOUND* | WORKBASKET_WITH_ID_NOT_FOUND | workbasketId
|
||||
| *404 NOT_FOUND* | WORKBASKET_WITH_KEY_NOT_FOUND | workbasketKey, domain
|
||||
| *404 NOT_FOUND* | USER_NOT_FOUND | userId
|
||||
| *409 CONFLICT* | ATTACHMENT_ALREADY_EXISTS | attachmentId, taskId
|
||||
| *409 CONFLICT* | CLASSIFICATION_ALREADY_EXISTS | classificationKey, domain
|
||||
| *409 CONFLICT* | ENTITY_NOT_UP_TO_DATE | entityId
|
||||
| *409 CONFLICT* | TASK_ALREADY_EXISTS | externalTaskId
|
||||
| *409 CONFLICT* | WORKBASKET_ACCESS_ITEM_ALREADY_EXISTS | accessId, workbasketId
|
||||
| *409 CONFLICT* | WORKBASKET_ALREADY_EXISTS | workbasketKey, domain
|
||||
| *409 CONFLICT* | USER_ALREADY_EXISTS | userID
|
||||
| *413 PAYLOAD_TOO_LARGE* | PAYLOAD_TOO_LARGE |
|
||||
| *423 LOCKED* | CLASSIFICATION_IN_USE | classificationKey, domain
|
||||
| *423 LOCKED* | WORKBASKET_IN_USE | workbasketId
|
||||
|
@ -152,6 +154,13 @@ include::{snippets}/AccessIdControllerRestDocTest/searchForAccessIdDocTest/auto-
|
|||
include::{snippets}/AccessIdControllerRestDocTest/getGroupsForAccessIdDocTest/auto-section.adoc[]
|
||||
include::{snippets}/AccessIdControllerRestDocTest/searchUsersByNameOrAccessIdForRoleTest/auto-section.adoc[]
|
||||
|
||||
== User Resource
|
||||
|
||||
include::{snippets}/UserControllerRestDocTest/getUserDocTest/auto-section.adoc[]
|
||||
include::{snippets}/UserControllerRestDocTest/createUserDocTest/auto-section.adoc[]
|
||||
include::{snippets}/UserControllerRestDocTest/updateUserDocTest/auto-section.adoc[]
|
||||
include::{snippets}/UserControllerRestDocTest/deleteUserDocTest/auto-section.adoc[]
|
||||
|
||||
== Configuration Resources
|
||||
|
||||
include::{snippets}/TaskanaEngineControllerRestDocTest/getAllDomainsDocTest/auto-section.adoc[]
|
||||
|
|
|
@ -18,6 +18,7 @@ import pro.taskana.classification.api.ClassificationService;
|
|||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.monitor.api.MonitorService;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.user.api.UserService;
|
||||
import pro.taskana.workbasket.api.WorkbasketService;
|
||||
|
||||
/** Configuration for REST service. */
|
||||
|
@ -52,6 +53,11 @@ public class RestConfiguration {
|
|||
return taskanaEngine.getWorkbasketService();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public UserService getUserService(TaskanaEngine taskanaEngine) {
|
||||
return taskanaEngine.getUserService();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(TaskanaEngine.class)
|
||||
public TaskanaEngine getTaskanaEngine(TaskanaEngineConfiguration taskanaEngineConfiguration)
|
||||
|
|
|
@ -69,5 +69,9 @@ public final class RestEndpoints {
|
|||
public static final String URL_MONITOR_TASK_STATUS_REPORT = API_V1 + "monitor/task-status-report";
|
||||
public static final String URL_MONITOR_TIMESTAMP_REPORT = API_V1 + "monitor/timestamp-report";
|
||||
|
||||
// user endpoints
|
||||
public static final String URL_USERS = API_V1 + "users";
|
||||
public static final String URL_USERS_ID = API_V1 + "users/{userId}";
|
||||
|
||||
private RestEndpoints() {}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@ import pro.taskana.task.api.exceptions.MismatchedTaskCommentCreatorException;
|
|||
import pro.taskana.task.api.exceptions.TaskAlreadyExistException;
|
||||
import pro.taskana.task.api.exceptions.TaskCommentNotFoundException;
|
||||
import pro.taskana.task.api.exceptions.TaskNotFoundException;
|
||||
import pro.taskana.user.api.exceptions.UserAlreadyExistException;
|
||||
import pro.taskana.user.api.exceptions.UserNotFoundException;
|
||||
import pro.taskana.workbasket.api.exceptions.MismatchedWorkbasketPermissionException;
|
||||
import pro.taskana.workbasket.api.exceptions.NotAuthorizedToQueryWorkbasketException;
|
||||
import pro.taskana.workbasket.api.exceptions.WorkbasketAccessItemAlreadyExistException;
|
||||
|
@ -81,7 +83,8 @@ public class TaskanaRestExceptionHandler extends ResponseEntityExceptionHandler
|
|||
TaskCommentNotFoundException.class,
|
||||
TaskNotFoundException.class,
|
||||
TaskanaHistoryEventNotFoundException.class,
|
||||
WorkbasketNotFoundException.class
|
||||
WorkbasketNotFoundException.class,
|
||||
UserNotFoundException.class
|
||||
})
|
||||
protected ResponseEntity<Object> handleNotFound(TaskanaException ex, WebRequest req) {
|
||||
return buildResponse(ex.getErrorCode(), ex, req, HttpStatus.NOT_FOUND);
|
||||
|
@ -93,6 +96,7 @@ public class TaskanaRestExceptionHandler extends ResponseEntityExceptionHandler
|
|||
ConcurrencyException.class,
|
||||
WorkbasketAlreadyExistException.class,
|
||||
WorkbasketAccessItemAlreadyExistException.class,
|
||||
UserAlreadyExistException.class,
|
||||
AttachmentPersistenceException.class,
|
||||
WorkbasketMarkedForDeletionException.class
|
||||
})
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
package pro.taskana.user.rest;
|
||||
|
||||
import static pro.taskana.common.rest.RestEndpoints.URL_USERS_ID;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.common.rest.RestEndpoints;
|
||||
import pro.taskana.user.api.UserService;
|
||||
import pro.taskana.user.api.exceptions.UserAlreadyExistException;
|
||||
import pro.taskana.user.api.exceptions.UserNotFoundException;
|
||||
import pro.taskana.user.api.models.User;
|
||||
import pro.taskana.user.rest.assembler.UserRepresentationModelAssembler;
|
||||
import pro.taskana.user.rest.models.UserRepresentationModel;
|
||||
|
||||
/** Controller for all {@linkplain User} related endpoints. */
|
||||
@RestController
|
||||
@EnableHypermediaSupport(type = HypermediaType.HAL)
|
||||
public class UserController {
|
||||
private final UserService userService;
|
||||
private final UserRepresentationModelAssembler assembler;
|
||||
|
||||
@Autowired
|
||||
UserController(UserService userService, UserRepresentationModelAssembler assembler) {
|
||||
this.userService = userService;
|
||||
this.assembler = assembler;
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint retrieves a User.
|
||||
*
|
||||
* @title Get a User
|
||||
* @param userId the id of the requested User
|
||||
* @return the requested User
|
||||
* @throws UserNotFoundException if the id has not been found
|
||||
*/
|
||||
@GetMapping(URL_USERS_ID)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<UserRepresentationModel> getUser(@PathVariable String userId)
|
||||
throws UserNotFoundException {
|
||||
User user = userService.getUser(userId);
|
||||
|
||||
return ResponseEntity.ok(assembler.toModel(user));
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint creates a User.
|
||||
*
|
||||
* @title Create a User
|
||||
* @param repModel the User which should be created
|
||||
* @return the inserted User
|
||||
* @throws InvalidArgumentException if the id has not been set
|
||||
* @throws UserAlreadyExistException if a User with id } is already existing
|
||||
* @throws NotAuthorizedException if the current user is no admin or business-admin
|
||||
*/
|
||||
@PostMapping(RestEndpoints.URL_USERS)
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseEntity<UserRepresentationModel> createUser(
|
||||
@RequestBody UserRepresentationModel repModel)
|
||||
throws InvalidArgumentException, UserAlreadyExistException, NotAuthorizedException {
|
||||
User user = assembler.toEntityModel(repModel);
|
||||
user = userService.createUser(user);
|
||||
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(assembler.toModel(user));
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint updates a User.
|
||||
*
|
||||
* @title Update a User
|
||||
* @param userId the id of the User to update
|
||||
* @param repModel the User with the updated fields
|
||||
* @return the updated User
|
||||
* @throws InvalidArgumentException if the id has not been set
|
||||
* @throws UserNotFoundException if a User with id is not existing in the database
|
||||
* @throws NotAuthorizedException if the current user is no admin or business-admin
|
||||
*/
|
||||
@PutMapping(URL_USERS_ID)
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseEntity<UserRepresentationModel> updateUser(
|
||||
@PathVariable(value = "userId") String userId, @RequestBody UserRepresentationModel repModel)
|
||||
throws InvalidArgumentException, UserNotFoundException, NotAuthorizedException {
|
||||
if (!userId.equals(repModel.getUserId())) {
|
||||
throw new InvalidArgumentException(
|
||||
String.format(
|
||||
"UserId '%s' of the URI is not identical"
|
||||
+ " with the userId '%s' of the object in the payload.",
|
||||
userId, repModel.getUserId()));
|
||||
}
|
||||
User user = assembler.toEntityModel(repModel);
|
||||
user = userService.updateUser(user);
|
||||
|
||||
return ResponseEntity.ok(assembler.toModel(user));
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint deletes a User.
|
||||
*
|
||||
* @title Delete a User
|
||||
* @param userId the id of the User to delete
|
||||
* @return no content
|
||||
* @throws UserNotFoundException if the id has not been found
|
||||
* @throws NotAuthorizedException if the current user is no admin or business-admin
|
||||
*/
|
||||
@DeleteMapping(URL_USERS_ID)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<UserRepresentationModel> deleteUser(@PathVariable String userId)
|
||||
throws UserNotFoundException, NotAuthorizedException {
|
||||
userService.deleteUser(userId);
|
||||
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package pro.taskana.user.rest.assembler;
|
||||
|
||||
import org.springframework.hateoas.server.RepresentationModelAssembler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import pro.taskana.user.api.models.User;
|
||||
import pro.taskana.user.internal.models.UserImpl;
|
||||
import pro.taskana.user.rest.models.UserRepresentationModel;
|
||||
|
||||
/**
|
||||
* The assembler transforms a {@link User} to its resource counterpart {@linkplain
|
||||
* UserRepresentationModel} and vice versa.
|
||||
*/
|
||||
@Component
|
||||
public class UserRepresentationModelAssembler
|
||||
implements RepresentationModelAssembler<User, UserRepresentationModel> {
|
||||
|
||||
@Override
|
||||
public UserRepresentationModel toModel(User entity) {
|
||||
UserRepresentationModel repModel = new UserRepresentationModel();
|
||||
repModel.setUserId(entity.getId());
|
||||
repModel.setFirstName(entity.getFirstName());
|
||||
repModel.setLastName(entity.getLastName());
|
||||
repModel.setFullName(entity.getFullName());
|
||||
repModel.setLongName(entity.getLongName());
|
||||
repModel.setEmail(entity.getEmail());
|
||||
repModel.setPhone(entity.getPhone());
|
||||
repModel.setMobilePhone(entity.getMobilePhone());
|
||||
repModel.setOrgLevel4(entity.getOrgLevel4());
|
||||
repModel.setOrgLevel3(entity.getOrgLevel3());
|
||||
repModel.setOrgLevel2(entity.getOrgLevel2());
|
||||
repModel.setOrgLevel1(entity.getOrgLevel1());
|
||||
repModel.setData(entity.getData());
|
||||
|
||||
return repModel;
|
||||
}
|
||||
|
||||
public User toEntityModel(UserRepresentationModel repModel) {
|
||||
UserImpl user = new UserImpl();
|
||||
user.setId(repModel.getUserId());
|
||||
user.setFirstName(repModel.getFirstName());
|
||||
user.setLastName(repModel.getLastName());
|
||||
user.setFullName(repModel.getFullName());
|
||||
user.setLongName(repModel.getLongName());
|
||||
user.setEmail(repModel.getEmail());
|
||||
user.setPhone(repModel.getPhone());
|
||||
user.setMobilePhone(repModel.getMobilePhone());
|
||||
user.setOrgLevel4(repModel.getOrgLevel4());
|
||||
user.setOrgLevel3(repModel.getOrgLevel3());
|
||||
user.setOrgLevel2(repModel.getOrgLevel2());
|
||||
user.setOrgLevel1(repModel.getOrgLevel1());
|
||||
user.setData(repModel.getData());
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
package pro.taskana.user.rest.models;
|
||||
|
||||
import java.util.Objects;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.springframework.hateoas.RepresentationModel;
|
||||
|
||||
import pro.taskana.user.api.models.User;
|
||||
|
||||
/** The entityModel class for {@linkplain User}. */
|
||||
public class UserRepresentationModel extends RepresentationModel<UserRepresentationModel> {
|
||||
|
||||
/** Unique Id. */
|
||||
@NotNull protected String userId;
|
||||
/** The first name of the User. */
|
||||
protected String firstName;
|
||||
/** The last name of the User. */
|
||||
protected String lastName;
|
||||
/** The full name of the User. */
|
||||
protected String fullName;
|
||||
/** The long name of the User. */
|
||||
protected String longName;
|
||||
/** The email of the User. */
|
||||
protected String email;
|
||||
/** The phone number of the User. */
|
||||
protected String phone;
|
||||
/** The mobile phone number of the User. */
|
||||
protected String mobilePhone;
|
||||
/** The fourth organisation level of the User. */
|
||||
protected String orgLevel4;
|
||||
/** The third organisation level of the User. */
|
||||
protected String orgLevel3;
|
||||
/** The second organisation level of the User. */
|
||||
protected String orgLevel2;
|
||||
/** The first organisation level of the User. */
|
||||
protected String orgLevel1;
|
||||
/** The data of the User. This field is used for additional information about the User. */
|
||||
protected String data;
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String id) {
|
||||
this.userId = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public void setFullName(String fullName) {
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public String getLongName() {
|
||||
return longName;
|
||||
}
|
||||
|
||||
public void setLongName(String longName) {
|
||||
this.longName = longName;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public String getMobilePhone() {
|
||||
return mobilePhone;
|
||||
}
|
||||
|
||||
public void setMobilePhone(String mobilePhone) {
|
||||
this.mobilePhone = mobilePhone;
|
||||
}
|
||||
|
||||
public String getOrgLevel4() {
|
||||
return orgLevel4;
|
||||
}
|
||||
|
||||
public void setOrgLevel4(String orgLevel4) {
|
||||
this.orgLevel4 = orgLevel4;
|
||||
}
|
||||
|
||||
public String getOrgLevel3() {
|
||||
return orgLevel3;
|
||||
}
|
||||
|
||||
public void setOrgLevel3(String orgLevel3) {
|
||||
this.orgLevel3 = orgLevel3;
|
||||
}
|
||||
|
||||
public String getOrgLevel2() {
|
||||
return orgLevel2;
|
||||
}
|
||||
|
||||
public void setOrgLevel2(String orgLevel2) {
|
||||
this.orgLevel2 = orgLevel2;
|
||||
}
|
||||
|
||||
public String getOrgLevel1() {
|
||||
return orgLevel1;
|
||||
}
|
||||
|
||||
public void setOrgLevel1(String orgLevel1) {
|
||||
this.orgLevel1 = orgLevel1;
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(
|
||||
super.hashCode(),
|
||||
userId,
|
||||
firstName,
|
||||
lastName,
|
||||
fullName,
|
||||
longName,
|
||||
email,
|
||||
phone,
|
||||
mobilePhone,
|
||||
orgLevel4,
|
||||
orgLevel3,
|
||||
orgLevel2,
|
||||
orgLevel1,
|
||||
data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
if (!super.equals(obj)) {
|
||||
return false;
|
||||
}
|
||||
UserRepresentationModel other = (UserRepresentationModel) obj;
|
||||
return userId.equals(other.userId)
|
||||
&& Objects.equals(firstName, other.firstName)
|
||||
&& Objects.equals(lastName, other.lastName)
|
||||
&& Objects.equals(fullName, other.fullName)
|
||||
&& Objects.equals(longName, other.longName)
|
||||
&& Objects.equals(email, other.email)
|
||||
&& Objects.equals(phone, other.phone)
|
||||
&& Objects.equals(mobilePhone, other.mobilePhone)
|
||||
&& Objects.equals(orgLevel4, other.orgLevel4)
|
||||
&& Objects.equals(orgLevel3, other.orgLevel3)
|
||||
&& Objects.equals(orgLevel2, other.orgLevel2)
|
||||
&& Objects.equals(orgLevel1, other.orgLevel1)
|
||||
&& Objects.equals(data, other.data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
package pro.taskana.user.rest;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static pro.taskana.common.test.rest.RestHelper.TEMPLATE;
|
||||
|
||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.HttpStatusCodeException;
|
||||
|
||||
import pro.taskana.common.rest.RestEndpoints;
|
||||
import pro.taskana.common.test.rest.RestHelper;
|
||||
import pro.taskana.common.test.rest.TaskanaSpringBootTest;
|
||||
import pro.taskana.user.rest.models.UserRepresentationModel;
|
||||
|
||||
/** Tests the endpoints of the UserController. */
|
||||
@TaskanaSpringBootTest
|
||||
class UserControllerIntTest {
|
||||
private final RestHelper restHelper;
|
||||
|
||||
@Autowired
|
||||
UserControllerIntTest(RestHelper restHelper) {
|
||||
this.restHelper = restHelper;
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_ReturnExistingUser_When_CallingGetEndpoint() throws Exception {
|
||||
String url = restHelper.toUrl(RestEndpoints.URL_USERS_ID, "teamlead-1");
|
||||
HttpEntity<?> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||
|
||||
ResponseEntity<UserRepresentationModel> responseEntity =
|
||||
TEMPLATE.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
auth,
|
||||
ParameterizedTypeReference.forType(UserRepresentationModel.class));
|
||||
assertThat(responseEntity.getBody()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_CreateValidUser_When_CallingCreateEndpoint() throws Exception {
|
||||
UserRepresentationModel newUser = new UserRepresentationModel();
|
||||
newUser.setUserId("12345");
|
||||
newUser.setFirstName("Hans");
|
||||
newUser.setLastName("Georg");
|
||||
newUser.setFullName("Georg, Hans");
|
||||
newUser.setLongName("Georg, Hans - (12345)");
|
||||
newUser.setEmail("hans.georg@web.com");
|
||||
newUser.setMobilePhone("017325862");
|
||||
|
||||
String url = restHelper.toUrl(RestEndpoints.URL_USERS);
|
||||
HttpEntity<?> auth = new HttpEntity<>(newUser, RestHelper.generateHeadersForUser("teamlead-1"));
|
||||
|
||||
ResponseEntity<UserRepresentationModel> responseEntity =
|
||||
TEMPLATE.exchange(
|
||||
url,
|
||||
HttpMethod.POST,
|
||||
auth,
|
||||
ParameterizedTypeReference.forType(UserRepresentationModel.class));
|
||||
assertThat(responseEntity).isNotNull();
|
||||
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.CREATED);
|
||||
|
||||
url = restHelper.toUrl(RestEndpoints.URL_USERS_ID, "12345");
|
||||
auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||
|
||||
responseEntity =
|
||||
TEMPLATE.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
auth,
|
||||
ParameterizedTypeReference.forType(UserRepresentationModel.class));
|
||||
assertThat(responseEntity.getBody()).isNotNull();
|
||||
assertThat(responseEntity.getBody()).isEqualTo(newUser);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_UpdateExistingUser_When_CallingUpdateEndpoint() throws Exception {
|
||||
String url = restHelper.toUrl(RestEndpoints.URL_USERS_ID, "teamlead-1");
|
||||
HttpEntity<?> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||
|
||||
ResponseEntity<UserRepresentationModel> responseEntity =
|
||||
TEMPLATE.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
auth,
|
||||
ParameterizedTypeReference.forType(UserRepresentationModel.class));
|
||||
assertThat(responseEntity.getBody()).isNotNull();
|
||||
|
||||
UserRepresentationModel model = responseEntity.getBody();
|
||||
model.setLastName("Mueller");
|
||||
|
||||
auth = new HttpEntity<>(model, RestHelper.generateHeadersForUser("teamlead-1"));
|
||||
responseEntity =
|
||||
TEMPLATE.exchange(
|
||||
url,
|
||||
HttpMethod.PUT,
|
||||
auth,
|
||||
ParameterizedTypeReference.forType(UserRepresentationModel.class));
|
||||
|
||||
assertThat(responseEntity.getBody()).isNotNull();
|
||||
assertThat(responseEntity.getBody().getLastName()).isEqualTo("Mueller");
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_DeleteExistingUser_When_CallingDeleteEndpoint() {
|
||||
String url = restHelper.toUrl(RestEndpoints.URL_USERS_ID, "user-1-1");
|
||||
HttpEntity<?> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||
|
||||
ResponseEntity<UserRepresentationModel> responseEntity =
|
||||
TEMPLATE.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
auth,
|
||||
ParameterizedTypeReference.forType(UserRepresentationModel.class));
|
||||
assertThat(responseEntity.getBody()).isNotNull();
|
||||
assertThat(responseEntity.getBody().getUserId()).isEqualTo("user-1-1");
|
||||
|
||||
responseEntity =
|
||||
TEMPLATE.exchange(
|
||||
url,
|
||||
HttpMethod.DELETE,
|
||||
auth,
|
||||
ParameterizedTypeReference.forType(UserRepresentationModel.class));
|
||||
assertThat(responseEntity.getBody()).isNull();
|
||||
|
||||
ThrowingCallable httpCall =
|
||||
() ->
|
||||
TEMPLATE.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
auth,
|
||||
ParameterizedTypeReference.forType(UserRepresentationModel.class));
|
||||
assertThatThrownBy(httpCall)
|
||||
.isInstanceOf(HttpStatusCodeException.class)
|
||||
.extracting(HttpStatusCodeException.class::cast)
|
||||
.extracting(HttpStatusCodeException::getStatusCode)
|
||||
.isEqualTo(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package pro.taskana.user.rest;
|
||||
|
||||
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
|
||||
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
|
||||
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
|
||||
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.put;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
|
||||
|
||||
import pro.taskana.common.rest.RestEndpoints;
|
||||
import pro.taskana.common.test.BaseRestDocTest;
|
||||
import pro.taskana.user.api.UserService;
|
||||
import pro.taskana.user.api.models.User;
|
||||
import pro.taskana.user.rest.assembler.UserRepresentationModelAssembler;
|
||||
import pro.taskana.user.rest.models.UserRepresentationModel;
|
||||
|
||||
class UserControllerRestDocTest extends BaseRestDocTest {
|
||||
@Autowired UserRepresentationModelAssembler assembler;
|
||||
@Autowired UserService userService;
|
||||
|
||||
@Test
|
||||
void getUserDocTest() throws Exception {
|
||||
mockMvc
|
||||
.perform(get(RestEndpoints.URL_USERS_ID, "teamlead-1"))
|
||||
.andExpect(MockMvcResultMatchers.status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
void createUserDocTest() throws Exception {
|
||||
User user = userService.newUser();
|
||||
user.setId("user-10-2");
|
||||
user.setFirstName("Hans");
|
||||
user.setLastName("Georg");
|
||||
UserRepresentationModel repModel = assembler.toModel(user);
|
||||
|
||||
mockMvc
|
||||
.perform(post(RestEndpoints.URL_USERS).content(objectMapper.writeValueAsString(repModel)))
|
||||
.andExpect(MockMvcResultMatchers.status().isCreated());
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateUserDocTest() throws Exception {
|
||||
User user = userService.getUser("teamlead-1");
|
||||
user.setFirstName("new name");
|
||||
UserRepresentationModel repModel = assembler.toModel(user);
|
||||
|
||||
mockMvc
|
||||
.perform(
|
||||
put(RestEndpoints.URL_USERS_ID, "teamlead-1")
|
||||
.content(objectMapper.writeValueAsString(repModel)))
|
||||
.andExpect(MockMvcResultMatchers.status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteUserDocTest() throws Exception {
|
||||
mockMvc
|
||||
.perform(delete(RestEndpoints.URL_USERS_ID, "user-1-1"))
|
||||
.andExpect(MockMvcResultMatchers.status().isNoContent());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
package pro.taskana.user.rest.assembler;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import pro.taskana.common.test.rest.TaskanaSpringBootTest;
|
||||
import pro.taskana.user.api.UserService;
|
||||
import pro.taskana.user.api.models.User;
|
||||
import pro.taskana.user.rest.models.UserRepresentationModel;
|
||||
|
||||
/** Test for {@linkplain UserRepresentationModelAssembler}. */
|
||||
@TaskanaSpringBootTest
|
||||
class UserRepresentationModelAssemblerTest {
|
||||
private final UserRepresentationModelAssembler assembler;
|
||||
private final UserService userService;
|
||||
|
||||
@Autowired
|
||||
UserRepresentationModelAssemblerTest(
|
||||
UserRepresentationModelAssembler assembler, UserService userService) {
|
||||
this.assembler = assembler;
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_ReturnRepresentationModel_When_ConvertingUserEntityToRepresentationModel() {
|
||||
User user = userService.newUser();
|
||||
user.setId("user-1-2");
|
||||
user.setFirstName("Hans");
|
||||
user.setLastName("Georg");
|
||||
user.setFullName("Hans Georg");
|
||||
user.setLongName("Georg, Hans - user-1-2");
|
||||
user.setEmail("hans.georg@web.com");
|
||||
user.setPhone("1234");
|
||||
user.setMobilePhone("01574275632");
|
||||
user.setOrgLevel4("Novatec");
|
||||
user.setOrgLevel3("BPM");
|
||||
user.setOrgLevel2("Human Workflow");
|
||||
user.setOrgLevel1("TASKANA");
|
||||
user.setData("xy");
|
||||
|
||||
UserRepresentationModel repModel = assembler.toModel(user);
|
||||
testEquality(user, repModel);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_ReturnEntity_When_ConvertingUserRepresentationModelToEntity() {
|
||||
UserRepresentationModel repModel = new UserRepresentationModel();
|
||||
repModel.setUserId("user-1-2");
|
||||
repModel.setFirstName("Hans");
|
||||
repModel.setLastName("Georg");
|
||||
repModel.setFullName("Hans Georg");
|
||||
repModel.setLongName("Georg, Hans - user-1-2");
|
||||
repModel.setEmail("hans.georg@web.com");
|
||||
repModel.setPhone("1234");
|
||||
repModel.setMobilePhone("01574275632");
|
||||
repModel.setOrgLevel4("Novatec");
|
||||
repModel.setOrgLevel3("BPM");
|
||||
repModel.setOrgLevel2("Human Workflow");
|
||||
repModel.setOrgLevel1("TASKANA");
|
||||
repModel.setData("xy");
|
||||
|
||||
User user = assembler.toEntityModel(repModel);
|
||||
testEquality(user, repModel);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_BeEqual_When_ConvertingEntityToRepModelAndBackToEntity() {
|
||||
User user = userService.newUser();
|
||||
user.setId("user-1-2");
|
||||
user.setFirstName("Hans");
|
||||
user.setLastName("Georg");
|
||||
user.setFullName("Hans Georg");
|
||||
user.setLongName("Georg, Hans - user-1-2");
|
||||
user.setEmail("hans.georg@web.com");
|
||||
user.setPhone("1234");
|
||||
user.setMobilePhone("01574275632");
|
||||
user.setOrgLevel4("Novatec");
|
||||
user.setOrgLevel3("BPM");
|
||||
user.setOrgLevel2("Human Workflow");
|
||||
user.setOrgLevel1("TASKANA");
|
||||
user.setData("xy");
|
||||
|
||||
UserRepresentationModel repModel = assembler.toModel(user);
|
||||
User userAfterConversion = assembler.toEntityModel(repModel);
|
||||
|
||||
assertThat(user)
|
||||
.hasNoNullFieldsOrProperties()
|
||||
.isNotSameAs(userAfterConversion)
|
||||
.isEqualTo(userAfterConversion);
|
||||
}
|
||||
|
||||
private static void testEquality(User entity, UserRepresentationModel repModel) {
|
||||
assertThat(entity).hasNoNullFieldsOrProperties();
|
||||
assertThat(entity).hasNoNullFieldsOrProperties();
|
||||
assertThat(repModel).hasNoNullFieldsOrProperties();
|
||||
|
||||
assertThat(entity.getId()).isEqualTo(repModel.getUserId());
|
||||
assertThat(entity.getFirstName()).isEqualTo(repModel.getFirstName());
|
||||
assertThat(entity.getLastName()).isEqualTo(repModel.getLastName());
|
||||
assertThat(entity.getFullName()).isEqualTo(repModel.getFullName());
|
||||
assertThat(entity.getLongName()).isEqualTo(repModel.getLongName());
|
||||
assertThat(entity.getEmail()).isEqualTo(repModel.getEmail());
|
||||
assertThat(entity.getPhone()).isEqualTo(repModel.getPhone());
|
||||
assertThat(entity.getMobilePhone()).isEqualTo(repModel.getMobilePhone());
|
||||
assertThat(entity.getOrgLevel4()).isEqualTo(repModel.getOrgLevel4());
|
||||
assertThat(entity.getOrgLevel3()).isEqualTo(repModel.getOrgLevel3());
|
||||
assertThat(entity.getOrgLevel2()).isEqualTo(repModel.getOrgLevel2());
|
||||
assertThat(entity.getOrgLevel1()).isEqualTo(repModel.getOrgLevel1());
|
||||
assertThat(entity.getData()).isEqualTo(repModel.getData());
|
||||
}
|
||||
}
|
|
@ -50,6 +50,9 @@ export const messageByErrorCode = {
|
|||
TASK_INVALID_OWNER: 'Current user {currentUserId} is not the owner of the Task with id {taskId}',
|
||||
TASK_INVALID_STATE: 'Task with id {taskId} is in state {taskState}. Required state(s): {requiredTaskStates}.',
|
||||
|
||||
USER_ALREADY_EXISTS: 'User with id {userId} cannot be created, because a User with that id does already exist',
|
||||
USER_NOT_FOUND: 'User with id {userId} cannot be found',
|
||||
|
||||
IMPORT_EXPORT_UPLOAD_FAILED: 'Upload failed. The uploaded file probably exceeded the maximum file size of 10 MB.',
|
||||
IMPORT_EXPORT_UPLOAD_FAILED_AUTH: 'Upload failed because you have no access to apply this operation.',
|
||||
IMPORT_EXPORT_UPLOAD_FAILED_NOT_FOUND: 'Upload failed because operation was not found',
|
||||
|
|
Loading…
Reference in New Issue