use of io.fabric8.kubernetes.api.model.authorization.v1beta1.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());
}
}
use of io.fabric8.kubernetes.api.model.authorization.v1beta1.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());
}
use of io.fabric8.kubernetes.api.model.authorization.v1beta1.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;
});
}
use of io.fabric8.kubernetes.api.model.authorization.v1beta1.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));
}
use of io.fabric8.kubernetes.api.model.authorization.v1beta1.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));
}
Aggregations