aboutsummaryrefslogtreecommitdiffstats
path: root/jdisc-security-filters/src/main/java/com/yahoo/jdisc/http/filter/security/cloud/Permission.java
blob: 4bab83f8576cfd6a5162e19a4a0628c1ac6ab3be (plain) (blame)
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
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

package com.yahoo.jdisc.http.filter.security.cloud;

import com.yahoo.container.jdisc.AclMapping;
import com.yahoo.container.jdisc.RequestHandlerSpec;
import com.yahoo.container.jdisc.RequestView;
import com.yahoo.jdisc.http.filter.DiscFilterRequest;

import java.util.Collection;
import java.util.EnumSet;
import java.util.Optional;
import java.util.logging.Logger;
import java.util.stream.Collectors;

/**
 * @author bjorncs
 */
enum Permission {
    READ, WRITE;

    private static final Logger log = Logger.getLogger(Permission.class.getName());

    String asString() {
        return switch (this) {
            case READ -> "read";
            case WRITE -> "write";
        };
    }

    static Permission of(String v) {
        return switch (v) {
            case "read" -> READ;
            case "write" -> WRITE;
            default -> throw new IllegalArgumentException("Invalid permission '%s'".formatted(v));
        };
    }

    static EnumSet<Permission> setOf(Collection<String> v) {
        return v.stream().map(Permission::of).collect(Collectors.toCollection(() -> EnumSet.noneOf(Permission.class)));
    }

    static Optional<Permission> getRequiredPermission(DiscFilterRequest req) {
        RequestView view = req.asRequestView();
        var result = Optional.ofNullable((RequestHandlerSpec) req.getAttribute(RequestHandlerSpec.ATTRIBUTE_NAME))
                .or(() -> Optional.of(RequestHandlerSpec.DEFAULT_INSTANCE))
                .flatMap(spec -> {
                    var action = spec.aclMapping().get(view);
                    var maybePermission = Permission.of(action);
                    if (maybePermission.isEmpty()) log.fine(() -> "Unknown action '%s'".formatted(action));
                    return maybePermission;
                });
        if (result.isEmpty())
            log.fine(() -> "No valid permission mapping defined for %s @ '%s'".formatted(view.method(), view.uri()));
        return result;
    }

    static Optional<Permission> of(AclMapping.Action a) {
        if (a.equals(AclMapping.Action.READ)) return Optional.of(READ);
        if (a.equals(AclMapping.Action.WRITE)) return Optional.of(WRITE);
        return Optional.empty();
    }
}