From 3709d9851158a90260b77b08a9b1b796939bde47 Mon Sep 17 00:00:00 2001 From: BerndBreier <33351391+BerndBreier@users.noreply.github.com> Date: Tue, 21 Jan 2020 17:05:31 +0100 Subject: [PATCH] TSK-1038 prevent duplicate workbasket access items --- .../java/pro/taskana/WorkbasketService.java | 8 +++- ...basketAccessItemAlreadyExistException.java | 18 ++++++++ .../taskana/impl/WorkbasketServiceImpl.java | 17 +++++-- .../main/resources/sql/taskana-schema-db2.sql | 1 + .../resources/sql/taskana-schema-postgres.sql | 1 + .../src/main/resources/sql/taskana-schema.sql | 1 + .../UpdateObjectsUseUtcTimeStampsAccTest.java | 4 +- .../workbasket/CreateWorkbasketAccTest.java | 33 ++++++++++++- .../workbasket/DeleteWorkbasketAccTest.java | 4 +- ...pdateWorkbasketAuthorizations2AccTest.java | 46 +++++++++++++++++++ ...UpdateWorkbasketAuthorizationsAccTest.java | 38 +++++---------- .../TaskServiceImplIntAutocommitTest.java | 6 ++- .../TaskServiceImplIntExplicitTest.java | 34 ++++++++++---- ...orkbasketServiceImplIntAutocommitTest.java | 10 ++-- .../WorkbasketServiceImplIntExplicitTest.java | 8 ++-- .../rest/WorkbasketDefinitionController.java | 5 +- 16 files changed, 179 insertions(+), 55 deletions(-) create mode 100644 lib/taskana-core/src/main/java/pro/taskana/exceptions/WorkbasketAccessItemAlreadyExistException.java create mode 100644 lib/taskana-core/src/test/java/acceptance/workbasket/UpdateWorkbasketAuthorizations2AccTest.java diff --git a/lib/taskana-core/src/main/java/pro/taskana/WorkbasketService.java b/lib/taskana-core/src/main/java/pro/taskana/WorkbasketService.java index 61cf25622..8e3a14cf5 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/WorkbasketService.java +++ b/lib/taskana-core/src/main/java/pro/taskana/WorkbasketService.java @@ -7,6 +7,7 @@ import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidWorkbasketException; import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.TaskanaException; +import pro.taskana.exceptions.WorkbasketAccessItemAlreadyExistException; import pro.taskana.exceptions.WorkbasketAlreadyExistException; import pro.taskana.exceptions.WorkbasketInUseException; import pro.taskana.exceptions.WorkbasketNotFoundException; @@ -82,10 +83,13 @@ public interface WorkbasketService { * @throws NotAuthorizedException if the current user is not member of role BUSINESS_ADMIN or * ADMIN * @throws WorkbasketNotFoundException if the workbasketAccessItem refers to a not existing - * workbasket + * workbasket * + * @throws WorkbasketAccessItemAlreadyExistException if there exists already a + * WorkbasketAccessItem for the same access id and workbasket */ WorkbasketAccessItem createWorkbasketAccessItem(WorkbasketAccessItem workbasketAccessItem) - throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException; + throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException, + WorkbasketAccessItemAlreadyExistException; /** * This method updates a {@link WorkbasketAccessItem}. diff --git a/lib/taskana-core/src/main/java/pro/taskana/exceptions/WorkbasketAccessItemAlreadyExistException.java b/lib/taskana-core/src/main/java/pro/taskana/exceptions/WorkbasketAccessItemAlreadyExistException.java new file mode 100644 index 000000000..111494810 --- /dev/null +++ b/lib/taskana-core/src/main/java/pro/taskana/exceptions/WorkbasketAccessItemAlreadyExistException.java @@ -0,0 +1,18 @@ +package pro.taskana.exceptions; + +import pro.taskana.WorkbasketAccessItem; + +public class WorkbasketAccessItemAlreadyExistException extends TaskanaException { + private static final long serialVersionUID = 4716611657569005013L; + + public WorkbasketAccessItemAlreadyExistException(WorkbasketAccessItem workbasketAccessItem) { + super( + "WorkbasketAccessItem for accessId " + + workbasketAccessItem.getAccessId() + + " and WorkbasketId " + + workbasketAccessItem.getWorkbasketId() + + ", WorkbasketKey " + + workbasketAccessItem.getWorkbasketKey() + + " exists already."); + } +} diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketServiceImpl.java index 29b10116b..2b409a050 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketServiceImpl.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; +import org.apache.ibatis.exceptions.PersistenceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,6 +25,7 @@ import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidWorkbasketException; import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.TaskanaException; +import pro.taskana.exceptions.WorkbasketAccessItemAlreadyExistException; import pro.taskana.exceptions.WorkbasketAlreadyExistException; import pro.taskana.exceptions.WorkbasketInUseException; import pro.taskana.exceptions.WorkbasketNotFoundException; @@ -171,7 +173,8 @@ public class WorkbasketServiceImpl implements WorkbasketService { @Override public WorkbasketAccessItem createWorkbasketAccessItem(WorkbasketAccessItem workbasketAccessItem) - throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException { + throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException, + WorkbasketAccessItemAlreadyExistException { LOGGER.debug( "entry to createWorkbasketAccessItemn(workbasketAccessItem = {})", workbasketAccessItem); taskanaEngine.getEngine().checkRoleMembership(TaskanaRole.BUSINESS_ADMIN, TaskanaRole.ADMIN); @@ -196,9 +199,15 @@ public class WorkbasketServiceImpl implements WorkbasketService { "WorkbasketAccessItem %s refers to a not existing workbasket", workbasketAccessItem)); } - workbasketAccessMapper.insert(accessItem); - LOGGER.debug( - "Method createWorkbasketAccessItem() created workbaskteAccessItem {}", accessItem); + try { + workbasketAccessMapper.insert(accessItem); + LOGGER.debug( + "Method createWorkbasketAccessItem() created workbaskteAccessItem {}", accessItem); + } catch (PersistenceException e) { + LOGGER.warn( + "when trying to insert WorkbasketAccessItem {} caught exception {}", accessItem, e); + throw new WorkbasketAccessItemAlreadyExistException(accessItem); + } return accessItem; } finally { taskanaEngine.returnConnection(); diff --git a/lib/taskana-core/src/main/resources/sql/taskana-schema-db2.sql b/lib/taskana-core/src/main/resources/sql/taskana-schema-db2.sql index 3236dc1d7..3905d79ef 100644 --- a/lib/taskana-core/src/main/resources/sql/taskana-schema-db2.sql +++ b/lib/taskana-core/src/main/resources/sql/taskana-schema-db2.sql @@ -145,6 +145,7 @@ CREATE TABLE WORKBASKET_ACCESS_LIST( PERM_CUSTOM_11 SMALLINT NOT NULL, PERM_CUSTOM_12 SMALLINT NOT NULL, PRIMARY KEY (ID), + CONSTRAINT UC_ACCESSID_WBID UNIQUE (ACCESS_ID, WORKBASKET_ID), CONSTRAINT ACCESS_LIST_WB FOREIGN KEY (WORKBASKET_ID) REFERENCES WORKBASKET ON DELETE CASCADE ); diff --git a/lib/taskana-core/src/main/resources/sql/taskana-schema-postgres.sql b/lib/taskana-core/src/main/resources/sql/taskana-schema-postgres.sql index ede121da2..1e27c0d99 100644 --- a/lib/taskana-core/src/main/resources/sql/taskana-schema-postgres.sql +++ b/lib/taskana-core/src/main/resources/sql/taskana-schema-postgres.sql @@ -147,6 +147,7 @@ CREATE TABLE WORKBASKET_ACCESS_LIST( PERM_CUSTOM_11 BOOLEAN NOT NULL, PERM_CUSTOM_12 BOOLEAN NOT NULL, PRIMARY KEY (ID), + CONSTRAINT UC_ACCESSID_WBID UNIQUE (ACCESS_ID, WORKBASKET_ID), CONSTRAINT ACCESS_LIST_WB FOREIGN KEY (WORKBASKET_ID) REFERENCES WORKBASKET ON DELETE CASCADE ); diff --git a/lib/taskana-core/src/main/resources/sql/taskana-schema.sql b/lib/taskana-core/src/main/resources/sql/taskana-schema.sql index 9b6953032..4b6dba377 100644 --- a/lib/taskana-core/src/main/resources/sql/taskana-schema.sql +++ b/lib/taskana-core/src/main/resources/sql/taskana-schema.sql @@ -147,6 +147,7 @@ CREATE TABLE WORKBASKET_ACCESS_LIST( PERM_CUSTOM_11 SMALLINT NOT NULL, PERM_CUSTOM_12 SMALLINT NOT NULL, PRIMARY KEY (ID), + CONSTRAINT UC_ACCESSID_WBID UNIQUE (ACCESS_ID, WORKBASKET_ID), CONSTRAINT ACCESS_LIST_WB FOREIGN KEY (WORKBASKET_ID) REFERENCES WORKBASKET ON DELETE CASCADE ); diff --git a/lib/taskana-core/src/test/java/acceptance/persistence/UpdateObjectsUseUtcTimeStampsAccTest.java b/lib/taskana-core/src/test/java/acceptance/persistence/UpdateObjectsUseUtcTimeStampsAccTest.java index 627e30372..e6984db16 100644 --- a/lib/taskana-core/src/test/java/acceptance/persistence/UpdateObjectsUseUtcTimeStampsAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/persistence/UpdateObjectsUseUtcTimeStampsAccTest.java @@ -33,6 +33,7 @@ import pro.taskana.exceptions.InvalidWorkbasketException; import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.TaskAlreadyExistException; import pro.taskana.exceptions.TaskNotFoundException; +import pro.taskana.exceptions.WorkbasketAccessItemAlreadyExistException; import pro.taskana.exceptions.WorkbasketAlreadyExistException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.impl.JobServiceImpl; @@ -181,7 +182,8 @@ public class UpdateObjectsUseUtcTimeStampsAccTest extends AbstractAccTest { @Test void testTimestampsOnCreateWorkbasket() throws NotAuthorizedException, InvalidArgumentException, WorkbasketNotFoundException, - InvalidWorkbasketException, WorkbasketAlreadyExistException, DomainNotFoundException { + InvalidWorkbasketException, WorkbasketAlreadyExistException, DomainNotFoundException, + WorkbasketAccessItemAlreadyExistException { WorkbasketService workbasketService = taskanaEngine.getWorkbasketService(); final int before = workbasketService.createWorkbasketQuery().domainIn("DOMAIN_A").list().size(); diff --git a/lib/taskana-core/src/test/java/acceptance/workbasket/CreateWorkbasketAccTest.java b/lib/taskana-core/src/test/java/acceptance/workbasket/CreateWorkbasketAccTest.java index ff1835ec9..880eda136 100644 --- a/lib/taskana-core/src/test/java/acceptance/workbasket/CreateWorkbasketAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/workbasket/CreateWorkbasketAccTest.java @@ -18,6 +18,7 @@ import pro.taskana.exceptions.DomainNotFoundException; import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidWorkbasketException; import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.WorkbasketAccessItemAlreadyExistException; import pro.taskana.exceptions.WorkbasketAlreadyExistException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.security.JaasExtension; @@ -37,7 +38,8 @@ class CreateWorkbasketAccTest extends AbstractAccTest { @Test void testCreateWorkbasket() throws NotAuthorizedException, InvalidArgumentException, WorkbasketNotFoundException, - InvalidWorkbasketException, WorkbasketAlreadyExistException, DomainNotFoundException { + InvalidWorkbasketException, WorkbasketAlreadyExistException, DomainNotFoundException, + WorkbasketAccessItemAlreadyExistException { WorkbasketService workbasketService = taskanaEngine.getWorkbasketService(); final int before = workbasketService.createWorkbasketQuery().domainIn("DOMAIN_A").list().size(); @@ -201,7 +203,8 @@ class CreateWorkbasketAccTest extends AbstractAccTest { @Test void testWorkbasketAccessItemSetName() throws NotAuthorizedException, InvalidArgumentException, WorkbasketNotFoundException, - InvalidWorkbasketException, WorkbasketAlreadyExistException, DomainNotFoundException { + InvalidWorkbasketException, WorkbasketAlreadyExistException, DomainNotFoundException, + WorkbasketAccessItemAlreadyExistException { WorkbasketService workbasketService = taskanaEngine.getWorkbasketService(); int before = workbasketService.createWorkbasketQuery().domainIn("DOMAIN_A").list().size(); @@ -226,4 +229,30 @@ class CreateWorkbasketAccTest extends AbstractAccTest { accessItems.stream().filter(t -> wbai.getId().equals(t.getId())).findFirst().orElse(null); assertEquals("Karl Napf", item.getAccessName()); } + + @WithAccessId( + userName = "user_1_2", + groupNames = {"businessadmin"}) + @Test + void testCreateDuplicateWorkbasketAccessListFails() + throws NotAuthorizedException, InvalidArgumentException, WorkbasketNotFoundException, + InvalidWorkbasketException, WorkbasketAlreadyExistException, DomainNotFoundException, + WorkbasketAccessItemAlreadyExistException { + WorkbasketService workbasketService = taskanaEngine.getWorkbasketService(); + final int before = workbasketService.createWorkbasketQuery().domainIn("DOMAIN_A").list().size(); + + Workbasket workbasket = workbasketService.newWorkbasket("NT4321", "DOMAIN_A"); + workbasket.setName("Terabasket"); + workbasket.setType(WorkbasketType.GROUP); + workbasket.setOrgLevel1("company"); + workbasket = workbasketService.createWorkbasket(workbasket); + WorkbasketAccessItem wbai = + workbasketService.newWorkbasketAccessItem(workbasket.getId(), "user_3_2"); + wbai.setPermRead(true); + workbasketService.createWorkbasketAccessItem(wbai); + + Assertions.assertThrows( + WorkbasketAccessItemAlreadyExistException.class, + () -> workbasketService.createWorkbasketAccessItem(wbai)); + } } diff --git a/lib/taskana-core/src/test/java/acceptance/workbasket/DeleteWorkbasketAccTest.java b/lib/taskana-core/src/test/java/acceptance/workbasket/DeleteWorkbasketAccTest.java index d9df1d372..bb92b2a02 100644 --- a/lib/taskana-core/src/test/java/acceptance/workbasket/DeleteWorkbasketAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/workbasket/DeleteWorkbasketAccTest.java @@ -22,6 +22,7 @@ import pro.taskana.exceptions.InvalidOwnerException; import pro.taskana.exceptions.InvalidStateException; import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.TaskNotFoundException; +import pro.taskana.exceptions.WorkbasketAccessItemAlreadyExistException; import pro.taskana.exceptions.WorkbasketInUseException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.impl.TaskImpl; @@ -151,7 +152,8 @@ class DeleteWorkbasketAccTest extends AbstractAccTest { groupNames = {"businessadmin"}) @Test void testCascadingDeleteOfAccessItems() - throws WorkbasketNotFoundException, NotAuthorizedException, InvalidArgumentException { + throws WorkbasketNotFoundException, NotAuthorizedException, InvalidArgumentException, + WorkbasketAccessItemAlreadyExistException { Workbasket wb = workbasketService.getWorkbasket("WBI:100000000000000000000000000000000008"); String wbId = wb.getId(); // create 2 access Items diff --git a/lib/taskana-core/src/test/java/acceptance/workbasket/UpdateWorkbasketAuthorizations2AccTest.java b/lib/taskana-core/src/test/java/acceptance/workbasket/UpdateWorkbasketAuthorizations2AccTest.java new file mode 100644 index 000000000..cacbffa1d --- /dev/null +++ b/lib/taskana-core/src/test/java/acceptance/workbasket/UpdateWorkbasketAuthorizations2AccTest.java @@ -0,0 +1,46 @@ +package acceptance.workbasket; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsEqual.equalTo; + +import acceptance.AbstractAccTest; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import pro.taskana.WorkbasketAccessItem; +import pro.taskana.WorkbasketService; +import pro.taskana.exceptions.InvalidArgumentException; +import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.security.JaasExtension; +import pro.taskana.security.WithAccessId; + +/** Acceptance test for all "update workbasket" scenarios that need a fresh database. */ +@ExtendWith(JaasExtension.class) +public class UpdateWorkbasketAuthorizations2AccTest extends AbstractAccTest { + + UpdateWorkbasketAuthorizations2AccTest() { + super(); + } + + @WithAccessId( + userName = "teamlead_1", + groupNames = {"group_1", "businessadmin"}) + @Test + void testUpdatedAccessItemListToEmptyList() + throws InvalidArgumentException, NotAuthorizedException { + WorkbasketService workbasketService = taskanaEngine.getWorkbasketService(); + final String wbId = "WBI:100000000000000000000000000000000004"; + List accessItems = workbasketService.getWorkbasketAccessItems(wbId); + int countBefore = accessItems.size(); + assertThat(3, equalTo(countBefore)); + + workbasketService.setWorkbasketAccessItems(wbId, new ArrayList<>()); + + List updatedAccessItems = + workbasketService.getWorkbasketAccessItems(wbId); + int countAfter = updatedAccessItems.size(); + assertThat(0, equalTo(countAfter)); + } +} diff --git a/lib/taskana-core/src/test/java/acceptance/workbasket/UpdateWorkbasketAuthorizationsAccTest.java b/lib/taskana-core/src/test/java/acceptance/workbasket/UpdateWorkbasketAuthorizationsAccTest.java index a48b47142..48a3ce462 100644 --- a/lib/taskana-core/src/test/java/acceptance/workbasket/UpdateWorkbasketAuthorizationsAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/workbasket/UpdateWorkbasketAuthorizationsAccTest.java @@ -11,6 +11,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import acceptance.AbstractAccTest; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -27,9 +28,9 @@ import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.NotAuthorizedToQueryWorkbasketException; import pro.taskana.exceptions.TaskAlreadyExistException; +import pro.taskana.exceptions.WorkbasketAccessItemAlreadyExistException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.impl.WorkbasketAccessItemImpl; -import pro.taskana.security.CurrentUserContext; import pro.taskana.security.JaasExtension; import pro.taskana.security.WithAccessId; @@ -46,7 +47,8 @@ class UpdateWorkbasketAuthorizationsAccTest extends AbstractAccTest { groupNames = {"group_1", "businessadmin"}) @Test void testUpdateWorkbasketAccessItemSucceeds() - throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException { + throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException, + WorkbasketAccessItemAlreadyExistException { WorkbasketService workbasketService = taskanaEngine.getWorkbasketService(); WorkbasketAccessItem accessItem = workbasketService.newWorkbasketAccessItem( @@ -81,7 +83,8 @@ class UpdateWorkbasketAuthorizationsAccTest extends AbstractAccTest { groupNames = {"group_1", "businessadmin"}) @Test void testUpdateWorkbasketAccessItemRejected() - throws NotAuthorizedException, InvalidArgumentException, WorkbasketNotFoundException { + throws NotAuthorizedException, InvalidArgumentException, WorkbasketNotFoundException, + WorkbasketAccessItemAlreadyExistException { WorkbasketService workbasketService = taskanaEngine.getWorkbasketService(); WorkbasketAccessItem accessItem = workbasketService.newWorkbasketAccessItem( @@ -203,26 +206,6 @@ class UpdateWorkbasketAuthorizationsAccTest extends AbstractAccTest { assertFalse(item1.isPermTransfer()); } - @WithAccessId( - userName = "teamlead_1", - groupNames = {"group_1", "businessadmin"}) - @Test - void testUpdatedAccessItemListToEmptyList() - throws InvalidArgumentException, NotAuthorizedException { - WorkbasketService workbasketService = taskanaEngine.getWorkbasketService(); - final String wbId = "WBI:100000000000000000000000000000000004"; - List accessItems = workbasketService.getWorkbasketAccessItems(wbId); - int countBefore = accessItems.size(); - assertThat(3, equalTo(countBefore)); - - workbasketService.setWorkbasketAccessItems(wbId, new ArrayList<>()); - - List updatedAccessItems = - workbasketService.getWorkbasketAccessItems(wbId); - int countAfter = updatedAccessItems.size(); - assertThat(0, equalTo(countAfter)); - } - @WithAccessId( userName = "teamlead_1", groupNames = {"group_1", "businessadmin"}) @@ -240,8 +223,7 @@ class UpdateWorkbasketAuthorizationsAccTest extends AbstractAccTest { item0.setPermTransfer(false); final String updateId0 = item0.getId(); // insert new entry - WorkbasketAccessItem newItem = - workbasketService.newWorkbasketAccessItem(wbId, CurrentUserContext.getUserid()); + WorkbasketAccessItem newItem = workbasketService.newWorkbasketAccessItem(wbId, "dummyUser1"); newItem.setPermRead(true); newItem.setPermOpen(true); newItem.setPermCustom12(true); @@ -292,7 +274,11 @@ class UpdateWorkbasketAuthorizationsAccTest extends AbstractAccTest { } List listEqualToOriginal = new ArrayList<>(workbasketService.getWorkbasketAccessItems(wbId)); - assertEquals(originalList, listEqualToOriginal); + + // with DB2 V 11, the lists are sorted differently... + assertEquals( + new HashSet(originalList), + new HashSet(listEqualToOriginal)); } @WithAccessId( diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntAutocommitTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntAutocommitTest.java index 82dd4cf13..062469c91 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntAutocommitTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntAutocommitTest.java @@ -39,6 +39,7 @@ import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.SystemException; import pro.taskana.exceptions.TaskAlreadyExistException; import pro.taskana.exceptions.TaskNotFoundException; +import pro.taskana.exceptions.WorkbasketAccessItemAlreadyExistException; import pro.taskana.exceptions.WorkbasketAlreadyExistException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.impl.ClassificationImpl; @@ -267,7 +268,7 @@ class TaskServiceImplIntAutocommitTest { throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException, ClassificationAlreadyExistException, SQLException, TaskAlreadyExistException, InvalidWorkbasketException, InvalidArgumentException, WorkbasketAlreadyExistException, - DomainNotFoundException { + DomainNotFoundException, WorkbasketAccessItemAlreadyExistException { final String user = CurrentUserContext.getUserid(); // Set up Security for this Test @@ -404,7 +405,8 @@ class TaskServiceImplIntAutocommitTest { boolean permRead, boolean permAppend, boolean permTransfer) - throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException { + throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException, + WorkbasketAccessItemAlreadyExistException { WorkbasketAccessItem accessItem = workbasketService.newWorkbasketAccessItem(wb.getId(), accessId); accessItem.setPermOpen(permOpen); diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntExplicitTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntExplicitTest.java index 078109004..ecb0593cd 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntExplicitTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/TaskServiceImplIntExplicitTest.java @@ -44,6 +44,7 @@ import pro.taskana.exceptions.NotAuthorizedException; import pro.taskana.exceptions.SystemException; import pro.taskana.exceptions.TaskAlreadyExistException; import pro.taskana.exceptions.TaskNotFoundException; +import pro.taskana.exceptions.WorkbasketAccessItemAlreadyExistException; import pro.taskana.exceptions.WorkbasketAlreadyExistException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.impl.ClassificationImpl; @@ -101,7 +102,11 @@ class TaskServiceImplIntExplicitTest { taskanaEngineImpl.setConnectionManagementMode(ConnectionManagementMode.EXPLICIT); workbasketService = taskanaEngine.getWorkbasketService(); try (Connection connection = dataSource.getConnection()) { - new DbSchemaCreator(dataSource, connection.getSchema()).run(); + SampleDataGenerator sampleDataGenerator = + new SampleDataGenerator(dataSource, TaskanaEngineTestConfiguration.getSchemaName()); + sampleDataGenerator.clearDb(); + DbSchemaCreator creator = new DbSchemaCreator(dataSource, connection.getSchema()); + creator.run(); } } @@ -121,7 +126,7 @@ class TaskServiceImplIntExplicitTest { WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException, TaskAlreadyExistException, InvalidWorkbasketException, InvalidArgumentException, WorkbasketAlreadyExistException, - DomainNotFoundException { + DomainNotFoundException, WorkbasketAccessItemAlreadyExistException { try (Connection connection = dataSource.getConnection()) { taskanaEngineImpl.setConnection(connection); @@ -168,7 +173,7 @@ class TaskServiceImplIntExplicitTest { WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException, TaskAlreadyExistException, InvalidWorkbasketException, InvalidArgumentException, WorkbasketAlreadyExistException, - DomainNotFoundException { + DomainNotFoundException, WorkbasketAccessItemAlreadyExistException { try (Connection connection = dataSource.getConnection()) { taskanaEngineImpl.setConnection(connection); @@ -218,7 +223,8 @@ class TaskServiceImplIntExplicitTest { void createManualTaskShouldThrowClassificationNotFoundException() throws NotAuthorizedException, WorkbasketNotFoundException, SQLException, ClassificationAlreadyExistException, InvalidWorkbasketException, InvalidArgumentException, - WorkbasketAlreadyExistException, DomainNotFoundException { + WorkbasketAlreadyExistException, DomainNotFoundException, + WorkbasketAccessItemAlreadyExistException { try (Connection connection = dataSource.getConnection()) { taskanaEngineImpl.setConnection(connection); @@ -251,7 +257,8 @@ class TaskServiceImplIntExplicitTest { throws SQLException, NotAuthorizedException, WorkbasketNotFoundException, ClassificationNotFoundException, ClassificationAlreadyExistException, TaskAlreadyExistException, InvalidWorkbasketException, InvalidArgumentException, - SystemException, WorkbasketAlreadyExistException, DomainNotFoundException { + SystemException, WorkbasketAlreadyExistException, DomainNotFoundException, + WorkbasketAccessItemAlreadyExistException { try (Connection connection = dataSource.getConnection()) { taskanaEngineImpl.setConnection(connection); WorkbasketImpl workbasket = @@ -308,7 +315,7 @@ class TaskServiceImplIntExplicitTest { ClassificationAlreadyExistException, TaskNotFoundException, InterruptedException, TaskAlreadyExistException, SQLException, InvalidWorkbasketException, InvalidArgumentException, WorkbasketAlreadyExistException, DomainNotFoundException, - InvalidStateException { + InvalidStateException, WorkbasketAccessItemAlreadyExistException { final int sleepTime = 100; final String user = CurrentUserContext.getUserid(); try (Connection connection = dataSource.getConnection()) { @@ -323,8 +330,14 @@ class TaskServiceImplIntExplicitTest { wb.setType(WorkbasketType.PERSONAL); Workbasket sourceWB = workbasketService.createWorkbasket(wb); - createWorkbasketWithSecurity(wb, wb.getOwner(), false, false, false, false); - createWorkbasketWithSecurity(sourceWB, sourceWB.getOwner(), true, true, true, true); + createWorkbasketWithSecurity(wb, wb.getOwner(), true, true, true, true); + connection.commit(); + Assertions.assertThrows( + WorkbasketAccessItemAlreadyExistException.class, + () -> + createWorkbasketWithSecurity( + sourceWB, sourceWB.getOwner(), false, false, false, false)); + connection.rollback(); // Destination Workbasket wb = (WorkbasketImpl) workbasketService.newWorkbasket("wb2Key", "DOMAIN_A"); @@ -389,7 +402,7 @@ class TaskServiceImplIntExplicitTest { throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException, ClassificationAlreadyExistException, SQLException, TaskAlreadyExistException, InvalidWorkbasketException, InvalidArgumentException, WorkbasketAlreadyExistException, - DomainNotFoundException { + DomainNotFoundException, WorkbasketAccessItemAlreadyExistException { final String user = "User"; // Set up Security for this Test @@ -514,7 +527,8 @@ class TaskServiceImplIntExplicitTest { boolean permRead, boolean permAppend, boolean permTransfer) - throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException { + throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException, + WorkbasketAccessItemAlreadyExistException { WorkbasketAccessItem accessItem = workbasketService.newWorkbasketAccessItem(wb.getId(), accessId); accessItem.setPermOpen(permOpen); diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntAutocommitTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntAutocommitTest.java index 2458976d7..713446853 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntAutocommitTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntAutocommitTest.java @@ -27,6 +27,7 @@ import pro.taskana.exceptions.DomainNotFoundException; import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidWorkbasketException; import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.WorkbasketAccessItemAlreadyExistException; import pro.taskana.exceptions.WorkbasketAlreadyExistException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.impl.WorkbasketImpl; @@ -138,7 +139,8 @@ class WorkbasketServiceImplIntAutocommitTest { @Test void testInsertWorkbasketAccessUser() throws NotAuthorizedException, InvalidArgumentException, DomainNotFoundException, - InvalidWorkbasketException, WorkbasketAlreadyExistException, WorkbasketNotFoundException { + InvalidWorkbasketException, WorkbasketAlreadyExistException, WorkbasketNotFoundException, + WorkbasketAccessItemAlreadyExistException { Workbasket wb = createTestWorkbasket( @@ -168,7 +170,8 @@ class WorkbasketServiceImplIntAutocommitTest { @Test void testUpdateWorkbasketAccessUser() throws NotAuthorizedException, InvalidArgumentException, WorkbasketNotFoundException, - DomainNotFoundException, InvalidWorkbasketException, WorkbasketAlreadyExistException { + DomainNotFoundException, InvalidWorkbasketException, WorkbasketAlreadyExistException, + WorkbasketAccessItemAlreadyExistException { WorkbasketImpl wb = (WorkbasketImpl) workBasketService.newWorkbasket("key", "DOMAIN_A"); wb.setId("k200000000000000000000000000000000000000"); wb.setName("name"); @@ -206,7 +209,8 @@ class WorkbasketServiceImplIntAutocommitTest { boolean permRead, boolean permAppend, boolean permTransfer) - throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException { + throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException, + WorkbasketAccessItemAlreadyExistException { WorkbasketAccessItem accessItem = workBasketService.newWorkbasketAccessItem(wb.getId(), accessId); accessItem.setPermOpen(permOpen); diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntExplicitTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntExplicitTest.java index 4a7b6357e..8e76ddfa5 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntExplicitTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/integration/WorkbasketServiceImplIntExplicitTest.java @@ -27,6 +27,7 @@ import pro.taskana.exceptions.DomainNotFoundException; import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidWorkbasketException; import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.WorkbasketAccessItemAlreadyExistException; import pro.taskana.exceptions.WorkbasketAlreadyExistException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.impl.TaskanaEngineImpl; @@ -143,7 +144,7 @@ class WorkbasketServiceImplIntExplicitTest { void testInsertWorkbasketAccessUser() throws NotAuthorizedException, SQLException, InvalidArgumentException, WorkbasketNotFoundException, DomainNotFoundException, InvalidWorkbasketException, - WorkbasketAlreadyExistException { + WorkbasketAlreadyExistException, WorkbasketAccessItemAlreadyExistException { try (Connection connection = dataSource.getConnection()) { taskanaEngineImpl.setConnection(connection); workBasketService = taskanaEngine.getWorkbasketService(); @@ -168,7 +169,7 @@ class WorkbasketServiceImplIntExplicitTest { void testUpdateWorkbasketAccessUser() throws NotAuthorizedException, SQLException, InvalidArgumentException, WorkbasketNotFoundException, DomainNotFoundException, InvalidWorkbasketException, - WorkbasketAlreadyExistException { + WorkbasketAlreadyExistException, WorkbasketAccessItemAlreadyExistException { try (Connection connection = dataSource.getConnection()) { taskanaEngineImpl.setConnection(connection); workBasketService = taskanaEngine.getWorkbasketService(); @@ -200,7 +201,8 @@ class WorkbasketServiceImplIntExplicitTest { boolean permRead, boolean permAppend, boolean permTransfer) - throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException { + throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException, + WorkbasketAccessItemAlreadyExistException { WorkbasketAccessItem accessItem = workBasketService.newWorkbasketAccessItem(wb.getId(), accessId); accessItem.setPermOpen(permOpen); diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketDefinitionController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketDefinitionController.java index e372dcdba..8609941bb 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketDefinitionController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketDefinitionController.java @@ -33,6 +33,7 @@ import pro.taskana.exceptions.DomainNotFoundException; import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidWorkbasketException; import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.WorkbasketAccessItemAlreadyExistException; import pro.taskana.exceptions.WorkbasketAlreadyExistException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.rest.resource.WorkbasketDefinitionResource; @@ -100,13 +101,15 @@ public class WorkbasketDefinitionController { * id. * @throws InvalidArgumentException if authorization information in workbaskets definitions is * incorrect. + * @throws WorkbasketAccessItemAlreadyExistException if a WorkbasketAccessItem for the same + * workbasket and access_id already exists. */ @PostMapping(path = Mapping.URL_WORKBASKETDEFIITIONS) @Transactional(rollbackFor = Exception.class) public ResponseEntity importWorkbaskets(@RequestParam("file") MultipartFile file) throws IOException, NotAuthorizedException, DomainNotFoundException, InvalidWorkbasketException, WorkbasketAlreadyExistException, WorkbasketNotFoundException, - InvalidArgumentException { + InvalidArgumentException, WorkbasketAccessItemAlreadyExistException { LOGGER.debug("Entry to importWorkbaskets()"); ObjectMapper mapper = new ObjectMapper(); mapper.enable(SerializationFeature.INDENT_OUTPUT);