刘光辉
3 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
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));
    }
}