NIFI-2530: - When no explicit policy is defined, defer to the parent Process Group instead of attempting to match component's within the flow.

This closes #826.

Signed-off-by: Bryan Bende <bbende@apache.org>
This commit is contained in:
Matt Gilman 2016-08-10 10:08:04 -04:00 committed by Bryan Bende
parent 84cac0daca
commit 219234d001
No known key found for this signature in database
GPG Key ID: A0DDA9ED50711C39
1 changed files with 2 additions and 156 deletions

View File

@ -16,38 +16,13 @@
*/
package org.apache.nifi.controller;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.AccessDeniedException;
import org.apache.nifi.authorization.AuthorizationRequest;
import org.apache.nifi.authorization.AuthorizationResult;
import org.apache.nifi.authorization.AuthorizationResult.Result;
import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.Resource;
import org.apache.nifi.authorization.UserContextKeys;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.resource.ResourceFactory;
import org.apache.nifi.authorization.resource.ResourceType;
import org.apache.nifi.authorization.user.NiFiUser;
import org.apache.nifi.connectable.Connection;
import org.apache.nifi.controller.label.Label;
import org.apache.nifi.controller.service.ControllerServiceNode;
import org.apache.nifi.groups.ProcessGroup;
import org.apache.nifi.groups.RemoteProcessGroup;
import org.apache.nifi.web.api.dto.ConnectionDTO;
import org.apache.nifi.web.api.dto.ControllerServiceDTO;
import org.apache.nifi.web.api.dto.FlowSnippetDTO;
import org.apache.nifi.web.api.dto.LabelDTO;
import org.apache.nifi.web.api.dto.ProcessGroupDTO;
import org.apache.nifi.web.api.dto.ProcessorDTO;
import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
import org.apache.nifi.web.api.dto.TemplateDTO;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class Template implements Authorizable {
private final TemplateDTO dto;
@ -81,7 +56,7 @@ public class Template implements Authorizable {
@Override
public Authorizable getParentAuthorizable() {
return null;
return processGroup;
}
@Override
@ -89,137 +64,8 @@ public class Template implements Authorizable {
return ResourceFactory.getComponentResource(ResourceType.Template, dto.getId(), dto.getName());
}
private ProcessGroup getRootGroup(final ProcessGroup currentGroup) {
if (currentGroup.getParent() == null) {
return currentGroup;
} else {
return getRootGroup(currentGroup.getParent());
}
}
private Set<Authorizable> getAuthorizableComponents() {
return getAuthorizableComponents(processGroup.getIdentifier(), dto.getSnippet());
}
private Set<Authorizable> getAuthorizableComponents(final String currentGroupId, final FlowSnippetDTO snippet) {
final Set<Authorizable> authComponents = new HashSet<>();
// If there is any component in the DTO that still exists in the flow, check its authorizations...
// need to go to the root group in case a sensitive processor was moved out of this processGroup
final ProcessGroup root = getRootGroup(processGroup);
// include the current group
final ProcessGroup currentGroup = root.findProcessGroup(currentGroupId);
authComponents.add(currentGroup);
for (final ConnectionDTO connectionDto : snippet.getConnections()) {
final Connection connection = root.findConnection(connectionDto.getId());
if (connection != null) {
authComponents.add(connection);
}
}
for (final ControllerServiceDTO service : snippet.getControllerServices()) {
final ControllerServiceNode controllerService = root.findControllerService(service.getId());
if (controllerService != null) {
authComponents.add(controllerService);
}
}
for (final LabelDTO labelDto : snippet.getLabels()) {
final Label label = root.findLabel(labelDto.getId());
if (label != null) {
authComponents.add(label);
}
}
for (final ProcessorDTO processorDto : snippet.getProcessors()) {
final ProcessorNode procNode = root.findProcessor(processorDto.getId());
if (procNode != null) {
authComponents.add(procNode);
}
}
for (final RemoteProcessGroupDTO groupDto : snippet.getRemoteProcessGroups()) {
final RemoteProcessGroup rpg = root.findRemoteProcessGroup(groupDto.getId());
if (rpg != null) {
authComponents.add(rpg);
}
}
for (final ProcessGroupDTO groupDto : snippet.getProcessGroups()) {
final ProcessGroup group = root.findProcessGroup(groupDto.getId());
if (group != null) {
authComponents.addAll(getAuthorizableComponents(groupDto.getId(), groupDto.getContents()));
}
}
return authComponents;
}
@Override
public void authorize(final Authorizer authorizer, final RequestAction action, final NiFiUser user, final Map<String, String> resourceContext) throws AccessDeniedException {
final AuthorizationResult result = checkAuthorization(authorizer, action, true, user, resourceContext);
if (Result.Denied.equals(result.getResult())) {
final String explanation = result.getExplanation() == null ? "Access is denied" : result.getExplanation();
throw new AccessDeniedException(explanation);
}
}
@Override
public AuthorizationResult checkAuthorization(final Authorizer authorizer, final RequestAction action, final NiFiUser user, final Map<String, String> resourceContext) {
return checkAuthorization(authorizer, action, false, user, resourceContext);
}
private AuthorizationResult checkAuthorization(final Authorizer authorizer, final RequestAction action, final boolean accessAttempt,
final NiFiUser user, final Map<String, String> resourceContext) {
if (user == null) {
return AuthorizationResult.denied("Unknown user");
}
final Map<String,String> userContext;
if (!StringUtils.isBlank(user.getClientAddress())) {
userContext = new HashMap<>();
userContext.put(UserContextKeys.CLIENT_ADDRESS.name(), user.getClientAddress());
} else {
userContext = null;
}
// build the request
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.identity(user.getIdentity())
.anonymous(user.isAnonymous())
.accessAttempt(accessAttempt)
.action(action)
.resource(getResource())
.userContext(userContext)
.resourceContext(resourceContext)
.build();
// perform the authorization
final AuthorizationResult result = authorizer.authorize(request);
// verify the results
if (Result.ResourceNotFound.equals(result.getResult())) {
for (final Authorizable child : getAuthorizableComponents()) {
final AuthorizationResult childResult = child.checkAuthorization(authorizer, action, user);
// if the authoriable in this template explicitly says no, respect it
if (Result.Denied.equals(childResult.getResult())) {
return childResult;
}
}
// if all authorizables are approved or no longer have a policy, approve it
return AuthorizationResult.approved();
} else {
return result;
}
}
@Override
public String toString() {
return "Template[id=" + getIdentifier() + ", Name=" + dto.getName() + "]";
return "Template[id=" + getIdentifier() + "]";
}
}