1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
| package jnpf.flowable.service;
|
| import jnpf.flowable.entity.TemplateNodeEntity;
| import jnpf.flowable.model.filepermission.*;
| import jnpf.flowable.model.filepermission.FilePermissionPolicy.Action;
| import jnpf.flowable.util.filepermission.*;
| import org.junit.Test;
| import java.util.*;
| import static org.junit.Assert.*;
|
| public class WorkflowSharedEditPermissionTest {
| @Test public void persistedDraftKeepsCreatorAttachmentAccessBeforeAnyOperatorExists() {
| Map<String,Object> rule = Map.of("id", "creator", "formId", "form", "field", "files", "subject", "CREATOR",
| "trigger", "ACTIVE", "triggerNodeId", "start", "actions", Map.of("EDIT", "ALLOW"));
| FilePermissionSnapshot snapshot = FilePermissionSnapshot.read(FilePermissionSnapshot.create("0", "draft", "flow",
| Map.of("version", 1, "rules", List.of(rule))), "0", "draft");
| FilePermissionNativeState state = new FilePermissionNativeState();
| state.setTaskId("draft"); state.setFlowId("flow"); state.setFlowType(0); state.setStatus(0); state.setCreatorId("creator");
| TemplateNodeEntity start = new TemplateNodeEntity(); start.setNodeCode("start"); start.setNodeType("start");
| start.setFormId("form"); start.setNodeJson("{\"formOperates\":[{\"id\":\"files\",\"read\":true,\"write\":true}]}");
| Map<String,Object> form = Map.of("fields", List.of(Map.of("__vModel__", "files", "onlineEdit", true,
| "__config__", Map.of("jnpfKey", "uploadFile"))));
| var creatorFacts = NativeFilePermissionRuntimeSource.project("0", "form", "creator", snapshot, state, List.of(start), form);
| FilePermissionView creator = FilePermissionRuntime.resolve(snapshot.getRules(), creatorFacts);
| for (Action action : List.of(Action.VIEW, Action.DOWNLOAD, Action.EDIT, Action.ADD, Action.REPLACE, Action.REMOVE)) {
| assertTrue(action.name(), creator.allows("files", action));
| }
| var strangerFacts = NativeFilePermissionRuntimeSource.project("0", "form", "stranger", snapshot, state, List.of(start), form);
| assertFalse(FilePermissionRuntime.resolve(snapshot.getRules(), strangerFacts).allows("files", Action.EDIT));
| assertTrue(state.getMembers().isEmpty());
| }
|
| @Test public void explicitEditIsIndependentOfReadonlyNodeButInheritRemainsReadonly() {
| assertTrue(resolve("ALLOW", "reviewer", false, true, 1).allows("files", Action.EDIT));
| assertTrue(resolve("ALLOW", "creator", false, true, 1).allows("files", Action.EDIT));
| assertFalse(resolve("INHERIT", "reviewer", false, true, 1).allows("files", Action.EDIT));
| assertFalse(resolve("DENY", "reviewer", false, true, 1).allows("files", Action.EDIT));
| assertFalse(resolve("ALLOW", "reviewer", false, true, 1).allows("files", Action.REPLACE));
| }
| @Test public void editCannotBypassStaticSwitchReadScopeOrTerminalState() {
| assertFalse(resolve("ALLOW", "reviewer", true, true, 1).allows("files", Action.EDIT));
| assertFalse(resolve("ALLOW", "reviewer", false, false, 1).allows("files", Action.EDIT));
| assertFalse(resolve("ALLOW", "stranger", false, true, 1).allows("files", Action.EDIT));
| assertFalse(resolve("ALLOW", "reviewer", false, true, 2).allows("files", Action.EDIT));
| }
| @Test public void assignedCandidateReceivesHandlerEditOnlyAfterStartingWork() {
| assertFalse(resolve("ALLOW", "reviewer", false, true, 1, false, "CURRENT_HANDLERS").allows("files", Action.EDIT));
| assertTrue(resolve("ALLOW", "reviewer", false, true, 1, true, "CURRENT_HANDLERS").allows("files", Action.EDIT));
| }
| private FilePermissionView resolve(String effect, String user, boolean disabled, boolean read, int status) {
| return resolve(effect, user, disabled, read, status, true, "PARTICIPANTS");
| }
| private FilePermissionView resolve(String effect, String user, boolean disabled, boolean read, int status, boolean started, String subject) {
| Map<String,Object> rule = Map.of("id", "rule", "formId", "form", "field", "files", "subject", subject,
| "trigger", "ACTIVE", "triggerNodeId", "review", "actions", Map.of("EDIT", effect));
| FilePermissionSnapshot snapshot = FilePermissionSnapshot.read(FilePermissionSnapshot.create("0", "task", "flow",
| Map.of("version", 1, "rules", List.of(rule))), "0", "task");
| FilePermissionNativeState state = new FilePermissionNativeState(); state.setTaskId("task"); state.setFlowId("flow");
| state.setFlowType(1); state.setStatus(status); state.setCreatorId("creator"); state.setCurrentNodeCode(status == 2 ? null : "review");
| FilePermissionNativeState.Member member = new FilePermissionNativeState.Member(); member.setId("operator");
| member.setKind("operator"); member.setUserId("reviewer"); member.setNodeCode("review"); member.setStatus(1); member.setCompletion(0);
| if (started) member.setStartHandleTime(new Date(1L));
| state.getMembers().add(member);
| List<TemplateNodeEntity> nodes = new ArrayList<>();
| for (String code : List.of("start", "review")) {
| TemplateNodeEntity node = new TemplateNodeEntity(); node.setNodeCode(code); node.setFormId("form");
| node.setNodeType(code.equals("start") ? "start" : "approver");
| node.setNodeJson("{\"formOperates\":[{\"id\":\"files\",\"read\":" + read + ",\"write\":false}]}"); nodes.add(node);
| }
| Map<String,Object> form = Map.of("fields", List.of(Map.of("__vModel__", "files", "onlineEdit", true, "disabled", disabled,
| "__config__", Map.of("jnpfKey", "uploadFile"))));
| return FilePermissionRuntime.resolve(snapshot.getRules(), NativeFilePermissionRuntimeSource.project("0", "form", user, snapshot, state, nodes, form));
| }
| }
|
|