Skip to content

Commit

Permalink
Closes Taskana#2295 - implement EDITTASKS Permission
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesrdi committed Jul 20, 2023
1 parent 548d319 commit 603984a
Show file tree
Hide file tree
Showing 22 changed files with 809 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@
import static pro.taskana.testapi.DefaultTestEntities.defaultTestWorkbasket;

import java.time.Instant;
import java.util.List;
import java.util.stream.Stream;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.api.function.ThrowingConsumer;
import pro.taskana.TaskanaConfiguration;
import pro.taskana.classification.api.ClassificationService;
import pro.taskana.classification.api.models.ClassificationSummary;
import pro.taskana.common.internal.util.Triplet;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.TaskState;
import pro.taskana.task.api.exceptions.InvalidOwnerException;
Expand Down Expand Up @@ -46,20 +52,54 @@ class ClaimTaskAccTest {
ClassificationSummary defaultClassificationSummary;
WorkbasketSummary defaultWorkbasketSummary;
ObjectReference defaultObjectReference;
WorkbasketSummary wbWithoutEditTasks;
WorkbasketSummary wbWithoutReadTasks;
WorkbasketSummary wbWithoutRead;

@WithAccessId(user = "businessadmin")
@BeforeAll
void setup() throws Exception {
defaultClassificationSummary =
defaultTestClassification().buildAndStoreAsSummary(classificationService);
defaultWorkbasketSummary = defaultTestWorkbasket().buildAndStoreAsSummary(workbasketService);
wbWithoutEditTasks = defaultTestWorkbasket().buildAndStoreAsSummary(workbasketService);
wbWithoutReadTasks = defaultTestWorkbasket().buildAndStoreAsSummary(workbasketService);
wbWithoutRead = defaultTestWorkbasket().buildAndStoreAsSummary(workbasketService);

WorkbasketAccessItemBuilder.newWorkbasketAccessItem()
.workbasketId(defaultWorkbasketSummary.getId())
.accessId("user-1-2")
.permission(WorkbasketPermission.OPEN)
.permission(WorkbasketPermission.READ)
.permission(WorkbasketPermission.READTASKS)
.permission(WorkbasketPermission.EDITTASKS)
.permission(WorkbasketPermission.APPEND)
.buildAndStore(workbasketService);

WorkbasketAccessItemBuilder.newWorkbasketAccessItem()
.workbasketId(wbWithoutEditTasks.getId())
.accessId("user-1-2")
.permission(WorkbasketPermission.OPEN)
.permission(WorkbasketPermission.READ)
.permission(WorkbasketPermission.READTASKS)
.permission(WorkbasketPermission.APPEND)
.buildAndStore(workbasketService);

WorkbasketAccessItemBuilder.newWorkbasketAccessItem()
.workbasketId(wbWithoutReadTasks.getId())
.accessId("user-1-2")
.permission(WorkbasketPermission.OPEN)
.permission(WorkbasketPermission.READ)
.permission(WorkbasketPermission.EDITTASKS)
.permission(WorkbasketPermission.APPEND)
.buildAndStore(workbasketService);

WorkbasketAccessItemBuilder.newWorkbasketAccessItem()
.workbasketId(wbWithoutRead.getId())
.accessId("user-1-2")
.permission(WorkbasketPermission.OPEN)
.permission(WorkbasketPermission.READTASKS)
.permission(WorkbasketPermission.EDITTASKS)
.permission(WorkbasketPermission.APPEND)
.buildAndStore(workbasketService);

Expand Down Expand Up @@ -240,28 +280,49 @@ void should_ForceClaimTask_When_InReviewByAnotherUser() throws Exception {
assertThat(claimedTask.getOwner()).isEqualTo("user-1-2");
}

@WithAccessId(user = "user-taskrouter")
@Test
void should_ThrowNotAuthorizedException_When_UserHasNoReadPermissionAndTaskIsReady()
@WithAccessId(user = "user-1-2")
@TestFactory
Stream<DynamicTest> should_ThrowException_When_ForceClaimingTaskWithMissingPermission()
throws Exception {
Task task =
TaskBuilder.newTask()
.state(TaskState.READY)
.classificationSummary(defaultClassificationSummary)
.workbasketSummary(defaultWorkbasketSummary)
.primaryObjRef(defaultObjectReference)
.buildAndStore(taskService, "user-1-2");

ThrowingCallable call = () -> taskService.claim(task.getId());

NotAuthorizedOnWorkbasketException e =
catchThrowableOfType(call, NotAuthorizedOnWorkbasketException.class);
assertThat(e.getCurrentUserId()).isEqualTo("user-taskrouter");
assertThat(e.getWorkbasketId()).isEqualTo(defaultWorkbasketSummary.getId());
assertThat(e.getRequiredPermissions())
.containsExactlyInAnyOrder(WorkbasketPermission.READ, WorkbasketPermission.READTASKS);

;
List<Triplet<String, WorkbasketSummary, WorkbasketPermission>> list =
List.of(
Triplet.of("With Missing Read Permission", wbWithoutRead, WorkbasketPermission.READ),
Triplet.of(
"With Missing ReadTasks Permission",
wbWithoutReadTasks,
WorkbasketPermission.READTASKS),
Triplet.of(
"With Missing EditTasks Permission",
wbWithoutEditTasks,
WorkbasketPermission.EDITTASKS));
ThrowingConsumer<Triplet<String, WorkbasketSummary, WorkbasketPermission>> testClaimTask =
t -> {
String anyUserName = "TestUser28";
Task task =
TaskBuilder.newTask()
.classificationSummary(defaultClassificationSummary)
.workbasketSummary(t.getMiddle())
.primaryObjRef(DefaultTestEntities.defaultTestObjectReference().build())
.state(TaskState.CLAIMED)
.owner(anyUserName)
.buildAndStore(taskService, "admin");

ThrowingCallable call = () -> taskService.forceClaim(task.getId());

NotAuthorizedOnWorkbasketException e =
catchThrowableOfType(call, NotAuthorizedOnWorkbasketException.class);

if (t.getRight() != WorkbasketPermission.EDITTASKS) {
assertThat(e.getRequiredPermissions())
.containsExactlyInAnyOrder(
WorkbasketPermission.READ, WorkbasketPermission.READTASKS);
} else {
assertThat(e.getRequiredPermissions()).containsExactly(WorkbasketPermission.EDITTASKS);
}
assertThat(e.getCurrentUserId()).isEqualTo("user-1-2");
assertThat(e.getWorkbasketId()).isEqualTo(t.getMiddle().getId());
};
return DynamicTest.stream(list.iterator(), Triplet::getLeft, testClaimTask);
}

@WithAccessId(user = "user-taskrouter")
Expand Down Expand Up @@ -370,6 +431,51 @@ void should_ThrowException_When_CancelClaimingATaskInReviewByAnotherUser() throw
assertThat(e.getTaskId()).isEqualTo(claimedTask.getId());
}

@WithAccessId(user = "user-1-2")
@TestFactory
Stream<DynamicTest> should_ThrowException_When_CancelClaimingTaskWithMissingPermission()
throws Exception {
List<Triplet<String, WorkbasketSummary, WorkbasketPermission>> list =
List.of(
Triplet.of("With Missing Read Permission", wbWithoutRead, WorkbasketPermission.READ),
Triplet.of(
"With Missing ReadTasks Permission",
wbWithoutReadTasks,
WorkbasketPermission.READTASKS),
Triplet.of(
"With Missing EditTasks Permission",
wbWithoutEditTasks,
WorkbasketPermission.EDITTASKS));
ThrowingConsumer<Triplet<String, WorkbasketSummary, WorkbasketPermission>> testCancelClaimTask =
t -> {
Task task =
TaskBuilder.newTask()
.classificationSummary(defaultClassificationSummary)
.workbasketSummary(t.getMiddle())
.primaryObjRef(DefaultTestEntities.defaultTestObjectReference().build())
.state(TaskState.CLAIMED)
.owner("user-1-2")
.buildAndStore(taskService, "admin");

task.setNote("Test Note");
ThrowingCallable call = () -> taskService.cancelClaim(task.getId());

NotAuthorizedOnWorkbasketException e =
catchThrowableOfType(call, NotAuthorizedOnWorkbasketException.class);

if (t.getRight() != WorkbasketPermission.EDITTASKS) {
assertThat(e.getRequiredPermissions())
.containsExactlyInAnyOrder(
WorkbasketPermission.READ, WorkbasketPermission.READTASKS);
} else {
assertThat(e.getRequiredPermissions()).containsExactly(WorkbasketPermission.EDITTASKS);
}
assertThat(e.getCurrentUserId()).isEqualTo("user-1-2");
assertThat(e.getWorkbasketId()).isEqualTo(t.getMiddle().getId());
};
return DynamicTest.stream(list.iterator(), Triplet::getLeft, testCancelClaimTask);
}

@WithAccessId(user = "user-1-2")
@Test
void should_ForceCancelClaim_When_TaskClaimedByAnotherUser() throws Exception {
Expand Down Expand Up @@ -414,6 +520,51 @@ void should_ForceCancelClaimTask_When_InReviewByAnotherUser() throws Exception {
assertThat(unclaimedTask.getOwner()).isNull();
}

@WithAccessId(user = "user-1-2")
@TestFactory
Stream<DynamicTest> should_ThrowException_When_ForceCancelClaimingTaskWithMissingPermission()
throws Exception {
List<Triplet<String, WorkbasketSummary, WorkbasketPermission>> list =
List.of(
Triplet.of("With Missing Read Permission", wbWithoutRead, WorkbasketPermission.READ),
Triplet.of(
"With Missing ReadTasks Permission",
wbWithoutReadTasks,
WorkbasketPermission.READTASKS),
Triplet.of(
"With Missing EditTasks Permission",
wbWithoutEditTasks,
WorkbasketPermission.EDITTASKS));
ThrowingConsumer<Triplet<String, WorkbasketSummary, WorkbasketPermission>> testCancelClaimTask =
t -> {
Task task =
TaskBuilder.newTask()
.classificationSummary(defaultClassificationSummary)
.workbasketSummary(t.getMiddle())
.primaryObjRef(DefaultTestEntities.defaultTestObjectReference().build())
.state(TaskState.CLAIMED)
.owner("user-1-2")
.buildAndStore(taskService, "admin");

task.setNote("Test Note");
ThrowingCallable call = () -> taskService.forceCancelClaim(task.getId());

NotAuthorizedOnWorkbasketException e =
catchThrowableOfType(call, NotAuthorizedOnWorkbasketException.class);

if (t.getRight() != WorkbasketPermission.EDITTASKS) {
assertThat(e.getRequiredPermissions())
.containsExactlyInAnyOrder(
WorkbasketPermission.READ, WorkbasketPermission.READTASKS);
} else {
assertThat(e.getRequiredPermissions()).containsExactly(WorkbasketPermission.EDITTASKS);
}
assertThat(e.getCurrentUserId()).isEqualTo("user-1-2");
assertThat(e.getWorkbasketId()).isEqualTo(t.getMiddle().getId());
};
return DynamicTest.stream(list.iterator(), Triplet::getLeft, testCancelClaimTask);
}

@WithAccessId(user = "user-1-2")
@Test
void should_ClaimTask_When_OwnerOfReadyForReviewTaskIsSet() throws Exception {
Expand Down Expand Up @@ -452,6 +603,51 @@ void should_ClaimTask_When_OwnerOfReadyTaskIsSet() throws Exception {
assertThat(taskClaimed.getOwner()).isEqualTo("user-1-2");
}

@WithAccessId(user = "user-1-2")
@TestFactory
Stream<DynamicTest> should_ThrowException_When_ClaimingTaskWithMissingPermission()
throws Exception {
List<Triplet<String, WorkbasketSummary, WorkbasketPermission>> list =
List.of(
Triplet.of("With Missing Read Permission", wbWithoutRead, WorkbasketPermission.READ),
Triplet.of(
"With Missing ReadTasks Permission",
wbWithoutReadTasks,
WorkbasketPermission.READTASKS),
Triplet.of(
"With Missing EditTasks Permission",
wbWithoutEditTasks,
WorkbasketPermission.EDITTASKS));
ThrowingConsumer<Triplet<String, WorkbasketSummary, WorkbasketPermission>> testClaimTask =
t -> {
String anyUserName = "TestUser28";
Task task =
TaskBuilder.newTask()
.classificationSummary(defaultClassificationSummary)
.workbasketSummary(t.getMiddle())
.primaryObjRef(DefaultTestEntities.defaultTestObjectReference().build())
.state(TaskState.READY)
.owner(anyUserName)
.buildAndStore(taskService, "admin");

ThrowingCallable call = () -> taskService.claim(task.getId());

NotAuthorizedOnWorkbasketException e =
catchThrowableOfType(call, NotAuthorizedOnWorkbasketException.class);

if (t.getRight() != WorkbasketPermission.EDITTASKS) {
assertThat(e.getRequiredPermissions())
.containsExactlyInAnyOrder(
WorkbasketPermission.READ, WorkbasketPermission.READTASKS);
} else {
assertThat(e.getRequiredPermissions()).containsExactly(WorkbasketPermission.EDITTASKS);
}
assertThat(e.getCurrentUserId()).isEqualTo("user-1-2");
assertThat(e.getWorkbasketId()).isEqualTo(t.getMiddle().getId());
};
return DynamicTest.stream(list.iterator(), Triplet::getLeft, testClaimTask);
}

@Nested
@TestInstance(Lifecycle.PER_CLASS)
class WithAdditionalUserInfoEnabled implements TaskanaConfigurationModifier {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ void setup() throws Exception {
.permission(WorkbasketPermission.OPEN)
.permission(WorkbasketPermission.READ)
.permission(WorkbasketPermission.READTASKS)
.permission(WorkbasketPermission.EDITTASKS)
.permission(WorkbasketPermission.APPEND)
.buildAndStore(workbasketService);

Expand Down
Loading

0 comments on commit 603984a

Please sign in to comment.