刘光辉
6 小时以前 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
package jnpf.flowable.util.filepermission;
 
import jnpf.flowable.model.filepermission.FilePermissionPolicy.Action;
import jnpf.flowable.model.filepermission.FilePermissionPolicy.Effect;
import jnpf.flowable.model.filepermission.FilePermissionPolicy.Rule;
import java.util.*;
 
/**
 * 纯规则裁决。调用方必须先按真实实例、执行轮次、人员关系解析适用规则。
 * 不可直接将请求中的规则、版本、人员或布尔权限传入作为可信授权。
 */
public final class FilePermissionEvaluator {
    private FilePermissionEvaluator() { }
 
    public static final class Result {
        public final long version;
        public final Map<Action, Boolean> actions;
        /** 原因保留到规则 ID;不返回其他参与人的身份。 */
        public final Map<Action, String> reasons;
 
        private Result(long version, Map<Action, Boolean> actions, Map<Action, String> reasons) {
            this.version = version;
            this.actions = Collections.unmodifiableMap(actions);
            this.reasons = Collections.unmodifiableMap(reasons);
        }
    }
 
    public static Result evaluate(String formId, String field, long version, boolean transitioning,
            Map<Action, Boolean> nativeUpperBound, Map<Action, Boolean> inherited,
            Collection<Rule> applicableRules) {
        Objects.requireNonNull(formId, "formId");
        Objects.requireNonNull(field, "field");
        Objects.requireNonNull(nativeUpperBound, "nativeUpperBound");
        Objects.requireNonNull(inherited, "inherited");
        Objects.requireNonNull(applicableRules, "applicableRules");
        if (version < 0) throw new IllegalArgumentException("权限版本无效");
        Map<Action, Boolean> actions = new EnumMap<>(Action.class);
        Map<Action, String> reasons = new EnumMap<>(Action.class);
        for (Action action : Action.values()) {
            boolean allow = Boolean.TRUE.equals(inherited.get(action));
            String deniedBy = null;
            for (Rule rule : applicableRules) {
                if (!formId.equals(rule.formId) || !field.equals(rule.field)) continue;
                Effect effect = rule.actions.get(action);
                if (effect == Effect.DENY) {
                    // 顺序不影响裁决和返回原因,便于缓存/审计一致性。
                    if (deniedBy == null || rule.id.compareTo(deniedBy) < 0) deniedBy = rule.id;
                } else if (effect == Effect.ALLOW) allow = true;
            }
            String reason = transitioning ? "TRANSITIONING" : !Boolean.TRUE.equals(nativeUpperBound.get(action))
                    ? "NATIVE_PERMISSION" : deniedBy != null ? "RULE:" + deniedBy : !allow ? "INHERITED_DENY" : null;
            actions.put(action, reason == null);
            if (reason != null) reasons.put(action, reason);
        }
        return new Result(version, actions, reasons);
    }
}