You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2016/06/17 20:33:28 UTC
nifi git commit: NIFI-1804 Adding ability for FileAuthorizer to
automatically convert existing authorized-users.xml to new model - Removing
Resources class from file authorizer and updating ResourceType enum -
Updating ResourceFactory to be in sync with
Repository: nifi
Updated Branches:
refs/heads/master db9a79f79 -> 679ad93f5
NIFI-1804 Adding ability for FileAuthorizer to automatically convert existing authorized-users.xml to new model
- Removing Resources class from file authorizer and updating ResourceType enum
- Updating ResourceFactory to be in sync with ResourceType enum and adding additional required permissions to the auto-conversion
- Adding root process group to the seeding of the initial admin
- Improvement so that users that are already part of a read-write policy, won't end up in a read policy for the same resource
- Removing rootGroupId from authorization context and auto-detecting it from the flow provided through nifi.properties
- This closes #507
Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/679ad93f
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/679ad93f
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/679ad93f
Branch: refs/heads/master
Commit: 679ad93f577e70d5d322fe368a5c333b525fb6da
Parents: db9a79f
Author: Bryan Bende <bb...@apache.org>
Authored: Mon Jun 6 16:32:19 2016 -0400
Committer: Matt Gilman <ma...@gmail.com>
Committed: Fri Jun 17 16:33:00 2016 -0400
----------------------------------------------------------------------
.../AuthorizerConfigurationContext.java | 5 -
.../authorization/AuthorizerFactoryBean.java | 8 +-
.../main/resources/nifi-authorizer-context.xml | 1 -
.../nifi-framework/nifi-file-authorizer/pom.xml | 4 +
.../nifi/authorization/FileAuthorizer.java | 451 ++++++++++++++++---
.../org/apache/nifi/authorization/Role.java | 30 ++
.../nifi/authorization/RoleAccessPolicy.java | 99 ++++
.../nifi/authorization/FileAuthorizerTest.java | 282 +++++++++++-
.../resources/authorized-users-multirole.xml | 21 +
.../src/test/resources/authorized-users.xml | 35 ++
.../src/test/resources/flow.xml.gz | Bin 0 -> 566 bytes
.../StandardAuthorizerConfigurationContext.java | 9 +-
.../authorization/resource/ResourceFactory.java | 370 +++++++++++++--
.../authorization/resource/ResourceType.java | 23 +-
.../src/main/resources/conf/authorizers.xml | 1 +
15 files changed, 1211 insertions(+), 128 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/nifi/blob/679ad93f/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java
----------------------------------------------------------------------
diff --git a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java
index 20cb69e..3721ab4 100644
--- a/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java
+++ b/nifi-api/src/main/java/org/apache/nifi/authorization/AuthorizerConfigurationContext.java
@@ -31,11 +31,6 @@ public interface AuthorizerConfigurationContext {
String getIdentifier();
/**
- * @return the id of the root process group
- */
- String getRootGroupId();
-
- /**
* Retrieves all properties the component currently understands regardless
* of whether a value has been set for them or not. If no value is present
* then its value is null and thus any registered default for the property
http://git-wip-us.apache.org/repos/asf/nifi/blob/679ad93f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
index e4d7318..d061fe1 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/java/org/apache/nifi/authorization/AuthorizerFactoryBean.java
@@ -23,7 +23,6 @@ import org.apache.nifi.authorization.exception.AuthorizerCreationException;
import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
import org.apache.nifi.authorization.generated.Authorizers;
import org.apache.nifi.authorization.generated.Property;
-import org.apache.nifi.controller.FlowController;
import org.apache.nifi.nar.ExtensionManager;
import org.apache.nifi.nar.NarCloseable;
import org.apache.nifi.util.NiFiProperties;
@@ -72,13 +71,8 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
private Authorizer authorizer;
private NiFiProperties properties;
- private FlowController flowController;
private final Map<String, Authorizer> authorizers = new HashMap<>();
- public void setFlowController(FlowController flowController) {
- this.flowController = flowController;
- }
-
@Override
public Authorizer getAuthorizer(String identifier) {
return authorizers.get(identifier);
@@ -195,7 +189,7 @@ public class AuthorizerFactoryBean implements FactoryBean, DisposableBean, Autho
authorizerProperties.put(property.getName(), property.getValue());
}
- return new StandardAuthorizerConfigurationContext(authorizer.getIdentifier(), flowController.getRootGroupId(), authorizerProperties);
+ return new StandardAuthorizerConfigurationContext(authorizer.getIdentifier(), authorizerProperties);
}
private void performMethodInjection(final Authorizer instance, final Class authorizerClass) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
http://git-wip-us.apache.org/repos/asf/nifi/blob/679ad93f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/resources/nifi-authorizer-context.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/resources/nifi-authorizer-context.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/resources/nifi-authorizer-context.xml
index b95db11..71bf684 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/resources/nifi-authorizer-context.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-authorizer/src/main/resources/nifi-authorizer-context.xml
@@ -21,7 +21,6 @@
<!-- user/entity authorizer -->
<bean id="authorizer" class="org.apache.nifi.authorization.AuthorizerFactoryBean">
<property name="properties" ref="nifiProperties"/>
- <property name="flowController" ref="flowController"/>
</bean>
</beans>
http://git-wip-us.apache.org/repos/asf/nifi/blob/679ad93f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/pom.xml
index 4f97220..c7fbb2c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/pom.xml
@@ -94,6 +94,10 @@
<artifactId>nifi-framework-authorization</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-framework-core</artifactId>
+ </dependency>
+ <dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<scope>test</scope>
http://git-wip-us.apache.org/repos/asf/nifi/blob/679ad93f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileAuthorizer.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileAuthorizer.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileAuthorizer.java
index ca99e09..20a43c3 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileAuthorizer.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/FileAuthorizer.java
@@ -25,11 +25,15 @@ import org.apache.nifi.authorization.file.generated.Groups;
import org.apache.nifi.authorization.file.generated.Policies;
import org.apache.nifi.authorization.file.generated.Policy;
import org.apache.nifi.authorization.file.generated.Users;
+import org.apache.nifi.authorization.resource.ResourceType;
import org.apache.nifi.components.PropertyValue;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.util.file.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
@@ -37,18 +41,29 @@ import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.zip.GZIPInputStream;
/**
* Provides identity checks and grants authorities.
@@ -56,30 +71,47 @@ import java.util.concurrent.atomic.AtomicReference;
public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
private static final Logger logger = LoggerFactory.getLogger(FileAuthorizer.class);
- private static final String USERS_XSD = "/authorizations.xsd";
- private static final String JAXB_GENERATED_PATH = "org.apache.nifi.authorization.file.generated";
- private static final JAXBContext JAXB_CONTEXT = initializeJaxbContext();
- static final String READ_CODE = "R";
- static final String WRITE_CODE = "W";
+ private static final String AUTHORIZATIONS_XSD = "/authorizations.xsd";
+ private static final String JAXB_AUTHORIZATIONS_PATH = "org.apache.nifi.authorization.file.generated";
+
+ private static final String USERS_XSD = "/users.xsd";
+ private static final String JAXB_USERS_PATH = "org.apache.nifi.user.generated";
+
+ private static final String FLOW_XSD = "/FlowConfiguration.xsd";
+
+ private static final JAXBContext JAXB_AUTHORIZATIONS_CONTEXT = initializeJaxbContext(JAXB_AUTHORIZATIONS_PATH);
+ private static final JAXBContext JAXB_USERS_CONTEXT = initializeJaxbContext(JAXB_USERS_PATH);
/**
* Load the JAXBContext.
*/
- private static JAXBContext initializeJaxbContext() {
+ private static JAXBContext initializeJaxbContext(final String contextPath) {
try {
- return JAXBContext.newInstance(JAXB_GENERATED_PATH, FileAuthorizer.class.getClassLoader());
+ return JAXBContext.newInstance(contextPath, FileAuthorizer.class.getClassLoader());
} catch (JAXBException e) {
throw new RuntimeException("Unable to create JAXBContext.");
}
}
- private Schema schema;
+ static final String READ_CODE = "R";
+ static final String WRITE_CODE = "W";
+
+ static final String PROP_AUTHORIZATIONS_FILE = "Authorizations File";
+ static final String PROP_INITIAL_ADMIN_IDENTITY = "Initial Admin Identity";
+ static final String PROP_LEGACY_AUTHORIZED_USERS_FILE = "Legacy Authorized Users File";
+ static final String PROP_ROOT_GROUP_ID = "Root Group ID";
+
+ private Schema flowSchema;
+ private Schema usersSchema;
+ private Schema authorizationsSchema;
private SchemaFactory schemaFactory;
private NiFiProperties properties;
private File authorizationsFile;
private File restoreAuthorizationsFile;
private String rootGroupId;
+ private String initialAdminIdentity;
+ private String legacyAuthorizedUsersFile;
private final AtomicReference<AuthorizationsHolder> authorizationsHolder = new AtomicReference<>();
@@ -87,7 +119,9 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
public void initialize(final AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException {
try {
schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
- schema = schemaFactory.newSchema(FileAuthorizer.class.getResource(USERS_XSD));
+ authorizationsSchema = schemaFactory.newSchema(FileAuthorizer.class.getResource(AUTHORIZATIONS_XSD));
+ usersSchema = schemaFactory.newSchema(FileAuthorizer.class.getResource(USERS_XSD));
+ flowSchema = schemaFactory.newSchema(FileAuthorizer.class.getResource(FLOW_XSD));
} catch (Exception e) {
throw new AuthorizerCreationException(e);
}
@@ -96,7 +130,7 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
@Override
public void onConfigured(final AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
try {
- final PropertyValue authorizationsPath = configurationContext.getProperty("Authorizations File");
+ final PropertyValue authorizationsPath = configurationContext.getProperty(PROP_AUTHORIZATIONS_FILE);
if (StringUtils.isBlank(authorizationsPath.getValue())) {
throw new AuthorizerCreationException("The authorizations file must be specified.");
}
@@ -132,11 +166,17 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
}
}
- final PropertyValue initialAdminIdentityProp = configurationContext.getProperty("Initial Admin Identity");
- final String initialAdminIdentity = initialAdminIdentityProp == null ? null : initialAdminIdentityProp.getValue();
+ final PropertyValue initialAdminIdentityProp = configurationContext.getProperty(PROP_INITIAL_ADMIN_IDENTITY);
+ initialAdminIdentity = initialAdminIdentityProp == null ? null : initialAdminIdentityProp.getValue();
+
+ final PropertyValue legacyAuthorizedUsersProp = configurationContext.getProperty(PROP_LEGACY_AUTHORIZED_USERS_FILE);
+ legacyAuthorizedUsersFile = legacyAuthorizedUsersProp == null ? null : legacyAuthorizedUsersProp.getValue();
+
+ // try to extract the root group id from the flow configuration file specified in nifi.properties
+ rootGroupId = getRootGroupId();
// load the authorizations
- load(initialAdminIdentity);
+ load();
// if we've copied the authorizations file to a restore directory synchronize it
if (restoreAuthorizationsFile != null) {
@@ -145,24 +185,82 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
logger.info(String.format("Authorizations file loaded at %s", new Date().toString()));
- this.rootGroupId = configurationContext.getRootGroupId();
-
} catch (IOException | AuthorizerCreationException | JAXBException | IllegalStateException e) {
throw new AuthorizerCreationException(e);
}
}
/**
+ * Extracts the root group id from the flow configuration file provided in nifi.properties.
+ *
+ * @return the root group id, or null if the files doesn't exist, was empty, or could not be parsed
+ */
+ private String getRootGroupId() {
+ final File flowFile = properties.getFlowConfigurationFile();
+ if (flowFile == null) {
+ logger.debug("Flow Configuration file was null");
+ return null;
+ }
+
+ // if the flow doesn't exist or is 0 bytes, then return null
+ final Path flowPath = flowFile.toPath();
+ try {
+ if (!Files.exists(flowPath) || Files.size(flowPath) == 0) {
+ logger.debug("Flow Configuration does not exist or was empty");
+ return null;
+ }
+ } catch (IOException e) {
+ logger.debug("An error occurred determining the size of the Flow Configuration file");
+ return null;
+ }
+
+ // otherwise create the appropriate input streams to read the file
+ try (final InputStream in = Files.newInputStream(flowPath, StandardOpenOption.READ);
+ final InputStream gzipIn = new GZIPInputStream(in)) {
+
+ // create validating document builder
+ final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ docFactory.setNamespaceAware(true);
+ docFactory.setSchema(flowSchema);
+
+ // parse the flow
+ final DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+ final Document document = docBuilder.parse(gzipIn);
+
+ // extract the root group id
+ final Element rootElement = document.getDocumentElement();
+
+ final Element rootGroupElement = (Element) rootElement.getElementsByTagName("rootGroup").item(0);
+ if (rootGroupElement == null) {
+ logger.debug("rootGroup element not found in Flow Configuration file");
+ return null;
+ }
+
+ final Element rootGroupIdElement = (Element) rootGroupElement.getElementsByTagName("id").item(0);
+ if (rootGroupIdElement == null) {
+ logger.debug("id element not found under rootGroup in Flow Configuration file");
+ return null;
+ }
+
+ return rootGroupIdElement.getTextContent();
+
+ } catch (final SAXException | ParserConfigurationException | IOException ex) {
+ logger.error("Unable to find root group id in {} due to {}", new Object[] { flowPath.toAbsolutePath(), ex });
+ return null;
+ }
+ }
+
+ /**
* Loads the authorizations file and populates the AuthorizationsHolder, only called during start-up.
*
* @throws JAXBException Unable to reload the authorized users file
* @throws IOException Unable to sync file with restore
* @throws IllegalStateException Unable to sync file with restore
*/
- private synchronized void load(final String initialAdminIdentity) throws JAXBException, IOException, IllegalStateException {
+ private synchronized void load() throws JAXBException, IOException, IllegalStateException {
// attempt to unmarshal
- final Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller();
- unmarshaller.setSchema(schema);
+ final Unmarshaller unmarshaller = JAXB_AUTHORIZATIONS_CONTEXT.createUnmarshaller();
+ unmarshaller.setSchema(authorizationsSchema);
final JAXBElement<Authorizations> element = unmarshaller.unmarshal(new StreamSource(authorizationsFile), Authorizations.class);
final Authorizations authorizations = element.getValue();
@@ -178,11 +276,24 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
}
final AuthorizationsHolder authorizationsHolder = new AuthorizationsHolder(authorizations);
+ final boolean emptyAuthorizations = authorizationsHolder.getAllUsers().isEmpty() && authorizationsHolder.getAllPolicies().isEmpty();
final boolean hasInitialAdminIdentity = (initialAdminIdentity != null && !StringUtils.isBlank(initialAdminIdentity));
+ final boolean hasLegacyAuthorizedUsers = (legacyAuthorizedUsersFile != null && !StringUtils.isBlank(legacyAuthorizedUsersFile));
+
+ // if we are starting fresh then we might need to populate an initial admin or convert legacy users
+ if (emptyAuthorizations) {
+
+ if (hasInitialAdminIdentity && hasLegacyAuthorizedUsers) {
+ throw new AuthorizerCreationException("Cannot provide an Initial Admin Identity and a Legacy Authorized Users File");
+ } else if (hasInitialAdminIdentity) {
+ logger.debug("Populating authorizations for Initial Admin: " + initialAdminIdentity);
+ populateInitialAdmin(authorizations);
+ } else if (hasLegacyAuthorizedUsers) {
+ logger.debug("Converting " + legacyAuthorizedUsersFile + " to new authorizations model");
+ convertLegacyAuthorizedUsers(authorizations);
+ }
- // if an initial admin was provided and there are no users or policies then automatically create the admin user & policies
- if (hasInitialAdminIdentity && authorizationsHolder.getAllUsers().isEmpty() && authorizationsHolder.getAllPolicies().isEmpty()) {
- populateInitialAdmin(authorizations, initialAdminIdentity);
+ // save any changes that were made and repopulate the holder
saveAndRefreshHolder(authorizations);
} else {
this.authorizationsHolder.set(authorizationsHolder);
@@ -191,60 +302,298 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
/**
* Creates the initial admin user and policies for access the flow and managing users and policies.
- *
- * @param adminIdentity the identity of the admin user
*/
- private void populateInitialAdmin(final Authorizations authorizations, final String adminIdentity) {
+ private void populateInitialAdmin(final Authorizations authorizations) {
// generate an identifier and add a User with the given identifier and identity
- final UUID adminIdentifier = UUID.nameUUIDFromBytes(adminIdentity.getBytes(StandardCharsets.UTF_8));
- final User adminUser = new User.Builder().identifier(adminIdentifier.toString()).identity(adminIdentity).build();
+ final UUID adminIdentifier = UUID.nameUUIDFromBytes(initialAdminIdentity.getBytes(StandardCharsets.UTF_8));
+ final User adminUser = new User.Builder().identifier(adminIdentifier.toString()).identity(initialAdminIdentity).build();
final org.apache.nifi.authorization.file.generated.User jaxbAdminUser = createJAXBUser(adminUser);
authorizations.getUsers().getUser().add(jaxbAdminUser);
// grant the user read access to the /flow resource
- final AccessPolicy flowPolicy = createInitialAdminPolicy("/flow", adminUser.getIdentifier(), RequestAction.READ);
- final Policy jaxbFlowPolicy = createJAXBPolicy(flowPolicy);
- authorizations.getPolicies().getPolicy().add(jaxbFlowPolicy);
+ addAccessPolicy(authorizations, ResourceType.Flow.getValue(), adminUser.getIdentifier(), READ_CODE);
+
+ // grant the user read access to the root process group resource
+ if (rootGroupId != null) {
+ addAccessPolicy(authorizations, ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, adminUser.getIdentifier(), READ_CODE + WRITE_CODE);
+ }
// grant the user read/write access to the /users resource
- final AccessPolicy usersPolicy = createInitialAdminPolicy("/users", adminUser.getIdentifier(), RequestAction.READ, RequestAction.WRITE);
- final Policy jaxbUsersPolicy = createJAXBPolicy(usersPolicy);
- authorizations.getPolicies().getPolicy().add(jaxbUsersPolicy);
+ addAccessPolicy(authorizations, ResourceType.User.getValue(), adminUser.getIdentifier(), READ_CODE + WRITE_CODE);
// grant the user read/write access to the /groups resource
- final AccessPolicy groupsPolicy = createInitialAdminPolicy("/groups", adminUser.getIdentifier(), RequestAction.READ, RequestAction.WRITE);
- final Policy jaxbGroupsPolicy = createJAXBPolicy(groupsPolicy);
- authorizations.getPolicies().getPolicy().add(jaxbGroupsPolicy);
+ addAccessPolicy(authorizations, ResourceType.Group.getValue(), adminUser.getIdentifier(), READ_CODE + WRITE_CODE);
// grant the user read/write access to the /policies resource
- final AccessPolicy policiesPolicy = createInitialAdminPolicy("/policies", adminUser.getIdentifier(), RequestAction.READ, RequestAction.WRITE);
- final Policy jaxbPoliciesPolicy = createJAXBPolicy(policiesPolicy);
- authorizations.getPolicies().getPolicy().add(jaxbPoliciesPolicy);
+ addAccessPolicy(authorizations, ResourceType.Policy.getValue(), adminUser.getIdentifier(), READ_CODE + WRITE_CODE);
}
/**
- * Creates an AccessPolicy based on the given parameters, generating an identifier from the resource and admin identity.
+ * Unmarshalls an existing authorized-users.xml and converts the object model to the new model.
*
+ * @param authorizations the current Authorizations instance that users, groups, and policies will be added to
+ * @throws AuthorizerCreationException if the legacy authorized users file that was provided does not exist
+ * @throws JAXBException if the legacy authorized users file that was provided could not be unmarshalled
+ */
+ private void convertLegacyAuthorizedUsers(final Authorizations authorizations) throws AuthorizerCreationException, JAXBException {
+ final File authorizedUsersFile = new File(legacyAuthorizedUsersFile);
+ if (!authorizedUsersFile.exists()) {
+ throw new AuthorizerCreationException("Legacy Authorized Users File '" + legacyAuthorizedUsersFile + "' does not exists");
+ }
+
+ final Unmarshaller unmarshaller = JAXB_USERS_CONTEXT.createUnmarshaller();
+ unmarshaller.setSchema(usersSchema);
+
+ final JAXBElement<org.apache.nifi.user.generated.Users> element = unmarshaller.unmarshal(
+ new StreamSource(authorizedUsersFile), org.apache.nifi.user.generated.Users.class);
+
+ final org.apache.nifi.user.generated.Users users = element.getValue();
+ if (users.getUser().isEmpty()) {
+ logger.info("Legacy Authorized Users File contained no users, nothing to convert");
+ return;
+ }
+
+ // get all the user DNs into a list
+ List<String> userIdentities = new ArrayList<>();
+ for (org.apache.nifi.user.generated.User legacyUser : users.getUser()) {
+ userIdentities.add(legacyUser.getDn());
+ }
+
+ // sort the list and pull out the first identity
+ Collections.sort(userIdentities);
+ final String seedIdentity = userIdentities.get(0);
+
+ // create mapping from Role to access policies
+ final Map<Role,Set<RoleAccessPolicy>> roleAccessPolicies = RoleAccessPolicy.getMappings(rootGroupId);
+
+ final List<Policy> readPolicies = new ArrayList<>();
+ final List<Policy> readWritePolicies = new ArrayList<>();
+
+ for (org.apache.nifi.user.generated.User legacyUser : users.getUser()) {
+ // create the identifier of the new user based on the DN
+ String legacyUserDn = legacyUser.getDn();
+ String userIdentifier = UUID.nameUUIDFromBytes(legacyUserDn.getBytes(StandardCharsets.UTF_8)).toString();
+
+ // create the new User and add it to the list of users
+ org.apache.nifi.authorization.file.generated.User user = new org.apache.nifi.authorization.file.generated.User();
+ user.setIdentifier(userIdentifier);
+ user.setIdentity(legacyUserDn);
+ authorizations.getUsers().getUser().add(user);
+
+ // if there was a group name find or create the group and add the user to it
+ org.apache.nifi.authorization.file.generated.Group group = getOrCreateGroup(authorizations, legacyUser.getGroup());
+ if (group != null) {
+ org.apache.nifi.authorization.file.generated.User.Group userGroup = new org.apache.nifi.authorization.file.generated.User.Group();
+ userGroup.setIdentifier(group.getIdentifier());
+ user.getGroup().add(userGroup);
+ }
+
+ // create policies based on the given role
+ for (org.apache.nifi.user.generated.Role jaxbRole : legacyUser.getRole()) {
+ Role role = Role.valueOf(jaxbRole.getName());
+ Set<RoleAccessPolicy> policies = roleAccessPolicies.get(role);
+
+ for (RoleAccessPolicy roleAccessPolicy : policies) {
+ // determine if we should use the read policies or read-write policies
+ List<Policy> searchPolicies = roleAccessPolicy.getActions().equals(RoleAccessPolicy.READ_ACTION)
+ ? readPolicies : readWritePolicies;
+
+ // get the matching policy, or create a new one
+ Policy policy = getOrCreatePolicy(
+ searchPolicies,
+ seedIdentity,
+ roleAccessPolicy.getResource(),
+ roleAccessPolicy.getActions());
+
+ // determine if the user already exists in the policy
+ boolean userExists = false;
+ for (Policy.User policyUser : policy.getUser()) {
+ if (policyUser.getIdentifier().equals(userIdentifier)) {
+ userExists = true;
+ break;
+ }
+ }
+
+ // add the user to the policy if doesn't already exist
+ if (!userExists) {
+ Policy.User policyUser = new Policy.User();
+ policyUser.setIdentifier(userIdentifier);
+ policy.getUser().add(policyUser);
+ }
+ }
+ }
+
+ }
+
+ // merge the policies and add the result to the overall authorizations instance
+ final List<Policy> mergedPolicies = merge(readPolicies, readWritePolicies);
+ authorizations.getPolicies().getPolicy().addAll(mergedPolicies);
+ }
+
+ /**
+ * Merges the provided read and read-write policies. Any users that are in a read policy and also in a read-write
+ * policy for the same resource will be removed from the read policy. If users are still left in the read policy
+ * after checking each user, then the read policy will still be included in the merged list.
+ *
+ * @param readPolicies the read policies
+ * @param readWritePolicies the read-write policies
+ * @return the merged list of policies
+ */
+ private List<Policy> merge(List<Policy> readPolicies, List<Policy> readWritePolicies) {
+ final List<Policy> mergedPolicies = new ArrayList<>(readWritePolicies);
+
+ logger.debug("Merging {} read policies and {} read-write policies",
+ new Object[] {readPolicies.size(), readWritePolicies.size()});
+
+ for (Policy readPolicy : readPolicies) {
+ logger.debug("Processing read policy {} for resource {} with actions {}",
+ new Object[] {readPolicy.getIdentifier(), readPolicy.getResource(), readPolicy.getAction()});
+
+ // try to find a matching read-write policy for the same resource
+ Policy foundReadWritePolicy = null;
+ for (Policy readWritePolicy : readWritePolicies) {
+ if (readWritePolicy.getResource().equals(readPolicy.getResource())) {
+ foundReadWritePolicy = readWritePolicy;
+ break;
+ }
+ }
+
+ // if we didn't find a match then we just add the current read policy to the merged list
+ if (foundReadWritePolicy == null) {
+ logger.debug("no matching write policy found, adding read policy {} to merged policies",
+ new Object[] {readPolicy.getIdentifier()});
+ mergedPolicies.add(readPolicy);
+ } else {
+ // check each user from the read policy
+ Iterator<Policy.User> userIter = readPolicy.getUser().iterator();
+ while (userIter.hasNext()) {
+ Policy.User readUser = userIter.next();
+
+ // determine if the user from the read policy exists in the read-write policy
+ boolean userInReadWrite = false;
+ for (Policy.User readWriteUser : foundReadWritePolicy.getUser()) {
+ if (readWriteUser.getIdentifier().equals(readUser.getIdentifier())) {
+ userInReadWrite = true;
+ break;
+ }
+ }
+
+ // if the user was in the read-write policy, remove them from read policy
+ if (userInReadWrite) {
+ logger.debug("Removing user {} from read policy {}", new Object[] {readUser.getIdentifier(), readPolicy.getIdentifier()});
+ userIter.remove();
+ }
+ }
+
+ // after checking all users, see if any are still left in the read policy
+ // if there are still some users, then add the read policy to the merged list
+ if (readPolicy.getUser().size() > 0) {
+ logger.debug("Read policy still has {} users, adding read policy {} to merged list",
+ new Object[] {readPolicy.getUser().size(), readPolicy.getIdentifier()});
+ mergedPolicies.add(readPolicy);
+ }
+ }
+ }
+
+ return mergedPolicies;
+ }
+
+ /**
+ * Finds the Group with the given name, or creates a new one and adds it to Authorizations.
+ *
+ * @param authorizations the Authorizations reference
+ * @param groupName the name of the group to look for
+ * @return the Group from Authorizations with the given name, or a new instance
+ */
+ private org.apache.nifi.authorization.file.generated.Group getOrCreateGroup(final Authorizations authorizations, final String groupName) {
+ if (StringUtils.isBlank(groupName)) {
+ return null;
+ }
+
+ org.apache.nifi.authorization.file.generated.Group foundGroup = null;
+ for (org.apache.nifi.authorization.file.generated.Group group : authorizations.getGroups().getGroup()) {
+ if (group.getName().equals(groupName)) {
+ foundGroup = group;
+ break;
+ }
+ }
+
+ if (foundGroup == null) {
+ UUID newGroupIdentifier = UUID.nameUUIDFromBytes(groupName.getBytes(StandardCharsets.UTF_8));
+ foundGroup = new org.apache.nifi.authorization.file.generated.Group();
+ foundGroup.setIdentifier(newGroupIdentifier.toString());
+ foundGroup.setName(groupName);
+ authorizations.getGroups().getGroup().add(foundGroup);
+ }
+
+ return foundGroup;
+ }
+
+ /**
+ * Finds the Policy matching the resource and action, or creates a new one and adds it to the list of policies.
+ *
+ * @param policies the policies to search through
+ * @param seedIdentity the seedIdentity to use when creating identifiers for new policies
* @param resource the resource for the policy
- * @param adminIdentity the identity of the admin user to add to the policy
+ * @param action the action string for the police (R or RW)
+ * @return the matching policy or a new policy
+ */
+ private Policy getOrCreatePolicy(final List<Policy> policies, final String seedIdentity, final String resource, final String action) {
+ Policy foundPolicy = null;
+
+ // try to find a policy with the same resource and actions
+ for (Policy policy : policies) {
+ if (policy.getResource().equals(resource) && policy.getAction().equals(action)) {
+ foundPolicy = policy;
+ break;
+ }
+ }
+
+ // if a matching policy wasn't found then create one
+ if (foundPolicy == null) {
+ final String uuidSeed = resource + action + seedIdentity;
+ final UUID policyIdentifier = UUID.nameUUIDFromBytes(uuidSeed.getBytes(StandardCharsets.UTF_8));
+
+ foundPolicy = new Policy();
+ foundPolicy.setIdentifier(policyIdentifier.toString());
+ foundPolicy.setResource(resource);
+ foundPolicy.setAction(action);
+
+ policies.add(foundPolicy);
+ }
+
+ return foundPolicy;
+ }
+
+ /**
+ * Creates and adds an access policy for the given resource, identity, and actions.
+ *
+ * @param authorizations the Authorizations instance to add the policy to
+ * @param resource the resource for the policy
+ * @param identity the identity for the policy
* @param actions the actions for the policy
- * @return the AccessPolicy based on the given parameters
*/
- private AccessPolicy createInitialAdminPolicy(final String resource, final String adminIdentity, final RequestAction ... actions) {
- final String uuidSeed = resource + adminIdentity;
- final UUID flowPolicyIdentifier = UUID.nameUUIDFromBytes(uuidSeed.getBytes(StandardCharsets.UTF_8));
+ private void addAccessPolicy(final Authorizations authorizations, final String resource, final String identity, final String actions) {
+ final String uuidSeed = resource + identity;
+ final UUID policyIdentifier = UUID.nameUUIDFromBytes(uuidSeed.getBytes(StandardCharsets.UTF_8));
final AccessPolicy.Builder builder = new AccessPolicy.Builder()
- .identifier(flowPolicyIdentifier.toString())
+ .identifier(policyIdentifier.toString())
.resource(resource)
- .addUser(adminIdentity);
+ .addUser(identity);
+
+ if (actions.contains(READ_CODE)) {
+ builder.addAction(RequestAction.READ);
+ }
- for (RequestAction action : actions) {
- builder.addAction(action);
+ if (actions.contains(WRITE_CODE)) {
+ builder.addAction(RequestAction.WRITE);
}
- return builder.build();
+ final AccessPolicy accessPolicy = builder.build();
+ final Policy jaxbPolicy = createJAXBPolicy(accessPolicy);
+ authorizations.getPolicies().getPolicy().add(jaxbPolicy);
}
/**
@@ -258,8 +607,8 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
*/
private synchronized void saveAndRefreshHolder(final Authorizations authorizations) throws AuthorizationAccessException {
try {
- final Marshaller marshaller = JAXB_CONTEXT.createMarshaller();
- marshaller.setSchema(schema);
+ final Marshaller marshaller = JAXB_AUTHORIZATIONS_CONTEXT.createMarshaller();
+ marshaller.setSchema(authorizationsSchema);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(authorizations, authorizationsFile);
http://git-wip-us.apache.org/repos/asf/nifi/blob/679ad93f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/Role.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/Role.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/Role.java
new file mode 100644
index 0000000..0f7b740
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/Role.java
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+/**
+ * Legacy Roles prior to the new authorization model.
+ */
+public enum Role {
+ ROLE_MONITOR,
+ ROLE_PROVENANCE,
+ ROLE_DFM,
+ ROLE_ADMIN,
+ ROLE_PROXY,
+ ROLE_NIFI;
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/679ad93f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/RoleAccessPolicy.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/RoleAccessPolicy.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/RoleAccessPolicy.java
new file mode 100644
index 0000000..6757402
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/main/java/org/apache/nifi/authorization/RoleAccessPolicy.java
@@ -0,0 +1,99 @@
+/*
+ * 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.authorization.resource.ResourceType;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Defines the mapping from legacy roles to access policies.
+ */
+public final class RoleAccessPolicy {
+
+ static final String READ_ACTION = "R";
+ static final String READ_WRITE_ACTION = "RW";
+
+ private final String resource;
+ private final String actions;
+
+ private RoleAccessPolicy(final String resource, final String actions) {
+ this.resource = resource;
+ this.actions = actions;
+ }
+
+ public String getResource() {
+ return resource;
+ }
+
+ public String getActions() {
+ return actions;
+ }
+
+ public static Map<Role,Set<RoleAccessPolicy>> getMappings(final String rootGroupId) {
+ final Map<Role,Set<RoleAccessPolicy>> roleAccessPolicies = new HashMap<>();
+
+ final Set<RoleAccessPolicy> monitorPolicies = new HashSet<>();
+ monitorPolicies.add(new RoleAccessPolicy(ResourceType.Flow.getValue(), READ_ACTION));
+ monitorPolicies.add(new RoleAccessPolicy(ResourceType.Controller.getValue(), READ_ACTION));
+ monitorPolicies.add(new RoleAccessPolicy(ResourceType.System.getValue(), READ_ACTION));
+ if (rootGroupId != null) {
+ monitorPolicies.add(new RoleAccessPolicy(ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, READ_ACTION));
+ }
+ roleAccessPolicies.put(Role.ROLE_MONITOR, Collections.unmodifiableSet(monitorPolicies));
+
+ final Set<RoleAccessPolicy> provenancePolicies = new HashSet<>();
+ provenancePolicies.add(new RoleAccessPolicy(ResourceType.Provenance.getValue(), READ_ACTION));
+ roleAccessPolicies.put(Role.ROLE_PROVENANCE, Collections.unmodifiableSet(provenancePolicies));
+
+ final Set<RoleAccessPolicy> dfmPolicies = new HashSet<>();
+ dfmPolicies.add(new RoleAccessPolicy(ResourceType.Flow.getValue(), READ_ACTION));
+ dfmPolicies.add(new RoleAccessPolicy(ResourceType.Controller.getValue(), READ_WRITE_ACTION));
+ dfmPolicies.add(new RoleAccessPolicy(ResourceType.System.getValue(), READ_ACTION));
+ if (rootGroupId != null) {
+ dfmPolicies.add(new RoleAccessPolicy(ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, READ_WRITE_ACTION));
+ }
+ roleAccessPolicies.put(Role.ROLE_DFM, Collections.unmodifiableSet(dfmPolicies));
+
+ final Set<RoleAccessPolicy> adminPolicies = new HashSet<>();
+ adminPolicies.add(new RoleAccessPolicy(ResourceType.Flow.getValue(), READ_ACTION));
+ adminPolicies.add(new RoleAccessPolicy(ResourceType.Controller.getValue(), READ_ACTION));
+ if (rootGroupId != null) {
+ adminPolicies.add(new RoleAccessPolicy(ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, READ_ACTION));
+ }
+ adminPolicies.add(new RoleAccessPolicy(ResourceType.User.getValue(), READ_WRITE_ACTION));
+ adminPolicies.add(new RoleAccessPolicy(ResourceType.Group.getValue(), READ_WRITE_ACTION));
+ adminPolicies.add(new RoleAccessPolicy(ResourceType.Policy.getValue(), READ_WRITE_ACTION));
+ roleAccessPolicies.put(Role.ROLE_ADMIN, Collections.unmodifiableSet(adminPolicies));
+
+ final Set<RoleAccessPolicy> proxyPolicies = new HashSet<>();
+ proxyPolicies.add(new RoleAccessPolicy(ResourceType.Proxy.getValue(), READ_WRITE_ACTION));
+ roleAccessPolicies.put(Role.ROLE_PROXY, Collections.unmodifiableSet(proxyPolicies));
+
+ final Set<RoleAccessPolicy> nifiPolicies = new HashSet<>();
+ nifiPolicies.add(new RoleAccessPolicy(ResourceType.Controller.getValue(), READ_ACTION));
+ nifiPolicies.add(new RoleAccessPolicy(ResourceType.SiteToSite.getValue(), READ_WRITE_ACTION));
+ roleAccessPolicies.put(Role.ROLE_NIFI, Collections.unmodifiableSet(nifiPolicies));
+
+ return roleAccessPolicies;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/679ad93f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/java/org/apache/nifi/authorization/FileAuthorizerTest.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/java/org/apache/nifi/authorization/FileAuthorizerTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/java/org/apache/nifi/authorization/FileAuthorizerTest.java
index 0822b60..6d18b4b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/java/org/apache/nifi/authorization/FileAuthorizerTest.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/java/org/apache/nifi/authorization/FileAuthorizerTest.java
@@ -20,6 +20,7 @@ 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;
@@ -31,6 +32,9 @@ 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.Set;
import static org.junit.Assert.assertEquals;
@@ -97,17 +101,14 @@ public class FileAuthorizerTest {
" </policies>" +
"</authorizations>";
- private static final String UPDATED_AUTHORIZATIONS =
- "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
- + "<resources>"
- + "<resource identifier=\"/flow\">"
- + "<authorization identity=\"user-1\" action=\"RW\"/>"
- + "</resource>"
- + "</resources>";
+ // 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 primary;
private File restore;
+ private File flow;
private AuthorizerConfigurationContext configurationContext;
@@ -121,8 +122,12 @@ public class FileAuthorizerTest {
restore = new File("target/restore/authorizations.xml");
FileUtils.ensureDirectoryExistAndCanAccess(restore.getParentFile());
- final NiFiProperties properties = mock(NiFiProperties.class);
+ flow = new File("src/test/resources/flow.xml.gz");
+ FileUtils.ensureDirectoryExistAndCanAccess(flow.getParentFile());
+
+ properties = mock(NiFiProperties.class);
when(properties.getRestoreDirectory()).thenReturn(restore.getParentFile());
+ when(properties.getFlowConfigurationFile()).thenReturn(flow);
configurationContext = mock(AuthorizerConfigurationContext.class);
when(configurationContext.getProperty(Mockito.eq("Authorizations File"))).thenReturn(new StandardPropertyValue(primary.getPath(), null));
@@ -139,10 +144,225 @@ public class FileAuthorizerTest {
}
@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));
+
+ writeAuthorizationsFile(primary, EMPTY_AUTHORIZATIONS_CONCISE);
+ authorizer.onConfigured(configurationContext);
+
+ final Set<User> users = authorizer.getUsers();
+ assertEquals(1, users.size());
+
+ // the user has monitor and DFM, but we should only end up with one policy per resource
+ // since DFM has RW to all the same resources that monitor has R
+ UsersAndAccessPolicies usersAndAccessPolicies = authorizer.getUsersAndAccessPolicies();
+ assertEquals(1, usersAndAccessPolicies.getAccessPolicies(ResourceType.Flow.getValue()).size());
+ assertEquals(1, usersAndAccessPolicies.getAccessPolicies(ResourceType.Controller.getValue()).size());
+ assertEquals(1, usersAndAccessPolicies.getAccessPolicies(ResourceType.System.getValue()).size());
+ assertEquals(1, usersAndAccessPolicies.getAccessPolicies(ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID).size());
+ }
+
+ @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));
+
+ writeAuthorizationsFile(primary, EMPTY_AUTHORIZATIONS_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());
+ assertEquals("group1", groups.iterator().next().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(1, 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(4, 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());
+
+ // 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.User.getValue()));
+ assertEquals(2, user4Policies.get(ResourceType.User.getValue()).size());
+
+ assertTrue(user4Policies.containsKey(ResourceType.Group.getValue()));
+ assertEquals(2, user4Policies.get(ResourceType.Group.getValue()).size());
+
+ assertTrue(user4Policies.containsKey(ResourceType.Policy.getValue()));
+ assertEquals(2, user4Policies.get(ResourceType.Policy.getValue()).size());
+
+ // verify user5's policies
+ final Map<String,Set<RequestAction>> user5Policies = getResourceActions(policies, user5);
+ assertEquals(1, user5Policies.size());
+
+ assertTrue(user5Policies.containsKey(ResourceType.Proxy.getValue()));
+ assertEquals(2, user5Policies.get(ResourceType.Proxy.getValue()).size());
+
+ // verify user6's policies
+ final Map<String,Set<RequestAction>> user6Policies = getResourceActions(policies, user6);
+ assertEquals(2, user6Policies.size());
+
+ assertTrue(user6Policies.containsKey(ResourceType.SiteToSite.getValue()));
+ assertEquals(2, user6Policies.get(ResourceType.SiteToSite.getValue()).size());
+ }
+
+ 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.addAll(accessPolicy.getActions());
+ }
+ }
+
+ return resourceActionMap;
+ }
+
+ @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));
+
+ writeAuthorizationsFile(primary, EMPTY_AUTHORIZATIONS_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));
+
+ writeAuthorizationsFile(primary, EMPTY_AUTHORIZATIONS_CONCISE);
+ authorizer.onConfigured(configurationContext);
+ }
+
+ @Test
+ public void testOnConfiguredWhenInitialAdminNotProvided() throws Exception {
+ writeAuthorizationsFile(primary, EMPTY_AUTHORIZATIONS_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("Initial Admin Identity")))
+ 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(adminIdentity, adminUser.getIdentity());
+
+ final Set<AccessPolicy> policies = authorizer.getAccessPolicies();
+ assertEquals(5, 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(restore.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));
writeAuthorizationsFile(primary, EMPTY_AUTHORIZATIONS_CONCISE);
@@ -156,20 +376,58 @@ public class FileAuthorizerTest {
final Set<AccessPolicy> policies = authorizer.getAccessPolicies();
assertEquals(4, 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 testOnConfiguredWhenInitialAdminNotProvided() throws Exception {
+ public void testOnConfiguredWhenInitialAdminProvidedAndFlowIsNull() throws Exception {
+ // setup NiFi properties to return a file that does not exist
+ properties = mock(NiFiProperties.class);
+ when(properties.getRestoreDirectory()).thenReturn(restore.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));
+
writeAuthorizationsFile(primary, EMPTY_AUTHORIZATIONS_CONCISE);
authorizer.onConfigured(configurationContext);
final Set<User> users = authorizer.getUsers();
- assertEquals(0, users.size());
+ assertEquals(1, users.size());
+
+ final User adminUser = users.iterator().next();
+ assertEquals(adminIdentity, adminUser.getIdentity());
final Set<AccessPolicy> policies = authorizer.getAccessPolicies();
- assertEquals(0, policies.size());
+ assertEquals(4, 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 testOnConfiguredWhenRestoreDoesNotExist() throws Exception {
writeAuthorizationsFile(primary, EMPTY_AUTHORIZATIONS_CONCISE);
http://git-wip-us.apache.org/repos/asf/nifi/blob/679ad93f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/resources/authorized-users-multirole.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/resources/authorized-users-multirole.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/resources/authorized-users-multirole.xml
new file mode 100644
index 0000000..493ed4b
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/resources/authorized-users-multirole.xml
@@ -0,0 +1,21 @@
+<?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="user1" group="group1">
+ <role name="ROLE_MONITOR"/>
+ <role name="ROLE_DFM" />
+ </user>
+</users>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/679ad93f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/resources/authorized-users.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/resources/authorized-users.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/resources/authorized-users.xml
new file mode 100644
index 0000000..0515a09
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/resources/authorized-users.xml
@@ -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="user1" group="group1">
+ <role name="ROLE_MONITOR"/>
+ </user>
+ <user dn="user2">
+ <role name="ROLE_PROVENANCE"/>
+ </user>
+ <user dn="user3">
+ <role name="ROLE_DFM"/>
+ </user>
+ <user dn="user4">
+ <role name="ROLE_ADMIN"/>
+ </user>
+ <user dn="user5">
+ <role name="ROLE_PROXY"/>
+ </user>
+ <user dn="user6">
+ <role name="ROLE_NIFI"/>
+ </user>
+</users>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi/blob/679ad93f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/resources/flow.xml.gz
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/resources/flow.xml.gz b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/resources/flow.xml.gz
new file mode 100644
index 0000000..c2ac4ed
Binary files /dev/null and b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-file-authorizer/src/test/resources/flow.xml.gz differ
http://git-wip-us.apache.org/repos/asf/nifi/blob/679ad93f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/StandardAuthorizerConfigurationContext.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/StandardAuthorizerConfigurationContext.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/StandardAuthorizerConfigurationContext.java
index fa205da..3010c92 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/StandardAuthorizerConfigurationContext.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/StandardAuthorizerConfigurationContext.java
@@ -29,12 +29,10 @@ import java.util.Map;
public class StandardAuthorizerConfigurationContext implements AuthorizerConfigurationContext {
private final String identifier;
- private final String rootGroupId;
private final Map<String, String> properties;
- public StandardAuthorizerConfigurationContext(String identifier, String rootGroupId, Map<String, String> properties) {
+ public StandardAuthorizerConfigurationContext(String identifier, Map<String, String> properties) {
this.identifier = identifier;
- this.rootGroupId = rootGroupId;
this.properties = Collections.unmodifiableMap(new HashMap<String, String>(properties));
}
@@ -44,11 +42,6 @@ public class StandardAuthorizerConfigurationContext implements AuthorizerConfigu
}
@Override
- public String getRootGroupId() {
- return rootGroupId;
- }
-
- @Override
public Map<String, String> getProperties() {
return properties;
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/679ad93f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java
index ce8f1bf..1e9b8c2 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceFactory.java
@@ -22,10 +22,58 @@ import java.util.Objects;
public final class ResourceFactory {
+ private final static Resource CONNECTION_RESOURCE = new Resource() {
+ @Override
+ public String getIdentifier() {
+ return ResourceType.Connection.getValue();
+ }
+
+ @Override
+ public String getName() {
+ return "Connection";
+ }
+ };
+
+ private final static Resource CONTROLLER_RESOURCE = new Resource() {
+ @Override
+ public String getIdentifier() {
+ return ResourceType.Controller.getValue();
+ }
+
+ @Override
+ public String getName() {
+ return "Controller";
+ }
+ };
+
+ private final static Resource CONTROLLER_SERVICE_RESOURCE = new Resource() {
+ @Override
+ public String getIdentifier() {
+ return ResourceType.ControllerService.getValue();
+ }
+
+ @Override
+ public String getName() {
+ return "Controller Service";
+ }
+ };
+
+ private final static Resource FUNNEL_RESOURCE = new Resource() {
+ @Override
+ public String getIdentifier() {
+ return ResourceType.Funnel.getValue();
+ }
+
+ @Override
+ public String getName() {
+ return "Funnel";
+ }
+ };
+
private final static Resource FLOW_RESOURCE = new Resource() {
@Override
public String getIdentifier() {
- return "/flow";
+ return ResourceType.Flow.getValue();
}
@Override
@@ -34,46 +82,94 @@ public final class ResourceFactory {
}
};
- private final static Resource RESOURCE_RESOURCE = new Resource() {
+ private final static Resource GROUP_RESOURCE = new Resource() {
@Override
public String getIdentifier() {
- return "/resources";
+ return ResourceType.Group.getValue();
}
@Override
public String getName() {
- return "NiFi Resources";
+ return "Group";
}
};
- private final static Resource SYSTEM_RESOURCE = new Resource() {
+ private final static Resource INPUT_PORT_RESOURCE = new Resource() {
@Override
public String getIdentifier() {
- return "/system";
+ return ResourceType.InputPort.getValue();
}
@Override
public String getName() {
- return "System";
+ return "Input Port";
}
};
- private final static Resource CONTROLLER_RESOURCE = new Resource() {
+ private final static Resource LABEL_RESOURCE = new Resource() {
@Override
public String getIdentifier() {
- return "/controller";
+ return ResourceType.Label.getValue();
}
@Override
public String getName() {
- return "Controller";
+ return "Label";
+ }
+ };
+
+ private final static Resource OUTPUT_PORT_RESOURCE = new Resource() {
+ @Override
+ public String getIdentifier() {
+ return ResourceType.OutputPort.getValue();
+ }
+
+ @Override
+ public String getName() {
+ return "Output Port";
+ }
+ };
+
+ private final static Resource POLICY_RESOURCE = new Resource() {
+ @Override
+ public String getIdentifier() {
+ return ResourceType.Policy.getValue();
+ }
+
+ @Override
+ public String getName() {
+ return "Policy";
+ }
+ };
+
+ private final static Resource PROCESSOR_RESOURCE = new Resource() {
+ @Override
+ public String getIdentifier() {
+ return ResourceType.Processor.getValue();
+ }
+
+ @Override
+ public String getName() {
+ return "Processor";
+ }
+ };
+
+ private final static Resource PROCESS_GROUP_RESOURCE = new Resource() {
+ @Override
+ public String getIdentifier() {
+ return ResourceType.ProcessGroup.getValue();
+ }
+
+ @Override
+ public String getName() {
+ return "Process Group";
}
};
private final static Resource PROVENANCE_RESOURCE = new Resource() {
@Override
public String getIdentifier() {
- return "/provenance";
+ return ResourceType.Provenance.getValue();
}
@Override
@@ -82,22 +178,58 @@ public final class ResourceFactory {
}
};
- private final static Resource TOKEN_RESOURCE = new Resource() {
+ private final static Resource PROXY_RESOURCE = new Resource() {
@Override
public String getIdentifier() {
- return "/token";
+ return ResourceType.Proxy.getValue();
}
@Override
public String getName() {
- return "API access token";
+ return "Proxy User Requests";
+ }
+ };
+
+ private final static Resource REMOTE_PROCESS_GROUP_RESOURCE = new Resource() {
+ @Override
+ public String getIdentifier() {
+ return ResourceType.RemoteProcessGroup.getValue();
+ }
+
+ @Override
+ public String getName() {
+ return "Remote Process Group";
+ }
+ };
+
+ private final static Resource REPORTING_TASK_RESOURCE = new Resource() {
+ @Override
+ public String getIdentifier() {
+ return ResourceType.ReportingTask.getValue();
+ }
+
+ @Override
+ public String getName() {
+ return "Reporting Task";
+ }
+ };
+
+ private final static Resource RESOURCE_RESOURCE = new Resource() {
+ @Override
+ public String getIdentifier() {
+ return ResourceType.Resource.getValue();
+ }
+
+ @Override
+ public String getName() {
+ return "NiFi Resources";
}
};
private final static Resource SITE_TO_SITE_RESOURCE = new Resource() {
@Override
public String getIdentifier() {
- return "/site-to-site";
+ return ResourceType.SiteToSite.getValue();
}
@Override
@@ -106,19 +238,91 @@ public final class ResourceFactory {
}
};
- private final static Resource PROXY_RESOURCE = new Resource() {
+ private final static Resource SYSTEM_RESOURCE = new Resource() {
@Override
public String getIdentifier() {
- return "/proxy";
+ return ResourceType.System.getValue();
}
@Override
public String getName() {
- return "Proxy User Requests";
+ return "System";
+ }
+ };
+
+ private final static Resource TEMPLATE_RESOURCE = new Resource() {
+ @Override
+ public String getIdentifier() {
+ return ResourceType.Template.getValue();
+ }
+
+ @Override
+ public String getName() {
+ return "Template";
+ }
+ };
+
+ private final static Resource TOKEN_RESOURCE = new Resource() {
+ @Override
+ public String getIdentifier() {
+ return ResourceType.Token.getValue();
+ }
+
+ @Override
+ public String getName() {
+ return "API access token";
+ }
+ };
+
+ private final static Resource USER_RESOURCE = new Resource() {
+ @Override
+ public String getIdentifier() {
+ return ResourceType.User.getValue();
+ }
+
+ @Override
+ public String getName() {
+ return "User";
}
};
/**
+ * Gets the Resource for accessing Connections.
+ *
+ * @return The resource for accessing connections
+ */
+ public static Resource getConnectionResource() {
+ return CONNECTION_RESOURCE;
+ }
+
+ /**
+ * Gets the Resource for accessing the Controller. This includes Controller level configuration, bulletins, reporting tasks, and the cluster.
+ *
+ * @return The resource for accessing the Controller
+ */
+ public static Resource getControllerResource() {
+ return CONTROLLER_RESOURCE;
+ }
+
+ /**
+ * Gets the Resource for accessing Controller Services.
+ *
+ * @return The resource for accessing Controller Services
+ */
+ public static Resource getControllerServiceResource() {
+ return CONTROLLER_SERVICE_RESOURCE;
+ }
+
+ /**
+ * Gets the Resource for accessing Funnels.
+ *
+ * @return The resource for accessing Funnels.
+ */
+ public static Resource getFunnelResource() {
+ return FUNNEL_RESOURCE;
+ }
+
+ /**
* Gets the Resource for accessing the NiFi flow. This includes the data flow structure, component status, search results, and banner/about text.
*
* @return The NiFi resource
@@ -128,30 +332,66 @@ public final class ResourceFactory {
}
/**
- * Gets the Resource for detailing all available NiFi Resources.
+ * Gets the Resource for accessing Groups which allows management of user groups.
*
- * @return The Resource resource
+ * @return The resource for accessing Groups
*/
- public static Resource getResourceResource() {
- return RESOURCE_RESOURCE;
+ public static Resource getGroupResource() {
+ return GROUP_RESOURCE;
}
/**
- * Gets the Resource for accessing details of the System NiFi is running on.
+ * Gets the Resource for accessing Input Ports.
*
- * @return The System resource
+ * @return The resource for accessing Input Ports
*/
- public static Resource getSystemResource() {
- return SYSTEM_RESOURCE;
+ public static Resource getInputPortResource() {
+ return INPUT_PORT_RESOURCE;
}
/**
- * Gets the Resource for accessing the Controller. This includes Controller level configuration, bulletins, reporting tasks, and the cluster.
+ * Gets the Resource for accessing Labels.
*
- * @return The resource for accessing the Controller
+ * @return The resource for accessing Labels
*/
- public static Resource getControllerResource() {
- return CONTROLLER_RESOURCE;
+ public static Resource getLabelResource() {
+ return LABEL_RESOURCE;
+ }
+
+ /**
+ * Gets the Resource for accessing Output Ports.
+ *
+ * @return The resource for accessing Output Ports
+ */
+ public static Resource getOutputPortResource() {
+ return OUTPUT_PORT_RESOURCE;
+ }
+
+ /**
+ * Gets the Resource for accessing Policies which allows management of Access Policies.
+ *
+ * @return The resource for accessing Policies
+ */
+ public static Resource getPolicyResource() {
+ return POLICY_RESOURCE;
+ }
+
+ /**
+ * Gets the Resource for accessing Processors.
+ *
+ * @return The resource for accessing Processors
+ */
+ public static Resource getProcessorResource() {
+ return PROCESSOR_RESOURCE;
+ }
+
+ /**
+ * Gets the Resource for accessing Process Groups.
+ *
+ * @return The resource for accessing Process Groups
+ */
+ public static Resource getProcessGroupResource() {
+ return PROCESS_GROUP_RESOURCE;
}
/**
@@ -165,12 +405,39 @@ public final class ResourceFactory {
}
/**
- * Gets the Resource for creating API access tokens.
+ * Gets the Resource for proxying a user request.
*
- * @return The token request resource
+ * @return The resource for proxying a user request
*/
- public static Resource getTokenResource() {
- return TOKEN_RESOURCE;
+ public static Resource getProxyResource() {
+ return PROXY_RESOURCE;
+ }
+
+ /**
+ * Gets the Resource for accessing Remote Process Groups.
+ *
+ * @return The resource accessing Remote Process Groups
+ */
+ public static Resource getRemoteProcessGroupResource() {
+ return REMOTE_PROCESS_GROUP_RESOURCE;
+ }
+
+ /**
+ * Gets the Resource for accessing Reporting Tasks.
+ *
+ * @return The resource for accessing Reporting Tasks
+ */
+ public static Resource getReportingTaskResource() {
+ return REPORTING_TASK_RESOURCE;
+ }
+
+ /**
+ * Gets the Resource for detailing all available NiFi Resources.
+ *
+ * @return The Resource resource
+ */
+ public static Resource getResourceResource() {
+ return RESOURCE_RESOURCE;
}
/**
@@ -184,12 +451,39 @@ public final class ResourceFactory {
}
/**
- * Gets the Resource for proxying a user request.
+ * Gets the Resource for accessing details of the System NiFi is running on.
*
- * @return The resource for proxying a user request
+ * @return The System resource
*/
- public static Resource getProxyResource() {
- return PROXY_RESOURCE;
+ public static Resource getSystemResource() {
+ return SYSTEM_RESOURCE;
+ }
+
+ /**
+ * Gets the Resource for accessing Templates.
+ *
+ * @return The Resource for accessing Tempaltes
+ */
+ public static Resource getTemplateResource() {
+ return TEMPLATE_RESOURCE;
+ }
+
+ /**
+ * Gets the Resource for creating API access tokens.
+ *
+ * @return The token request resource
+ */
+ public static Resource getTokenResource() {
+ return TOKEN_RESOURCE;
+ }
+
+ /**
+ * Gets the Resource for accessing Users which includes creating, modifying, and deleting Users.
+ *
+ * @return The Resource for accessing Users
+ */
+ public static Resource getUserResource() {
+ return USER_RESOURCE;
}
/**
http://git-wip-us.apache.org/repos/asf/nifi/blob/679ad93f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceType.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceType.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceType.java
index f3e9b6c..784af6d 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceType.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-authorization/src/main/java/org/apache/nifi/authorization/resource/ResourceType.java
@@ -17,17 +17,28 @@
package org.apache.nifi.authorization.resource;
public enum ResourceType {
- Processor("/processors"),
+ Connection("/connections"),
+ Controller("/controller"),
+ ControllerService("/controller-services"),
+ Funnel("/funnel"),
+ Flow("/flow"),
+ Group("/groups"),
InputPort("/input-ports"),
+ Label("/labels"),
OutputPort("/output-ports"),
- Funnel("/funnel"),
- Connection("/connections"),
+ Policy("/policies"),
+ Processor("/processors"),
ProcessGroup("/process-groups"),
+ Provenance("/provenance"),
+ Proxy("/proxy"),
RemoteProcessGroup("/remote-process-groups"),
- Label("/labels"),
- ControllerService("/controller-services"),
ReportingTask("/reporting-tasks"),
- Template("/templates");
+ Resource("/resources"),
+ SiteToSite("/site-to-site"),
+ System("/system"),
+ Template("/templates"),
+ Token("/token"),
+ User("/users");
final String value;
http://git-wip-us.apache.org/repos/asf/nifi/blob/679ad93f/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/authorizers.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/authorizers.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/authorizers.xml
index 74255dc..12efb79 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/authorizers.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/authorizers.xml
@@ -24,5 +24,6 @@
<class>org.apache.nifi.authorization.FileAuthorizer</class>
<property name="Authorizations File">./conf/authorizations.xml</property>
<property name="Initial Admin Identity"></property>
+ <property name="Legacy Authorized Users File"></property>
</authorizer>
</authorizers>
\ No newline at end of file