mirror of https://github.com/apache/nifi.git
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
This commit is contained in:
parent
db9a79f79d
commit
679ad93f57
|
@ -30,11 +30,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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -93,6 +93,10 @@
|
|||
<groupId>org.apache.nifi</groupId>
|
||||
<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>
|
||||
|
|
|
@ -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,13 +185,71 @@ 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.
|
||||
*
|
||||
|
@ -159,10 +257,10 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
|||
* @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 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);
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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 resource the resource for the policy
|
||||
* @param adminIdentity the identity of the admin user to add to the policy
|
||||
* @param actions the actions for the policy
|
||||
* @return the AccessPolicy based on the given parameters
|
||||
* @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 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));
|
||||
|
||||
final AccessPolicy.Builder builder = new AccessPolicy.Builder()
|
||||
.identifier(flowPolicyIdentifier.toString())
|
||||
.resource(resource)
|
||||
.addUser(adminIdentity);
|
||||
|
||||
for (RequestAction action : actions) {
|
||||
builder.addAction(action);
|
||||
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");
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
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 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
|
||||
*/
|
||||
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(policyIdentifier.toString())
|
||||
.resource(resource)
|
||||
.addUser(identity);
|
||||
|
||||
if (actions.contains(READ_CODE)) {
|
||||
builder.addAction(RequestAction.READ);
|
||||
}
|
||||
|
||||
if (actions.contains(WRITE_CODE)) {
|
||||
builder.addAction(RequestAction.WRITE);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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,11 +144,9 @@ public class FileAuthorizerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testOnConfiguredWhenInitialAdminProvided() throws Exception {
|
||||
final String adminIdentity = "admin-user";
|
||||
|
||||
when(configurationContext.getProperty(Mockito.eq("Initial Admin Identity")))
|
||||
.thenReturn(new StandardPropertyValue(adminIdentity, null));
|
||||
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);
|
||||
|
@ -151,11 +154,159 @@ public class FileAuthorizerTest {
|
|||
final Set<User> users = authorizer.getUsers();
|
||||
assertEquals(1, users.size());
|
||||
|
||||
final User adminUser = users.iterator().next();
|
||||
assertEquals(adminIdentity, adminUser.getIdentity());
|
||||
// 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();
|
||||
assertEquals(4, policies.size());
|
||||
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
|
||||
|
@ -170,6 +321,113 @@ public class FileAuthorizerTest {
|
|||
assertEquals(0, policies.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnConfiguredWhenInitialAdminProvided() throws Exception {
|
||||
final String adminIdentity = "admin-user";
|
||||
|
||||
when(configurationContext.getProperty(Mockito.eq(FileAuthorizer.PROP_INITIAL_ADMIN_IDENTITY)))
|
||||
.thenReturn(new StandardPropertyValue(adminIdentity, null));
|
||||
|
||||
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);
|
||||
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(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 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(1, users.size());
|
||||
|
||||
final User adminUser = users.iterator().next();
|
||||
assertEquals(adminIdentity, adminUser.getIdentity());
|
||||
|
||||
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 testOnConfiguredWhenRestoreDoesNotExist() throws Exception {
|
||||
writeAuthorizationsFile(primary, EMPTY_AUTHORIZATIONS_CONCISE);
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
Binary file not shown.
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -43,11 +41,6 @@ public class StandardAuthorizerConfigurationContext implements AuthorizerConfigu
|
|||
return identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRootGroupId() {
|
||||
return rootGroupId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getProperties() {
|
||||
return properties;
|
||||
|
|
|
@ -22,46 +22,22 @@ import java.util.Objects;
|
|||
|
||||
public final class ResourceFactory {
|
||||
|
||||
private final static Resource FLOW_RESOURCE = new Resource() {
|
||||
private final static Resource CONNECTION_RESOURCE = new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "/flow";
|
||||
return ResourceType.Connection.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "NiFi Flow";
|
||||
}
|
||||
};
|
||||
|
||||
private final static Resource RESOURCE_RESOURCE = new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "/resources";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "NiFi Resources";
|
||||
}
|
||||
};
|
||||
|
||||
private final static Resource SYSTEM_RESOURCE = new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "/system";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "System";
|
||||
return "Connection";
|
||||
}
|
||||
};
|
||||
|
||||
private final static Resource CONTROLLER_RESOURCE = new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "/controller";
|
||||
return ResourceType.Controller.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -70,10 +46,130 @@ public final class ResourceFactory {
|
|||
}
|
||||
};
|
||||
|
||||
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 ResourceType.Flow.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "NiFi Flow";
|
||||
}
|
||||
};
|
||||
|
||||
private final static Resource GROUP_RESOURCE = new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return ResourceType.Group.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Group";
|
||||
}
|
||||
};
|
||||
|
||||
private final static Resource INPUT_PORT_RESOURCE = new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return ResourceType.InputPort.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Input Port";
|
||||
}
|
||||
};
|
||||
|
||||
private final static Resource LABEL_RESOURCE = new Resource() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return ResourceType.Label.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
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,18 +238,90 @@ 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.
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,17 +17,28 @@
|
|||
package org.apache.nifi.authorization.resource;
|
||||
|
||||
public enum ResourceType {
|
||||
Processor("/processors"),
|
||||
InputPort("/input-ports"),
|
||||
OutputPort("/output-ports"),
|
||||
Funnel("/funnel"),
|
||||
Connection("/connections"),
|
||||
ProcessGroup("/process-groups"),
|
||||
RemoteProcessGroup("/remote-process-groups"),
|
||||
Label("/labels"),
|
||||
Controller("/controller"),
|
||||
ControllerService("/controller-services"),
|
||||
Funnel("/funnel"),
|
||||
Flow("/flow"),
|
||||
Group("/groups"),
|
||||
InputPort("/input-ports"),
|
||||
Label("/labels"),
|
||||
OutputPort("/output-ports"),
|
||||
Policy("/policies"),
|
||||
Processor("/processors"),
|
||||
ProcessGroup("/process-groups"),
|
||||
Provenance("/provenance"),
|
||||
Proxy("/proxy"),
|
||||
RemoteProcessGroup("/remote-process-groups"),
|
||||
ReportingTask("/reporting-tasks"),
|
||||
Template("/templates");
|
||||
Resource("/resources"),
|
||||
SiteToSite("/site-to-site"),
|
||||
System("/system"),
|
||||
Template("/templates"),
|
||||
Token("/token"),
|
||||
User("/users");
|
||||
|
||||
final String value;
|
||||
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue