mirror of https://github.com/apache/nifi.git
NIFI-2389 Refactoring identity mapping and applying it to FileAuthorizer for initial admin, cluster nodes, and legacy authorized users. This closes #719
This commit is contained in:
parent
52bc23f5db
commit
c3b4872b55
|
@ -27,6 +27,8 @@ import org.apache.nifi.authorization.file.generated.Policy;
|
||||||
import org.apache.nifi.authorization.file.generated.Users;
|
import org.apache.nifi.authorization.file.generated.Users;
|
||||||
import org.apache.nifi.authorization.resource.ResourceFactory;
|
import org.apache.nifi.authorization.resource.ResourceFactory;
|
||||||
import org.apache.nifi.authorization.resource.ResourceType;
|
import org.apache.nifi.authorization.resource.ResourceType;
|
||||||
|
import org.apache.nifi.authorization.util.IdentityMapping;
|
||||||
|
import org.apache.nifi.authorization.util.IdentityMappingUtil;
|
||||||
import org.apache.nifi.components.PropertyValue;
|
import org.apache.nifi.components.PropertyValue;
|
||||||
import org.apache.nifi.util.NiFiProperties;
|
import org.apache.nifi.util.NiFiProperties;
|
||||||
import org.apache.nifi.util.file.FileUtils;
|
import org.apache.nifi.util.file.FileUtils;
|
||||||
|
@ -106,6 +108,7 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
||||||
private String legacyAuthorizedUsersFile;
|
private String legacyAuthorizedUsersFile;
|
||||||
private Set<String> nodeIdentities;
|
private Set<String> nodeIdentities;
|
||||||
private List<PortDTO> ports = new ArrayList<>();
|
private List<PortDTO> ports = new ArrayList<>();
|
||||||
|
private List<IdentityMapping> identityMappings;
|
||||||
|
|
||||||
private final AtomicReference<AuthorizationsHolder> authorizationsHolder = new AtomicReference<>();
|
private final AtomicReference<AuthorizationsHolder> authorizationsHolder = new AtomicReference<>();
|
||||||
|
|
||||||
|
@ -160,9 +163,12 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extract the identity mappings from nifi.properties if any are provided
|
||||||
|
identityMappings = Collections.unmodifiableList(IdentityMappingUtil.getIdentityMappings(properties));
|
||||||
|
|
||||||
// get the value of the initial admin identity
|
// get the value of the initial admin identity
|
||||||
final PropertyValue initialAdminIdentityProp = configurationContext.getProperty(PROP_INITIAL_ADMIN_IDENTITY);
|
final PropertyValue initialAdminIdentityProp = configurationContext.getProperty(PROP_INITIAL_ADMIN_IDENTITY);
|
||||||
initialAdminIdentity = initialAdminIdentityProp == null ? null : initialAdminIdentityProp.getValue();
|
initialAdminIdentity = initialAdminIdentityProp == null ? null : IdentityMappingUtil.mapIdentity(initialAdminIdentityProp.getValue(), identityMappings);
|
||||||
|
|
||||||
// get the value of the legacy authorized users file
|
// get the value of the legacy authorized users file
|
||||||
final PropertyValue legacyAuthorizedUsersProp = configurationContext.getProperty(PROP_LEGACY_AUTHORIZED_USERS_FILE);
|
final PropertyValue legacyAuthorizedUsersProp = configurationContext.getProperty(PROP_LEGACY_AUTHORIZED_USERS_FILE);
|
||||||
|
@ -173,7 +179,7 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
||||||
for (Map.Entry<String,String> entry : configurationContext.getProperties().entrySet()) {
|
for (Map.Entry<String,String> entry : configurationContext.getProperties().entrySet()) {
|
||||||
Matcher matcher = NODE_IDENTITY_PATTERN.matcher(entry.getKey());
|
Matcher matcher = NODE_IDENTITY_PATTERN.matcher(entry.getKey());
|
||||||
if (matcher.matches() && !StringUtils.isBlank(entry.getValue())) {
|
if (matcher.matches() && !StringUtils.isBlank(entry.getValue())) {
|
||||||
nodeIdentities.add(entry.getValue());
|
nodeIdentities.add(IdentityMappingUtil.mapIdentity(entry.getValue(), identityMappings));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,7 +368,7 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
||||||
// get all the user DNs into a list
|
// get all the user DNs into a list
|
||||||
List<String> userIdentities = new ArrayList<>();
|
List<String> userIdentities = new ArrayList<>();
|
||||||
for (org.apache.nifi.user.generated.User legacyUser : users.getUser()) {
|
for (org.apache.nifi.user.generated.User legacyUser : users.getUser()) {
|
||||||
userIdentities.add(legacyUser.getDn());
|
userIdentities.add(IdentityMappingUtil.mapIdentity(legacyUser.getDn(), identityMappings));
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort the list and pull out the first identity
|
// sort the list and pull out the first identity
|
||||||
|
@ -376,7 +382,7 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
||||||
|
|
||||||
for (org.apache.nifi.user.generated.User legacyUser : users.getUser()) {
|
for (org.apache.nifi.user.generated.User legacyUser : users.getUser()) {
|
||||||
// create the identifier of the new user based on the DN
|
// create the identifier of the new user based on the DN
|
||||||
final String legacyUserDn = legacyUser.getDn();
|
final String legacyUserDn = IdentityMappingUtil.mapIdentity(legacyUser.getDn(), identityMappings);
|
||||||
final String userIdentifier = UUID.nameUUIDFromBytes(legacyUserDn.getBytes(StandardCharsets.UTF_8)).toString();
|
final String userIdentifier = UUID.nameUUIDFromBytes(legacyUserDn.getBytes(StandardCharsets.UTF_8)).toString();
|
||||||
|
|
||||||
// create the new User and add it to the list of users
|
// create the new User and add it to the list of users
|
||||||
|
@ -421,10 +427,13 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
||||||
|
|
||||||
if (portDTO.getUserAccessControl() != null) {
|
if (portDTO.getUserAccessControl() != null) {
|
||||||
for (String userAccessControl : portDTO.getUserAccessControl()) {
|
for (String userAccessControl : portDTO.getUserAccessControl()) {
|
||||||
|
// need to perform the identity mapping on the access control so it matches the identities in the User objects
|
||||||
|
final String mappedUserAccessControl = IdentityMappingUtil.mapIdentity(userAccessControl, identityMappings);
|
||||||
|
|
||||||
// find a user where the identity is the userAccessControl
|
// find a user where the identity is the userAccessControl
|
||||||
org.apache.nifi.authorization.file.generated.User foundUser = null;
|
org.apache.nifi.authorization.file.generated.User foundUser = null;
|
||||||
for (org.apache.nifi.authorization.file.generated.User jaxbUser : authorizations.getUsers().getUser()) {
|
for (org.apache.nifi.authorization.file.generated.User jaxbUser : authorizations.getUsers().getUser()) {
|
||||||
if (jaxbUser.getIdentity().equals(userAccessControl)) {
|
if (jaxbUser.getIdentity().equals(mappedUserAccessControl)) {
|
||||||
foundUser = jaxbUser;
|
foundUser = jaxbUser;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@ import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
@ -36,6 +38,7 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
@ -43,6 +46,7 @@ import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ -112,6 +116,7 @@ public class FileAuthorizerTest {
|
||||||
private File restore;
|
private File restore;
|
||||||
private File flow;
|
private File flow;
|
||||||
private File flowNoPorts;
|
private File flowNoPorts;
|
||||||
|
private File flowWithDns;
|
||||||
|
|
||||||
private AuthorizerConfigurationContext configurationContext;
|
private AuthorizerConfigurationContext configurationContext;
|
||||||
|
|
||||||
|
@ -131,6 +136,9 @@ public class FileAuthorizerTest {
|
||||||
flowNoPorts = new File("src/test/resources/flow-no-ports.xml.gz");
|
flowNoPorts = new File("src/test/resources/flow-no-ports.xml.gz");
|
||||||
FileUtils.ensureDirectoryExistAndCanAccess(flowNoPorts.getParentFile());
|
FileUtils.ensureDirectoryExistAndCanAccess(flowNoPorts.getParentFile());
|
||||||
|
|
||||||
|
flowWithDns = new File("src/test/resources/flow-with-dns.xml.gz");
|
||||||
|
FileUtils.ensureDirectoryExistAndCanAccess(flowWithDns.getParentFile());
|
||||||
|
|
||||||
properties = mock(NiFiProperties.class);
|
properties = mock(NiFiProperties.class);
|
||||||
when(properties.getRestoreDirectory()).thenReturn(restore.getParentFile());
|
when(properties.getRestoreDirectory()).thenReturn(restore.getParentFile());
|
||||||
when(properties.getFlowConfigurationFile()).thenReturn(flow);
|
when(properties.getFlowConfigurationFile()).thenReturn(flow);
|
||||||
|
@ -332,6 +340,62 @@ public class FileAuthorizerTest {
|
||||||
return resourceActionMap;
|
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(restore.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));
|
||||||
|
|
||||||
|
writeAuthorizationsFile(primary, EMPTY_AUTHORIZATIONS_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(true, "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(false, "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)
|
@Test(expected = AuthorizerCreationException.class)
|
||||||
public void testOnConfiguredWhenBadLegacyUsersFileProvided() throws Exception {
|
public void testOnConfiguredWhenBadLegacyUsersFileProvided() throws Exception {
|
||||||
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_LEGACY_AUTHORIZED_USERS_FILE)))
|
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_LEGACY_AUTHORIZED_USERS_FILE)))
|
||||||
|
@ -473,6 +537,31 @@ public class FileAuthorizerTest {
|
||||||
assertFalse(foundRootGroupPolicy);
|
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(restore.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));
|
||||||
|
|
||||||
|
writeAuthorizationsFile(primary, EMPTY_AUTHORIZATIONS_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
|
@Test
|
||||||
public void testOnConfiguredWhenNodeIdentitiesProvided() throws Exception {
|
public void testOnConfiguredWhenNodeIdentitiesProvided() throws Exception {
|
||||||
final String adminIdentity = "admin-user";
|
final String adminIdentity = "admin-user";
|
||||||
|
@ -513,6 +602,43 @@ public class FileAuthorizerTest {
|
||||||
assertTrue(proxyWritePolicy.getUsers().contains(nodeUser2.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(restore.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);
|
||||||
|
|
||||||
|
writeAuthorizationsFile(primary, EMPTY_AUTHORIZATIONS_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);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOnConfiguredWhenAuthorizationsFileDoesNotExist() {
|
public void testOnConfiguredWhenAuthorizationsFileDoesNotExist() {
|
||||||
authorizer.onConfigured(configurationContext);
|
authorizer.onConfigured(configurationContext);
|
||||||
|
@ -1178,4 +1304,18 @@ public class FileAuthorizerTest {
|
||||||
}
|
}
|
||||||
return FileUtils.deleteFile(file, null, 10);
|
return FileUtils.deleteFile(file, null, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NiFiProperties getNiFiProperties(final Properties properties) {
|
||||||
|
final NiFiProperties nifiProperties = Mockito.mock(NiFiProperties.class);
|
||||||
|
when(nifiProperties.stringPropertyNames()).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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<users>
|
||||||
|
<user dn="CN=user1, OU=Apache NiFi, O=Apache, L=Santa Monica, ST=CA, C=US" group="group1">
|
||||||
|
<role name="ROLE_MONITOR"/>
|
||||||
|
</user>
|
||||||
|
<user dn="CN=user2, OU=Apache NiFi, O=Apache, L=Santa Monica, ST=CA, C=US">
|
||||||
|
<role name="ROLE_PROVENANCE"/>
|
||||||
|
</user>
|
||||||
|
<user dn="CN=user3, OU=Apache NiFi, O=Apache, L=Santa Monica, ST=CA, C=US">
|
||||||
|
<role name="ROLE_DFM"/>
|
||||||
|
</user>
|
||||||
|
<user dn="CN=user4, OU=Apache NiFi, O=Apache, L=Santa Monica, ST=CA, C=US">
|
||||||
|
<role name="ROLE_ADMIN"/>
|
||||||
|
</user>
|
||||||
|
<user dn="CN=user5, OU=Apache NiFi, O=Apache, L=Santa Monica, ST=CA, C=US">
|
||||||
|
<role name="ROLE_PROXY"/>
|
||||||
|
</user>
|
||||||
|
<user dn="CN=user6, OU=Apache NiFi, O=Apache, L=Santa Monica, ST=CA, C=US">
|
||||||
|
<role name="ROLE_NIFI"/>
|
||||||
|
</user>
|
||||||
|
</users>
|
Binary file not shown.
|
@ -35,6 +35,10 @@
|
||||||
<groupId>org.apache.nifi</groupId>
|
<groupId>org.apache.nifi</groupId>
|
||||||
<artifactId>nifi-expression-language</artifactId>
|
<artifactId>nifi-expression-language</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.nifi</groupId>
|
||||||
|
<artifactId>nifi-properties</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.security</groupId>
|
<groupId>org.springframework.security</groupId>
|
||||||
<artifactId>spring-security-core</artifactId>
|
<artifactId>spring-security-core</artifactId>
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holder to pass around the key, pattern, and replacement from an identity mapping in NiFiProperties.
|
||||||
|
*/
|
||||||
|
public class IdentityMapping {
|
||||||
|
|
||||||
|
private final String key;
|
||||||
|
private final Pattern pattern;
|
||||||
|
private final String replacementValue;
|
||||||
|
|
||||||
|
public IdentityMapping(String key, Pattern pattern, String replacementValue) {
|
||||||
|
this.key = key;
|
||||||
|
this.pattern = pattern;
|
||||||
|
this.replacementValue = replacementValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pattern getPattern() {
|
||||||
|
return pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReplacementValue() {
|
||||||
|
return replacementValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,145 @@
|
||||||
|
/*
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.nifi.util.NiFiProperties;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class IdentityMappingUtil {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(IdentityMappingUtil.class);
|
||||||
|
private static final Pattern backReferencePattern = Pattern.compile("\\$(\\d+)");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the identity mappings from NiFiProperties.
|
||||||
|
*
|
||||||
|
* @param properties the NiFiProperties instance
|
||||||
|
* @return a list of identity mappings
|
||||||
|
*/
|
||||||
|
public static List<IdentityMapping> getIdentityMappings(final NiFiProperties properties) {
|
||||||
|
final List<IdentityMapping> mappings = new ArrayList<>();
|
||||||
|
|
||||||
|
// go through each property
|
||||||
|
for (String propertyName : properties.stringPropertyNames()) {
|
||||||
|
if (StringUtils.startsWith(propertyName, NiFiProperties.SECURITY_IDENTITY_MAPPING_PATTERN_PREFIX)) {
|
||||||
|
final String key = StringUtils.substringAfter(propertyName, NiFiProperties.SECURITY_IDENTITY_MAPPING_PATTERN_PREFIX);
|
||||||
|
final String identityPattern = properties.getProperty(propertyName);
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(identityPattern)) {
|
||||||
|
LOGGER.warn("Identity Mapping property {} was found, but was empty", new Object[]{propertyName});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String identityValueProperty = NiFiProperties.SECURITY_IDENTITY_MAPPING_VALUE_PREFIX + key;
|
||||||
|
final String identityValue = properties.getProperty(identityValueProperty);
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(identityValue)) {
|
||||||
|
LOGGER.warn("Identity Mapping property {} was found, but corresponding value {} was not found",
|
||||||
|
new Object[]{propertyName, identityValueProperty});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final IdentityMapping identityMapping = new IdentityMapping(key, Pattern.compile(identityPattern), identityValue);
|
||||||
|
mappings.add(identityMapping);
|
||||||
|
|
||||||
|
LOGGER.debug("Found Identity Mapping with key = {}, pattern = {}, value = {}",
|
||||||
|
new Object[] {key, identityPattern, identityValue});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort the list by the key so users can control the ordering in nifi.properties
|
||||||
|
Collections.sort(mappings, new Comparator<IdentityMapping>() {
|
||||||
|
@Override
|
||||||
|
public int compare(IdentityMapping m1, IdentityMapping m2) {
|
||||||
|
return m1.getKey().compareTo(m2.getKey());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return mappings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the given identity against each provided mapping and performs the mapping using the first one that matches.
|
||||||
|
* If none match then the identity is returned as is.
|
||||||
|
*
|
||||||
|
* @param identity the identity to map
|
||||||
|
* @param mappings the mappings
|
||||||
|
* @return the mapped identity, or the same identity if no mappings matched
|
||||||
|
*/
|
||||||
|
public static String mapIdentity(final String identity, List<IdentityMapping> mappings) {
|
||||||
|
for (IdentityMapping mapping : mappings) {
|
||||||
|
Matcher m = mapping.getPattern().matcher(identity);
|
||||||
|
if (m.matches()) {
|
||||||
|
final String pattern = mapping.getPattern().pattern();
|
||||||
|
final String replacementValue = escapeLiteralBackReferences(mapping.getReplacementValue(), m.groupCount());
|
||||||
|
return identity.replaceAll(pattern, replacementValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we find a back reference that is not valid, then we will treat it as a literal string. For example, if we have 3 capturing
|
||||||
|
// groups and the Replacement Value has the value is "I owe $8 to him", then we want to treat the $8 as a literal "$8", rather
|
||||||
|
// than attempting to use it as a back reference.
|
||||||
|
private static String escapeLiteralBackReferences(final String unescaped, final int numCapturingGroups) {
|
||||||
|
if (numCapturingGroups == 0) {
|
||||||
|
return unescaped;
|
||||||
|
}
|
||||||
|
|
||||||
|
String value = unescaped;
|
||||||
|
final Matcher backRefMatcher = backReferencePattern.matcher(value);
|
||||||
|
while (backRefMatcher.find()) {
|
||||||
|
final String backRefNum = backRefMatcher.group(1);
|
||||||
|
if (backRefNum.startsWith("0")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final int originalBackRefIndex = Integer.parseInt(backRefNum);
|
||||||
|
int backRefIndex = originalBackRefIndex;
|
||||||
|
|
||||||
|
// if we have a replacement value like $123, and we have less than 123 capturing groups, then
|
||||||
|
// we want to truncate the 3 and use capturing group 12; if we have less than 12 capturing groups,
|
||||||
|
// then we want to truncate the 2 and use capturing group 1; if we don't have a capturing group then
|
||||||
|
// we want to truncate the 1 and get 0.
|
||||||
|
while (backRefIndex > numCapturingGroups && backRefIndex >= 10) {
|
||||||
|
backRefIndex /= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backRefIndex > numCapturingGroups) {
|
||||||
|
final StringBuilder sb = new StringBuilder(value.length() + 1);
|
||||||
|
final int groupStart = backRefMatcher.start(1);
|
||||||
|
|
||||||
|
sb.append(value.substring(0, groupStart - 1));
|
||||||
|
sb.append("\\");
|
||||||
|
sb.append(value.substring(groupStart - 1));
|
||||||
|
value = sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -31,6 +31,9 @@
|
||||||
are no other users, groups, and policies defined. If this property is specified then a Legacy Authorized
|
are no other users, groups, and policies defined. If this property is specified then a Legacy Authorized
|
||||||
Users File can not be specified.
|
Users File can not be specified.
|
||||||
|
|
||||||
|
NOTE: Any identity mapping rules specified in nifi.properties will also be applied to the initial admin identity,
|
||||||
|
so the value should be the unmapped identity.
|
||||||
|
|
||||||
- Legacy Authorized Users File - The full path to an existing authorized-users.xml that will be automatically
|
- Legacy Authorized Users File - The full path to an existing authorized-users.xml that will be automatically
|
||||||
converted to the new authorizations model. If this property is specified then an Initial Admin Identity can
|
converted to the new authorizations model. If this property is specified then an Initial Admin Identity can
|
||||||
not be specified, and this property will only be used when there are no other users, groups, and policies defined.
|
not be specified, and this property will only be used when there are no other users, groups, and policies defined.
|
||||||
|
@ -39,6 +42,9 @@
|
||||||
should be defined, so that every node knows about every other node. If not clustered these properties can be ignored.
|
should be defined, so that every node knows about every other node. If not clustered these properties can be ignored.
|
||||||
The name of each property must be unique, for example for a three node cluster:
|
The name of each property must be unique, for example for a three node cluster:
|
||||||
"Node Identity A", "Node Identity B", "Node Identity C" or "Node Identity 1", "Node Identity 2", "Node Identity 3"
|
"Node Identity A", "Node Identity B", "Node Identity C" or "Node Identity 1", "Node Identity 2", "Node Identity 3"
|
||||||
|
|
||||||
|
NOTE: Any identity mapping rules specified in nifi.properties will also be applied to the node identities,
|
||||||
|
so the values should be the unmapped identities (i.e. full DN from a certificate).
|
||||||
-->
|
-->
|
||||||
<authorizer>
|
<authorizer>
|
||||||
<identifier>file-provider</identifier>
|
<identifier>file-provider</identifier>
|
||||||
|
|
|
@ -16,18 +16,15 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.web.security;
|
package org.apache.nifi.web.security;
|
||||||
|
|
||||||
|
import org.apache.nifi.authorization.util.IdentityMapping;
|
||||||
|
import org.apache.nifi.authorization.util.IdentityMappingUtil;
|
||||||
import org.apache.nifi.util.NiFiProperties;
|
import org.apache.nifi.util.NiFiProperties;
|
||||||
import org.apache.nifi.util.StringUtils;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.security.authentication.AuthenticationProvider;
|
import org.springframework.security.authentication.AuthenticationProvider;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base AuthenticationProvider that provides common functionality to mapping identities.
|
* Base AuthenticationProvider that provides common functionality to mapping identities.
|
||||||
|
@ -35,7 +32,6 @@ import java.util.regex.Pattern;
|
||||||
public abstract class NiFiAuthenticationProvider implements AuthenticationProvider {
|
public abstract class NiFiAuthenticationProvider implements AuthenticationProvider {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(NiFiAuthenticationProvider.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(NiFiAuthenticationProvider.class);
|
||||||
private static final Pattern backReferencePattern = Pattern.compile("\\$(\\d+)");
|
|
||||||
|
|
||||||
private NiFiProperties properties;
|
private NiFiProperties properties;
|
||||||
private List<IdentityMapping> mappings;
|
private List<IdentityMapping> mappings;
|
||||||
|
@ -45,55 +41,7 @@ public abstract class NiFiAuthenticationProvider implements AuthenticationProvid
|
||||||
*/
|
*/
|
||||||
public NiFiAuthenticationProvider(final NiFiProperties properties) {
|
public NiFiAuthenticationProvider(final NiFiProperties properties) {
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.mappings = Collections.unmodifiableList(getIdentityMappings(properties));
|
this.mappings = Collections.unmodifiableList(IdentityMappingUtil.getIdentityMappings(properties));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds the identity mappings from NiFiProperties.
|
|
||||||
*
|
|
||||||
* @param properties the NiFiProperties instance
|
|
||||||
* @return a list of identity mappings
|
|
||||||
*/
|
|
||||||
private List<IdentityMapping> getIdentityMappings(final NiFiProperties properties) {
|
|
||||||
final List<IdentityMapping> mappings = new ArrayList<>();
|
|
||||||
|
|
||||||
// go through each property
|
|
||||||
for (String propertyName : properties.stringPropertyNames()) {
|
|
||||||
if (StringUtils.startsWith(propertyName, NiFiProperties.SECURITY_IDENTITY_MAPPING_PATTERN_PREFIX)) {
|
|
||||||
final String key = StringUtils.substringAfter(propertyName, NiFiProperties.SECURITY_IDENTITY_MAPPING_PATTERN_PREFIX);
|
|
||||||
final String identityPattern = properties.getProperty(propertyName);
|
|
||||||
|
|
||||||
if (StringUtils.isBlank(identityPattern)) {
|
|
||||||
LOGGER.warn("Identity Mapping property {} was found, but was empty", new Object[]{propertyName});
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String identityValueProperty = NiFiProperties.SECURITY_IDENTITY_MAPPING_VALUE_PREFIX + key;
|
|
||||||
final String identityValue = properties.getProperty(identityValueProperty);
|
|
||||||
|
|
||||||
if (StringUtils.isBlank(identityValue)) {
|
|
||||||
LOGGER.warn("Identity Mapping property {} was found, but corresponding value {} was not found",
|
|
||||||
new Object[]{propertyName, identityValueProperty});
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final IdentityMapping identityMapping = new IdentityMapping(key, Pattern.compile(identityPattern), identityValue);
|
|
||||||
mappings.add(identityMapping);
|
|
||||||
|
|
||||||
LOGGER.debug("Found Identity Mapping with key = {}, pattern = {}, value = {}",
|
|
||||||
new Object[] {key, identityPattern, identityValue});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sort the list by the key so users can control the ordering in nifi.properties
|
|
||||||
Collections.sort(mappings, new Comparator<IdentityMapping>() {
|
|
||||||
@Override
|
|
||||||
public int compare(IdentityMapping m1, IdentityMapping m2) {
|
|
||||||
return m1.getKey().compareTo(m2.getKey());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return mappings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<IdentityMapping> getMappings() {
|
public List<IdentityMapping> getMappings() {
|
||||||
|
@ -101,85 +49,7 @@ public abstract class NiFiAuthenticationProvider implements AuthenticationProvid
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String mapIdentity(final String identity) {
|
protected String mapIdentity(final String identity) {
|
||||||
for (IdentityMapping mapping : mappings) {
|
return IdentityMappingUtil.mapIdentity(identity, mappings);
|
||||||
Matcher m = mapping.getPattern().matcher(identity);
|
|
||||||
if (m.matches()) {
|
|
||||||
final String pattern = mapping.getPattern().pattern();
|
|
||||||
final String replacementValue = escapeLiteralBackReferences(mapping.getReplacementValue(), m.groupCount());
|
|
||||||
return identity.replaceAll(pattern, replacementValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return identity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we find a back reference that is not valid, then we will treat it as a literal string. For example, if we have 3 capturing
|
|
||||||
// groups and the Replacement Value has the value is "I owe $8 to him", then we want to treat the $8 as a literal "$8", rather
|
|
||||||
// than attempting to use it as a back reference.
|
|
||||||
private static String escapeLiteralBackReferences(final String unescaped, final int numCapturingGroups) {
|
|
||||||
if (numCapturingGroups == 0) {
|
|
||||||
return unescaped;
|
|
||||||
}
|
|
||||||
|
|
||||||
String value = unescaped;
|
|
||||||
final Matcher backRefMatcher = backReferencePattern.matcher(value);
|
|
||||||
while (backRefMatcher.find()) {
|
|
||||||
final String backRefNum = backRefMatcher.group(1);
|
|
||||||
if (backRefNum.startsWith("0")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final int originalBackRefIndex = Integer.parseInt(backRefNum);
|
|
||||||
int backRefIndex = originalBackRefIndex;
|
|
||||||
|
|
||||||
// if we have a replacement value like $123, and we have less than 123 capturing groups, then
|
|
||||||
// we want to truncate the 3 and use capturing group 12; if we have less than 12 capturing groups,
|
|
||||||
// then we want to truncate the 2 and use capturing group 1; if we don't have a capturing group then
|
|
||||||
// we want to truncate the 1 and get 0.
|
|
||||||
while (backRefIndex > numCapturingGroups && backRefIndex >= 10) {
|
|
||||||
backRefIndex /= 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backRefIndex > numCapturingGroups) {
|
|
||||||
final StringBuilder sb = new StringBuilder(value.length() + 1);
|
|
||||||
final int groupStart = backRefMatcher.start(1);
|
|
||||||
|
|
||||||
sb.append(value.substring(0, groupStart - 1));
|
|
||||||
sb.append("\\");
|
|
||||||
sb.append(value.substring(groupStart - 1));
|
|
||||||
value = sb.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holder to pass around the key, pattern, and replacement from an identity mapping in NiFiProperties.
|
|
||||||
*/
|
|
||||||
public static final class IdentityMapping {
|
|
||||||
|
|
||||||
private final String key;
|
|
||||||
private final Pattern pattern;
|
|
||||||
private final String replacementValue;
|
|
||||||
|
|
||||||
public IdentityMapping(String key, Pattern pattern, String replacementValue) {
|
|
||||||
this.key = key;
|
|
||||||
this.pattern = pattern;
|
|
||||||
this.replacementValue = replacementValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getKey() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pattern getPattern() {
|
|
||||||
return pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getReplacementValue() {
|
|
||||||
return replacementValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.web.security;
|
package org.apache.nifi.web.security;
|
||||||
|
|
||||||
|
import org.apache.nifi.authorization.util.IdentityMapping;
|
||||||
import org.apache.nifi.util.NiFiProperties;
|
import org.apache.nifi.util.NiFiProperties;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
@ -45,7 +46,7 @@ public class NiFiAuthenticationProviderTest {
|
||||||
final NiFiProperties nifiProperties = getNiFiProperties(properties);
|
final NiFiProperties nifiProperties = getNiFiProperties(properties);
|
||||||
|
|
||||||
TestableNiFiAuthenticationProvider provider = new TestableNiFiAuthenticationProvider(nifiProperties);
|
TestableNiFiAuthenticationProvider provider = new TestableNiFiAuthenticationProvider(nifiProperties);
|
||||||
List<NiFiAuthenticationProvider.IdentityMapping> mappings = provider.getMappings();
|
List<IdentityMapping> mappings = provider.getMappings();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
assertEquals("dn", mappings.get(0).getKey());
|
assertEquals("dn", mappings.get(0).getKey());
|
||||||
assertEquals(pattern, mappings.get(0).getPattern().pattern());
|
assertEquals(pattern, mappings.get(0).getPattern().pattern());
|
||||||
|
@ -58,7 +59,7 @@ public class NiFiAuthenticationProviderTest {
|
||||||
final NiFiProperties nifiProperties = getNiFiProperties(properties);
|
final NiFiProperties nifiProperties = getNiFiProperties(properties);
|
||||||
|
|
||||||
TestableNiFiAuthenticationProvider provider = new TestableNiFiAuthenticationProvider(nifiProperties);
|
TestableNiFiAuthenticationProvider provider = new TestableNiFiAuthenticationProvider(nifiProperties);
|
||||||
List<NiFiAuthenticationProvider.IdentityMapping> mappings = provider.getMappings();
|
List<IdentityMapping> mappings = provider.getMappings();
|
||||||
assertEquals(0, mappings.size());
|
assertEquals(0, mappings.size());
|
||||||
|
|
||||||
final String identity = "john";
|
final String identity = "john";
|
||||||
|
@ -74,7 +75,7 @@ public class NiFiAuthenticationProviderTest {
|
||||||
final NiFiProperties nifiProperties = getNiFiProperties(properties);
|
final NiFiProperties nifiProperties = getNiFiProperties(properties);
|
||||||
|
|
||||||
TestableNiFiAuthenticationProvider provider = new TestableNiFiAuthenticationProvider(nifiProperties);
|
TestableNiFiAuthenticationProvider provider = new TestableNiFiAuthenticationProvider(nifiProperties);
|
||||||
List<NiFiAuthenticationProvider.IdentityMapping> mappings = provider.getMappings();
|
List<IdentityMapping> mappings = provider.getMappings();
|
||||||
assertEquals(0, mappings.size());
|
assertEquals(0, mappings.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +87,7 @@ public class NiFiAuthenticationProviderTest {
|
||||||
final NiFiProperties nifiProperties = getNiFiProperties(properties);
|
final NiFiProperties nifiProperties = getNiFiProperties(properties);
|
||||||
|
|
||||||
TestableNiFiAuthenticationProvider provider = new TestableNiFiAuthenticationProvider(nifiProperties);
|
TestableNiFiAuthenticationProvider provider = new TestableNiFiAuthenticationProvider(nifiProperties);
|
||||||
List<NiFiAuthenticationProvider.IdentityMapping> mappings = provider.getMappings();
|
List<IdentityMapping> mappings = provider.getMappings();
|
||||||
assertEquals(0, mappings.size());
|
assertEquals(0, mappings.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +104,7 @@ public class NiFiAuthenticationProviderTest {
|
||||||
final NiFiProperties nifiProperties = getNiFiProperties(properties);
|
final NiFiProperties nifiProperties = getNiFiProperties(properties);
|
||||||
|
|
||||||
TestableNiFiAuthenticationProvider provider = new TestableNiFiAuthenticationProvider(nifiProperties);
|
TestableNiFiAuthenticationProvider provider = new TestableNiFiAuthenticationProvider(nifiProperties);
|
||||||
List<NiFiAuthenticationProvider.IdentityMapping> mappings = provider.getMappings();
|
List<IdentityMapping> mappings = provider.getMappings();
|
||||||
assertEquals(3, mappings.size());
|
assertEquals(3, mappings.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue