Search in sources :

Example 1 with SelfSubjectAccessReview

use of io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReview in project kubernetes-client by fabric8io.

the class CanIEquivalent method main.

public static void main(String[] args) {
    try (KubernetesClient client = new KubernetesClientBuilder().build()) {
        SelfSubjectAccessReview ssar = new SelfSubjectAccessReviewBuilder().withNewSpec().withNewResourceAttributes().withGroup("apps").withResource("deployments").withVerb("create").withNamespace("dev").endResourceAttributes().endSpec().build();
        ssar = client.authorization().v1().selfSubjectAccessReview().create(ssar);
        logger.info("Allowed: {}", ssar.getStatus().getAllowed());
    }
}
Also used : KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) KubernetesClientBuilder(io.fabric8.kubernetes.client.KubernetesClientBuilder) SelfSubjectAccessReview(io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReview) SelfSubjectAccessReviewBuilder(io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReviewBuilder)

Example 2 with SelfSubjectAccessReview

use of io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReview in project kubernetes-client by fabric8io.

the class SelfSubjectAccessReviewIT method testCreate.

@Test
public void testCreate() {
    // Given
    SelfSubjectAccessReview selfSubjectAccessReview = new SelfSubjectAccessReviewBuilder().withNewSpec().withNewResourceAttributes().withNamespace(session.getNamespace()).withVerb("get").withResource("pods").endResourceAttributes().endSpec().build();
    // When
    selfSubjectAccessReview = client.authorization().v1().selfSubjectAccessReview().create(selfSubjectAccessReview);
    // Then
    assertTrue(selfSubjectAccessReview.getStatus().getAllowed());
    assertNull(selfSubjectAccessReview.getStatus().getDenied());
}
Also used : SelfSubjectAccessReview(io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReview) SelfSubjectAccessReviewBuilder(io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReviewBuilder) Test(org.junit.Test)

Example 3 with SelfSubjectAccessReview

use of io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReview in project cryostat by cryostatio.

the class OpenShiftAuthManager method validateAction.

private Stream<CompletableFuture<Void>> validateAction(OpenShiftClient client, String namespace, ResourceAction resourceAction) {
    Set<GroupResource> resources = resourceMap.getOrDefault(resourceAction.getResource(), Set.of());
    if (resources.isEmpty()) {
        return Stream.of();
    }
    String verb = map(resourceAction.getVerb());
    return resources.stream().map(resource -> new SelfSubjectAccessReviewBuilder().withNewSpec().withNewResourceAttributes().withNamespace(namespace).withGroup(resource.getGroup()).withResource(resource.getResource()).withSubresource(resource.getSubResource()).withVerb(verb).endResourceAttributes().endSpec().build()).map(accessReview -> {
        CompletableFuture<Void> result = new CompletableFuture<>();
        AuthRequest evt = new AuthRequest();
        try {
            evt.begin();
            SelfSubjectAccessReview accessReviewResult = client.authorization().v1().selfSubjectAccessReview().create(accessReview);
            evt.setRequestSuccessful(true);
            if (accessReviewResult.getStatus().getAllowed()) {
                result.complete(null);
            } else {
                result.completeExceptionally(new PermissionDeniedException(namespace, new GroupResource(accessReview.getSpec().getResourceAttributes()).toString(), verb, accessReviewResult.getStatus().getReason()));
            }
        } catch (Exception e) {
            result.completeExceptionally(e);
        } finally {
            if (evt.shouldCommit()) {
                evt.end();
                evt.commit();
            }
        }
        return result;
    });
}
Also used : JsonProperty(com.fasterxml.jackson.annotation.JsonProperty) Event(jdk.jfr.Event) Label(jdk.jfr.Label) Arrays(java.util.Arrays) URISyntaxException(java.net.URISyntaxException) Scheduler(com.github.benmanes.caffeine.cache.Scheduler) StringUtils(org.apache.commons.lang3.StringUtils) UserInfo(io.cryostat.net.UserInfo) Future(java.util.concurrent.Future) Matcher(java.util.regex.Matcher) MissingEnvironmentVariableException(io.cryostat.net.MissingEnvironmentVariableException) Duration(java.time.Duration) Map(java.util.Map) AuthenticationScheme(io.cryostat.net.AuthenticationScheme) ResponseBody(okhttp3.ResponseBody) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException) Request(okhttp3.Request) LoadingCache(com.github.benmanes.caffeine.cache.LoadingCache) URIBuilder(org.apache.http.client.utils.URIBuilder) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ResourceType(io.cryostat.net.security.ResourceType) Set(java.util.Set) TokenReview(io.fabric8.kubernetes.api.model.authentication.TokenReview) Collectors(java.util.stream.Collectors) Lazy(dagger.Lazy) StandardCharsets(java.nio.charset.StandardCharsets) Objects(java.util.Objects) Base64(java.util.Base64) List(java.util.List) Stream(java.util.stream.Stream) TokenNotFoundException(io.cryostat.net.TokenNotFoundException) Optional(java.util.Optional) Pattern(java.util.regex.Pattern) HttpUrl(okhttp3.HttpUrl) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) JsonIgnoreProperties(com.fasterxml.jackson.annotation.JsonIgnoreProperties) SelfSubjectAccessReviewBuilder(io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReviewBuilder) SelfSubjectAccessReview(io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReview) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ResourceVerb(io.cryostat.net.security.ResourceVerb) Function(java.util.function.Function) Supplier(java.util.function.Supplier) AbstractAuthManager(io.cryostat.net.AbstractAuthManager) Name(jdk.jfr.Name) Category(jdk.jfr.Category) Logger(io.cryostat.core.log.Logger) Response(okhttp3.Response) Call(okhttp3.Call) Callback(okhttp3.Callback) Environment(io.cryostat.core.sys.Environment) AuthorizationErrorException(io.cryostat.net.AuthorizationErrorException) Caffeine(com.github.benmanes.caffeine.cache.Caffeine) Executor(java.util.concurrent.Executor) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) IOException(java.io.IOException) ResourceAttributes(io.fabric8.kubernetes.api.model.authorization.v1.ResourceAttributes) OpenShiftClient(io.fabric8.openshift.client.OpenShiftClient) PermissionDeniedException(io.cryostat.net.PermissionDeniedException) TokenReviewBuilder(io.fabric8.kubernetes.api.model.authentication.TokenReviewBuilder) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) OkHttpClient(okhttp3.OkHttpClient) TokenReviewStatus(io.fabric8.kubernetes.api.model.authentication.TokenReviewStatus) DigestUtils(org.apache.commons.codec.digest.DigestUtils) Collections(java.util.Collections) ClassPropertiesLoader(io.cryostat.util.resource.ClassPropertiesLoader) ResourceAction(io.cryostat.net.security.ResourceAction) CompletableFuture(java.util.concurrent.CompletableFuture) PermissionDeniedException(io.cryostat.net.PermissionDeniedException) SelfSubjectAccessReviewBuilder(io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReviewBuilder) SelfSubjectAccessReview(io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReview) URISyntaxException(java.net.URISyntaxException) MissingEnvironmentVariableException(io.cryostat.net.MissingEnvironmentVariableException) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException) TokenNotFoundException(io.cryostat.net.TokenNotFoundException) AuthorizationErrorException(io.cryostat.net.AuthorizationErrorException) IOException(java.io.IOException) PermissionDeniedException(io.cryostat.net.PermissionDeniedException) ExecutionException(java.util.concurrent.ExecutionException)

Example 4 with SelfSubjectAccessReview

use of io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReview in project cryostat by cryostatio.

the class OpenShiftAuthManagerTest method shouldValidateTokenWithSufficientPermissions.

@Test
void shouldValidateTokenWithSufficientPermissions() throws Exception {
    SelfSubjectAccessReview accessReview = new SelfSubjectAccessReviewBuilder().withNewStatus().withAllowed(true).endStatus().build();
    server.expect().post().withPath(SUBJECT_REVIEW_API_PATH).andReturn(HttpURLConnection.HTTP_CREATED, accessReview).once();
    MatcherAssert.assertThat(mgr.validateToken(() -> "token", Set.of(ResourceAction.READ_RECORDING)).get(), Matchers.is(true));
}
Also used : SelfSubjectAccessReview(io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReview) SelfSubjectAccessReviewBuilder(io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReviewBuilder) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 5 with SelfSubjectAccessReview

use of io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReview in project cryostat by cryostatio.

the class OpenShiftAuthManagerTest method shouldValidateExpectedPermissionsPerSecuredResource.

@ParameterizedTest
@EnumSource(mode = EnumSource.Mode.MATCH_ANY, names = "^([a-zA-Z]+_(RECORDING|CERTIFICATE))$")
void shouldValidateExpectedPermissionsPerSecuredResource(ResourceAction resourceAction) throws Exception {
    String expectedVerb;
    if (resourceAction.getVerb() == ResourceVerb.CREATE) {
        expectedVerb = "create";
    } else if (resourceAction.getVerb() == ResourceVerb.READ) {
        expectedVerb = "get";
    } else if (resourceAction.getVerb() == ResourceVerb.UPDATE) {
        expectedVerb = "patch";
    } else if (resourceAction.getVerb() == ResourceVerb.DELETE) {
        expectedVerb = "delete";
    } else {
        throw new IllegalArgumentException(resourceAction.getVerb().toString());
    }
    Set<String> expectedGroups;
    Set<String> expectedResources;
    if (resourceAction.getResource() == ResourceType.RECORDING) {
        expectedGroups = Set.of("operator.cryostat.io");
        expectedResources = Set.of("recordings");
    } else if (resourceAction.getResource() == ResourceType.CERTIFICATE) {
        expectedGroups = Set.of("apps", "");
        expectedResources = Set.of("deployments", "pods");
    } else {
        throw new IllegalArgumentException(resourceAction.getResource().toString());
    }
    SelfSubjectAccessReview accessReview = new SelfSubjectAccessReviewBuilder().withNewStatus().withAllowed(true).endStatus().build();
    server.expect().post().withPath(SUBJECT_REVIEW_API_PATH).andReturn(HttpURLConnection.HTTP_CREATED, accessReview).times(expectedResources.size());
    String token = "abcd1234";
    MatcherAssert.assertThat(mgr.validateToken(() -> token, Set.of(resourceAction)).get(), Matchers.is(true));
    // server.takeRequest() returns each request fired in order, so do that repeatedly and drop
    // any initial requests that are made by the OpenShiftClient that aren't directly
    // SelfSubjectAccessReview requests made by the OpenShiftAuthManager
    int maxDroppedRequests = 2;
    int requestCount = 0;
    RecordedRequest req = server.takeRequest();
    while (true) {
        if (++requestCount > maxDroppedRequests) {
            throw new IllegalStateException();
        }
        String path = req.getPath();
        if (SUBJECT_REVIEW_API_PATH.equals(path)) {
            break;
        }
        req = server.takeRequest();
    }
    MatcherAssert.assertThat(req.getPath(), Matchers.equalTo(SUBJECT_REVIEW_API_PATH));
    MatcherAssert.assertThat(tokenProvider.token, Matchers.equalTo(token));
    MatcherAssert.assertThat(req.getMethod(), Matchers.equalTo("POST"));
    SelfSubjectAccessReview body = gson.fromJson(req.getBody().readUtf8(), SelfSubjectAccessReview.class);
    MatcherAssert.assertThat(body.getSpec().getResourceAttributes().getVerb(), Matchers.equalTo(expectedVerb));
    Set<String> actualGroups = new HashSet<>();
    Set<String> actualResources = new HashSet<>();
    actualGroups.add(body.getSpec().getResourceAttributes().getGroup());
    actualResources.add(body.getSpec().getResourceAttributes().getResource());
    // start at 1 because we've already checked the first request above
    for (int i = 1; i < expectedResources.size(); i++) {
        // request should already have been made, so there should be no time waiting for a
        // request to come in
        req = server.takeRequest(1, TimeUnit.SECONDS);
        if (req == null) {
            throw new IllegalStateException("Expected request not received in time");
        }
        body = gson.fromJson(req.getBody().readUtf8(), SelfSubjectAccessReview.class);
        MatcherAssert.assertThat(req.getPath(), Matchers.equalTo(SUBJECT_REVIEW_API_PATH));
        MatcherAssert.assertThat(tokenProvider.token, Matchers.equalTo(token));
        MatcherAssert.assertThat(req.getMethod(), Matchers.equalTo("POST"));
        MatcherAssert.assertThat(body.getSpec().getResourceAttributes().getVerb(), Matchers.equalTo(expectedVerb));
        actualGroups.add(body.getSpec().getResourceAttributes().getGroup());
        actualResources.add(body.getSpec().getResourceAttributes().getResource());
    }
    MatcherAssert.assertThat(actualGroups, Matchers.equalTo(expectedGroups));
    MatcherAssert.assertThat(actualResources, Matchers.equalTo(expectedResources));
}
Also used : RecordedRequest(okhttp3.mockwebserver.RecordedRequest) SelfSubjectAccessReview(io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReview) SelfSubjectAccessReviewBuilder(io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReviewBuilder) HashSet(java.util.HashSet) EnumSource(org.junit.jupiter.params.provider.EnumSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Aggregations

SelfSubjectAccessReview (io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReview)12 SelfSubjectAccessReviewBuilder (io.fabric8.kubernetes.api.model.authorization.v1.SelfSubjectAccessReviewBuilder)12 Test (org.junit.jupiter.api.Test)6 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)6 KubernetesClient (io.fabric8.kubernetes.client.KubernetesClient)3 BufferedReader (java.io.BufferedReader)3 StringReader (java.io.StringReader)3 List (java.util.List)3 ExecutionException (java.util.concurrent.ExecutionException)3 PermissionDeniedException (io.cryostat.net.PermissionDeniedException)2 EnableKubernetesMockClient (io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient)2 KubernetesMockServer (io.fabric8.kubernetes.client.server.mock.KubernetesMockServer)2 Serialization (io.fabric8.kubernetes.client.utils.Serialization)2 HttpURLConnection (java.net.HttpURLConnection)2 Charset (java.nio.charset.Charset)2 Path (java.nio.file.Path)2 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 RecordedRequest (okhttp3.mockwebserver.RecordedRequest)2 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)2