/*
* 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.authorization;
import org.apache.nifi.attribute.expression.language.StandardPropertyValue;
import org.apache.nifi.authorization.AuthorizationResult.Result;
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
import org.apache.nifi.authorization.resource.ResourceFactory;
import org.apache.nifi.authorization.resource.ResourceType;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.util.file.FileUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class FileAuthorizerTest {
private static final String EMPTY_AUTHORIZATIONS_CONCISE =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+ "<authorizations/>";
private static final String EMPTY_TENANTS_CONCISE =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+ "<tenants/>";
private static final String EMPTY_AUTHORIZATIONS =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+ "<authorizations>"
+ "</authorizations>";
private static final String EMPTY_TENANTS =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+ "<tenants>"
+ "</tenants>";
private static final String BAD_SCHEMA_AUTHORIZATIONS =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+ "<authorization>"
+ "</authorization>";
private static final String BAD_SCHEMA_TENANTS =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+ "<tenant>"
+ "</tenant>";
private static final String SIMPLE_AUTHORIZATION_BY_USER =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
"<authorizations>" +
" <policies>" +
" <policy identifier=\"policy-1\" resource=\"/flow\" action=\"R\">" +
" <user identifier=\"user-1\" />" +
" </policy>" +
" </policies>" +
"</authorizations>";
private static final String SIMPLE_TENANTS_BY_USER =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
"<tenants>" +
" <users>" +
" <user identifier=\"user-1\" identity=\"user-1\"/>" +
" <user identifier=\"user-2\" identity=\"user-2\"/>" +
" </users>" +
"</tenants>";
private static final String AUTHORIZATIONS =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
"<authorizations>" +
" <policies>" +
" <policy identifier=\"policy-1\" resource=\"/flow\" action=\"R\">" +
" <group identifier=\"group-1\" />" +
" <group identifier=\"group-2\" />" +
" <user identifier=\"user-1\" />" +
" </policy>" +
" <policy identifier=\"policy-2\" resource=\"/flow\" action=\"W\">" +
" <user identifier=\"user-2\" />" +
" </policy>" +
" </policies>" +
"</authorizations>";
private static final String TENANTS =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
"<tenants>" +
" <groups>" +
" <group identifier=\"group-1\" name=\"group-1\">" +
" <user identifier=\"user-1\" />" +
" </group>" +
" <group identifier=\"group-2\" name=\"group-2\">" +
" <user identifier=\"user-2\" />" +
" </group>" +
" </groups>" +
" <users>" +
" <user identifier=\"user-1\" identity=\"user-1\" />" +
" <user identifier=\"user-2\" identity=\"user-2\" />" +
" </users>" +
"</tenants>";
private static final String TENANTS_FOR_ADMIN_AND_NODES =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
"<tenants>" +
" <users>" +
" <user identifier=\"admin-user\" identity=\"admin-user\"/>" +
" <user identifier=\"node1\" identity=\"node1\"/>" +
" <user identifier=\"node2\" identity=\"node2\"/>" +
" </users>" +
"</tenants>";
// This is the root group id from the flow.xml.gz in src/test/resources
private static final String ROOT_GROUP_ID = "e530e14c-adcf-41c2-b5d6-d9a59ba8765c";
private NiFiProperties properties;
private FileAuthorizer authorizer;
private File primaryAuthorizations;
private File primaryTenants;
private File restoreAuthorizations;
private File restoreTenants;
private File flow;
private File flowNoPorts;
private File flowWithDns;
private AuthorizerConfigurationContext configurationContext;
@Before
public void setup() throws IOException {
// primary authorizations
primaryAuthorizations = new File("target/authorizations/authorizations.xml");
FileUtils.ensureDirectoryExistAndCanAccess(primaryAuthorizations.getParentFile());
// primary tenants
primaryTenants = new File("target/authorizations/users.xml");
FileUtils.ensureDirectoryExistAndCanAccess(primaryTenants.getParentFile());
// restore authorizations
restoreAuthorizations = new File("target/restore/authorizations.xml");
FileUtils.ensureDirectoryExistAndCanAccess(restoreAuthorizations.getParentFile());
// restore authorizations
restoreTenants = new File("target/restore/users.xml");
FileUtils.ensureDirectoryExistAndCanAccess(restoreTenants.getParentFile());
flow = new File("src/test/resources/flow.xml.gz");
FileUtils.ensureDirectoryExistAndCanAccess(flow.getParentFile());
flowNoPorts = new File("src/test/resources/flow-no-ports.xml.gz");
FileUtils.ensureDirectoryExistAndCanAccess(flowNoPorts.getParentFile());
flowWithDns = new File("src/test/resources/flow-with-dns.xml.gz");
FileUtils.ensureDirectoryExistAndCanAccess(flowWithDns.getParentFile());
properties = mock(NiFiProperties.class);
when(properties.getRestoreDirectory()).thenReturn(restoreAuthorizations.getParentFile());
when(properties.getFlowConfigurationFile()).thenReturn(flow);
configurationContext = mock(AuthorizerConfigurationContext.class);
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_AUTHORIZATIONS_FILE))).thenReturn(new StandardPropertyValue(primaryAuthorizations.getPath(), null));
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_TENANTS_FILE))).thenReturn(new StandardPropertyValue(primaryTenants.getPath(), null));
authorizer = new FileAuthorizer();
authorizer.setNiFiProperties(properties);
authorizer.initialize(null);
}
@After
public void cleanup() throws Exception {
deleteFile(primaryAuthorizations);
deleteFile(primaryTenants);
deleteFile(restoreAuthorizations);
deleteFile(restoreTenants);
}
@Test
public void testOnConfiguredWhenLegacyUsersFileProvidedWithOverlappingRoles() throws Exception {
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_LEGACY_AUTHORIZED_USERS_FILE)))
.thenReturn(new StandardPropertyValue("src/test/resources/authorized-users-multirole.xml", null));
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(primaryTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
final Set<User> users = authorizer.getUsers();
assertEquals(1, users.size());
UsersAndAccessPolicies usersAndAccessPolicies = authorizer.getUsersAndAccessPolicies();
assertNotNull(usersAndAccessPolicies.getAccessPolicy(ResourceType.Flow.getValue(), RequestAction.READ));
assertNotNull(usersAndAccessPolicies.getAccessPolicy(ResourceType.Controller.getValue(), RequestAction.READ));
assertNotNull(usersAndAccessPolicies.getAccessPolicy(ResourceType.Controller.getValue(), RequestAction.WRITE));
assertNotNull(usersAndAccessPolicies.getAccessPolicy(ResourceType.System.getValue(), RequestAction.READ));
assertNotNull(usersAndAccessPolicies.getAccessPolicy(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID, RequestAction.READ));
assertNotNull(usersAndAccessPolicies.getAccessPolicy(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID, RequestAction.WRITE));
}
@Test
public void testOnConfiguredWhenLegacyUsersFileProvidedAndFlowHasNoPorts() throws Exception {
properties = mock(NiFiProperties.class);
when(properties.getRestoreDirectory()).thenReturn(restoreAuthorizations.getParentFile());
when(properties.getFlowConfigurationFile()).thenReturn(flowNoPorts);
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_LEGACY_AUTHORIZED_USERS_FILE)))
.thenReturn(new StandardPropertyValue("src/test/resources/authorized-users.xml", null));
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(primaryTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
boolean foundDataTransferPolicy = false;
for (AccessPolicy policy : authorizer.getAccessPolicies()) {
if (policy.getResource().contains(ResourceType.DataTransfer.name())) {
foundDataTransferPolicy = true;
break;
}
}
assertFalse(foundDataTransferPolicy);
}
@Test
public void testOnConfiguredWhenLegacyUsersFileProvided() throws Exception {
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_LEGACY_AUTHORIZED_USERS_FILE)))
.thenReturn(new StandardPropertyValue("src/test/resources/authorized-users.xml", null));
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(primaryTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
// verify all users got created correctly
final Set<User> users = authorizer.getUsers();
assertEquals(6, users.size());
final User user1 = authorizer.getUserByIdentity("user1");
assertNotNull(user1);
final User user2 = authorizer.getUserByIdentity("user2");
assertNotNull(user2);
final User user3 = authorizer.getUserByIdentity("user3");
assertNotNull(user3);
final User user4 = authorizer.getUserByIdentity("user4");
assertNotNull(user4);
final User user5 = authorizer.getUserByIdentity("user5");
assertNotNull(user5);
final User user6 = authorizer.getUserByIdentity("user6");
assertNotNull(user6);
// verify one group got created
final Set<Group> groups = authorizer.getGroups();
assertEquals(1, groups.size());
final Group group1 = groups.iterator().next();
assertEquals("group1", group1.getName());
// verify more than one policy got created
final Set<AccessPolicy> policies = authorizer.getAccessPolicies();
assertTrue(policies.size() > 0);
// verify user1's policies
final Map<String,Set<RequestAction>> user1Policies = getResourceActions(policies, user1);
assertEquals(4, user1Policies.size());
assertTrue(user1Policies.containsKey(ResourceType.Flow.getValue()));
assertEquals(1, user1Policies.get(ResourceType.Flow.getValue()).size());
assertTrue(user1Policies.get(ResourceType.Flow.getValue()).contains(RequestAction.READ));
assertTrue(user1Policies.containsKey(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID));
assertEquals(1, user1Policies.get(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID).size());
assertTrue(user1Policies.get(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID).contains(RequestAction.READ));
// verify user2's policies
final Map<String,Set<RequestAction>> user2Policies = getResourceActions(policies, user2);
assertEquals(2, user2Policies.size());
assertTrue(user2Policies.containsKey(ResourceType.Provenance.getValue()));
assertEquals(1, user2Policies.get(ResourceType.Provenance.getValue()).size());
assertTrue(user2Policies.get(ResourceType.Provenance.getValue()).contains(RequestAction.READ));
// verify user3's policies
final Map<String,Set<RequestAction>> user3Policies = getResourceActions(policies, user3);
assertEquals(6, user3Policies.size());
assertTrue(user3Policies.containsKey(ResourceType.Flow.getValue()));
assertEquals(1, user3Policies.get(ResourceType.Flow.getValue()).size());
assertTrue(user3Policies.get(ResourceType.Flow.getValue()).contains(RequestAction.READ));
assertTrue(user3Policies.containsKey(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID));
assertEquals(2, user3Policies.get(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID).size());
assertTrue(user3Policies.get(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID).contains(RequestAction.WRITE));
// verify user4's policies
final Map<String,Set<RequestAction>> user4Policies = getResourceActions(policies, user4);
assertEquals(6, user4Policies.size());
assertTrue(user4Policies.containsKey(ResourceType.Flow.getValue()));
assertEquals(1, user4Policies.get(ResourceType.Flow.getValue()).size());
assertTrue(user4Policies.get(ResourceType.Flow.getValue()).contains(RequestAction.READ));
assertTrue(user4Policies.containsKey(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID));
assertEquals(1, user4Policies.get(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID).size());
assertTrue(user4Policies.get(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID).contains(RequestAction.READ));
assertTrue(user4Policies.containsKey(ResourceType.Tenant.getValue()));
assertEquals(2, user4Policies.get(ResourceType.Tenant.getValue()).size());
assertTrue(user4Policies.get(ResourceType.Tenant.getValue()).contains(RequestAction.WRITE));
assertTrue(user4Policies.containsKey(ResourceType.Policy.getValue()));
assertEquals(2, user4Policies.get(ResourceType.Policy.getValue()).size());
assertTrue(user4Policies.get(ResourceType.Policy.getValue()).contains(RequestAction.WRITE));
// verify user5's policies
final Map<String,Set<RequestAction>> user5Policies = getResourceActions(policies, user5);
assertEquals(2, user5Policies.size());
assertTrue(user5Policies.containsKey(ResourceType.Proxy.getValue()));
assertEquals(1, user5Policies.get(ResourceType.Proxy.getValue()).size());
assertTrue(user5Policies.get(ResourceType.Proxy.getValue()).contains(RequestAction.WRITE));
// verify user6's policies
final Map<String,Set<RequestAction>> user6Policies = getResourceActions(policies, user6);
assertEquals(3, user6Policies.size());
assertTrue(user6Policies.containsKey(ResourceType.SiteToSite.getValue()));
assertEquals(1, user6Policies.get(ResourceType.SiteToSite.getValue()).size());
assertTrue(user6Policies.get(ResourceType.SiteToSite.getValue()).contains(RequestAction.READ));
final Resource inputPortResource = ResourceFactory.getDataTransferResource(
ResourceFactory.getComponentResource(ResourceType.InputPort, "2f7d1606-b090-4be7-a592-a5b70fb55531", "TCP Input"));
final AccessPolicy inputPortPolicy = authorizer.getUsersAndAccessPolicies().getAccessPolicy(inputPortResource.getIdentifier(), RequestAction.WRITE);
assertNotNull(inputPortPolicy);
assertEquals(1, inputPortPolicy.getUsers().size());
assertTrue(inputPortPolicy.getUsers().contains(user6.getIdentifier()));
assertEquals(1, inputPortPolicy.getGroups().size());
assertTrue(inputPortPolicy.getGroups().contains(group1.getIdentifier()));
final Resource outputPortResource = ResourceFactory.getDataTransferResource(
ResourceFactory.getComponentResource(ResourceType.OutputPort, "2f7d1606-b090-4be7-a592-a5b70fb55532", "TCP Output"));
final AccessPolicy outputPortPolicy = authorizer.getUsersAndAccessPolicies().getAccessPolicy(outputPortResource.getIdentifier(), RequestAction.WRITE);
assertNotNull(outputPortPolicy);
assertEquals(1, outputPortPolicy.getUsers().size());
assertTrue(outputPortPolicy.getUsers().contains(user4.getIdentifier()));
}
private Map<String,Set<RequestAction>> getResourceActions(final Set<AccessPolicy> policies, final User user) {
Map<String,Set<RequestAction>> resourceActionMap = new HashMap<>();
for (AccessPolicy accessPolicy : policies) {
if (accessPolicy.getUsers().contains(user.getIdentifier())) {
Set<RequestAction> actions = resourceActionMap.get(accessPolicy.getResource());
if (actions == null) {
actions = new HashSet<>();
resourceActionMap.put(accessPolicy.getResource(), actions);
}
actions.add(accessPolicy.getAction());
}
}
return resourceActionMap;
}
@Test
public void testOnConfiguredWhenLegacyUsersFileProvidedWithIdentityMappings() throws Exception {
final Properties props = new Properties();
props.setProperty("nifi.security.identity.mapping.pattern.dn1", "^CN=(.*?), OU=(.*?), O=(.*?), L=(.*?), ST=(.*?), C=(.*?)$");
props.setProperty("nifi.security.identity.mapping.value.dn1", "$1");
properties = getNiFiProperties(props);
when(properties.getRestoreDirectory()).thenReturn(restoreAuthorizations.getParentFile());
when(properties.getFlowConfigurationFile()).thenReturn(flowWithDns);
authorizer.setNiFiProperties(properties);
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_LEGACY_AUTHORIZED_USERS_FILE)))
.thenReturn(new StandardPropertyValue("src/test/resources/authorized-users-with-dns.xml", null));
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(primaryTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
final User user1 = authorizer.getUserByIdentity("user1");
assertNotNull(user1);
final User user2 = authorizer.getUserByIdentity("user2");
assertNotNull(user2);
final User user3 = authorizer.getUserByIdentity("user3");
assertNotNull(user3);
final User user4 = authorizer.getUserByIdentity("user4");
assertNotNull(user4);
final User user5 = authorizer.getUserByIdentity("user5");
assertNotNull(user5);
final User user6 = authorizer.getUserByIdentity("user6");
assertNotNull(user6);
// verify one group got created
final Set<Group> groups = authorizer.getGroups();
assertEquals(1, groups.size());
final Group group1 = groups.iterator().next();
assertEquals("group1", group1.getName());
final Resource inputPortResource = ResourceFactory.getDataTransferResource(
ResourceFactory.getComponentResource(ResourceType.InputPort, "2f7d1606-b090-4be7-a592-a5b70fb55531", "TCP Input"));
final AccessPolicy inputPortPolicy = authorizer.getUsersAndAccessPolicies().getAccessPolicy(inputPortResource.getIdentifier(), RequestAction.WRITE);
assertNotNull(inputPortPolicy);
assertEquals(1, inputPortPolicy.getUsers().size());
assertTrue(inputPortPolicy.getUsers().contains(user6.getIdentifier()));
assertEquals(1, inputPortPolicy.getGroups().size());
assertTrue(inputPortPolicy.getGroups().contains(group1.getIdentifier()));
final Resource outputPortResource = ResourceFactory.getDataTransferResource(
ResourceFactory.getComponentResource(ResourceType.OutputPort, "2f7d1606-b090-4be7-a592-a5b70fb55532", "TCP Output"));
final AccessPolicy outputPortPolicy = authorizer.getUsersAndAccessPolicies().getAccessPolicy(outputPortResource.getIdentifier(), RequestAction.WRITE);
assertNotNull(outputPortPolicy);
assertEquals(1, outputPortPolicy.getUsers().size());
assertTrue(outputPortPolicy.getUsers().contains(user4.getIdentifier()));
}
@Test(expected = AuthorizerCreationException.class)
public void testOnConfiguredWhenBadLegacyUsersFileProvided() throws Exception {
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_LEGACY_AUTHORIZED_USERS_FILE)))
.thenReturn(new StandardPropertyValue("src/test/resources/does-not-exist.xml", null));
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(primaryTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
}
@Test(expected = AuthorizerCreationException.class)
public void testOnConfiguredWhenInitialAdminAndLegacyUsersProvided() throws Exception {
final String adminIdentity = "admin-user";
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_INITIAL_ADMIN_IDENTITY)))
.thenReturn(new StandardPropertyValue(adminIdentity, null));
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_LEGACY_AUTHORIZED_USERS_FILE)))
.thenReturn(new StandardPropertyValue("src/test/resources/authorized-users.xml", null));
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(primaryTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
}
@Test
public void testOnConfiguredWhenInitialAdminNotProvided() throws Exception {
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(primaryTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
final Set<User> users = authorizer.getUsers();
assertEquals(0, users.size());
final Set<AccessPolicy> policies = authorizer.getAccessPolicies();
assertEquals(0, policies.size());
}
@Test
public void testOnConfiguredWhenInitialAdminProvided() throws Exception {
final String adminIdentity = "admin-user";
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_INITIAL_ADMIN_IDENTITY)))
.thenReturn(new StandardPropertyValue(adminIdentity, null));
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(primaryTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
final Set<User> users = authorizer.getUsers();
assertEquals(1, users.size());
final User adminUser = users.iterator().next();
assertEquals(adminIdentity, adminUser.getIdentity());
final Set<AccessPolicy> policies = authorizer.getAccessPolicies();
assertEquals(12, policies.size());
final String rootGroupResource = ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID;
boolean foundRootGroupPolicy = false;
for (AccessPolicy policy : policies) {
if (policy.getResource().equals(rootGroupResource)) {
foundRootGroupPolicy = true;
break;
}
}
assertTrue(foundRootGroupPolicy);
}
@Test
public void testOnConfiguredWhenInitialAdminProvidedAndNoFlowExists() throws Exception {
// setup NiFi properties to return a file that does not exist
properties = mock(NiFiProperties.class);
when(properties.getRestoreDirectory()).thenReturn(restoreAuthorizations.getParentFile());
when(properties.getFlowConfigurationFile()).thenReturn(new File("src/test/resources/does-not-exist.xml.gz"));
authorizer.setNiFiProperties(properties);
final String adminIdentity = "admin-user";
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_INITIAL_ADMIN_IDENTITY)))
.thenReturn(new StandardPropertyValue(adminIdentity, null));
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(primaryTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
final Set<User> users = authorizer.getUsers();
assertEquals(1, users.size());
final User adminUser = users.iterator().next();
assertEquals(adminIdentity, adminUser.getIdentity());
final Set<AccessPolicy> policies = authorizer.getAccessPolicies();
assertEquals(8, policies.size());
final String rootGroupResource = ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID;
boolean foundRootGroupPolicy = false;
for (AccessPolicy policy : policies) {
if (policy.getResource().equals(rootGroupResource)) {
foundRootGroupPolicy = true;
break;
}
}
assertFalse(foundRootGroupPolicy);
}
@Test
public void testOnConfiguredWhenInitialAdminProvidedAndFlowIsNull() throws Exception {
// setup NiFi properties to return a file that does not exist
properties = mock(NiFiProperties.class);
when(properties.getRestoreDirectory()).thenReturn(restoreAuthorizations.getParentFile());
when(properties.getFlowConfigurationFile()).thenReturn(null);
authorizer.setNiFiProperties(properties);
final String adminIdentity = "admin-user";
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_INITIAL_ADMIN_IDENTITY)))
.thenReturn(new StandardPropertyValue(adminIdentity, null));
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(primaryTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
final Set<User> users = authorizer.getUsers();
assertEquals(1, users.size());
final User adminUser = users.iterator().next();
assertEquals(adminIdentity, adminUser.getIdentity());
final Set<AccessPolicy> policies = authorizer.getAccessPolicies();
assertEquals(8, policies.size());
final String rootGroupResource = ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID;
boolean foundRootGroupPolicy = false;
for (AccessPolicy policy : policies) {
if (policy.getResource().equals(rootGroupResource)) {
foundRootGroupPolicy = true;
break;
}
}
assertFalse(foundRootGroupPolicy);
}
@Test
public void testOnConfiguredWhenInitialAdminProvidedWithIdentityMapping() throws Exception {
final Properties props = new Properties();
props.setProperty("nifi.security.identity.mapping.pattern.dn1", "^CN=(.*?), OU=(.*?), O=(.*?), L=(.*?), ST=(.*?), C=(.*?)$");
props.setProperty("nifi.security.identity.mapping.value.dn1", "$1_$2_$3");
properties = getNiFiProperties(props);
when(properties.getRestoreDirectory()).thenReturn(restoreAuthorizations.getParentFile());
when(properties.getFlowConfigurationFile()).thenReturn(flow);
authorizer.setNiFiProperties(properties);
final String adminIdentity = "CN=localhost, OU=Apache NiFi, O=Apache, L=Santa Monica, ST=CA, C=US";
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_INITIAL_ADMIN_IDENTITY)))
.thenReturn(new StandardPropertyValue(adminIdentity, null));
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(primaryTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
final Set<User> users = authorizer.getUsers();
assertEquals(1, users.size());
final User adminUser = users.iterator().next();
assertEquals("localhost_Apache NiFi_Apache", adminUser.getIdentity());
}
@Test
public void testOnConfiguredWhenNodeIdentitiesProvided() throws Exception {
final String adminIdentity = "admin-user";
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_INITIAL_ADMIN_IDENTITY)))
.thenReturn(new StandardPropertyValue(adminIdentity, null));
final String nodeIdentity1 = "node1";
final String nodeIdentity2 = "node2";
final Map<String,String> props = new HashMap<>();
props.put("Node Identity 1", nodeIdentity1);
props.put("Node Identity 2", nodeIdentity2);
when(configurationContext.getProperties()).thenReturn(props);
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(primaryTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
User adminUser = authorizer.getUserByIdentity(adminIdentity);
assertNotNull(adminUser);
User nodeUser1 = authorizer.getUserByIdentity(nodeIdentity1);
assertNotNull(nodeUser1);
User nodeUser2 = authorizer.getUserByIdentity(nodeIdentity2);
assertNotNull(nodeUser2);
AccessPolicy proxyWritePolicy = authorizer.getUsersAndAccessPolicies().getAccessPolicy(ResourceType.Proxy.getValue(), RequestAction.WRITE);
assertNotNull(proxyWritePolicy);
assertTrue(proxyWritePolicy.getUsers().contains(nodeUser1.getIdentifier()));
assertTrue(proxyWritePolicy.getUsers().contains(nodeUser2.getIdentifier()));
}
@Test
public void testOnConfiguredWhenNodeIdentitiesProvidedAndUsersAlreadyExist() throws Exception {
final String adminIdentity = "admin-user";
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_INITIAL_ADMIN_IDENTITY)))
.thenReturn(new StandardPropertyValue(adminIdentity, null));
final String nodeIdentity1 = "node1";
final String nodeIdentity2 = "node2";
final Map<String,String> props = new HashMap<>();
props.put("Node Identity 1", nodeIdentity1);
props.put("Node Identity 2", nodeIdentity2);
when(configurationContext.getProperties()).thenReturn(props);
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(primaryTenants, TENANTS_FOR_ADMIN_AND_NODES);
authorizer.onConfigured(configurationContext);
assertEquals(3, authorizer.getUsers().size());
User adminUser = authorizer.getUserByIdentity(adminIdentity);
assertNotNull(adminUser);
User nodeUser1 = authorizer.getUserByIdentity(nodeIdentity1);
assertNotNull(nodeUser1);
User nodeUser2 = authorizer.getUserByIdentity(nodeIdentity2);
assertNotNull(nodeUser2);
AccessPolicy proxyWritePolicy = authorizer.getUsersAndAccessPolicies().getAccessPolicy(ResourceType.Proxy.getValue(), RequestAction.WRITE);
assertNotNull(proxyWritePolicy);
assertTrue(proxyWritePolicy.getUsers().contains(nodeUser1.getIdentifier()));
assertTrue(proxyWritePolicy.getUsers().contains(nodeUser2.getIdentifier()));
}
@Test
public void testOnConfiguredWhenNodeIdentitiesProvidedWithIdentityMappings() throws Exception {
final Properties props = new Properties();
props.setProperty("nifi.security.identity.mapping.pattern.dn1", "^CN=(.*?), OU=(.*?), O=(.*?), L=(.*?), ST=(.*?), C=(.*?)$");
props.setProperty("nifi.security.identity.mapping.value.dn1", "$1");
properties = getNiFiProperties(props);
when(properties.getRestoreDirectory()).thenReturn(restoreAuthorizations.getParentFile());
when(properties.getFlowConfigurationFile()).thenReturn(flow);
authorizer.setNiFiProperties(properties);
final String adminIdentity = "CN=user1, OU=Apache NiFi, O=Apache, L=Santa Monica, ST=CA, C=US";
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_INITIAL_ADMIN_IDENTITY)))
.thenReturn(new StandardPropertyValue(adminIdentity, null));
final String nodeIdentity1 = "CN=node1, OU=Apache NiFi, O=Apache, L=Santa Monica, ST=CA, C=US";
final String nodeIdentity2 = "CN=node2, OU=Apache NiFi, O=Apache, L=Santa Monica, ST=CA, C=US";
final Map<String,String> nodeProps = new HashMap<>();
nodeProps.put("Node Identity 1", nodeIdentity1);
nodeProps.put("Node Identity 2", nodeIdentity2);
when(configurationContext.getProperties()).thenReturn(nodeProps);
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(primaryTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
User adminUser = authorizer.getUserByIdentity("user1");
assertNotNull(adminUser);
User nodeUser1 = authorizer.getUserByIdentity("node1");
assertNotNull(nodeUser1);
User nodeUser2 = authorizer.getUserByIdentity("node2");
assertNotNull(nodeUser2);
}
public void testOnConfiguredWhenTenantsAndAuthorizationsFileDoesNotExist() {
authorizer.onConfigured(configurationContext);
assertEquals(0, authorizer.getAccessPolicies().size());
}
@Test
public void testOnConfiguredWhenAuthorizationsFileDoesNotExist() throws Exception {
writeFile(primaryTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
assertEquals(0, authorizer.getAccessPolicies().size());
}
@Test
public void testOnConfiguredWhenTenantsFileDoesNotExist() throws Exception {
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
authorizer.onConfigured(configurationContext);
assertEquals(0, authorizer.getAccessPolicies().size());
}
@Test
public void testOnConfiguredWhenRestoreDoesNotExist() throws Exception {
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(primaryTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
assertEquals(primaryAuthorizations.length(), restoreAuthorizations.length());
assertEquals(primaryTenants.length(), restoreTenants.length());
}
@Test(expected = AuthorizerCreationException.class)
public void testOnConfiguredWhenPrimaryDoesNotExist() throws Exception {
writeFile(restoreAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
writeFile(restoreTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
}
@Test(expected = AuthorizerCreationException.class)
public void testOnConfiguredWhenPrimaryAuthorizationsDifferentThanRestore() throws Exception {
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS);
writeFile(restoreAuthorizations, EMPTY_AUTHORIZATIONS_CONCISE);
authorizer.onConfigured(configurationContext);
}
@Test(expected = AuthorizerCreationException.class)
public void testOnConfiguredWhenPrimaryTenantsDifferentThanRestore() throws Exception {
writeFile(primaryTenants, EMPTY_TENANTS);
writeFile(restoreTenants, EMPTY_TENANTS_CONCISE);
authorizer.onConfigured(configurationContext);
}
@Test(expected = AuthorizerCreationException.class)
public void testOnConfiguredWithBadAuthorizationsSchema() throws Exception {
writeFile(primaryAuthorizations, BAD_SCHEMA_AUTHORIZATIONS);
authorizer.onConfigured(configurationContext);
}
@Test(expected = AuthorizerCreationException.class)
public void testOnConfiguredWithBadTenantsSchema() throws Exception {
writeFile(primaryTenants, BAD_SCHEMA_TENANTS);
authorizer.onConfigured(configurationContext);
}
@Test
public void testAuthorizedUserAction() throws Exception {
writeFile(primaryAuthorizations, SIMPLE_AUTHORIZATION_BY_USER);
writeFile(primaryTenants, SIMPLE_TENANTS_BY_USER);
authorizer.onConfigured(configurationContext);
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.resource(ResourceFactory.getFlowResource())
.identity("user-1")
.anonymous(false)
.accessAttempt(true)
.action(RequestAction.READ)
.build();
final AuthorizationResult result = authorizer.authorize(request);
assertTrue(Result.Approved.equals(result.getResult()));
}
@Test
public void testUnauthorizedUser() throws Exception {
writeFile(primaryAuthorizations, SIMPLE_AUTHORIZATION_BY_USER);
writeFile(primaryTenants, SIMPLE_TENANTS_BY_USER);
authorizer.onConfigured(configurationContext);
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.resource(ResourceFactory.getFlowResource())
.identity("user-2")
.anonymous(false)
.accessAttempt(true)
.action(RequestAction.READ)
.build();
final AuthorizationResult result = authorizer.authorize(request);
assertFalse(Result.Approved.equals(result.getResult()));
}
@Test
public void testUnauthorizedAction() throws Exception {
writeFile(primaryAuthorizations, SIMPLE_AUTHORIZATION_BY_USER);
writeFile(primaryTenants, SIMPLE_TENANTS_BY_USER);
authorizer.onConfigured(configurationContext);
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.resource(ResourceFactory.getFlowResource())
.identity("user-1")
.anonymous(false)
.accessAttempt(true)
.action(RequestAction.WRITE)
.build();
final AuthorizationResult result = authorizer.authorize(request);
assertFalse(Result.Approved.equals(result.getResult()));
}
@Test
public void testGetAllUsersGroupsPolicies() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
final Set<Group> groups = authorizer.getGroups();
assertEquals(2, groups.size());
boolean foundGroup1 = false;
boolean foundGroup2 = false;
for (Group group : groups) {
if (group.getIdentifier().equals("group-1") && group.getName().equals("group-1")
&& group.getUsers().size() == 1 && group.getUsers().contains("user-1")) {
foundGroup1 = true;
} else if (group.getIdentifier().equals("group-2") && group.getName().equals("group-2")
&& group.getUsers().size() == 1 && group.getUsers().contains("user-2")) {
foundGroup2 = true;
}
}
assertTrue(foundGroup1);
assertTrue(foundGroup2);
final Set<User> users = authorizer.getUsers();
assertEquals(2, users.size());
boolean foundUser1 = false;
boolean foundUser2 = false;
for (User user : users) {
if (user.getIdentifier().equals("user-1") && user.getIdentity().equals("user-1")) {
foundUser1 = true;
} else if (user.getIdentifier().equals("user-2") && user.getIdentity().equals("user-2")) {
foundUser2 = true;
}
}
assertTrue(foundUser1);
assertTrue(foundUser2);
final Set<AccessPolicy> policies = authorizer.getAccessPolicies();
assertEquals(2, policies.size());
boolean foundPolicy1 = false;
boolean foundPolicy2 = false;
for (AccessPolicy policy : policies) {
if (policy.getIdentifier().equals("policy-1")
&& policy.getResource().equals("/flow")
&& policy.getAction() == RequestAction.READ
&& policy.getGroups().size() == 2
&& policy.getGroups().contains("group-1")
&& policy.getGroups().contains("group-2")
&& policy.getUsers().size() == 1
&& policy.getUsers().contains("user-1")) {
foundPolicy1 = true;
} else if (policy.getIdentifier().equals("policy-2")
&& policy.getResource().equals("/flow")
&& policy.getAction() == RequestAction.WRITE
&& policy.getGroups().size() == 0
&& policy.getUsers().size() == 1
&& policy.getUsers().contains("user-2")) {
foundPolicy2 = true;
}
}
assertTrue(foundPolicy1);
assertTrue(foundPolicy2);
}
// --------------- User Tests ------------------------
@Test
public void testAddUser() throws Exception {
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS);
writeFile(primaryTenants, EMPTY_TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(0, authorizer.getUsers().size());
final User user = new User.Builder()
.identifier("user-1")
.identity("user-identity-1")
.build();
final User addedUser = authorizer.addUser(user);
assertNotNull(addedUser);
assertEquals(user.getIdentifier(), addedUser.getIdentifier());
assertEquals(user.getIdentity(), addedUser.getIdentity());
final Set<User> users = authorizer.getUsers();
assertEquals(1, users.size());
}
@Test
public void testGetUserByIdentifierWhenFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getUsers().size());
final String identifier = "user-1";
final User user = authorizer.getUser(identifier);
assertNotNull(user);
assertEquals(identifier, user.getIdentifier());
}
@Test
public void testGetUserByIdentifierWhenNotFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getUsers().size());
final String identifier = "user-X";
final User user = authorizer.getUser(identifier);
assertNull(user);
}
@Test
public void testGetUserByIdentityWhenFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getUsers().size());
final String identity = "user-1";
final User user = authorizer.getUserByIdentity(identity);
assertNotNull(user);
assertEquals(identity, user.getIdentifier());
}
@Test
public void testGetUserByIdentityWhenNotFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getUsers().size());
final String identity = "user-X";
final User user = authorizer.getUserByIdentity(identity);
assertNull(user);
}
@Test
public void testDeleteUser() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getUsers().size());
// retrieve user-1 and verify it exists
final User user = authorizer.getUser("user-1");
assertEquals("user-1", user.getIdentifier());
final AccessPolicy policy1 = authorizer.getAccessPolicy("policy-1");
assertTrue(policy1.getUsers().contains("user-1"));
// delete user-1
final User deletedUser = authorizer.deleteUser(user);
assertNotNull(deletedUser);
assertEquals("user-1", deletedUser.getIdentifier());
// should be one less user
assertEquals(1, authorizer.getUsers().size());
assertNull(authorizer.getUser(user.getIdentifier()));
// verify policy-1 no longer has a reference to user-1
final AccessPolicy updatedPolicy1 = authorizer.getAccessPolicy("policy-1");
assertFalse(updatedPolicy1.getUsers().contains("user-1"));
}
@Test
public void testDeleteUserWhenNotFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getUsers().size());
//user that doesn't exist
final User user = new User.Builder().identifier("user-X").identity("user-identity-X").build();
// should return null and still have 2 users because nothing was deleted
final User deletedUser = authorizer.deleteUser(user);
assertNull(deletedUser);
assertEquals(2, authorizer.getUsers().size());
}
@Test
public void testUpdateUserWhenFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getUsers().size());
final User user = new User.Builder()
.identifier("user-1")
.identity("new-identity")
.build();
final User updatedUser = authorizer.updateUser(user);
assertNotNull(updatedUser);
assertEquals(user.getIdentifier(), updatedUser.getIdentifier());
assertEquals(user.getIdentity(), updatedUser.getIdentity());
}
@Test
public void testUpdateUserWhenNotFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getUsers().size());
final User user = new User.Builder()
.identifier("user-X")
.identity("new-identity")
.build();
final User updatedUser = authorizer.updateUser(user);
assertNull(updatedUser);
}
// --------------- Group Tests ------------------------
@Test
public void testAddGroup() throws Exception {
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS);
writeFile(primaryTenants, EMPTY_TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(0, authorizer.getGroups().size());
final Group group = new Group.Builder()
.identifier("group-id-1")
.name("group-name-1")
.build();
final Group addedGroup = authorizer.addGroup(group);
assertNotNull(addedGroup);
assertEquals(group.getIdentifier(), addedGroup.getIdentifier());
assertEquals(group.getName(), addedGroup.getName());
assertEquals(0, addedGroup.getUsers().size());
final Set<Group> groups = authorizer.getGroups();
assertEquals(1, groups.size());
}
@Test
public void testAddGroupWithUser() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getGroups().size());
final Group group = new Group.Builder()
.identifier("group-id-XXX")
.name("group-name-XXX")
.addUser("user-1")
.build();
final Group addedGroup = authorizer.addGroup(group);
assertNotNull(addedGroup);
assertEquals(group.getIdentifier(), addedGroup.getIdentifier());
assertEquals(group.getName(), addedGroup.getName());
assertEquals(1, addedGroup.getUsers().size());
final Set<Group> groups = authorizer.getGroups();
assertEquals(3, groups.size());
}
@Test(expected = IllegalStateException.class)
public void testAddGroupWhenUserDoesNotExist() throws Exception {
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS);
writeFile(primaryTenants, EMPTY_TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(0, authorizer.getGroups().size());
final Group group = new Group.Builder()
.identifier("group-id-1")
.name("group-name-1")
.addUser("user1")
.build();
authorizer.addGroup(group);
}
@Test
public void testGetGroupByIdentifierWhenFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getGroups().size());
final String identifier = "group-1";
final Group group = authorizer.getGroup(identifier);
assertNotNull(group);
assertEquals(identifier, group.getIdentifier());
}
@Test
public void testGetGroupByIdentifierWhenNotFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getGroups().size());
final String identifier = "group-X";
final Group group = authorizer.getGroup(identifier);
assertNull(group);
}
@Test
public void testDeleteGroupWhenFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getGroups().size());
final AccessPolicy policy1 = authorizer.getAccessPolicy("policy-1");
assertTrue(policy1.getGroups().contains("group-1"));
// retrieve group-1
final Group group = authorizer.getGroup("group-1");
assertEquals("group-1", group.getIdentifier());
// delete group-1
final Group deletedGroup = authorizer.deleteGroup(group);
assertNotNull(deletedGroup);
assertEquals("group-1", deletedGroup.getIdentifier());
// verify there is one less overall group
assertEquals(1, authorizer.getGroups().size());
// verify we can no longer retrieve group-1 by identifier
assertNull(authorizer.getGroup(group.getIdentifier()));
// verify group-1 is no longer in policy-1
final AccessPolicy updatedPolicy1 = authorizer.getAccessPolicy("policy-1");
assertFalse(updatedPolicy1.getGroups().contains("group-1"));
}
@Test
public void testDeleteGroupWhenNotFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getGroups().size());
final Group group = new Group.Builder()
.identifier("group-id-X")
.name("group-name-X")
.build();
final Group deletedGroup = authorizer.deleteGroup(group);
assertNull(deletedGroup);
assertEquals(2, authorizer.getGroups().size());
}
@Test
public void testUpdateGroupWhenFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getGroups().size());
// verify user-1 is in group-1 before the update
final Group groupBefore = authorizer.getGroup("group-1");
assertEquals(1, groupBefore.getUsers().size());
assertTrue(groupBefore.getUsers().contains("user-1"));
final Group group = new Group.Builder()
.identifier("group-1")
.name("new-name")
.addUser("user-2")
.build();
final Group updatedGroup = authorizer.updateGroup(group);
assertEquals(group.getIdentifier(), updatedGroup.getIdentifier());
assertEquals(group.getName(), updatedGroup.getName());
assertEquals(1, updatedGroup.getUsers().size());
assertTrue(updatedGroup.getUsers().contains("user-2"));
}
@Test
public void testUpdateGroupWhenNotFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getGroups().size());
final Group group = new Group.Builder()
.identifier("group-X")
.name("group-X")
.build();
final Group updatedGroup = authorizer.updateGroup(group);
assertNull(updatedGroup);
assertEquals(2, authorizer.getGroups().size());
}
// --------------- AccessPolicy Tests ------------------------
@Test
public void testAddAccessPolicy() throws Exception {
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS);
writeFile(primaryTenants, EMPTY_TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(0, authorizer.getAccessPolicies().size());
final AccessPolicy policy1 = new AccessPolicy.Builder()
.identifier("policy-1")
.resource("resource-1")
.addUser("user-1")
.addGroup("group-1")
.action(RequestAction.READ)
.build();
final AccessPolicy returnedPolicy1 = authorizer.addAccessPolicy(policy1);
assertNotNull(returnedPolicy1);
assertEquals(policy1.getIdentifier(), returnedPolicy1.getIdentifier());
assertEquals(policy1.getResource(), returnedPolicy1.getResource());
assertEquals(policy1.getUsers(), returnedPolicy1.getUsers());
assertEquals(policy1.getGroups(), returnedPolicy1.getGroups());
assertEquals(policy1.getAction(), returnedPolicy1.getAction());
assertEquals(1, authorizer.getAccessPolicies().size());
// second policy for the same resource
final AccessPolicy policy2 = new AccessPolicy.Builder()
.identifier("policy-2")
.resource("resource-1")
.addUser("user-1")
.addGroup("group-1")
.action(RequestAction.READ)
.build();
try {
final AccessPolicy returnedPolicy2 = authorizer.addAccessPolicy(policy2);
Assert.fail("Should have thrown exception");
} catch (Exception e) {
}
assertEquals(1, authorizer.getAccessPolicies().size());
}
@Test
public void testAddAccessPolicyWithEmptyUsersAndGroups() throws Exception {
writeFile(primaryAuthorizations, EMPTY_AUTHORIZATIONS);
writeFile(primaryTenants, EMPTY_TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(0, authorizer.getAccessPolicies().size());
final AccessPolicy policy1 = new AccessPolicy.Builder()
.identifier("policy-1")
.resource("resource-1")
.action(RequestAction.READ)
.build();
final AccessPolicy returnedPolicy1 = authorizer.addAccessPolicy(policy1);
assertNotNull(returnedPolicy1);
assertEquals(policy1.getIdentifier(), returnedPolicy1.getIdentifier());
assertEquals(policy1.getResource(), returnedPolicy1.getResource());
assertEquals(policy1.getUsers(), returnedPolicy1.getUsers());
assertEquals(policy1.getGroups(), returnedPolicy1.getGroups());
assertEquals(policy1.getAction(), returnedPolicy1.getAction());
assertEquals(1, authorizer.getAccessPolicies().size());
}
@Test
public void testGetAccessPolicy() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getAccessPolicies().size());
final AccessPolicy policy = authorizer.getAccessPolicy("policy-1");
assertNotNull(policy);
assertEquals("policy-1", policy.getIdentifier());
assertEquals("/flow", policy.getResource());
assertEquals(RequestAction.READ, policy.getAction());
assertEquals(1, policy.getUsers().size());
assertTrue(policy.getUsers().contains("user-1"));
assertEquals(2, policy.getGroups().size());
assertTrue(policy.getGroups().contains("group-1"));
assertTrue(policy.getGroups().contains("group-2"));
}
@Test
public void testGetAccessPolicyWhenNotFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getAccessPolicies().size());
final AccessPolicy policy = authorizer.getAccessPolicy("policy-X");
assertNull(policy);
}
@Test
public void testUpdateAccessPolicy() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getAccessPolicies().size());
final AccessPolicy policy = new AccessPolicy.Builder()
.identifier("policy-1")
.resource("resource-A")
.addUser("user-A")
.addGroup("group-A")
.action(RequestAction.READ)
.build();
final AccessPolicy updateAccessPolicy = authorizer.updateAccessPolicy(policy);
assertNotNull(updateAccessPolicy);
assertEquals("policy-1", updateAccessPolicy.getIdentifier());
assertEquals("/flow", updateAccessPolicy.getResource());
assertEquals(1, updateAccessPolicy.getUsers().size());
assertTrue(updateAccessPolicy.getUsers().contains("user-A"));
assertEquals(1, updateAccessPolicy.getGroups().size());
assertTrue(updateAccessPolicy.getGroups().contains("group-A"));
assertEquals(RequestAction.READ, updateAccessPolicy.getAction());
}
@Test
public void testUpdateAccessPolicyWhenResourceNotFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getAccessPolicies().size());
final AccessPolicy policy = new AccessPolicy.Builder()
.identifier("policy-XXX")
.resource("resource-A")
.addUser("user-A")
.addGroup("group-A")
.action(RequestAction.READ)
.build();
final AccessPolicy updateAccessPolicy = authorizer.updateAccessPolicy(policy);
assertNull(updateAccessPolicy);
}
@Test
public void testDeleteAccessPolicy() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getAccessPolicies().size());
final AccessPolicy policy = new AccessPolicy.Builder()
.identifier("policy-1")
.resource("resource-A")
.addUser("user-A")
.addGroup("group-A")
.action(RequestAction.READ)
.build();
final AccessPolicy deletedAccessPolicy = authorizer.deleteAccessPolicy(policy);
assertNotNull(deletedAccessPolicy);
assertEquals(policy.getIdentifier(), deletedAccessPolicy.getIdentifier());
// should have one less policy, and get by policy id should return null
assertEquals(1, authorizer.getAccessPolicies().size());
assertNull(authorizer.getAccessPolicy(policy.getIdentifier()));
}
@Test
public void testDeleteAccessPolicyWhenNotFound() throws Exception {
writeFile(primaryAuthorizations, AUTHORIZATIONS);
writeFile(primaryTenants, TENANTS);
authorizer.onConfigured(configurationContext);
assertEquals(2, authorizer.getAccessPolicies().size());
final AccessPolicy policy = new AccessPolicy.Builder()
.identifier("policy-XXX")
.resource("resource-A")
.addUser("user-A")
.addGroup("group-A")
.action(RequestAction.READ)
.build();
final AccessPolicy deletedAccessPolicy = authorizer.deleteAccessPolicy(policy);
assertNull(deletedAccessPolicy);
}
private static void writeFile(final File file, final String content) throws Exception {
byte[] bytes = content.getBytes(StandardCharsets.UTF_8);
try (final FileOutputStream fos = new FileOutputStream(file)) {
fos.write(bytes);
}
}
private static boolean deleteFile(final File file) {
if (file.isDirectory()) {
FileUtils.deleteFilesInDir(file, null, null, true, true);
}
return FileUtils.deleteFile(file, null, 10);
}
private NiFiProperties getNiFiProperties(final Properties properties) {
final NiFiProperties nifiProperties = Mockito.mock(NiFiProperties.class);
when(nifiProperties.getPropertyKeys()).thenReturn(properties.stringPropertyNames());
when(nifiProperties.getProperty(anyString())).then(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocationOnMock) throws Throwable {
return properties.getProperty((String)invocationOnMock.getArguments()[0]);
}
});
return nifiProperties;
}
}