| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.nifi.integration.accesscontrol; |
| |
| import org.apache.nifi.integration.util.NiFiTestAuthorizer; |
| import org.apache.nifi.integration.util.NiFiTestUser; |
| import org.apache.nifi.web.api.dto.LabelDTO; |
| import org.apache.nifi.web.api.dto.RevisionDTO; |
| import org.apache.nifi.web.api.dto.flow.FlowDTO; |
| import org.apache.nifi.web.api.entity.LabelEntity; |
| import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity; |
| import org.junit.jupiter.api.AfterAll; |
| import org.junit.jupiter.api.BeforeAll; |
| import org.junit.jupiter.api.Test; |
| |
| import jakarta.ws.rs.core.Response; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.NONE_CLIENT_ID; |
| import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_CLIENT_ID; |
| import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.READ_WRITE_CLIENT_ID; |
| import static org.apache.nifi.integration.accesscontrol.AccessControlHelper.WRITE_CLIENT_ID; |
| import static org.junit.jupiter.api.Assertions.assertEquals; |
| import static org.junit.jupiter.api.Assertions.assertFalse; |
| import static org.junit.jupiter.api.Assertions.assertNotNull; |
| import static org.junit.jupiter.api.Assertions.assertNull; |
| import static org.junit.jupiter.api.Assertions.assertTrue; |
| |
| /** |
| * Access control test for labels. |
| */ |
| public class ITLabelAccessControl { |
| |
| private static AccessControlHelper helper; |
| |
| @BeforeAll |
| public static void setup() throws Exception { |
| helper = new AccessControlHelper(); |
| } |
| |
| /** |
| * Ensures the READ user can get a label. |
| * |
| * @throws Exception ex |
| */ |
| @Test |
| public void testReadUserGetLabel() throws Exception { |
| final LabelEntity entity = getRandomLabel(helper.getReadUser()); |
| assertTrue(entity.getPermissions().getCanRead()); |
| assertFalse(entity.getPermissions().getCanWrite()); |
| assertNotNull(entity.getComponent()); |
| } |
| |
| /** |
| * Ensures the READ WRITE user can get a label. |
| * |
| * @throws Exception ex |
| */ |
| @Test |
| public void testReadWriteUserGetLabel() throws Exception { |
| final LabelEntity entity = getRandomLabel(helper.getReadWriteUser()); |
| assertTrue(entity.getPermissions().getCanRead()); |
| assertTrue(entity.getPermissions().getCanWrite()); |
| assertNotNull(entity.getComponent()); |
| } |
| |
| /** |
| * Ensures the WRITE user can get a label. |
| * |
| * @throws Exception ex |
| */ |
| @Test |
| public void testWriteUserGetLabel() throws Exception { |
| final LabelEntity entity = getRandomLabel(helper.getWriteUser()); |
| assertFalse(entity.getPermissions().getCanRead()); |
| assertTrue(entity.getPermissions().getCanWrite()); |
| assertNull(entity.getComponent()); |
| } |
| |
| /** |
| * Ensures the NONE user can get a label. |
| * |
| * @throws Exception ex |
| */ |
| @Test |
| public void testNoneUserGetLabel() throws Exception { |
| final LabelEntity entity = getRandomLabel(helper.getNoneUser()); |
| assertFalse(entity.getPermissions().getCanRead()); |
| assertFalse(entity.getPermissions().getCanWrite()); |
| assertNull(entity.getComponent()); |
| } |
| |
| /** |
| * Ensures the READ user cannot put a label. |
| * |
| * @throws Exception ex |
| */ |
| @Test |
| public void testReadUserPutLabel() throws Exception { |
| final LabelEntity entity = getRandomLabel(helper.getReadUser()); |
| assertTrue(entity.getPermissions().getCanRead()); |
| assertFalse(entity.getPermissions().getCanWrite()); |
| assertNotNull(entity.getComponent()); |
| |
| // attempt update the name |
| entity.getRevision().setClientId(READ_CLIENT_ID); |
| entity.getComponent().setLabel("Updated Label"); |
| |
| // perform the request |
| final Response response = updateLabel(helper.getReadUser(), entity); |
| |
| // ensure forbidden response |
| assertEquals(403, response.getStatus()); |
| } |
| |
| /** |
| * Ensures the READ_WRITE user can put a label. |
| * |
| * @throws Exception ex |
| */ |
| @Test |
| public void testReadWriteUserPutLabel() throws Exception { |
| final LabelEntity entity = getRandomLabel(helper.getReadWriteUser()); |
| assertTrue(entity.getPermissions().getCanRead()); |
| assertTrue(entity.getPermissions().getCanWrite()); |
| assertNotNull(entity.getComponent()); |
| |
| final String updatedLabel = "Updated Name"; |
| |
| // attempt to update the name |
| final long version = entity.getRevision().getVersion(); |
| entity.getRevision().setClientId(AccessControlHelper.READ_WRITE_CLIENT_ID); |
| entity.getComponent().setLabel(updatedLabel); |
| |
| // perform the request |
| final Response response = updateLabel(helper.getReadWriteUser(), entity); |
| |
| // ensure successful response |
| assertEquals(200, response.getStatus()); |
| |
| // get the response |
| final LabelEntity responseEntity = response.readEntity(LabelEntity.class); |
| |
| // verify |
| assertEquals(READ_WRITE_CLIENT_ID, responseEntity.getRevision().getClientId()); |
| assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue()); |
| assertEquals(updatedLabel, responseEntity.getComponent().getLabel()); |
| } |
| |
| /** |
| * Ensures the READ_WRITE user can put a label. |
| * |
| * @throws Exception ex |
| */ |
| @Test |
| public void testReadWriteUserPutLabelThroughInheritedPolicy() throws Exception { |
| final LabelEntity entity = createLabel(NiFiTestAuthorizer.NO_POLICY_COMPONENT_NAME); |
| |
| final String updatedLabel = "Updated name"; |
| |
| // attempt to update the name |
| final long version = entity.getRevision().getVersion(); |
| entity.getRevision().setClientId(READ_WRITE_CLIENT_ID); |
| entity.getComponent().setLabel(updatedLabel); |
| |
| // perform the request |
| final Response response = updateLabel(helper.getReadWriteUser(), entity); |
| |
| // ensure successful response |
| assertEquals(200, response.getStatus()); |
| |
| // get the response |
| final LabelEntity responseEntity = response.readEntity(LabelEntity.class); |
| |
| // verify |
| assertEquals(AccessControlHelper.READ_WRITE_CLIENT_ID, responseEntity.getRevision().getClientId()); |
| assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue()); |
| assertEquals(updatedLabel, responseEntity.getComponent().getLabel()); |
| } |
| |
| /** |
| * Ensures the WRITE user can put a label. |
| * |
| * @throws Exception ex |
| */ |
| @Test |
| public void testWriteUserPutLabel() throws Exception { |
| final LabelEntity entity = getRandomLabel(helper.getWriteUser()); |
| assertFalse(entity.getPermissions().getCanRead()); |
| assertTrue(entity.getPermissions().getCanWrite()); |
| assertNull(entity.getComponent()); |
| |
| final String updatedLabel = "Updated Name"; |
| |
| // attempt to update the label |
| final LabelDTO requestDto = new LabelDTO(); |
| requestDto.setId(entity.getId()); |
| requestDto.setLabel(updatedLabel); |
| |
| final long version = entity.getRevision().getVersion(); |
| final RevisionDTO requestRevision = new RevisionDTO(); |
| requestRevision.setVersion(version); |
| requestRevision.setClientId(AccessControlHelper.WRITE_CLIENT_ID); |
| |
| final LabelEntity requestEntity = new LabelEntity(); |
| requestEntity.setId(entity.getId()); |
| requestEntity.setRevision(requestRevision); |
| requestEntity.setComponent(requestDto); |
| |
| // perform the request |
| final Response response = updateLabel(helper.getWriteUser(), requestEntity); |
| |
| // ensure successful response |
| assertEquals(200, response.getStatus()); |
| |
| // get the response |
| final LabelEntity responseEntity = response.readEntity(LabelEntity.class); |
| |
| // verify |
| assertEquals(WRITE_CLIENT_ID, responseEntity.getRevision().getClientId()); |
| assertEquals(version + 1, responseEntity.getRevision().getVersion().longValue()); |
| } |
| |
| /** |
| * Ensures the NONE user cannot put a label. |
| * |
| * @throws Exception ex |
| */ |
| @Test |
| public void testNoneUserPutLabel() throws Exception { |
| final LabelEntity entity = getRandomLabel(helper.getNoneUser()); |
| assertFalse(entity.getPermissions().getCanRead()); |
| assertFalse(entity.getPermissions().getCanWrite()); |
| assertNull(entity.getComponent()); |
| |
| final String updatedName = "Updated Name"; |
| |
| // attempt to update the name |
| final LabelDTO requestDto = new LabelDTO(); |
| requestDto.setId(entity.getId()); |
| requestDto.setLabel(updatedName); |
| |
| final long version = entity.getRevision().getVersion(); |
| final RevisionDTO requestRevision = new RevisionDTO(); |
| requestRevision.setVersion(version); |
| requestRevision.setClientId(AccessControlHelper.NONE_CLIENT_ID); |
| |
| final LabelEntity requestEntity = new LabelEntity(); |
| requestEntity.setId(entity.getId()); |
| requestEntity.setRevision(requestRevision); |
| requestEntity.setComponent(requestDto); |
| |
| // perform the request |
| final Response response = updateLabel(helper.getNoneUser(), requestEntity); |
| |
| // ensure forbidden response |
| assertEquals(403, response.getStatus()); |
| } |
| |
| /** |
| * Ensures the READ user cannot delete a label. |
| * |
| * @throws Exception ex |
| */ |
| @Test |
| public void testReadUserDeleteLabel() throws Exception { |
| verifyDelete(helper.getReadUser(), AccessControlHelper.READ_CLIENT_ID, 403); |
| } |
| |
| /** |
| * Ensures the READ WRITE user can delete a label. |
| * |
| * @throws Exception ex |
| */ |
| @Test |
| public void testReadWriteUserDeleteLabel() throws Exception { |
| verifyDelete(helper.getReadWriteUser(), AccessControlHelper.READ_WRITE_CLIENT_ID, 200); |
| } |
| |
| /** |
| * Ensures the WRITE user can delete a label. |
| * |
| * @throws Exception ex |
| */ |
| @Test |
| public void testWriteUserDeleteLabel() throws Exception { |
| verifyDelete(helper.getWriteUser(), AccessControlHelper.WRITE_CLIENT_ID, 200); |
| } |
| |
| /** |
| * Ensures the NONE user can delete a label. |
| * |
| * @throws Exception ex |
| */ |
| @Test |
| public void testNoneUserDeleteLabel() throws Exception { |
| verifyDelete(helper.getNoneUser(), NONE_CLIENT_ID, 403); |
| } |
| |
| private LabelEntity getRandomLabel(final NiFiTestUser user) throws Exception { |
| final String url = helper.getBaseUrl() + "/flow/process-groups/root"; |
| |
| // get the labels |
| final Response response = user.testGet(url); |
| |
| // ensure the response was successful |
| assertEquals(200, response.getStatus()); |
| |
| // unmarshal |
| final ProcessGroupFlowEntity flowEntity = response.readEntity(ProcessGroupFlowEntity.class); |
| final FlowDTO flowDto = flowEntity.getProcessGroupFlow().getFlow(); |
| final Set<LabelEntity> labels = flowDto.getLabels(); |
| |
| // ensure the correct number of labels |
| assertFalse(labels.isEmpty()); |
| |
| // use the first label as the target |
| Iterator<LabelEntity> labelIter = labels.iterator(); |
| assertTrue(labelIter.hasNext()); |
| return labelIter.next(); |
| } |
| |
| private Response updateLabel(final NiFiTestUser user, final LabelEntity entity) throws Exception { |
| final String url = helper.getBaseUrl() + "/labels/" + entity.getId(); |
| |
| // perform the request |
| return user.testPut(url, entity); |
| } |
| |
| private LabelEntity createLabel(final String name) throws Exception { |
| String url = helper.getBaseUrl() + "/process-groups/root/labels"; |
| |
| // create the label |
| LabelDTO label = new LabelDTO(); |
| label.setLabel(name); |
| |
| // create the revision |
| final RevisionDTO revision = new RevisionDTO(); |
| revision.setClientId(READ_WRITE_CLIENT_ID); |
| revision.setVersion(0L); |
| |
| // create the entity body |
| LabelEntity entity = new LabelEntity(); |
| entity.setRevision(revision); |
| entity.setComponent(label); |
| |
| // perform the request |
| Response response = helper.getReadWriteUser().testPost(url, entity); |
| |
| // ensure the request is successful |
| assertEquals(201, response.getStatus()); |
| |
| // get the entity body |
| entity = response.readEntity(LabelEntity.class); |
| |
| // verify creation |
| label = entity.getComponent(); |
| assertEquals(name, label.getLabel()); |
| |
| // get the label id |
| return entity; |
| } |
| |
| private void verifyDelete(final NiFiTestUser user, final String clientId, final int responseCode) throws Exception { |
| final LabelEntity entity = createLabel("Copy"); |
| |
| // create the entity body |
| final Map<String, String> queryParams = new HashMap<>(); |
| queryParams.put("version", String.valueOf(entity.getRevision().getVersion())); |
| queryParams.put("clientId", clientId); |
| |
| // perform the request |
| Response response = user.testDelete(entity.getUri(), queryParams); |
| |
| // ensure the request is failed with a forbidden status code |
| assertEquals(responseCode, response.getStatus()); |
| } |
| |
| @AfterAll |
| public static void cleanup() throws Exception { |
| helper.cleanup(); |
| } |
| } |