NIFI-2095:

- Adding a page for managing users and groups.
- Adding a page for managing access policies.
- Renaming accessPolicy in entity to permissions to avoid confusion with the accessPolicy model.
- Adding an Authorizable for access policies.
- Refactoring access policies endpoints.
NIFI-2022:
- Implementing site to site authorizations.
This commit is contained in:
Matt Gilman 2016-07-12 15:45:13 -04:00
parent ba763b95e8
commit e0c96794fa
109 changed files with 6186 additions and 2334 deletions

View File

@ -20,6 +20,27 @@ package org.apache.nifi.authorization;
* Actions a user/entity can take on a resource.
*/
public enum RequestAction {
READ,
WRITE;
READ("read"),
WRITE("write");
private String value;
RequestAction(String value) {
this.value = value;
}
@Override
public String toString() {
return value.toLowerCase();
}
public static RequestAction valueOfValue(final String action) {
if (RequestAction.READ.toString().equals(action)) {
return RequestAction.READ;
} else if (RequestAction.WRITE.toString().equals(action)) {
return RequestAction.WRITE;
} else {
throw new IllegalArgumentException("Action must be one of [" + READ.toString() + ", " + WRITE.toString() + "]");
}
}
}

View File

@ -326,7 +326,7 @@ public class SiteToSiteRestApiClient implements Closeable {
private String initiateTransaction(String portType, String portId) throws IOException {
logger.debug("initiateTransaction handshaking portType={}, portId={}", portType, portId);
HttpPost post = createPost("/site-to-site/" + portType + "/" + portId + "/transactions");
HttpPost post = createPost("/data-transfer/" + portType + "/" + portId + "/transactions");
post.setHeader("Accept", "application/json");

View File

@ -386,29 +386,29 @@ public class TestHttpClient {
servletHandler.addServletWithMapping(SiteInfoServlet.class, "/site-to-site");
servletHandler.addServletWithMapping(PeersServlet.class, "/site-to-site/peers");
servletHandler.addServletWithMapping(PortTransactionsServlet.class, "/site-to-site/input-ports/input-running-id/transactions");
servletHandler.addServletWithMapping(InputPortTransactionServlet.class, "/site-to-site/input-ports/input-running-id/transactions/transaction-id");
servletHandler.addServletWithMapping(FlowFilesServlet.class, "/site-to-site/input-ports/input-running-id/transactions/transaction-id/flow-files");
servletHandler.addServletWithMapping(PortTransactionsServlet.class, "/data-transfer/input-ports/input-running-id/transactions");
servletHandler.addServletWithMapping(InputPortTransactionServlet.class, "/data-transfer/input-ports/input-running-id/transactions/transaction-id");
servletHandler.addServletWithMapping(FlowFilesServlet.class, "/data-transfer/input-ports/input-running-id/transactions/transaction-id/flow-files");
servletHandler.addServletWithMapping(PortTransactionsServlet.class, "/site-to-site/input-ports/input-timeout-id/transactions");
servletHandler.addServletWithMapping(InputPortTransactionServlet.class, "/site-to-site/input-ports/input-timeout-id/transactions/transaction-id");
servletHandler.addServletWithMapping(FlowFilesTimeoutServlet.class, "/site-to-site/input-ports/input-timeout-id/transactions/transaction-id/flow-files");
servletHandler.addServletWithMapping(PortTransactionsServlet.class, "/data-transfer/input-ports/input-timeout-id/transactions");
servletHandler.addServletWithMapping(InputPortTransactionServlet.class, "/data-transfer/input-ports/input-timeout-id/transactions/transaction-id");
servletHandler.addServletWithMapping(FlowFilesTimeoutServlet.class, "/data-transfer/input-ports/input-timeout-id/transactions/transaction-id/flow-files");
servletHandler.addServletWithMapping(PortTransactionsServlet.class, "/site-to-site/input-ports/input-timeout-data-ex-id/transactions");
servletHandler.addServletWithMapping(InputPortTransactionServlet.class, "/site-to-site/input-ports/input-timeout-data-ex-id/transactions/transaction-id");
servletHandler.addServletWithMapping(FlowFilesTimeoutAfterDataExchangeServlet.class, "/site-to-site/input-ports/input-timeout-data-ex-id/transactions/transaction-id/flow-files");
servletHandler.addServletWithMapping(PortTransactionsServlet.class, "/data-transfer/input-ports/input-timeout-data-ex-id/transactions");
servletHandler.addServletWithMapping(InputPortTransactionServlet.class, "/data-transfer/input-ports/input-timeout-data-ex-id/transactions/transaction-id");
servletHandler.addServletWithMapping(FlowFilesTimeoutAfterDataExchangeServlet.class, "/data-transfer/input-ports/input-timeout-data-ex-id/transactions/transaction-id/flow-files");
servletHandler.addServletWithMapping(PortTransactionsServlet.class, "/site-to-site/output-ports/output-running-id/transactions");
servletHandler.addServletWithMapping(OutputPortTransactionServlet.class, "/site-to-site/output-ports/output-running-id/transactions/transaction-id");
servletHandler.addServletWithMapping(FlowFilesServlet.class, "/site-to-site/output-ports/output-running-id/transactions/transaction-id/flow-files");
servletHandler.addServletWithMapping(PortTransactionsServlet.class, "/data-transfer/output-ports/output-running-id/transactions");
servletHandler.addServletWithMapping(OutputPortTransactionServlet.class, "/data-transfer/output-ports/output-running-id/transactions/transaction-id");
servletHandler.addServletWithMapping(FlowFilesServlet.class, "/data-transfer/output-ports/output-running-id/transactions/transaction-id/flow-files");
servletHandler.addServletWithMapping(PortTransactionsServlet.class, "/site-to-site/output-ports/output-timeout-id/transactions");
servletHandler.addServletWithMapping(OutputPortTransactionServlet.class, "/site-to-site/output-ports/output-timeout-id/transactions/transaction-id");
servletHandler.addServletWithMapping(FlowFilesTimeoutServlet.class, "/site-to-site/output-ports/output-timeout-id/transactions/transaction-id/flow-files");
servletHandler.addServletWithMapping(PortTransactionsServlet.class, "/data-transfer/output-ports/output-timeout-id/transactions");
servletHandler.addServletWithMapping(OutputPortTransactionServlet.class, "/data-transfer/output-ports/output-timeout-id/transactions/transaction-id");
servletHandler.addServletWithMapping(FlowFilesTimeoutServlet.class, "/data-transfer/output-ports/output-timeout-id/transactions/transaction-id/flow-files");
servletHandler.addServletWithMapping(PortTransactionsServlet.class, "/site-to-site/output-ports/output-timeout-data-ex-id/transactions");
servletHandler.addServletWithMapping(OutputPortTransactionServlet.class, "/site-to-site/output-ports/output-timeout-data-ex-id/transactions/transaction-id");
servletHandler.addServletWithMapping(FlowFilesTimeoutAfterDataExchangeServlet.class, "/site-to-site/output-ports/output-timeout-data-ex-id/transactions/transaction-id/flow-files");
servletHandler.addServletWithMapping(PortTransactionsServlet.class, "/data-transfer/output-ports/output-timeout-data-ex-id/transactions");
servletHandler.addServletWithMapping(OutputPortTransactionServlet.class, "/data-transfer/output-ports/output-timeout-data-ex-id/transactions/transaction-id");
servletHandler.addServletWithMapping(FlowFilesTimeoutAfterDataExchangeServlet.class, "/data-transfer/output-ports/output-timeout-data-ex-id/transactions/transaction-id/flow-files");
server.start();

View File

@ -100,7 +100,7 @@ public class TestHttpClientTransaction {
public void testReceiveZeroFlowFile() throws IOException {
SiteToSiteRestApiClient apiClient = mock(SiteToSiteRestApiClient.class);
final String transactionUrl = "http://www.example.com/site-to-site/input-ports/portId/transactions/transactionId";
final String transactionUrl = "http://www.example.com/data-transfer/input-ports/portId/transactions/transactionId";
doReturn(false).when(apiClient).openConnectionForReceive(eq(transactionUrl), any(CommunicationsSession.class));
ByteArrayInputStream serverResponse = new ByteArrayInputStream(new byte[0]);
@ -116,7 +116,7 @@ public class TestHttpClientTransaction {
public void testReceiveOneFlowFile() throws IOException {
SiteToSiteRestApiClient apiClient = mock(SiteToSiteRestApiClient.class);
final String transactionUrl = "http://www.example.com/site-to-site/input-ports/portId/transactions/transactionId";
final String transactionUrl = "http://www.example.com/data-transfer/input-ports/portId/transactions/transactionId";
doReturn(true).when(apiClient).openConnectionForReceive(eq(transactionUrl), any(CommunicationsSession.class));
TransactionResultEntity resultEntity = new TransactionResultEntity();
resultEntity.setResponseCode(CONFIRM_TRANSACTION.getCode());
@ -138,7 +138,7 @@ public class TestHttpClientTransaction {
public void testReceiveTwoFlowFiles() throws IOException {
SiteToSiteRestApiClient apiClient = mock(SiteToSiteRestApiClient.class);
final String transactionUrl = "http://www.example.com/site-to-site/input-ports/portId/transactions/transactionId";
final String transactionUrl = "http://www.example.com/data-transfer/input-ports/portId/transactions/transactionId";
doReturn(true).when(apiClient).openConnectionForReceive(eq(transactionUrl), any(CommunicationsSession.class));
TransactionResultEntity resultEntity = new TransactionResultEntity();
resultEntity.setResponseCode(CONFIRM_TRANSACTION.getCode());
@ -161,7 +161,7 @@ public class TestHttpClientTransaction {
public void testReceiveWithInvalidChecksum() throws IOException {
SiteToSiteRestApiClient apiClient = mock(SiteToSiteRestApiClient.class);
final String transactionUrl = "http://www.example.com/site-to-site/input-ports/portId/transactions/transactionId";
final String transactionUrl = "http://www.example.com/data-transfer/input-ports/portId/transactions/transactionId";
doReturn(true).when(apiClient).openConnectionForReceive(eq(transactionUrl), any(CommunicationsSession.class));
// The checksum is correct, but here we simulate as if it's wrong, BAD_CHECKSUM.
TransactionResultEntity resultEntity = new TransactionResultEntity();
@ -185,7 +185,7 @@ public class TestHttpClientTransaction {
public void testSendZeroFlowFile() throws IOException {
SiteToSiteRestApiClient apiClient = mock(SiteToSiteRestApiClient.class);
final String transactionUrl = "http://www.example.com/site-to-site/input-ports/portId/transactions/transactionId";
final String transactionUrl = "http://www.example.com/data-transfer/input-ports/portId/transactions/transactionId";
doNothing().when(apiClient).openConnectionForSend(eq(transactionUrl), any(CommunicationsSession.class));
ByteArrayOutputStream serverResponseBos = new ByteArrayOutputStream();
@ -202,7 +202,7 @@ public class TestHttpClientTransaction {
public void testSendOneFlowFile() throws IOException {
SiteToSiteRestApiClient apiClient = mock(SiteToSiteRestApiClient.class);
final String transactionUrl = "http://www.example.com/site-to-site/input-ports/portId/transactions/transactionId";
final String transactionUrl = "http://www.example.com/data-transfer/input-ports/portId/transactions/transactionId";
doNothing().when(apiClient).openConnectionForSend(eq(transactionUrl), any(CommunicationsSession.class));
// Emulate that server returns correct checksum.
doAnswer(new Answer() {
@ -236,7 +236,7 @@ public class TestHttpClientTransaction {
public void testSendTwoFlowFiles() throws IOException {
SiteToSiteRestApiClient apiClient = mock(SiteToSiteRestApiClient.class);
final String transactionUrl = "http://www.example.com/site-to-site/input-ports/portId/transactions/transactionId";
final String transactionUrl = "http://www.example.com/data-transfer/input-ports/portId/transactions/transactionId";
doNothing().when(apiClient).openConnectionForSend(eq("portId"), any(CommunicationsSession.class));
// Emulate that server returns correct checksum.
doAnswer(new Answer() {
@ -271,7 +271,7 @@ public class TestHttpClientTransaction {
@Test
public void testSendWithInvalidChecksum() throws IOException {
SiteToSiteRestApiClient apiClient = mock(SiteToSiteRestApiClient.class);
final String transactionUrl = "http://www.example.com/site-to-site/input-ports/portId/transactions/transactionId";
final String transactionUrl = "http://www.example.com/data-transfer/input-ports/portId/transactions/transactionId";
doNothing().when(apiClient).openConnectionForSend(eq(transactionUrl), any(CommunicationsSession.class));
// Emulate that server returns incorrect checksum.
doAnswer(new Answer() {
@ -312,7 +312,7 @@ public class TestHttpClientTransaction {
public void testSendButDestinationFull() throws IOException {
SiteToSiteRestApiClient apiClient = mock(SiteToSiteRestApiClient.class);
final String transactionUrl = "http://www.example.com/site-to-site/input-ports/portId/transactions/transactionId";
final String transactionUrl = "http://www.example.com/data-transfer/input-ports/portId/transactions/transactionId";
doNothing().when(apiClient).openConnectionForSend(eq("portId"), any(CommunicationsSession.class));
// Emulate that server returns correct checksum.
doAnswer(new Answer() {

View File

@ -26,55 +26,10 @@ import java.util.Set;
* Details for the access configuration.
*/
@XmlType(name = "accessPolicy")
public class AccessPolicyDTO extends ComponentDTO {
public class AccessPolicyDTO extends AccessPolicySummaryDTO {
private String resource;
private Set<TenantEntity> users;
private Set<TenantEntity> userGroups;
private Boolean canRead;
private Boolean canWrite;
/**
* @return Indicates whether the user can read a given resource.
*/
@ApiModelProperty(
value = "Indicates whether the user can read a given resource.",
readOnly = true
)
public Boolean getCanRead() {
return canRead;
}
public void setCanRead(Boolean canRead) {
this.canRead = canRead;
}
/**
* @return Indicates whether the user can write a given resource.
*/
@ApiModelProperty(
value = "Indicates whether the user can write a given resource.",
readOnly = true
)
public Boolean getCanWrite() {
return canWrite;
}
public void setCanWrite(Boolean canWrite) {
this.canWrite = canWrite;
}
/**
* @return The resource ID for this access policy.
*/
@ApiModelProperty(value="The resource ID for this access policy.")
public String getResource() {
return resource;
}
public void setResource(String resource) {
this.resource = resource;
}
/**
* @return The set of user IDs associated with this access policy.

View File

@ -0,0 +1,59 @@
/*
* 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.web.api.dto;
import com.wordnik.swagger.annotations.ApiModelProperty;
import javax.xml.bind.annotation.XmlType;
/**
* Details for the access configuration.
*/
@XmlType(name = "accessPolicy")
public class AccessPolicySummaryDTO extends ComponentDTO {
private String resource;
private String action;
/**
* @return The action associated with this access policy.
*/
@ApiModelProperty(
value = "The action associated with this access policy.",
allowableValues = "READ, WRITE"
)
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
/**
* @return The resource for this access policy.
*/
@ApiModelProperty(value="The resource for this access policy.")
public String getResource() {
return resource;
}
public void setResource(String resource) {
this.resource = resource;
}
}

View File

@ -0,0 +1,61 @@
/*
* 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.web.api.dto;
import com.wordnik.swagger.annotations.ApiModelProperty;
import javax.xml.bind.annotation.XmlType;
/**
* Details for the access configuration.
*/
@XmlType(name = "permission")
public class PermissionsDTO {
private Boolean canRead;
private Boolean canWrite;
/**
* @return Indicates whether the user can read a given resource.
*/
@ApiModelProperty(
value = "Indicates whether the user can read a given resource.",
readOnly = true
)
public Boolean getCanRead() {
return canRead;
}
public void setCanRead(Boolean canRead) {
this.canRead = canRead;
}
/**
* @return Indicates whether the user can write a given resource.
*/
@ApiModelProperty(
value = "Indicates whether the user can write a given resource.",
readOnly = true
)
public Boolean getCanWrite() {
return canWrite;
}
public void setCanWrite(Boolean canWrite) {
this.canWrite = canWrite;
}
}

View File

@ -17,6 +17,7 @@
package org.apache.nifi.web.api.dto;
import com.wordnik.swagger.annotations.ApiModelProperty;
import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity;
import org.apache.nifi.web.api.entity.TenantEntity;
import javax.xml.bind.annotation.XmlType;
@ -29,11 +30,15 @@ import java.util.Set;
public class UserDTO extends TenantDTO {
private Set<TenantEntity> userGroups;
private Set<AccessPolicySummaryEntity> accessPolicies;
/**
* @return groups to which the user belongs
*/
@ApiModelProperty(value = "The groups to which the user belongs.")
@ApiModelProperty(
value = "The groups to which the user belongs. This field is read only and it provided for convenience.",
readOnly = true
)
public Set<TenantEntity> getUserGroups() {
return userGroups;
}
@ -41,4 +46,19 @@ public class UserDTO extends TenantDTO {
public void setUserGroups(Set<TenantEntity> userGroups) {
this.userGroups = userGroups;
}
/**
* @return policies this user is part of
*/
@ApiModelProperty(
value = "The access policies this user belongs to.",
readOnly = true
)
public Set<AccessPolicySummaryEntity> getAccessPolicies() {
return accessPolicies;
}
public void setAccessPolicies(Set<AccessPolicySummaryEntity> accessPolicies) {
this.accessPolicies = accessPolicies;
}
}

View File

@ -17,6 +17,7 @@
package org.apache.nifi.web.api.dto;
import com.wordnik.swagger.annotations.ApiModelProperty;
import org.apache.nifi.web.api.entity.AccessPolicyEntity;
import org.apache.nifi.web.api.entity.TenantEntity;
import javax.xml.bind.annotation.XmlType;
@ -29,6 +30,7 @@ import java.util.Set;
public class UserGroupDTO extends TenantDTO {
private Set<TenantEntity> users;
private Set<AccessPolicyEntity> accessPolicies;
/**
* @return users in this group
@ -41,4 +43,19 @@ public class UserGroupDTO extends TenantDTO {
public void setUsers(Set<TenantEntity> users) {
this.users = users;
}
/**
* @return policies this user group is part of
*/
@ApiModelProperty(
value = "The access policies this user group belongs to.",
readOnly = true
)
public Set<AccessPolicyEntity> getAccessPolicies() {
return accessPolicies;
}
public void setAccessPolicies(Set<AccessPolicyEntity> accessPolicies) {
this.accessPolicies = accessPolicies;
}
}

View File

@ -17,8 +17,11 @@
package org.apache.nifi.web.api.entity;
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
import org.apache.nifi.web.api.dto.util.TimeAdapter;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Date;
/**
* A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to an {@link AccessPolicyDTO}.
@ -26,6 +29,7 @@ import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "accessPolicyEntity")
public class AccessPolicyEntity extends ComponentEntity {
private Date generated;
private AccessPolicyDTO component;
/**
@ -41,4 +45,15 @@ public class AccessPolicyEntity extends ComponentEntity {
this.component = component;
}
/**
* @return When this content was generated
*/
@XmlJavaTypeAdapter(TimeAdapter.class)
public Date getGenerated() {
return generated;
}
public void setGenerated(Date generated) {
this.generated = generated;
}
}

View File

@ -0,0 +1,45 @@
/*
* 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.web.api.entity;
import org.apache.nifi.web.api.dto.AccessPolicySummaryDTO;
import javax.xml.bind.annotation.XmlRootElement;
/**
* A serialized representation of this class can be placed in the entity body of a request or response to or from the API.
* This particular entity holds a reference to an {@link AccessPolicySummaryDTO}.
*/
@XmlRootElement(name = "accessPolicySummaryEntity")
public class AccessPolicySummaryEntity extends ComponentEntity {
private AccessPolicySummaryDTO component;
/**
* The {@link AccessPolicySummaryDTO} that is being serialized.
*
* @return The {@link AccessPolicySummaryDTO} object
*/
public AccessPolicySummaryDTO getComponent() {
return component;
}
public void setComponent(AccessPolicySummaryDTO component) {
this.component = component;
}
}

View File

@ -17,8 +17,8 @@
package org.apache.nifi.web.api.entity;
import com.wordnik.swagger.annotations.ApiModelProperty;
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
import org.apache.nifi.web.api.dto.BulletinDTO;
import org.apache.nifi.web.api.dto.PermissionsDTO;
import org.apache.nifi.web.api.dto.PositionDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
@ -35,7 +35,7 @@ public class ComponentEntity extends Entity {
private RevisionDTO revision;
private String id;
private PositionDTO position;
private AccessPolicyDTO accessPolicy;
private PermissionsDTO permissions;
private List<BulletinDTO> bulletins;
/**
@ -85,19 +85,19 @@ public class ComponentEntity extends Entity {
}
/**
* The access policy for this component.
* The permissions for this component.
*
* @return The access policy
* @return The permissions
*/
@ApiModelProperty(
value = "The access policy for this component."
value = "The permissions for this component."
)
public AccessPolicyDTO getAccessPolicy() {
return accessPolicy;
public PermissionsDTO getPermissions() {
return permissions;
}
public void setAccessPolicy(AccessPolicyDTO accessPolicy) {
this.accessPolicy = accessPolicy;
public void setPermissions(PermissionsDTO permissions) {
this.permissions = permissions;
}
/**

View File

@ -17,8 +17,8 @@
package org.apache.nifi.web.api.entity;
import com.wordnik.swagger.annotations.ApiModelProperty;
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
import org.apache.nifi.web.api.dto.ControllerConfigurationDTO;
import org.apache.nifi.web.api.dto.PermissionsDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.util.TimeAdapter;
@ -35,7 +35,7 @@ public class ControllerConfigurationEntity extends Entity {
private Date currentTime;
private ControllerConfigurationDTO controllerConfiguration;
private RevisionDTO revision;
private AccessPolicyDTO accessPolicy;
private PermissionsDTO permissions;
/**
* @return revision for this request/response
@ -72,19 +72,19 @@ public class ControllerConfigurationEntity extends Entity {
}
/**
* The access policy for this component.
* The permissions for this component.
*
* @return The access policy
* @return The permissions
*/
@ApiModelProperty(
value = "The access policy for the controller."
value = "The permissions for this component."
)
public AccessPolicyDTO getAccessPolicy() {
return accessPolicy;
public PermissionsDTO getPermissions() {
return permissions;
}
public void setAccessPolicy(AccessPolicyDTO accessPolicy) {
this.accessPolicy = accessPolicy;
public void setPermissions(PermissionsDTO permissions) {
this.permissions = permissions;
}
/**

View File

@ -16,7 +16,8 @@
*/
package org.apache.nifi.web.api.entity;
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
import com.wordnik.swagger.annotations.ApiModelProperty;
import org.apache.nifi.web.api.dto.PermissionsDTO;
import javax.xml.bind.annotation.XmlRootElement;
@ -29,14 +30,16 @@ public class CurrentUserEntity extends Entity {
private String identity;
private boolean anonymous;
private AccessPolicyDTO provenancePermissions;
private AccessPolicyDTO countersPermissions;
private AccessPolicyDTO tenantsPermissions;
private AccessPolicyDTO controllerPermissions;
private PermissionsDTO provenancePermissions;
private PermissionsDTO countersPermissions;
private PermissionsDTO tenantsPermissions;
private PermissionsDTO controllerPermissions;
private PermissionsDTO policiesPermissions;
/**
* @return the user identity being serialized
*/
@ApiModelProperty("The user identity being serialized.")
public String getIdentity() {
return identity;
}
@ -48,6 +51,7 @@ public class CurrentUserEntity extends Entity {
/**
* @return if the user is anonymous
*/
@ApiModelProperty("Whether the current user is anonymous.")
public boolean isAnonymous() {
return anonymous;
}
@ -59,44 +63,60 @@ public class CurrentUserEntity extends Entity {
/**
* @return if the use can query provenance
*/
public AccessPolicyDTO getProvenancePermissions() {
@ApiModelProperty("Permissions for querying provenance.")
public PermissionsDTO getProvenancePermissions() {
return provenancePermissions;
}
public void setProvenancePermissions(AccessPolicyDTO provenancePermissions) {
public void setProvenancePermissions(PermissionsDTO provenancePermissions) {
this.provenancePermissions = provenancePermissions;
}
/**
* @return permissions for accessing counters
*/
public AccessPolicyDTO getCountersPermissions() {
@ApiModelProperty("Permissions for accessing counters.")
public PermissionsDTO getCountersPermissions() {
return countersPermissions;
}
public void setCountersPermissions(AccessPolicyDTO countersPermissions) {
public void setCountersPermissions(PermissionsDTO countersPermissions) {
this.countersPermissions = countersPermissions;
}
/**
* @return permissions for accessing users
*/
public AccessPolicyDTO getTenantsPermissions() {
@ApiModelProperty("Permissions for accessing tenants.")
public PermissionsDTO getTenantsPermissions() {
return tenantsPermissions;
}
public void setTenantsPermissions(AccessPolicyDTO tenantsPermissions) {
public void setTenantsPermissions(PermissionsDTO tenantsPermissions) {
this.tenantsPermissions = tenantsPermissions;
}
/**
* @return permissions for accessing the controller
*/
public AccessPolicyDTO getControllerPermissions() {
@ApiModelProperty("Permissions for accessing the controller.")
public PermissionsDTO getControllerPermissions() {
return controllerPermissions;
}
public void setControllerPermissions(AccessPolicyDTO controllerPermissions) {
public void setControllerPermissions(PermissionsDTO controllerPermissions) {
this.controllerPermissions = controllerPermissions;
}
/**
* @return permissions for accessing the all policies
*/
@ApiModelProperty("Permissions for accessing the policies.")
public PermissionsDTO getPoliciesPermissions() {
return policiesPermissions;
}
public void setPoliciesPermissions(PermissionsDTO policiesPermissions) {
this.policiesPermissions = policiesPermissions;
}
}

View File

@ -17,7 +17,7 @@
package org.apache.nifi.web.api.entity;
import com.wordnik.swagger.annotations.ApiModelProperty;
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
import org.apache.nifi.web.api.dto.PermissionsDTO;
import org.apache.nifi.web.api.dto.flow.FlowBreadcrumbDTO;
import javax.xml.bind.annotation.XmlRootElement;
@ -29,7 +29,7 @@ import javax.xml.bind.annotation.XmlRootElement;
public class FlowBreadcrumbEntity extends Entity {
private String id;
private AccessPolicyDTO accessPolicy;
private PermissionsDTO permissions;
private FlowBreadcrumbDTO breadcrumb;
private FlowBreadcrumbEntity parentBreadcrumb;
@ -50,19 +50,19 @@ public class FlowBreadcrumbEntity extends Entity {
}
/**
* The access policy for this ancestor ProcessGroup.
* The permissions for this ancestor ProcessGroup.
*
* @return The access policy
* @return The permissions
*/
@ApiModelProperty(
value = "The access policy for this ancestor ProcessGroup."
value = "The permissions for this ancestor ProcessGroup."
)
public AccessPolicyDTO getAccessPolicy() {
return accessPolicy;
public PermissionsDTO getPermissions() {
return permissions;
}
public void setAccessPolicy(AccessPolicyDTO accessPolicy) {
this.accessPolicy = accessPolicy;
public void setPermissions(PermissionsDTO permissions) {
this.permissions = permissions;
}
/**

View File

@ -16,12 +16,12 @@
*/
package org.apache.nifi.web.api.entity;
import javax.xml.bind.annotation.XmlRootElement;
import com.wordnik.swagger.annotations.ApiModelProperty;
import org.apache.nifi.web.api.dto.ProcessGroupDTO;
import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
import javax.xml.bind.annotation.XmlRootElement;
/**
* A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ProcessGroupDTO.
*/
@ -44,7 +44,7 @@ public class ProcessGroupEntity extends ComponentEntity {
/**
* The ProcessGroupDTO that is being serialized.
*
* @return The ControllerDTO object
* @return The ProcessGroupDTO object
*/
public ProcessGroupDTO getComponent() {
return component;

View File

@ -17,7 +17,7 @@
package org.apache.nifi.web.api.entity;
import com.wordnik.swagger.annotations.ApiModelProperty;
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
import org.apache.nifi.web.api.dto.PermissionsDTO;
import org.apache.nifi.web.api.dto.flow.ProcessGroupFlowDTO;
import javax.xml.bind.annotation.XmlRootElement;
@ -28,23 +28,23 @@ import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "processGroupFlowEntity")
public class ProcessGroupFlowEntity extends Entity {
private AccessPolicyDTO accessPolicy;
private PermissionsDTO permissions;
private ProcessGroupFlowDTO processGroupFlow;
/**
* The access policy for this component.
* The permissions for this component.
*
* @return The access policy
* @return The permissions
*/
@ApiModelProperty(
value = "The access policy for this process group."
)
public AccessPolicyDTO getAccessPolicy() {
return accessPolicy;
public PermissionsDTO getPermissions() {
return permissions;
}
public void setAccessPolicy(AccessPolicyDTO accessPolicy) {
this.accessPolicy = accessPolicy;
public void setPermissions(PermissionsDTO permissions) {
this.permissions = permissions;
}
/**

View File

@ -14,9 +14,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#process-group-details {
z-index: 1301;
display: none;
width: 400px;
height: 290px;
}
package org.apache.nifi.web.api.entity;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Set;
/**
* A serialized representation of this class can be placed in the entity body of a request or response to or from the API.
*/
@XmlRootElement(name = "tenantCollectionEntity")
public class TenantCollectionEntity extends ComponentEntity {
private Set<String> tenants;
/**
* The tenants being serialized.
*
* @return The tenants
*/
public Set<String> getTenants() {
return tenants;
}
public void setTenants(Set<String> tenants) {
this.tenants = tenants;
}
}

View File

@ -0,0 +1,57 @@
/*
* 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.web.api.entity;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Collection;
/**
* A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a collection of
* TenantEntity objects.
*/
@XmlRootElement(name = "tenantsEntity")
public class TenantsEntity {
private Collection<TenantEntity> users;
private Collection<TenantEntity> userGroups;
/**
* The collection of users that are being serialized.
*
* @return users
*/
public Collection<TenantEntity> getUsers() {
return users;
}
public void setUsers(Collection<TenantEntity> users) {
this.users = users;
}
/**
* The collection of user groups that are being serialized.
*
* @return user groups
*/
public Collection<TenantEntity> getUserGroups() {
return userGroups;
}
public void setUserGroups(Collection<TenantEntity> userGroups) {
this.userGroups = userGroups;
}
}

View File

@ -16,8 +16,12 @@
*/
package org.apache.nifi.web.api.entity;
import org.apache.nifi.web.api.dto.util.TimeAdapter;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Collection;
import java.util.Date;
/**
* A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a collection of UserEntity
@ -26,6 +30,7 @@ import java.util.Collection;
@XmlRootElement(name = "usersEntity")
public class UsersEntity extends Entity {
private Date generated;
private Collection<UserEntity> users;
/**
@ -40,4 +45,16 @@ public class UsersEntity extends Entity {
public void setUsers(Collection<UserEntity> users) {
this.users = users;
}
/**
* @return When this content was generated
*/
@XmlJavaTypeAdapter(TimeAdapter.class)
public Date getGenerated() {
return generated;
}
public void setGenerated(Date generated) {
this.generated = generated;
}
}

View File

@ -16,38 +16,39 @@
*/
package org.apache.nifi.authorization.resource;
import org.apache.nifi.authorization.AccessPolicy;
import org.apache.nifi.authorization.Resource;
/**
* Authorizable for policies of an Authorizable.
*/
public class AccessPolicyAuthorizable implements Authorizable {
final Authorizable authorizable;
private final AccessPolicy policy;
public AccessPolicyAuthorizable(AccessPolicy policy) {
this.policy = policy;
public AccessPolicyAuthorizable(Authorizable authorizable) {
this.authorizable = authorizable;
}
@Override
public Authorizable getParentAuthorizable() {
return new Authorizable() {
@Override
public Authorizable getParentAuthorizable() {
return null;
}
if (authorizable.getParentAuthorizable() == null) {
return new Authorizable() {
@Override
public Authorizable getParentAuthorizable() {
return null;
}
@Override
public Resource getResource() {
return ResourceFactory.getPoliciesResource();
}
};
@Override
public Resource getResource() {
return ResourceFactory.getPoliciesResource();
}
};
} else {
return new AccessPolicyAuthorizable(authorizable.getParentAuthorizable());
}
}
@Override
public Resource getResource() {
return ResourceFactory.getPolicyResource(policy.getIdentifier());
}
public AccessPolicy getPolicy() {
return policy;
return ResourceFactory.getPolicyResource(authorizable.getResource());
}
}

View File

@ -18,7 +18,15 @@ package org.apache.nifi.authorization.resource;
import org.apache.nifi.authorization.Resource;
public class AccessPoliciesAuthorizable implements Authorizable {
/**
* Authorizable for policies of an Authorizable.
*/
public class DataTransferAuthorizable implements Authorizable {
final Authorizable authorizable;
public DataTransferAuthorizable(Authorizable authorizable) {
this.authorizable = authorizable;
}
@Override
public Authorizable getParentAuthorizable() {
@ -27,6 +35,6 @@ public class AccessPoliciesAuthorizable implements Authorizable {
@Override
public Resource getResource() {
return ResourceFactory.getPoliciesResource();
return ResourceFactory.getDataTransferResource(authorizable.getResource());
}
}

View File

@ -16,7 +16,6 @@
*/
package org.apache.nifi.authorization.resource;
import org.apache.nifi.authorization.AccessPolicy;
import org.apache.nifi.authorization.Resource;
import java.util.Objects;
@ -287,18 +286,6 @@ public final class ResourceFactory {
}
};
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 POLICIES_RESOURCE = new Resource() {
@Override
@ -384,15 +371,6 @@ public final class ResourceFactory {
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.
*
@ -494,15 +472,6 @@ public final class ResourceFactory {
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 Tenants which includes creating, modifying, and deleting Users and UserGroups.
*
@ -513,19 +482,20 @@ public final class ResourceFactory {
}
/**
* Gets a Resource for performing site to site on a port.
* Gets a Resource for performing transferring data to a port.
*
* @param isInputPort Whether this port is an input port or an output port
* @param identifier The identifier of the component being accessed
* @param name The name of the component being accessed
* @return The resource
*/
public static Resource getSiteToSiteResource(final String identifier, final String name) {
public static Resource getDataTransferResource(final boolean isInputPort, final String identifier, final String name) {
Objects.requireNonNull(identifier, "The component identifier must be specified.");
return new Resource() {
@Override
public String getIdentifier() {
return String.format("%s/%s", ResourceType.SiteToSite.getValue(), identifier);
return String.format("%s/%s/%s", ResourceType.DataTransfer.getValue(), isInputPort ? "input-ports" : "output-ports", identifier);
}
@Override
@ -536,7 +506,29 @@ public final class ResourceFactory {
}
/**
* Gets the {@link Resource} for accessing {@link AccessPolicy}s.
* Gets a Resource for performing transferring data to a port.
*
* @param resource The resource to transfer data to
* @return The resource
*/
public static Resource getDataTransferResource(final Resource resource) {
Objects.requireNonNull(resource, "The resource must be specified.");
return new Resource() {
@Override
public String getIdentifier() {
return String.format("%s%s", ResourceType.DataTransfer.getValue(), resource.getIdentifier());
}
@Override
public String getName() {
return "Transfer data to " + resource.getName();
}
};
}
/**
* Gets the {@link Resource} for accessing access policies.
* @return The policies resource
*/
public static Resource getPoliciesResource() {
@ -544,23 +536,23 @@ public final class ResourceFactory {
}
/**
* Gets a Resource for accessing an {@link AccessPolicy} configuration.
* Gets a Resource for accessing a resources's policies.
*
* @param identifier The identifier of the component being accessed
* @param resource The resource being accessed
* @return The resource
*/
public static Resource getPolicyResource(final String identifier) {
Objects.requireNonNull(identifier, "The component identifier must be specified.");
public static Resource getPolicyResource(final Resource resource) {
Objects.requireNonNull(resource, "The resource type must be specified.");
return new Resource() {
@Override
public String getIdentifier() {
return String.format("%s/%s", POLICIES_RESOURCE.getIdentifier(), identifier);
return String.format("%s%s", POLICY_RESOURCE.getIdentifier(), resource.getIdentifier());
}
@Override
public String getName() {
return identifier;
return "Policies for " + resource.getName();
}
};
}

View File

@ -36,10 +36,10 @@ public enum ResourceType {
ReportingTask("/reporting-tasks"),
Resource("/resources"),
SiteToSite("/site-to-site"),
DataTransfer("/data-transfer"),
System("/system"),
Template("/templates"),
Tenant("/tenants"),
Token("/token");
Tenant("/tenants");
final String value;
@ -50,4 +50,21 @@ public enum ResourceType {
public String getValue() {
return value;
}
public static ResourceType valueOfValue(final String rawValue) {
ResourceType type = null;
for (final ResourceType rt : values()) {
if (rt.getValue().equals(rawValue)) {
type = rt;
break;
}
}
if (type == null) {
throw new IllegalArgumentException("Unknown resource type value " + rawValue);
}
return type;
}
}

View File

@ -16,12 +16,13 @@
*/
package org.apache.nifi.remote;
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.ResourceFactory;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.resource.DataTransferAuthorizable;
import org.apache.nifi.authorization.user.StandardNiFiUser;
import org.apache.nifi.components.ValidationResult;
import org.apache.nifi.connectable.ConnectableType;
import org.apache.nifi.controller.AbstractPort;
@ -355,17 +356,10 @@ public class StandardRootGroupPort extends AbstractPort implements RootGroupPort
return new StandardPortAuthorizationResult(false, "User DN is not known");
}
// build the request
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.identity(dn)
.anonymous(false)
.accessAttempt(true)
.action(RequestAction.WRITE)
.resource(ResourceFactory.getSiteToSiteResource(getIdentifier(), getName()))
.build();
// perform the authorization
final AuthorizationResult result = authorizer.authorize(request);
final Authorizable dataTransferAuthorizable = new DataTransferAuthorizable(this);
final AuthorizationResult result = dataTransferAuthorizable.checkAuthorization(authorizer, RequestAction.WRITE, new StandardNiFiUser(dn));
if (!Result.Approved.equals(result.getResult())) {
final String message = String.format("%s authorization failed for user %s because %s", this, dn, result.getExplanation());
logger.warn(message);

View File

@ -16,7 +16,6 @@
*/
package org.apache.nifi.web;
import org.apache.nifi.authorization.AccessPolicy;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.controller.Snippet;
@ -178,18 +177,36 @@ public interface AuthorizableLookup {
* Get the {@link Authorizable} that represents the resource of users and user groups.
* @return authorizable
*/
Authorizable getTenantAuthorizable();
Authorizable getTenant();
/**
* Get the {@link Authorizable} the represents the parent resource of {@link AccessPolicy} resources.
* Get the authorizable for access all policies.
*
* @return authorizable
*/
Authorizable getAccessPoliciesAuthorizable();
Authorizable getPolicies();
/**
* Get the {@link Authorizable} the represents the {@link AccessPolicy} with the given ID.
* @param id access policy ID
* Get the authorizable for the policy of the policy id.
*
* @param id id
* @return authorizable
*/
Authorizable getAccessPolicyAuthorizable(String id);
Authorizable getAccessPolicyById(String id);
/**
* Get the authorizable for the policy of the specified resource.
*
* @param resource resource
* @return authorizable
*/
Authorizable getAccessPolicyByResource(String resource);
/**
* Get the authorizable of the specified resource.
*
* @param resource resource
* @return authorizable
*/
Authorizable getAuthorizableFromResource(final String resource);
}

View File

@ -16,13 +16,7 @@
*/
package org.apache.nifi.web;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.user.NiFiUser;
import org.apache.nifi.controller.ScheduledState;
import org.apache.nifi.controller.repository.claim.ContentDirection;
@ -98,6 +92,13 @@ import org.apache.nifi.web.api.entity.TemplateEntity;
import org.apache.nifi.web.api.entity.UserEntity;
import org.apache.nifi.web.api.entity.UserGroupEntity;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
/**
* Defines the NiFiServiceFacade interface.
*/
@ -152,7 +153,7 @@ public interface NiFiServiceFacade {
// ----------------------------------------
// Controller methods
// ----------------------------------------
ControllerDTO getController();
ControllerDTO getSiteToSiteDetails();
/**
* Searches the controller for the specified query string.
@ -1274,6 +1275,14 @@ public interface NiFiServiceFacade {
*/
AccessPolicyEntity getAccessPolicy(String accessPolicyId);
/**
* Gets the access policy for the specified action, resource type, and component id.
*
* @param resource resource
* @return access policy
*/
AccessPolicyEntity getAccessPolicy(RequestAction requestAction, String resource);
/**
* Updates the specified access policy.
* @param revision Revision to compare with current base revision

View File

@ -16,11 +16,15 @@
*/
package org.apache.nifi.web;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.AccessPolicy;
import org.apache.nifi.authorization.Resource;
import org.apache.nifi.authorization.resource.AccessPoliciesAuthorizable;
import org.apache.nifi.authorization.resource.AccessPolicyAuthorizable;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.resource.DataTransferAuthorizable;
import org.apache.nifi.authorization.resource.ProvenanceEventAuthorizable;
import org.apache.nifi.authorization.resource.ResourceFactory;
import org.apache.nifi.authorization.resource.ResourceType;
import org.apache.nifi.authorization.resource.TenantAuthorizable;
import org.apache.nifi.controller.ConfiguredComponent;
import org.apache.nifi.controller.Snippet;
@ -46,7 +50,17 @@ import org.apache.nifi.web.dao.TemplateDAO;
class StandardAuthorizableLookup implements AuthorizableLookup {
private static final TenantAuthorizable TENANT_AUTHORIZABLE = new TenantAuthorizable();
private static final Authorizable ACCESS_POLICIES_AUTHORIZABLE = new AccessPoliciesAuthorizable();
private static final Authorizable POLICIES_AUTHORIZABLE = new Authorizable() {
@Override
public Authorizable getParentAuthorizable() {
return null;
}
@Override
public Resource getResource() {
return ResourceFactory.getPoliciesResource();
}
};
private static final Authorizable PROVENANCE_AUTHORIZABLE = new Authorizable() {
@Override
@ -193,18 +207,243 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
}
@Override
public Authorizable getTenantAuthorizable() {
public Authorizable getTenant() {
return TENANT_AUTHORIZABLE;
}
@Override
public Authorizable getAccessPoliciesAuthorizable() {
return ACCESS_POLICIES_AUTHORIZABLE;
public Authorizable getPolicies() {
return POLICIES_AUTHORIZABLE;
}
@Override
public Authorizable getAccessPolicyAuthorizable(String id) {
return new AccessPolicyAuthorizable(accessPolicyDAO.getAccessPolicy(id));
public Authorizable getAccessPolicyById(final String id) {
final AccessPolicy policy = accessPolicyDAO.getAccessPolicy(id);
return getAccessPolicyByResource(policy.getResource());
}
@Override
public Authorizable getAccessPolicyByResource(final String resource) {
try {
return new AccessPolicyAuthorizable(getAuthorizableFromResource(resource));
} catch (final ResourceNotFoundException e) {
// the underlying component has been removed or resource is invalid... require /policies permissions
return POLICIES_AUTHORIZABLE;
}
}
@Override
public Authorizable getAuthorizableFromResource(String resource) {
// parse the resource type
ResourceType resourceType = null;
for (ResourceType type : ResourceType.values()) {
if (resource.equals(type.getValue()) || resource.startsWith(type.getValue() + "/")) {
resourceType = type;
}
}
if (resourceType == null) {
throw new ResourceNotFoundException("Unrecognized resource: " + resource);
}
// if this is a policy or a provenance event resource, there should be another resource type
if (ResourceType.Policy.equals(resourceType) || ResourceType.ProvenanceEvent.equals(resourceType) || ResourceType.DataTransfer.equals(resourceType)) {
final ResourceType primaryResourceType = resourceType;
// get the resource type
resource = StringUtils.substringAfter(resource, resourceType.getValue());
for (ResourceType type : ResourceType.values()) {
if (resource.equals(type.getValue()) || resource.startsWith(type.getValue() + "/")) {
resourceType = type;
}
}
if (resourceType == null) {
throw new ResourceNotFoundException("Unrecognized resource: " + resource);
}
// must either be a policy, event, or data transfer
if (ResourceType.Policy.equals(primaryResourceType)) {
return new AccessPolicyAuthorizable(getAccessPolicy(resourceType, resource));
} else if (ResourceType.ProvenanceEvent.equals(primaryResourceType)) {
return new ProvenanceEventAuthorizable(getAccessPolicy(resourceType, resource));
} else {
return new DataTransferAuthorizable(getAccessPolicy(resourceType, resource));
}
} else {
return getAccessPolicy(resourceType, resource);
}
}
private Authorizable getAccessPolicy(final ResourceType resourceType, final String resource) {
final String slashComponentId = StringUtils.substringAfter(resource, resourceType.getValue());
if (slashComponentId.startsWith("/")) {
return getAccessPolicyByResource(resourceType, slashComponentId.substring(1));
} else {
return getAccessPolicyByResource(resourceType);
}
}
private Authorizable getAccessPolicyByResource(final ResourceType resourceType, final String componentId) {
Authorizable authorizable = null;
switch (resourceType) {
case Connection:
authorizable = getConnection(componentId);
break;
case ControllerService:
authorizable = getControllerService(componentId);
break;
case Funnel:
authorizable = getFunnel(componentId);
break;
case InputPort:
authorizable = getInputPort(componentId);
break;
case Label:
authorizable = getLabel(componentId);
break;
case OutputPort:
authorizable = getOutputPort(componentId);
break;
case Processor:
authorizable = getProcessor(componentId);
break;
case ProcessGroup:
authorizable = getProcessGroup(componentId);
break;
case RemoteProcessGroup:
authorizable = getRemoteProcessGroup(componentId);
break;
case ReportingTask:
authorizable = getReportingTask(componentId);
break;
case Template:
authorizable = getTemplate(componentId);
break;
case ProvenanceEvent:
authorizable = controllerFacade.getProvenanceEventAuthorizable(componentId);
break;
}
if (authorizable == null) {
throw new IllegalArgumentException("An unexpected type of resource in this policy " + resourceType.getValue());
}
return authorizable;
}
private Authorizable getAccessPolicyByResource(final ResourceType resourceType) {
Authorizable authorizable = null;
switch (resourceType) {
case Controller:
authorizable = getController();
break;
case Counters:
authorizable = new Authorizable() {
@Override
public Authorizable getParentAuthorizable() {
return null;
}
@Override
public Resource getResource() {
return ResourceFactory.getCountersResource();
}
};
break;
case Flow:
authorizable = new Authorizable() {
@Override
public Authorizable getParentAuthorizable() {
return null;
}
@Override
public Resource getResource() {
return ResourceFactory.getFlowResource();
}
};
break;
case Provenance:
authorizable = new Authorizable() {
@Override
public Authorizable getParentAuthorizable() {
return null;
}
@Override
public Resource getResource() {
return ResourceFactory.getProvenanceResource();
}
};
break;
case Proxy:
authorizable = new Authorizable() {
@Override
public Authorizable getParentAuthorizable() {
return null;
}
@Override
public Resource getResource() {
return ResourceFactory.getProxyResource();
}
};
break;
case Policy:
authorizable = POLICIES_AUTHORIZABLE;
break;
case Resource:
authorizable = new Authorizable() {
@Override
public Authorizable getParentAuthorizable() {
return null;
}
@Override
public Resource getResource() {
return ResourceFactory.getResourceResource();
}
};
break;
case SiteToSite:
// TODO - new site-to-site and port specific site-to-site
authorizable = new Authorizable() {
@Override
public Authorizable getParentAuthorizable() {
return null;
}
@Override
public Resource getResource() {
return ResourceFactory.getSiteToSiteResource();
}
};
break;
case System:
authorizable = new Authorizable() {
@Override
public Authorizable getParentAuthorizable() {
return null;
}
@Override
public Resource getResource() {
return ResourceFactory.getSystemResource();
}
};
break;
case Tenant:
authorizable = getTenant();
break;
}
if (authorizable == null) {
throw new IllegalArgumentException("An unexpected type of resource in this policy " + resourceType.getValue());
}
return authorizable;
}
@Override

View File

@ -16,29 +16,7 @@
*/
package org.apache.nifi.web;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import com.google.common.collect.Sets;
import org.apache.nifi.action.Action;
import org.apache.nifi.action.Component;
import org.apache.nifi.action.FlowChangeAction;
@ -55,6 +33,7 @@ import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.Resource;
import org.apache.nifi.authorization.User;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.resource.DataTransferAuthorizable;
import org.apache.nifi.authorization.user.NiFiUser;
import org.apache.nifi.authorization.user.NiFiUserUtils;
import org.apache.nifi.cluster.coordination.ClusterCoordinator;
@ -101,6 +80,7 @@ import org.apache.nifi.reporting.BulletinQuery;
import org.apache.nifi.reporting.BulletinRepository;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
import org.apache.nifi.web.api.dto.AccessPolicySummaryDTO;
import org.apache.nifi.web.api.dto.BulletinBoardDTO;
import org.apache.nifi.web.api.dto.BulletinDTO;
import org.apache.nifi.web.api.dto.BulletinQueryDTO;
@ -127,6 +107,7 @@ import org.apache.nifi.web.api.dto.FunnelDTO;
import org.apache.nifi.web.api.dto.LabelDTO;
import org.apache.nifi.web.api.dto.ListingRequestDTO;
import org.apache.nifi.web.api.dto.NodeDTO;
import org.apache.nifi.web.api.dto.PermissionsDTO;
import org.apache.nifi.web.api.dto.PortDTO;
import org.apache.nifi.web.api.dto.PreviousValueDTO;
import org.apache.nifi.web.api.dto.ProcessGroupDTO;
@ -160,6 +141,7 @@ import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
import org.apache.nifi.web.api.dto.status.StatusHistoryDTO;
import org.apache.nifi.web.api.entity.AccessPolicyEntity;
import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity;
import org.apache.nifi.web.api.entity.ConnectionEntity;
import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
@ -210,7 +192,27 @@ import org.apache.nifi.web.util.SnippetUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Sets;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
* Implementation of NiFiServiceFacade that performs revision checking.
@ -451,11 +453,12 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
// -----------------------------------------
// Write Operations
// -----------------------------------------
@Override
public AccessPolicyEntity updateAccessPolicy(final Revision revision, final AccessPolicyDTO accessPolicyDTO) {
final Authorizable accessPolicyAuthorizable = authorizableLookup.getAccessPolicyAuthorizable(accessPolicyDTO.getId());
final Authorizable authorizable = authorizableLookup.getAccessPolicyById(accessPolicyDTO.getId());
final RevisionUpdate<AccessPolicyDTO> snapshot = updateComponent(revision,
accessPolicyAuthorizable,
authorizable,
() -> accessPolicyDAO.updateAccessPolicy(accessPolicyDTO),
accessPolicy -> {
final Set<TenantEntity> users = accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet());
@ -463,33 +466,38 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
return dtoFactory.createAccessPolicyDto(accessPolicy, userGroups, users);
});
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(accessPolicyAuthorizable);
return entityFactory.createAccessPolicyEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizable);
return entityFactory.createAccessPolicyEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions);
}
@Override
public UserEntity updateUser(final Revision revision, final UserDTO userDTO) {
final Authorizable usersAuthorizable = authorizableLookup.getTenantAuthorizable();
final Authorizable usersAuthorizable = authorizableLookup.getTenant();
final Set<Group> groups = userGroupDAO.getUserGroupsForUser(userDTO.getId());
final Set<AccessPolicy> policies = userGroupDAO.getAccessPoliciesForUser(userDTO.getId());
final RevisionUpdate<UserDTO> snapshot = updateComponent(revision,
usersAuthorizable,
() -> userDAO.updateUser(userDTO),
user -> dtoFactory.createUserDto(user, groups.stream().map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet())));
user -> {
final Set<TenantEntity> tenantEntities = groups.stream().map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet());
final Set<AccessPolicySummaryEntity> policyEntities = policies.stream().map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
return dtoFactory.createUserDto(user, tenantEntities, policyEntities);
});
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(usersAuthorizable);
return entityFactory.createUserEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(usersAuthorizable);
return entityFactory.createUserEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions);
}
@Override
public UserGroupEntity updateUserGroup(final Revision revision, final UserGroupDTO userGroupDTO) {
final Authorizable userGroupsAuthorizable = authorizableLookup.getTenantAuthorizable();
final Authorizable userGroupsAuthorizable = authorizableLookup.getTenant();
final RevisionUpdate<UserGroupDTO> snapshot = updateComponent(revision,
userGroupsAuthorizable,
() -> userGroupDAO.updateUserGroup(userGroupDTO),
userGroup -> dtoFactory.createUserGroupDto(userGroup, userGroup.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet())));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(userGroupsAuthorizable);
return entityFactory.createUserGroupEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(userGroupsAuthorizable);
return entityFactory.createUserGroupEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions);
}
@Override
@ -502,9 +510,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
() -> connectionDAO.updateConnection(connectionDTO),
connection -> dtoFactory.createConnectionDto(connection));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(connectionNode);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(connectionNode);
final ConnectionStatusDTO status = dtoFactory.createConnectionStatusDto(controllerFacade.getConnectionStatus(connectionNode.getIdentifier()));
return entityFactory.createConnectionEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status);
return entityFactory.createConnectionEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, status);
}
@Override
@ -516,10 +524,10 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
() -> processorDAO.updateProcessor(processorDTO),
proc -> dtoFactory.createProcessorDto(proc));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(processorNode);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processorNode);
final ProcessorStatusDTO status = dtoFactory.createProcessorStatusDto(controllerFacade.getProcessorStatus(processorNode.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(processorNode.getIdentifier()));
return entityFactory.createProcessorEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status, bulletins);
return entityFactory.createProcessorEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, status, bulletins);
}
@Override
@ -530,8 +538,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
() -> labelDAO.updateLabel(labelDTO),
label -> dtoFactory.createLabelDto(label));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(labelNode);
return entityFactory.createLabelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(labelNode);
return entityFactory.createLabelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions);
}
@Override
@ -542,8 +550,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
() -> funnelDAO.updateFunnel(funnelDTO),
funnel -> dtoFactory.createFunnelDto(funnel));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(funnelNode);
return entityFactory.createFunnelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(funnelNode);
return entityFactory.createFunnelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions);
}
@ -638,10 +646,10 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
() -> inputPortDAO.updatePort(inputPortDTO),
port -> dtoFactory.createPortDto(port));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(inputPortNode);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(inputPortNode);
final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getInputPortStatus(inputPortNode.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(inputPortNode.getIdentifier()));
return entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status, bulletins);
return entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, status, bulletins);
}
@Override
@ -652,10 +660,10 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
() -> outputPortDAO.updatePort(outputPortDTO),
port -> dtoFactory.createPortDto(port));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(outputPortNode);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(outputPortNode);
final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getOutputPortStatus(outputPortNode.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(outputPortNode.getIdentifier()));
return entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status, bulletins);
return entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, status, bulletins);
}
@Override
@ -667,11 +675,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
() -> remoteProcessGroupDAO.updateRemoteProcessGroup(remoteProcessGroupDTO),
remoteProcessGroup -> dtoFactory.createRemoteProcessGroupDto(remoteProcessGroup));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(remoteProcessGroupNode);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(remoteProcessGroupNode);
final RevisionDTO updateRevision = dtoFactory.createRevisionDTO(snapshot.getLastModification());
final RemoteProcessGroupStatusDTO status = dtoFactory.createRemoteProcessGroupStatusDto(controllerFacade.getRemoteProcessGroupStatus(remoteProcessGroupNode.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(remoteProcessGroupNode.getIdentifier()));
return entityFactory.createRemoteProcessGroupEntity(snapshot.getComponent(), updateRevision, accessPolicy, status, bulletins);
return entityFactory.createRemoteProcessGroupEntity(snapshot.getComponent(), updateRevision, permissions, status, bulletins);
}
@Override
@ -685,9 +693,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
() -> remoteProcessGroupDAO.updateRemoteProcessGroupInputPort(remoteProcessGroupId, remoteProcessGroupPortDTO),
remoteGroupPort -> dtoFactory.createRemoteProcessGroupPortDto(remoteGroupPort));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(remoteProcessGroupNode);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(remoteProcessGroupNode);
final RevisionDTO updatedRevision = dtoFactory.createRevisionDTO(snapshot.getLastModification());
return entityFactory.createRemoteProcessGroupPortEntity(snapshot.getComponent(), updatedRevision, accessPolicy);
return entityFactory.createRemoteProcessGroupPortEntity(snapshot.getComponent(), updatedRevision, permissions);
}
@Override
@ -701,9 +709,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
() -> remoteProcessGroupDAO.updateRemoteProcessGroupOutputPort(remoteProcessGroupId, remoteProcessGroupPortDTO),
remoteGroupPort -> dtoFactory.createRemoteProcessGroupPortDto(remoteGroupPort));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(remoteProcessGroupNode);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(remoteProcessGroupNode);
final RevisionDTO updatedRevision = dtoFactory.createRevisionDTO(snapshot.getLastModification());
return entityFactory.createRemoteProcessGroupPortEntity(snapshot.getComponent(), updatedRevision, accessPolicy);
return entityFactory.createRemoteProcessGroupPortEntity(snapshot.getComponent(), updatedRevision, permissions);
}
@Override
@ -714,11 +722,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
() -> processGroupDAO.updateProcessGroup(processGroupDTO),
processGroup -> dtoFactory.createProcessGroupDto(processGroup));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(processGroupNode);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroupNode);
final RevisionDTO updatedRevision = dtoFactory.createRevisionDTO(snapshot.getLastModification());
final ProcessGroupStatusDTO status = dtoFactory.createConciseProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(processGroupNode.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(processGroupNode.getIdentifier()));
return entityFactory.createProcessGroupEntity(snapshot.getComponent(), updatedRevision, accessPolicy, status, bulletins);
return entityFactory.createProcessGroupEntity(snapshot.getComponent(), updatedRevision, permissions, status, bulletins);
}
@Override
@ -766,9 +774,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
},
controller -> dtoFactory.createControllerConfigurationDto(controllerFacade));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(controllerFacade);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(controllerFacade);
final RevisionDTO updateRevision = dtoFactory.createRevisionDTO(updatedComponent.getLastModification());
return entityFactory.createControllerConfigurationEntity(updatedComponent.getComponent(), updateRevision, accessPolicy);
return entityFactory.createControllerConfigurationEntity(updatedComponent.getComponent(), updateRevision, permissions);
}
@Override
@ -892,11 +900,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final User user = userDAO.getUser(userId);
final Set<TenantEntity> userGroups = user != null ? userGroupDAO.getUserGroupsForUser(userId).stream()
.map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()) : null;
final Set<AccessPolicySummaryEntity> policyEntities = user != null ? userGroupDAO.getAccessPoliciesForUser(userId).stream()
.map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet()) : null;
final UserDTO snapshot = deleteComponent(
revision,
authorizableLookup.getTenantAuthorizable(),
authorizableLookup.getTenant(),
() -> userDAO.deleteUser(userId),
dtoFactory.createUserDto(user, userGroups));
dtoFactory.createUserDto(user, userGroups, policyEntities));
return entityFactory.createUserEntity(snapshot, null, null);
}
@ -909,7 +919,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
null;
final UserGroupDTO snapshot = deleteComponent(
revision,
authorizableLookup.getTenantAuthorizable(),
authorizableLookup.getTenant(),
() -> userGroupDAO.deleteUserGroup(userGroupId),
dtoFactory.createUserGroupDto(userGroup, users));
@ -923,7 +933,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final Set<TenantEntity> users = accessPolicy != null ? accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet()) : null;
final AccessPolicyDTO snapshot = deleteComponent(
revision,
authorizableLookup.getAccessPolicyAuthorizable(accessPolicyId),
authorizableLookup.getAccessPolicyById(accessPolicyId),
() -> accessPolicyDAO.deleteAccessPolicy(accessPolicyId),
dtoFactory.createAccessPolicyDto(accessPolicy, userGroups,
users));
@ -1064,9 +1074,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
connection -> dtoFactory.createConnectionDto(connection));
final Connection connection = connectionDAO.getConnection(connectionDTO.getId());
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(connection);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(connection);
final ConnectionStatusDTO status = dtoFactory.createConnectionStatusDto(controllerFacade.getConnectionStatus(connectionDTO.getId()));
return entityFactory.createConnectionEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status);
return entityFactory.createConnectionEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, status);
}
@Override
@ -1099,10 +1109,10 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
processor -> dtoFactory.createProcessorDto(processor));
final ProcessorNode processor = processorDAO.getProcessor(processorDTO.getId());
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(processor);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processor);
final ProcessorStatusDTO status = dtoFactory.createProcessorStatusDto(controllerFacade.getProcessorStatus(processorDTO.getId()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(processorDTO.getId()));
return entityFactory.createProcessorEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status, bulletins);
return entityFactory.createProcessorEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, status, bulletins);
}
@Override
@ -1114,8 +1124,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
label -> dtoFactory.createLabelDto(label));
final Label label = labelDAO.getLabel(labelDTO.getId());
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(label);
return entityFactory.createLabelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(label);
return entityFactory.createLabelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions);
}
/**
@ -1159,55 +1169,63 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
funnel -> dtoFactory.createFunnelDto(funnel));
final Funnel funnel = funnelDAO.getFunnel(funnelDTO.getId());
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(funnel);
return entityFactory.createFunnelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(funnel);
return entityFactory.createFunnelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions);
}
@Override
public AccessPolicyEntity createAccessPolicy(final Revision revision, final AccessPolicyDTO accessPolicyDTO) {
// TODO read lock on users and groups (and resource+action?) while the policy is being created?
final Authorizable tenantAuthorizable = authorizableLookup.getTenantAuthorizable();
final Authorizable tenantAuthorizable = authorizableLookup.getTenant();
final String creator = NiFiUserUtils.getNiFiUserIdentity();
final AccessPolicy newAccessPolicy = accessPolicyDAO.createAccessPolicy(accessPolicyDTO);
final AccessPolicyDTO newAccessPolicyDto = dtoFactory.createAccessPolicyDto(newAccessPolicy,
newAccessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()),
newAccessPolicy.getUsers().stream().map(userId -> {
final RevisionDTO userRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userId));
return entityFactory.createTenantEntity(dtoFactory.createTenantDTO(userDAO.getUser(userId)), userRevision,
dtoFactory.createAccessPolicyDto(tenantAuthorizable));
dtoFactory.createPermissionsDto(tenantAuthorizable));
}).collect(Collectors.toSet()));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(authorizableLookup.getAccessPolicyAuthorizable(newAccessPolicy.getIdentifier()));
return entityFactory.createAccessPolicyEntity(newAccessPolicyDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), accessPolicy);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getAccessPolicyById(accessPolicyDTO.getId()));
return entityFactory.createAccessPolicyEntity(newAccessPolicyDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), permissions);
}
@Override
public UserEntity createUser(final Revision revision, final UserDTO userDTO) {
final Authorizable tenantAuthorizable = authorizableLookup.getTenantAuthorizable();
final String creator = NiFiUserUtils.getNiFiUserIdentity();
final User newUser = userDAO.createUser(userDTO);
final Set<Group> groups = userGroupDAO.getUserGroupsForUser(newUser.getIdentifier());
final UserDTO newUserDto = dtoFactory.createUserDto(newUser, groups.stream()
.map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()));
final Set<TenantEntity> tenantEntities = userGroupDAO.getUserGroupsForUser(newUser.getIdentifier()).stream()
.map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet());
final Set<AccessPolicySummaryEntity> policyEntities = userGroupDAO.getAccessPoliciesForUser(newUser.getIdentifier()).stream()
.map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
final UserDTO newUserDto = dtoFactory.createUserDto(newUser, tenantEntities, policyEntities);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(authorizableLookup.getTenantAuthorizable());
return entityFactory.createUserEntity(newUserDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), accessPolicy);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
return entityFactory.createUserEntity(newUserDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), permissions);
}
private AccessPolicySummaryEntity createAccessPolicySummaryEntity(final AccessPolicy ap) {
final AccessPolicySummaryDTO apSummary = dtoFactory.createAccessPolicySummaryDto(ap);
final PermissionsDTO apPermissions = dtoFactory.createPermissionsDto(authorizableLookup.getAccessPolicyById(ap.getIdentifier()));
final RevisionDTO apRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(ap.getIdentifier()));
return entityFactory.createAccessPolicySummaryEntity(apSummary, apRevision, apPermissions);
}
@Override
public UserGroupEntity createUserGroup(final Revision revision, final UserGroupDTO userGroupDTO) {
final Authorizable tenantAuthorizable = authorizableLookup.getTenantAuthorizable();
final Authorizable tenantAuthorizable = authorizableLookup.getTenant();
final String creator = NiFiUserUtils.getNiFiUserIdentity();
final Group newUserGroup = userGroupDAO.createUserGroup(userGroupDTO);
final UserGroupDTO newUserGroupDto = dtoFactory.createUserGroupDto(newUserGroup, newUserGroup.getUsers().stream()
.map(userId -> {
final RevisionDTO userRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userId));
return entityFactory.createTenantEntity(dtoFactory.createTenantDTO(userDAO.getUser(userId)), userRevision,
dtoFactory.createAccessPolicyDto(tenantAuthorizable));
dtoFactory.createPermissionsDto(tenantAuthorizable));
}).collect(Collectors.toSet()));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(authorizableLookup.getTenantAuthorizable());
return entityFactory.createUserGroupEntity(newUserGroupDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), accessPolicy);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
return entityFactory.createUserGroupEntity(newUserGroupDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), permissions);
}
private void validateSnippetContents(final FlowSnippetDTO flow) {
@ -1308,10 +1326,10 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
port -> dtoFactory.createPortDto(port));
final Port port = inputPortDAO.getPort(inputPortDTO.getId());
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(port);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(port);
final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getInputPortStatus(port.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(port.getIdentifier()));
return entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status, bulletins);
return entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, status, bulletins);
}
@Override
@ -1323,10 +1341,10 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
port -> dtoFactory.createPortDto(port));
final Port port = outputPortDAO.getPort(outputPortDTO.getId());
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(port);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(port);
final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getOutputPortStatus(port.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(port.getIdentifier()));
return entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status, bulletins);
return entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, status, bulletins);
}
@Override
@ -1338,10 +1356,10 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
processGroup -> dtoFactory.createProcessGroupDto(processGroup));
final ProcessGroup processGroup = processGroupDAO.getProcessGroup(processGroupDTO.getId());
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(processGroup);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup);
final ProcessGroupStatusDTO status = dtoFactory.createConciseProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(processGroup.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(processGroup.getIdentifier()));
return entityFactory.createProcessGroupEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status, bulletins);
return entityFactory.createProcessGroupEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, status, bulletins);
}
@Override
@ -1353,10 +1371,10 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
remoteProcessGroup -> dtoFactory.createRemoteProcessGroupDto(remoteProcessGroup));
final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupDTO.getId());
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(remoteProcessGroup);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(remoteProcessGroup);
final RemoteProcessGroupStatusDTO status = dtoFactory.createRemoteProcessGroupStatusDto(controllerFacade.getRemoteProcessGroupStatus(remoteProcessGroup.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(remoteProcessGroup.getIdentifier()));
return entityFactory.createRemoteProcessGroupEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status, bulletins);
return entityFactory.createRemoteProcessGroupEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, status, bulletins);
}
@Override
@ -1515,9 +1533,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerServiceDTO.getId());
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(controllerService);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(controllerService);
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(controllerServiceDTO.getId()));
return entityFactory.createControllerServiceEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, bulletins);
return entityFactory.createControllerServiceEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, bulletins);
}
@Override
@ -1529,9 +1547,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
() -> controllerServiceDAO.updateControllerService(controllerServiceDTO),
cs -> dtoFactory.createControllerServiceDto(cs));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(controllerService);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(controllerService);
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(controllerServiceDTO.getId()));
return entityFactory.createControllerServiceEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, bulletins);
return entityFactory.createControllerServiceEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, bulletins);
}
@Override
@ -1567,18 +1585,16 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
* Finds the identifiers for all components referencing a ControllerService.
*
* @param reference ControllerServiceReference
* @param referencingIds Collection of identifiers
* @param visited ControllerServices we've already visited
*/
private void findControllerServiceReferencingComponentIdentifiers(final ControllerServiceReference reference, final Set<String> referencingIds, final Set<ControllerServiceNode> visited) {
private void findControllerServiceReferencingComponentIdentifiers(final ControllerServiceReference reference, final Set<ControllerServiceNode> visited) {
for (final ConfiguredComponent component : reference.getReferencingComponents()) {
referencingIds.add(component.getIdentifier());
// if this is a ControllerService consider it's referencing components
if (component instanceof ControllerServiceNode) {
final ControllerServiceNode node = (ControllerServiceNode) component;
if (!visited.contains(node)) {
findControllerServiceReferencingComponentIdentifiers(node.getReferences(), referencingIds, visited);
findControllerServiceReferencingComponentIdentifiers(node.getReferences(), visited);
}
visited.add(node);
}
@ -1592,13 +1608,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
* @return The entity
*/
private ControllerServiceReferencingComponentsEntity createControllerServiceReferencingComponentsEntity(final ControllerServiceReference reference, final Set<String> lockedIds) {
final Set<String> referencingIds = new HashSet<>();
final Set<ControllerServiceNode> visited = new HashSet<>();
visited.add(reference.getReferencedComponent());
findControllerServiceReferencingComponentIdentifiers(reference, referencingIds, visited);
// TODO remove once we can update a read lock
referencingIds.removeAll(lockedIds);
findControllerServiceReferencingComponentIdentifiers(reference, visited);
final Map<String, Revision> referencingRevisions = new HashMap<>();
for (final ConfiguredComponent component : reference.getReferencingComponents()) {
@ -1635,9 +1647,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final Set<ControllerServiceReferencingComponentEntity> componentEntities = new HashSet<>();
for (final ConfiguredComponent refComponent : referencingComponents) {
AccessPolicyDTO accessPolicy = null;
PermissionsDTO permissions = null;
if (refComponent instanceof Authorizable) {
accessPolicy = dtoFactory.createAccessPolicyDto(refComponent);
permissions = dtoFactory.createPermissionsDto(refComponent);
}
final Revision revision = revisions.get(refComponent.getIdentifier());
@ -1661,7 +1673,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
visited.add(node);
}
componentEntities.add(entityFactory.createControllerServiceReferencingComponentEntity(dto, revisionDto, accessPolicy));
componentEntities.add(entityFactory.createControllerServiceReferencingComponentEntity(dto, revisionDto, permissions));
}
final ControllerServiceReferencingComponentsEntity entity = new ControllerServiceReferencingComponentsEntity();
@ -1703,9 +1715,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
});
final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskDTO.getId());
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(reportingTask);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(reportingTask);
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(reportingTask.getIdentifier()));
return entityFactory.createReportingTaskEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, bulletins);
return entityFactory.createReportingTaskEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, bulletins);
}
@Override
@ -1717,9 +1729,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
() -> reportingTaskDAO.updateReportingTask(reportingTaskDTO),
rt -> dtoFactory.createReportingTaskDto(rt));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(reportingTask);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(reportingTask);
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(reportingTask.getIdentifier()));
return entityFactory.createReportingTaskEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, bulletins);
return entityFactory.createReportingTaskEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, bulletins);
}
@Override
@ -1881,9 +1893,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
private ConnectionEntity createConnectionEntity(final Connection connection) {
final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(connection.getIdentifier()));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(connection);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(connection);
final ConnectionStatusDTO status = dtoFactory.createConnectionStatusDto(controllerFacade.getConnectionStatus(connection.getIdentifier()));
return entityFactory.createConnectionEntity(dtoFactory.createConnectionDto(connection), revision, accessPolicy, status);
return entityFactory.createConnectionEntity(dtoFactory.createConnectionDto(connection), revision, permissions, status);
}
@Override
@ -1938,7 +1950,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
private ProcessorEntity createProcessorEntity(final ProcessorNode processor) {
final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(processor.getIdentifier()));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(processor);
final PermissionsDTO accessPolicy = dtoFactory.createPermissionsDto(processor);
final ProcessorStatusDTO status = dtoFactory.createProcessorStatusDto(controllerFacade.getProcessorStatus(processor.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(processor.getIdentifier()));
return entityFactory.createProcessorEntity(dtoFactory.createProcessorDto(processor), revision, accessPolicy, status, bulletins);
@ -1972,11 +1984,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
return templateDAO.getTemplates().stream()
.map(template -> {
final TemplateDTO dto = dtoFactory.createTemplateDTO(template);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(template);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(template);
final TemplateEntity entity = new TemplateEntity();
entity.setId(dto.getId());
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setTemplate(dto);
return entity;
}).collect(Collectors.toSet());
@ -2087,21 +2099,19 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
return true;
}
// TODO - defer to authorizer to see if user is able to retrieve site-to-site details for the specified port
return true;
// authorize this port for data transfer
final Authorizable dataTransferAuthorizable = new DataTransferAuthorizable(port);
final AuthorizationResult result = dataTransferAuthorizable.checkAuthorization(authorizer, RequestAction.WRITE, user);
return Result.Approved.equals(result.getResult());
}
@Override
public ControllerDTO getController() {
public ControllerDTO getSiteToSiteDetails() {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
if (user == null) {
throw new WebApplicationException(new Throwable("Unable to access details for current user."));
}
// TODO - defer to authorizer to see if user is able to retrieve site-to-site details
// TODO - filter response for access to specific ports
// serialize the input ports this NiFi has access to
final Set<PortDTO> inputPortDtos = new LinkedHashSet<>();
final Set<RootGroupPort> inputPorts = controllerFacade.getInputPorts();
@ -2164,9 +2174,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public ControllerConfigurationEntity getControllerConfiguration() {
final Revision rev = revisionManager.getRevision(FlowController.class.getSimpleName());
final ControllerConfigurationDTO dto = dtoFactory.createControllerConfigurationDto(controllerFacade);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(controllerFacade);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(controllerFacade);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
return entityFactory.createControllerConfigurationEntity(dto, revision, accessPolicy);
return entityFactory.createControllerConfigurationEntity(dto, revision, permissions);
}
@Override
@ -2179,14 +2189,53 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public AccessPolicyEntity getAccessPolicy(final String accessPolicyId) {
final RevisionDTO requestedAccessPolicyRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(accessPolicyId));
final AccessPolicy requestedAccessPolicy = accessPolicyDAO.getAccessPolicy(accessPolicyId);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(authorizableLookup.getAccessPolicyAuthorizable(accessPolicyId));
final AccessPolicy accessPolicy = accessPolicyDAO.getAccessPolicy(accessPolicyId);
return createAccessPolicyEntity(accessPolicy);
}
@Override
public AccessPolicyEntity getAccessPolicy(final RequestAction requestAction, final String resource) {
Authorizable authorizable;
try {
authorizable = authorizableLookup.getAuthorizableFromResource(resource);
} catch (final ResourceNotFoundException e) {
// unable to find the underlying authorizable... user authorized based on top level /policies... create
// an anonymous authorizable to attempt to locate an existing policy for this resource
authorizable = new Authorizable() {
@Override
public Authorizable getParentAuthorizable() {
return null;
}
@Override
public Resource getResource() {
return new Resource() {
@Override
public String getIdentifier() {
return resource;
}
@Override
public String getName() {
return resource;
}
};
}
};
}
final AccessPolicy accessPolicy = accessPolicyDAO.getAccessPolicy(requestAction, authorizable);
return createAccessPolicyEntity(accessPolicy);
}
private AccessPolicyEntity createAccessPolicyEntity(final AccessPolicy accessPolicy) {
final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(accessPolicy.getIdentifier()));
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getAccessPolicyById(accessPolicy.getIdentifier()));
return entityFactory.createAccessPolicyEntity(
dtoFactory.createAccessPolicyDto(requestedAccessPolicy,
requestedAccessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()),
requestedAccessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet())),
requestedAccessPolicyRevision, accessPolicy);
dtoFactory.createAccessPolicyDto(accessPolicy,
accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet()),
accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet())),
revision, permissions);
}
@Override
@ -2205,17 +2254,19 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
private UserEntity createUserEntity(final User user) {
final RevisionDTO userRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(user.getIdentifier()));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(authorizableLookup.getTenantAuthorizable());
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant());
final Set<TenantEntity> userGroups = userGroupDAO.getUserGroupsForUser(user.getIdentifier()).stream()
.map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity()).collect(Collectors.toSet());
return entityFactory.createUserEntity(dtoFactory.createUserDto(user, userGroups), userRevision, accessPolicy);
final Set<AccessPolicySummaryEntity> policyEntities = userGroupDAO.getAccessPoliciesForUser(user.getIdentifier()).stream()
.map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet());
return entityFactory.createUserEntity(dtoFactory.createUserDto(user, userGroups, policyEntities), userRevision, permissions);
}
private UserGroupEntity createUserGroupEntity(final Group userGroup) {
final RevisionDTO userGroupRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userGroup.getIdentifier()));
final Set<TenantEntity> users = userGroup.getUsers().stream().map(mapUserIdToTenantEntity()).collect(Collectors.toSet());
return entityFactory.createUserGroupEntity(dtoFactory.createUserGroupDto(userGroup, users), userGroupRevision,
dtoFactory.createAccessPolicyDto(authorizableLookup.getTenantAuthorizable()));
dtoFactory.createPermissionsDto(authorizableLookup.getTenant()));
}
@Override
@ -2234,8 +2285,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
private LabelEntity createLabelEntity(final Label label) {
final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(label.getIdentifier()));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(label);
return entityFactory.createLabelEntity(dtoFactory.createLabelDto(label), revision, accessPolicy);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(label);
return entityFactory.createLabelEntity(dtoFactory.createLabelDto(label), revision, permissions);
}
@Override
@ -2254,8 +2305,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
private FunnelEntity createFunnelEntity(final Funnel funnel) {
final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(funnel.getIdentifier()));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(funnel);
return entityFactory.createFunnelEntity(dtoFactory.createFunnelDto(funnel), revision, accessPolicy);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(funnel);
return entityFactory.createFunnelEntity(dtoFactory.createFunnelDto(funnel), revision, permissions);
}
@Override
@ -2274,18 +2325,18 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
private PortEntity createInputPortEntity(final Port port) {
final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(port.getIdentifier()));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(port);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(port);
final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getInputPortStatus(port.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(port.getIdentifier()));
return entityFactory.createPortEntity(dtoFactory.createPortDto(port), revision, accessPolicy, status, bulletins);
return entityFactory.createPortEntity(dtoFactory.createPortDto(port), revision, permissions, status, bulletins);
}
private PortEntity createOutputPortEntity(final Port port) {
final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(port.getIdentifier()));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(port);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(port);
final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getOutputPortStatus(port.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(port.getIdentifier()));
return entityFactory.createPortEntity(dtoFactory.createPortDto(port), revision, accessPolicy, status, bulletins);
return entityFactory.createPortEntity(dtoFactory.createPortDto(port), revision, permissions, status, bulletins);
}
@Override
@ -2306,10 +2357,10 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
private ProcessGroupEntity createProcessGroupEntity(final ProcessGroup group) {
final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(group.getIdentifier()));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(group);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(group);
final ProcessGroupStatusDTO status = dtoFactory.createConciseProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(group.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(group.getIdentifier()));
return entityFactory.createProcessGroupEntity(dtoFactory.createProcessGroupDto(group), revision, accessPolicy, status, bulletins);
return entityFactory.createProcessGroupEntity(dtoFactory.createProcessGroupDto(group), revision, permissions, status, bulletins);
}
@Override
@ -2322,10 +2373,10 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
private RemoteProcessGroupEntity createRemoteGroupEntity(final RemoteProcessGroup rpg) {
final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(rpg.getIdentifier()));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(rpg);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(rpg);
final RemoteProcessGroupStatusDTO status = dtoFactory.createRemoteProcessGroupStatusDto(controllerFacade.getRemoteProcessGroupStatus(rpg.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(rpg.getIdentifier()));
return entityFactory.createRemoteProcessGroupEntity(dtoFactory.createRemoteProcessGroupDto(rpg), revision, accessPolicy, status, bulletins);
return entityFactory.createRemoteProcessGroupEntity(dtoFactory.createRemoteProcessGroupDto(rpg), revision, permissions, status, bulletins);
}
@Override
@ -2380,10 +2431,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final CurrentUserEntity entity = new CurrentUserEntity();
entity.setIdentity(user.getIdentity());
entity.setAnonymous(user.isAnonymous());
entity.setProvenancePermissions(dtoFactory.createAccessPolicyDto(authorizableLookup.getProvenance()));
entity.setCountersPermissions(dtoFactory.createAccessPolicyDto(authorizableLookup.getCounters()));
entity.setTenantsPermissions(dtoFactory.createAccessPolicyDto(authorizableLookup.getTenantAuthorizable()));
entity.setControllerPermissions(dtoFactory.createAccessPolicyDto(authorizableLookup.getController()));
entity.setProvenancePermissions(dtoFactory.createPermissionsDto(authorizableLookup.getProvenance()));
entity.setCountersPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getCounters()));
entity.setTenantsPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getTenant()));
entity.setControllerPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getController()));
entity.setPoliciesPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getPolicies()));
return entity;
}
@ -2421,8 +2473,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
// read lock on every component being accessed in the dto conversion
final ProcessGroupStatus groupStatus = controllerFacade.getProcessGroupStatus(groupId);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(processGroup);
return entityFactory.createProcessGroupFlowEntity(dtoFactory.createProcessGroupFlowDto(processGroup, groupStatus, revisionManager), accessPolicy);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup);
return entityFactory.createProcessGroupFlowEntity(dtoFactory.createProcessGroupFlowDto(processGroup, groupStatus, revisionManager), permissions);
}
@Override
@ -2439,9 +2491,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
dto.setReferencingComponents(referencingComponentsEntity.getControllerServiceReferencingComponents());
final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(serviceNode.getIdentifier()));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(serviceNode);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(serviceNode);
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(serviceNode.getIdentifier()));
return entityFactory.createControllerServiceEntity(dto, revision, accessPolicy, bulletins);
return entityFactory.createControllerServiceEntity(dto, revision, permissions, bulletins);
}
@Override
@ -2483,9 +2535,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
private ReportingTaskEntity createReportingTaskEntity(final ReportingTaskNode reportingTask) {
final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(reportingTask.getIdentifier()));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(reportingTask);
final PermissionsDTO permissions = dtoFactory.createPermissionsDto(reportingTask);
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(reportingTask.getIdentifier()));
return entityFactory.createReportingTaskEntity(dtoFactory.createReportingTaskDto(reportingTask), revision, accessPolicy, bulletins);
return entityFactory.createReportingTaskEntity(dtoFactory.createReportingTaskDto(reportingTask), revision, permissions, bulletins);
}
@Override
@ -2734,7 +2786,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
return userGroupId -> {
final RevisionDTO userGroupRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userGroupId));
return entityFactory.createTenantEntity(dtoFactory.createTenantDTO(userGroupDAO.getUserGroup(userGroupId)), userGroupRevision,
dtoFactory.createAccessPolicyDto(authorizableLookup.getTenantAuthorizable()));
dtoFactory.createPermissionsDto(authorizableLookup.getTenant()));
};
}
@ -2742,7 +2794,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
return userId -> {
final RevisionDTO userRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userId));
return entityFactory.createTenantEntity(dtoFactory.createTenantDTO(userDAO.getUser(userId)), userRevision,
dtoFactory.createAccessPolicyDto(authorizableLookup.getTenantAuthorizable()));
dtoFactory.createPermissionsDto(authorizableLookup.getTenant()));
};
}

View File

@ -98,6 +98,74 @@ public class AccessPolicyResource extends ApplicationResource {
return accessPolicy;
}
// -----------------
// get access policy
// -----------------
/**
* Retrieves the specified access policy.
*
* @return An accessPolicyEntity.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("{action}/{resource: .+}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Gets an access policy",
response = AccessPolicyEntity.class,
authorizations = {
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
@Authorization(value = "Administrator", type = "ROLE_ADMIN")
}
)
@ApiResponses(
value = {
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
@ApiResponse(code = 401, message = "Client could not be authenticated."),
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
@ApiResponse(code = 404, message = "The specified resource could not be found."),
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
}
)
public Response getAccessPolicyForResource(
@ApiParam(
value = "The request action.",
allowableValues = "read, write",
required = true
) @PathParam("action") final String action,
@ApiParam(
value = "The resource of the policy.",
required = true
) @PathParam("resource") String rawResource) {
// parse the action and resource type
final RequestAction requestAction = RequestAction.valueOfValue(action);
final String resource = "/" + rawResource;
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
}
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable accessPolicy = lookup.getAccessPolicyByResource(resource);
accessPolicy.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
});
// get the access policy
final AccessPolicyEntity entity = serviceFacade.getAccessPolicy(requestAction, resource);
populateRemainingAccessPolicyEntityContent(entity);
return clusterContext(generateOkResponse(entity)).build();
}
// -----------------------
// manage an access policy
// -----------------------
/**
* Creates a new access policy.
*
@ -111,58 +179,6 @@ public class AccessPolicyResource extends ApplicationResource {
// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
@ApiOperation(
value = "Creates an access policy",
notes = " Available resources:\n" +
" /flow - READ - allows user/entity to load the UI and see the flow structure\n" +
" - WRITE - NA\n" +
" /resource - READ - allows user/entity to retrieve the available resources\n" +
" - WRITE - NA\n" +
" /system - READ - allows user/entity to retrieve system level diagnostics (CPU load, disk utilization, etc)\n" +
" - WRITE - NA\n" +
" /controller - READ - allows user/entity to retrieve configuration details for the controller (controller bulletins, thread pool, reporting tasks, etc)\n" +
" - WRITE - allows user/entity to modify configuration details for the controller\n" +
" /provenance - READ - allows user/entity to perform provenance requests. results will be filtered based on access to provenance data per component\n" +
" - WRITE - NA\n" +
" /token - READ - NA\n" +
" - WRITE - allows user/entity to create a token for access the REST API\n" +
" /site-to-site - READ - allows user/entity to retrieve configuration details for performing site to site data transfers with this NiFi\n" +
" - WRITE - NA\n" +
" /proxy - READ - NA\n" +
" - WRITE - allows user/entity to create a proxy request on behalf of another user\n" +
" /process-groups/{id} - READ - allows user/entity to retrieve configuration details for the process group and all descendant components without explicit " +
"access policies\n" +
" - WRITE - allows user/entity to create/update/delete configuration details for the process group and all descendant components without " +
"explicit access policies\n" +
" /processors/{id} - READ - allows user/entity to retrieve configuration details for the processor overriding any inherited authorizations from an ancestor " +
"process group\n" +
" - WRITE - allows user/entity to update/delete the processor overriding any inherited authorizations from an ancestor process group\n" +
" /input-ports/{id} - READ - allows user/entity to retrieve configuration details for the input port overriding any inherited authorizations from an ancestor " +
"process group\n" +
" - WRITE - allows user/entity to update/delete the input port overriding any inherited authorizations from an ancestor process group\n" +
" /output-ports/{id} - READ - allows user/entity to retrieve configuration details for the output port overriding any inherited authorizations from an ancestor " +
"process group\n" +
" - WRITE - allows user/entity to update/delete the output port overriding any inherited authorizations from an ancestor process group\n" +
" /labels/{id} - READ - allows user/entity to retrieve configuration details for the label overriding any inherited authorizations from an ancestor " +
"process group\n" +
" - WRITE - allows user/entity to update/delete the label overriding any inherited authorizations from an ancestor process group\n" +
" /connections/{id} - READ - allows user/entity to retrieve configuration details for the connection overriding any inherited authorizations from an ancestor " +
"process group\n" +
" - WRITE - allows user/entity to update/delete the label overriding any inherited authorizations from an ancestor process group\n" +
" /remote-process-groups/{id} - READ - allows user/entity to retrieve configuration details for the remote process group overriding any inherited authorizations from an " +
"ancestor process group\n" +
" - WRITE - allows user/entity to update/delete the remote process group overriding any inherited authorizations from an ancestor process " +
"group\n" +
" /templates/{id} - READ - allows user/entity to retrieve configuration details for the template overriding any inherited authorizations from an ancestor " +
"process group\n" +
" - WRITE - allows user/entity to create/update/delete the template overriding any inherited authorizations from an ancestor process group\n" +
" /controller-services/{id} - READ - allows user/entity to retrieve configuration details for the controller service overriding any inherited authorizations from an " +
"ancestor process group\n" +
" - WRITE - allows user/entity to update/delete the controller service overriding any inherited authorizations from an ancestor process " +
"group\n" +
" /reporting-tasks/{id} - READ - allows user/entity to retrieve configuration details for the reporting tasks overriding any inherited authorizations from the " +
"controller\n" +
" - WRITE - allows user/entity to create/update/delete the reporting tasks overriding any inherited authorizations from the controller\n" +
" /{type}/{id}/provenance - READ - allows user/entity to view provenance data from the underlying component\n" +
" - WRITE - NA\n",
response = AccessPolicyEntity.class,
authorizations = {
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
@ -192,10 +208,18 @@ public class AccessPolicyResource extends ApplicationResource {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Policy.");
}
if (accessPolicyEntity.getComponent().getId() != null) {
final AccessPolicyDTO requestAccessPolicy = accessPolicyEntity.getComponent();
if (requestAccessPolicy.getId() != null) {
throw new IllegalArgumentException("Access policy ID cannot be specified.");
}
if (requestAccessPolicy.getResource() == null) {
throw new IllegalArgumentException("Access policy resource must be specified.");
}
// ensure this is a valid action
RequestAction.valueOfValue(requestAccessPolicy.getAction());
if (isReplicateRequest()) {
return replicate(HttpMethod.POST, accessPolicyEntity);
}
@ -205,7 +229,7 @@ public class AccessPolicyResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable accessPolicies = lookup.getAccessPoliciesAuthorizable();
final Authorizable accessPolicies = lookup.getAccessPolicyByResource(requestAccessPolicy.getResource());
accessPolicies.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
});
}
@ -270,8 +294,8 @@ public class AccessPolicyResource extends ApplicationResource {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable accessPolicy = lookup.getAccessPolicyAuthorizable(id);
accessPolicy.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
Authorizable authorizable = lookup.getAccessPolicyById(id);
authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
});
// get the access policy
@ -347,8 +371,8 @@ public class AccessPolicyResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
Authorizable authorizable = lookup.getAccessPolicyAuthorizable(id);
authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
Authorizable authorizable = lookup.getAccessPolicyById(id);
authorizable.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
},
null,
() -> {
@ -422,8 +446,8 @@ public class AccessPolicyResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable accessPolicy = lookup.getAccessPolicyAuthorizable(id);
accessPolicy.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
final Authorizable accessPolicy = lookup.getAccessPolicyById(id);
accessPolicy.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
},
() -> {
},

View File

@ -16,6 +16,54 @@
*/
package org.apache.nifi.web.api;
import com.sun.jersey.api.core.HttpContext;
import com.sun.jersey.api.representation.Form;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import com.sun.jersey.server.impl.model.method.dispatch.FormDispatchProvider;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.user.NiFiUser;
import org.apache.nifi.authorization.user.NiFiUserUtils;
import org.apache.nifi.cluster.coordination.ClusterCoordinator;
import org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
import org.apache.nifi.cluster.manager.NodeResponse;
import org.apache.nifi.cluster.manager.exception.NoClusterCoordinatorException;
import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.controller.Snippet;
import org.apache.nifi.remote.HttpRemoteSiteListener;
import org.apache.nifi.remote.VersionNegotiator;
import org.apache.nifi.remote.exception.BadRequestException;
import org.apache.nifi.remote.exception.HandshakeException;
import org.apache.nifi.remote.exception.NotAuthorizedException;
import org.apache.nifi.remote.protocol.ResponseCode;
import org.apache.nifi.remote.protocol.http.HttpHeaders;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.AuthorizableLookup;
import org.apache.nifi.web.AuthorizeAccess;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.SnippetDTO;
import org.apache.nifi.web.api.entity.ComponentEntity;
import org.apache.nifi.web.api.entity.TransactionResultEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriBuilderException;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
@ -30,46 +78,10 @@ import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Supplier;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriBuilderException;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.user.NiFiUser;
import org.apache.nifi.authorization.user.NiFiUserUtils;
import org.apache.nifi.cluster.coordination.ClusterCoordinator;
import org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
import org.apache.nifi.cluster.manager.NodeResponse;
import org.apache.nifi.cluster.manager.exception.NoClusterCoordinatorException;
import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.controller.Snippet;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.AuthorizableLookup;
import org.apache.nifi.web.AuthorizeAccess;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.SnippetDTO;
import org.apache.nifi.web.api.entity.ComponentEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jersey.api.core.HttpContext;
import com.sun.jersey.api.representation.Form;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import com.sun.jersey.server.impl.model.method.dispatch.FormDispatchProvider;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.LOCATION_URI_INTENT_NAME;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.LOCATION_URI_INTENT_VALUE;
/**
* Base class for controllers.
@ -712,4 +724,152 @@ public abstract class ApplicationResource {
public static enum ReplicationTarget {
CLUSTER_NODES, CLUSTER_COORDINATOR;
}
// -----------------
// HTTP site to site
// -----------------
protected Integer negotiateTransportProtocolVersion(final HttpServletRequest req, final VersionNegotiator transportProtocolVersionNegotiator) throws BadRequestException {
String protocolVersionStr = req.getHeader(HttpHeaders.PROTOCOL_VERSION);
if (isEmpty(protocolVersionStr)) {
throw new BadRequestException("Protocol version was not specified.");
}
final Integer requestedProtocolVersion;
try {
requestedProtocolVersion = Integer.valueOf(protocolVersionStr);
} catch (NumberFormatException e) {
throw new BadRequestException("Specified protocol version was not in a valid number format: " + protocolVersionStr);
}
Integer protocolVersion;
if (transportProtocolVersionNegotiator.isVersionSupported(requestedProtocolVersion)) {
return requestedProtocolVersion;
} else {
protocolVersion = transportProtocolVersionNegotiator.getPreferredVersion(requestedProtocolVersion);
}
if (protocolVersion == null) {
throw new BadRequestException("Specified protocol version is not supported: " + protocolVersionStr);
}
return protocolVersion;
}
protected Response.ResponseBuilder setCommonHeaders(final Response.ResponseBuilder builder, final Integer transportProtocolVersion, final HttpRemoteSiteListener transactionManager) {
return builder.header(HttpHeaders.PROTOCOL_VERSION, transportProtocolVersion)
.header(HttpHeaders.SERVER_SIDE_TRANSACTION_TTL, transactionManager.getTransactionTtlSec());
}
protected class ResponseCreator {
public Response nodeTypeErrorResponse(String errMsg) {
return noCache(Response.status(Response.Status.FORBIDDEN)).type(MediaType.TEXT_PLAIN).entity(errMsg).build();
}
public Response httpSiteToSiteIsNotEnabledResponse() {
return noCache(Response.status(Response.Status.FORBIDDEN)).type(MediaType.TEXT_PLAIN).entity("HTTP(S) Site-to-Site is not enabled on this host.").build();
}
public Response wrongPortTypeResponse(String portType, String portId) {
logger.debug("Port type was wrong. portType={}, portId={}", portType, portId);
TransactionResultEntity entity = new TransactionResultEntity();
entity.setResponseCode(ResponseCode.ABORT.getCode());
entity.setMessage("Port was not found.");
entity.setFlowFileSent(0);
return Response.status(NOT_FOUND).entity(entity).type(MediaType.APPLICATION_JSON_TYPE).build();
}
public Response transactionNotFoundResponse(String portId, String transactionId) {
logger.debug("Transaction was not found. portId={}, transactionId={}", portId, transactionId);
TransactionResultEntity entity = new TransactionResultEntity();
entity.setResponseCode(ResponseCode.ABORT.getCode());
entity.setMessage("Transaction was not found.");
entity.setFlowFileSent(0);
return Response.status(NOT_FOUND).entity(entity).type(MediaType.APPLICATION_JSON_TYPE).build();
}
public Response unexpectedErrorResponse(String portId, Exception e) {
logger.error("Unexpected exception occurred. portId={}", portId);
logger.error("Exception detail:", e);
TransactionResultEntity entity = new TransactionResultEntity();
entity.setResponseCode(ResponseCode.ABORT.getCode());
entity.setMessage("Server encountered an exception.");
entity.setFlowFileSent(0);
return Response.serverError().entity(entity).type(MediaType.APPLICATION_JSON_TYPE).build();
}
public Response unexpectedErrorResponse(String portId, String transactionId, Exception e) {
logger.error("Unexpected exception occurred. portId={}, transactionId={}", portId, transactionId);
logger.error("Exception detail:", e);
TransactionResultEntity entity = new TransactionResultEntity();
entity.setResponseCode(ResponseCode.ABORT.getCode());
entity.setMessage("Server encountered an exception.");
entity.setFlowFileSent(0);
return Response.serverError().entity(entity).type(MediaType.APPLICATION_JSON_TYPE).build();
}
public Response unauthorizedResponse(NotAuthorizedException e) {
if (logger.isDebugEnabled()) {
logger.debug("Client request was not authorized. {}", e.getMessage());
}
TransactionResultEntity entity = new TransactionResultEntity();
entity.setResponseCode(ResponseCode.UNAUTHORIZED.getCode());
entity.setMessage(e.getMessage());
entity.setFlowFileSent(0);
return Response.status(Response.Status.UNAUTHORIZED).type(MediaType.APPLICATION_JSON_TYPE).entity(e.getMessage()).build();
}
public Response badRequestResponse(Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("Client sent a bad request. {}", e.getMessage());
}
TransactionResultEntity entity = new TransactionResultEntity();
entity.setResponseCode(ResponseCode.ABORT.getCode());
entity.setMessage(e.getMessage());
entity.setFlowFileSent(0);
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(entity).build();
}
public Response handshakeExceptionResponse(HandshakeException e) {
if(logger.isDebugEnabled()){
logger.debug("Handshake failed, {}", e.getMessage());
}
ResponseCode handshakeRes = e.getResponseCode();
Response.Status statusCd;
TransactionResultEntity entity = new TransactionResultEntity();
entity.setResponseCode(handshakeRes != null ? handshakeRes.getCode() : ResponseCode.ABORT.getCode());
entity.setMessage(e.getMessage());
entity.setFlowFileSent(0);
switch (handshakeRes) {
case PORT_NOT_IN_VALID_STATE:
case PORTS_DESTINATION_FULL:
return Response.status(Response.Status.SERVICE_UNAVAILABLE).type(MediaType.APPLICATION_JSON_TYPE).entity(entity).build();
case UNAUTHORIZED:
statusCd = Response.Status.UNAUTHORIZED;
break;
case UNKNOWN_PORT:
statusCd = NOT_FOUND;
break;
default:
statusCd = Response.Status.BAD_REQUEST;
}
return Response.status(statusCd).type(MediaType.APPLICATION_JSON_TYPE).entity(entity).build();
}
public Response acceptedResponse(final HttpRemoteSiteListener transactionManager, final Object entity, final Integer protocolVersion) {
return noCache(setCommonHeaders(Response.status(Response.Status.ACCEPTED), protocolVersion, transactionManager))
.entity(entity).build();
}
public Response locationResponse(UriInfo uriInfo, String portType, String portId, String transactionId, Object entity,
Integer protocolVersion, final HttpRemoteSiteListener transactionManager) {
String path = "/data-transfer/" + portType + "/" + portId + "/transactions/" + transactionId;
URI location = uriInfo.getBaseUriBuilder().path(path).build();
return noCache(setCommonHeaders(Response.created(location), protocolVersion, transactionManager)
.header(LOCATION_URI_INTENT_NAME, LOCATION_URI_INTENT_VALUE))
.entity(entity).build();
}
}
}

View File

@ -0,0 +1,837 @@
/*
* 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.web.api;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses;
import com.wordnik.swagger.annotations.Authorization;
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.resource.ResourceFactory;
import org.apache.nifi.authorization.resource.ResourceType;
import org.apache.nifi.authorization.user.NiFiUser;
import org.apache.nifi.authorization.user.NiFiUserUtils;
import org.apache.nifi.remote.HttpRemoteSiteListener;
import org.apache.nifi.remote.Peer;
import org.apache.nifi.remote.PeerDescription;
import org.apache.nifi.remote.StandardVersionNegotiator;
import org.apache.nifi.remote.VersionNegotiator;
import org.apache.nifi.remote.client.http.TransportProtocolVersionNegotiator;
import org.apache.nifi.remote.exception.BadRequestException;
import org.apache.nifi.remote.exception.HandshakeException;
import org.apache.nifi.remote.exception.NotAuthorizedException;
import org.apache.nifi.remote.exception.RequestExpiredException;
import org.apache.nifi.remote.io.http.HttpOutput;
import org.apache.nifi.remote.io.http.HttpServerCommunicationsSession;
import org.apache.nifi.remote.protocol.HandshakeProperty;
import org.apache.nifi.remote.protocol.ResponseCode;
import org.apache.nifi.remote.protocol.http.HttpFlowFileServerProtocol;
import org.apache.nifi.remote.protocol.http.HttpFlowFileServerProtocolImpl;
import org.apache.nifi.stream.io.ByteArrayOutputStream;
import org.apache.nifi.web.api.entity.TransactionResultEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.apache.nifi.remote.protocol.HandshakeProperty.BATCH_COUNT;
import static org.apache.nifi.remote.protocol.HandshakeProperty.BATCH_DURATION;
import static org.apache.nifi.remote.protocol.HandshakeProperty.BATCH_SIZE;
import static org.apache.nifi.remote.protocol.HandshakeProperty.REQUEST_EXPIRATION_MILLIS;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_BATCH_COUNT;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_BATCH_DURATION;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_BATCH_SIZE;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_REQUEST_EXPIRATION;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_USE_COMPRESSION;
/**
* RESTful endpoint for managing a SiteToSite connection.
*/
@Path("/data-transfer")
@Api(
value = "/data-transfer",
description = "Supports data transfers with this NiFi using HTTP based site to site"
)
public class DataTransferResource extends ApplicationResource {
private static final Logger logger = LoggerFactory.getLogger(DataTransferResource.class);
public static final String CHECK_SUM = "checksum";
public static final String RESPONSE_CODE = "responseCode";
private static final String PORT_TYPE_INPUT = "input-ports";
private static final String PORT_TYPE_OUTPUT = "output-ports";
private Authorizer authorizer;
private final ResponseCreator responseCreator = new ResponseCreator();
private final VersionNegotiator transportProtocolVersionNegotiator = new TransportProtocolVersionNegotiator(1);
private final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
/**
* Authorizes access to data transfers.
*
* Note: Protected for testing purposes
*/
protected void authorizeDataTransfer(final ResourceType resourceType, final String identifier) {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
if (!ResourceType.InputPort.equals(resourceType) && !ResourceType.OutputPort.equals(resourceType)) {
throw new IllegalArgumentException("The resource must be an Input or Output Port.");
}
// TODO - use DataTransferAuthorizable after looking up underlying component for consistentency
final Resource resource = ResourceFactory.getComponentResource(resourceType, identifier, identifier);
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.resource(ResourceFactory.getDataTransferResource(resource))
.identity(user.getIdentity())
.anonymous(user.isAnonymous())
.accessAttempt(true)
.action(RequestAction.WRITE)
.build();
final AuthorizationResult result = authorizer.authorize(request);
if (!Result.Approved.equals(result.getResult())) {
final String message = StringUtils.isNotBlank(result.getExplanation()) ? result.getExplanation() : "Access is denied";
throw new AccessDeniedException(message);
}
}
@POST
@Produces(MediaType.APPLICATION_JSON)
@Path("{portType}/{portId}/transactions")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Create a transaction to the specified output port or input port",
response = TransactionResultEntity.class,
authorizations = {
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
@Authorization(value = "Administrator", type = "ROLE_ADMIN")
}
)
@ApiResponses(
value = {
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
@ApiResponse(code = 401, message = "Client could not be authenticated."),
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
@ApiResponse(code = 404, message = "The specified resource could not be found."),
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful."),
@ApiResponse(code = 503, message = "NiFi instance is not ready for serving request, or temporarily overloaded. Retrying the same request later may be successful"),
}
)
public Response createPortTransaction(
@ApiParam(
value = "The port type.",
required = true,
allowableValues = "input-ports, output-ports"
)
@PathParam("portType") String portType,
@PathParam("portId") String portId,
@Context HttpServletRequest req,
@Context ServletContext context,
@Context UriInfo uriInfo,
InputStream inputStream) {
if(!PORT_TYPE_INPUT.equals(portType) && !PORT_TYPE_OUTPUT.equals(portType)){
return responseCreator.wrongPortTypeResponse(portType, portId);
}
// authorize access
authorizeDataTransfer(PORT_TYPE_INPUT.equals(portType) ? ResourceType.InputPort : ResourceType.OutputPort, portId);
final ValidateRequestResult validationResult = validateResult(req, portId);
if (validationResult.errResponse != null) {
return validationResult.errResponse;
}
logger.debug("createPortTransaction request: clientId={}, portType={}, portId={}", portType, portId);
final ByteArrayOutputStream out = new ByteArrayOutputStream();
final String transactionId = transactionManager.createTransaction();
final Peer peer = constructPeer(req, inputStream, out, portId, transactionId);
final int transportProtocolVersion = validationResult.transportProtocolVersion;
try {
// Execute handshake.
initiateServerProtocol(peer, transportProtocolVersion);
TransactionResultEntity entity = new TransactionResultEntity();
entity.setResponseCode(ResponseCode.PROPERTIES_OK.getCode());
entity.setMessage("Handshake properties are valid, and port is running. A transaction is created:" + transactionId);
return responseCreator.locationResponse(uriInfo, portType, portId, transactionId, entity, transportProtocolVersion, transactionManager);
} catch (HandshakeException e) {
transactionManager.cancelTransaction(transactionId);
return responseCreator.handshakeExceptionResponse(e);
} catch (Exception e) {
transactionManager.cancelTransaction(transactionId);
return responseCreator.unexpectedErrorResponse(portId, e);
}
}
@POST
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
@Produces(MediaType.TEXT_PLAIN)
@Path("input-ports/{portId}/transactions/{transactionId}/flow-files")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Transfer flow files to the input port",
response = String.class,
authorizations = {
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
@Authorization(value = "Administrator", type = "ROLE_ADMIN")
}
)
@ApiResponses(
value = {
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
@ApiResponse(code = 401, message = "Client could not be authenticated."),
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
@ApiResponse(code = 404, message = "The specified resource could not be found."),
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful."),
@ApiResponse(code = 503, message = "NiFi instance is not ready for serving request, or temporarily overloaded. Retrying the same request later may be successful"),
}
)
public Response receiveFlowFiles(
@ApiParam(
value = "The input port id.",
required = true
)
@PathParam("portId") String portId,
@PathParam("transactionId") String transactionId,
@Context HttpServletRequest req,
@Context ServletContext context,
InputStream inputStream) {
// authorize access
authorizeDataTransfer(ResourceType.InputPort, portId);
final ValidateRequestResult validationResult = validateResult(req, portId, transactionId);
if (validationResult.errResponse != null) {
return validationResult.errResponse;
}
logger.debug("receiveFlowFiles request: portId={}", portId);
final ByteArrayOutputStream out = new ByteArrayOutputStream();
final Peer peer = constructPeer(req, inputStream, out, portId, transactionId);
final int transportProtocolVersion = validationResult.transportProtocolVersion;
try {
HttpFlowFileServerProtocol serverProtocol = initiateServerProtocol(peer, transportProtocolVersion);
int numOfFlowFiles = serverProtocol.getPort().receiveFlowFiles(peer, serverProtocol);
logger.debug("finished receiving flow files, numOfFlowFiles={}", numOfFlowFiles);
if (numOfFlowFiles < 1) {
return Response.status(Response.Status.BAD_REQUEST)
.entity("Client should send request when there is data to send. There was no flow file sent.").build();
}
} catch (HandshakeException e) {
return responseCreator.handshakeExceptionResponse(e);
} catch (NotAuthorizedException e) {
return responseCreator.unauthorizedResponse(e);
} catch (BadRequestException | RequestExpiredException e) {
return responseCreator.badRequestResponse(e);
} catch (Exception e) {
return responseCreator.unexpectedErrorResponse(portId, e);
}
String serverChecksum = ((HttpServerCommunicationsSession)peer.getCommunicationsSession()).getChecksum();
return responseCreator.acceptedResponse(transactionManager, serverChecksum, transportProtocolVersion);
}
private HttpFlowFileServerProtocol initiateServerProtocol(Peer peer, Integer transportProtocolVersion) throws IOException {
// Switch transaction protocol version based on transport protocol version.
TransportProtocolVersionNegotiator negotiatedTransportProtocolVersion = new TransportProtocolVersionNegotiator(transportProtocolVersion);
VersionNegotiator versionNegotiator = new StandardVersionNegotiator(negotiatedTransportProtocolVersion.getTransactionProtocolVersion());
HttpFlowFileServerProtocol serverProtocol = getHttpFlowFileServerProtocol(versionNegotiator);
HttpRemoteSiteListener.getInstance().setupServerProtocol(serverProtocol);
// TODO: How should I pass cluster information?
// serverProtocol.setNodeInformant(clusterManager);
serverProtocol.handshake(peer);
return serverProtocol;
}
HttpFlowFileServerProtocol getHttpFlowFileServerProtocol(VersionNegotiator versionNegotiator) {
return new HttpFlowFileServerProtocolImpl(versionNegotiator);
}
private Peer constructPeer(HttpServletRequest req, InputStream inputStream, OutputStream outputStream, String portId, String transactionId) {
String clientHostName = req.getRemoteHost();
int clientPort = req.getRemotePort();
PeerDescription peerDescription = new PeerDescription(clientHostName, clientPort, req.isSecure());
HttpServerCommunicationsSession commSession = new HttpServerCommunicationsSession(inputStream, outputStream, transactionId);
boolean useCompression = false;
final String useCompressionStr = req.getHeader(HANDSHAKE_PROPERTY_USE_COMPRESSION);
if (!isEmpty(useCompressionStr) && Boolean.valueOf(useCompressionStr)) {
useCompression = true;
}
final String requestExpiration = req.getHeader(HANDSHAKE_PROPERTY_REQUEST_EXPIRATION);
final String batchCount = req.getHeader(HANDSHAKE_PROPERTY_BATCH_COUNT);
final String batchSize = req.getHeader(HANDSHAKE_PROPERTY_BATCH_SIZE);
final String batchDuration = req.getHeader(HANDSHAKE_PROPERTY_BATCH_DURATION);
commSession.putHandshakeParam(HandshakeProperty.PORT_IDENTIFIER, portId);
commSession.putHandshakeParam(HandshakeProperty.GZIP, String.valueOf(useCompression));
if (!isEmpty(requestExpiration)) commSession.putHandshakeParam(REQUEST_EXPIRATION_MILLIS, requestExpiration);
if (!isEmpty(batchCount)) commSession.putHandshakeParam(BATCH_COUNT, batchCount);
if (!isEmpty(batchSize)) commSession.putHandshakeParam(BATCH_SIZE, batchSize);
if (!isEmpty(batchDuration)) commSession.putHandshakeParam(BATCH_DURATION, batchDuration);
if(peerDescription.isSecure()){
NiFiUser nifiUser = NiFiUserUtils.getNiFiUser();
logger.debug("initiating peer, nifiUser={}", nifiUser);
commSession.setUserDn(nifiUser.getIdentity());
}
// TODO: Followed how SocketRemoteSiteListener define peerUrl and clusterUrl, but it can be more meaningful values, especially for clusterUrl.
String peerUrl = "nifi://" + clientHostName + ":" + clientPort;
String clusterUrl = "nifi://localhost:" + req.getLocalPort();
return new Peer(peerDescription, commSession, peerUrl, clusterUrl);
}
@DELETE
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
@Produces(MediaType.APPLICATION_JSON)
@Path("output-ports/{portId}/transactions/{transactionId}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Commit or cancel the specified transaction",
response = TransactionResultEntity.class,
authorizations = {
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
@Authorization(value = "Administrator", type = "ROLE_ADMIN")
}
)
@ApiResponses(
value = {
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
@ApiResponse(code = 401, message = "Client could not be authenticated."),
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
@ApiResponse(code = 404, message = "The specified resource could not be found."),
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful."),
@ApiResponse(code = 503, message = "NiFi instance is not ready for serving request, or temporarily overloaded. Retrying the same request later may be successful"),
}
)
public Response commitOutputPortTransaction(
@ApiParam(
value = "The response code. Available values are CONFIRM_TRANSACTION(12) or CANCEL_TRANSACTION(15).",
required = true
)
@QueryParam(RESPONSE_CODE) Integer responseCode,
@ApiParam(
value = "A checksum calculated at client side using CRC32 to check flow file content integrity. It must match with the value calculated at server side.",
required = true
)
@QueryParam(CHECK_SUM) @DefaultValue(StringUtils.EMPTY) String checksum,
@ApiParam(
value = "The output port id.",
required = true
)
@PathParam("portId") String portId,
@ApiParam(
value = "The transaction id.",
required = true
)
@PathParam("transactionId") String transactionId,
@Context HttpServletRequest req,
@Context ServletContext context,
InputStream inputStream) {
// authorize access
authorizeDataTransfer(ResourceType.OutputPort, portId);
final ValidateRequestResult validationResult = validateResult(req, portId, transactionId);
if (validationResult.errResponse != null) {
return validationResult.errResponse;
}
logger.debug("commitOutputPortTransaction request: portId={}, transactionId={}", portId, transactionId);
final int transportProtocolVersion = validationResult.transportProtocolVersion;
final ByteArrayOutputStream out = new ByteArrayOutputStream();
final Peer peer = constructPeer(req, inputStream, out, portId, transactionId);
final TransactionResultEntity entity = new TransactionResultEntity();
try {
HttpFlowFileServerProtocol serverProtocol = initiateServerProtocol(peer, transportProtocolVersion);
String inputErrMessage = null;
if (responseCode == null) {
inputErrMessage = "responseCode is required.";
} else if(ResponseCode.CONFIRM_TRANSACTION.getCode() != responseCode
&& ResponseCode.CANCEL_TRANSACTION.getCode() != responseCode) {
inputErrMessage = "responseCode " + responseCode + " is invalid. ";
}
if (inputErrMessage != null){
entity.setMessage(inputErrMessage);
entity.setResponseCode(ResponseCode.ABORT.getCode());
return Response.status(Response.Status.BAD_REQUEST).entity(entity).build();
}
if (ResponseCode.CANCEL_TRANSACTION.getCode() == responseCode) {
return cancelTransaction(transactionId, entity);
}
int flowFileSent = serverProtocol.commitTransferTransaction(peer, checksum);
entity.setResponseCode(ResponseCode.CONFIRM_TRANSACTION.getCode());
entity.setFlowFileSent(flowFileSent);
} catch (HandshakeException e) {
return responseCreator.handshakeExceptionResponse(e);
} catch (Exception e) {
HttpServerCommunicationsSession commsSession = (HttpServerCommunicationsSession) peer.getCommunicationsSession();
logger.error("Failed to process the request", e);
if(ResponseCode.BAD_CHECKSUM.equals(commsSession.getResponseCode())){
entity.setResponseCode(commsSession.getResponseCode().getCode());
entity.setMessage(e.getMessage());
Response.ResponseBuilder builder = Response.status(Response.Status.BAD_REQUEST).entity(entity);
return clusterContext(noCache(builder)).build();
}
return responseCreator.unexpectedErrorResponse(portId, transactionId, e);
}
return clusterContext(noCache(setCommonHeaders(Response.ok(entity), transportProtocolVersion, transactionManager))).build();
}
@DELETE
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
@Produces(MediaType.APPLICATION_JSON)
@Path("input-ports/{portId}/transactions/{transactionId}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Commit or cancel the specified transaction",
response = TransactionResultEntity.class,
authorizations = {
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
@Authorization(value = "Administrator", type = "ROLE_ADMIN")
}
)
@ApiResponses(
value = {
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
@ApiResponse(code = 401, message = "Client could not be authenticated."),
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
@ApiResponse(code = 404, message = "The specified resource could not be found."),
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful."),
@ApiResponse(code = 503, message = "NiFi instance is not ready for serving request, or temporarily overloaded. Retrying the same request later may be successful"),
}
)
public Response commitInputPortTransaction(
@ApiParam(
value = "The response code. Available values are BAD_CHECKSUM(19), CONFIRM_TRANSACTION(12) or CANCEL_TRANSACTION(15).",
required = true
)
@QueryParam(RESPONSE_CODE) Integer responseCode,
@ApiParam(
value = "The input port id.",
required = true
)
@PathParam("portId") String portId,
@ApiParam(
value = "The transaction id.",
required = true
)
@PathParam("transactionId") String transactionId,
@Context HttpServletRequest req,
@Context ServletContext context,
InputStream inputStream) {
// authorize access
authorizeDataTransfer(ResourceType.InputPort, portId);
final ValidateRequestResult validationResult = validateResult(req, portId, transactionId);
if (validationResult.errResponse != null) {
return validationResult.errResponse;
}
logger.debug("commitInputPortTransaction request: portId={}, transactionId={}, responseCode={}",
portId, transactionId, responseCode);
final int transportProtocolVersion = validationResult.transportProtocolVersion;
final ByteArrayOutputStream out = new ByteArrayOutputStream();
final Peer peer = constructPeer(req, inputStream, out, portId, transactionId);
final TransactionResultEntity entity = new TransactionResultEntity();
try {
HttpFlowFileServerProtocol serverProtocol = initiateServerProtocol(peer, transportProtocolVersion);
HttpServerCommunicationsSession commsSession = (HttpServerCommunicationsSession) peer.getCommunicationsSession();
// Pass the response code sent from the client.
String inputErrMessage = null;
if (responseCode == null) {
inputErrMessage = "responseCode is required.";
} else if(ResponseCode.BAD_CHECKSUM.getCode() != responseCode
&& ResponseCode.CONFIRM_TRANSACTION.getCode() != responseCode
&& ResponseCode.CANCEL_TRANSACTION.getCode() != responseCode) {
inputErrMessage = "responseCode " + responseCode + " is invalid. ";
}
if (inputErrMessage != null){
entity.setMessage(inputErrMessage);
entity.setResponseCode(ResponseCode.ABORT.getCode());
return Response.status(Response.Status.BAD_REQUEST).entity(entity).build();
}
if (ResponseCode.CANCEL_TRANSACTION.getCode() == responseCode) {
return cancelTransaction(transactionId, entity);
}
commsSession.setResponseCode(ResponseCode.fromCode(responseCode));
try {
int flowFileSent = serverProtocol.commitReceiveTransaction(peer);
entity.setResponseCode(commsSession.getResponseCode().getCode());
entity.setFlowFileSent(flowFileSent);
} catch (IOException e){
if (ResponseCode.BAD_CHECKSUM.getCode() == responseCode && e.getMessage().contains("Received a BadChecksum response")){
// AbstractFlowFileServerProtocol throws IOException after it canceled transaction.
// This is a known behavior and if we return 500 with this exception,
// it's not clear if there is an issue at server side, or cancel operation has been accomplished.
// Above conditions can guarantee this is the latter case, we return 200 OK here.
entity.setResponseCode(ResponseCode.CANCEL_TRANSACTION.getCode());
return clusterContext(noCache(Response.ok(entity))).build();
} else {
return responseCreator.unexpectedErrorResponse(portId, transactionId, e);
}
}
} catch (HandshakeException e) {
return responseCreator.handshakeExceptionResponse(e);
} catch (Exception e) {
return responseCreator.unexpectedErrorResponse(portId, transactionId, e);
}
return clusterContext(noCache(setCommonHeaders(Response.ok(entity), transportProtocolVersion, transactionManager))).build();
}
private Response cancelTransaction(String transactionId, TransactionResultEntity entity) {
transactionManager.cancelTransaction(transactionId);
entity.setMessage("Transaction has been canceled.");
entity.setResponseCode(ResponseCode.CANCEL_TRANSACTION.getCode());
return Response.ok(entity).build();
}
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_OCTET_STREAM)
@Path("output-ports/{portId}/transactions/{transactionId}/flow-files")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Transfer flow files from the output port",
response = StreamingOutput.class,
authorizations = {
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
@Authorization(value = "Administrator", type = "ROLE_ADMIN")
}
)
@ApiResponses(
value = {
@ApiResponse(code = 200, message = "There is no flow file to return."),
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
@ApiResponse(code = 401, message = "Client could not be authenticated."),
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
@ApiResponse(code = 404, message = "The specified resource could not be found."),
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful."),
@ApiResponse(code = 503, message = "NiFi instance is not ready for serving request, or temporarily overloaded. Retrying the same request later may be successful"),
}
)
public Response transferFlowFiles(
@ApiParam(
value = "The output port id.",
required = true
)
@PathParam("portId") String portId,
@PathParam("transactionId") String transactionId,
@Context HttpServletRequest req,
@Context HttpServletResponse res,
@Context ServletContext context,
InputStream inputStream) {
// authorize access
authorizeDataTransfer(ResourceType.OutputPort, portId);
final ValidateRequestResult validationResult = validateResult(req, portId, transactionId);
if (validationResult.errResponse != null) {
return validationResult.errResponse;
}
logger.debug("transferFlowFiles request: portId={}", portId);
// Before opening the real output stream for HTTP response,
// use this temporary output stream to buffer handshake result.
final ByteArrayOutputStream tempBos = new ByteArrayOutputStream();
final Peer peer = constructPeer(req, inputStream, tempBos, portId, transactionId);
final int transportProtocolVersion = validationResult.transportProtocolVersion;
try {
final HttpFlowFileServerProtocol serverProtocol = initiateServerProtocol(peer, transportProtocolVersion);
StreamingOutput flowFileContent = new StreamingOutput() {
@Override
public void write(OutputStream outputStream) throws IOException, WebApplicationException {
HttpOutput output = (HttpOutput)peer.getCommunicationsSession().getOutput();
output.setOutputStream(outputStream);
try {
int numOfFlowFiles = serverProtocol.getPort().transferFlowFiles(peer, serverProtocol);
logger.debug("finished transferring flow files, numOfFlowFiles={}", numOfFlowFiles);
if(numOfFlowFiles < 1){
// There was no flow file to transfer. Throw this exception to stop responding with SEE OTHER.
throw new WebApplicationException(Response.Status.OK);
}
} catch (NotAuthorizedException | BadRequestException | RequestExpiredException e) {
// Handshake is done outside of write() method, so these exception wouldn't be thrown.
throw new IOException("Failed to process the request.", e);
}
}
};
return responseCreator.acceptedResponse(transactionManager, flowFileContent, transportProtocolVersion);
} catch (HandshakeException e) {
return responseCreator.handshakeExceptionResponse(e);
} catch (Exception e) {
return responseCreator.unexpectedErrorResponse(portId, e);
}
}
@PUT
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("input-ports/{portId}/transactions/{transactionId}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Extend transaction TTL",
response = TransactionResultEntity.class,
authorizations = {
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
@Authorization(value = "Administrator", type = "ROLE_ADMIN")
}
)
@ApiResponses(
value = {
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
@ApiResponse(code = 401, message = "Client could not be authenticated."),
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
@ApiResponse(code = 404, message = "The specified resource could not be found."),
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
}
)
public Response extendInputPortTransactionTTL(
@PathParam("portId") String portId,
@PathParam("transactionId") String transactionId,
@Context HttpServletRequest req,
@Context HttpServletResponse res,
@Context ServletContext context,
@Context UriInfo uriInfo,
InputStream inputStream) {
// authorize access
authorizeDataTransfer(ResourceType.InputPort, portId);
return extendPortTransactionTTL(PORT_TYPE_INPUT, portId, transactionId, req, res, context, uriInfo, inputStream);
}
@PUT
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("output-ports/{portId}/transactions/{transactionId}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Extend transaction TTL",
response = TransactionResultEntity.class,
authorizations = {
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
@Authorization(value = "Administrator", type = "ROLE_ADMIN")
}
)
@ApiResponses(
value = {
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
@ApiResponse(code = 401, message = "Client could not be authenticated."),
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
@ApiResponse(code = 404, message = "The specified resource could not be found."),
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful."),
@ApiResponse(code = 503, message = "NiFi instance is not ready for serving request, or temporarily overloaded. Retrying the same request later may be successful"),
}
)
public Response extendOutputPortTransactionTTL(
@PathParam("portId") String portId,
@PathParam("transactionId") String transactionId,
@Context HttpServletRequest req,
@Context HttpServletResponse res,
@Context ServletContext context,
@Context UriInfo uriInfo,
InputStream inputStream) {
// authorize access
authorizeDataTransfer(ResourceType.OutputPort, portId);
return extendPortTransactionTTL(PORT_TYPE_OUTPUT, portId, transactionId, req, res, context, uriInfo, inputStream);
}
public Response extendPortTransactionTTL(
String portType,
String portId,
String transactionId,
HttpServletRequest req,
HttpServletResponse res,
ServletContext context,
UriInfo uriInfo,
InputStream inputStream) {
final ValidateRequestResult validationResult = validateResult(req, portId, transactionId);
if (validationResult.errResponse != null) {
return validationResult.errResponse;
}
if(!PORT_TYPE_INPUT.equals(portType) && !PORT_TYPE_OUTPUT.equals(portType)){
return responseCreator.wrongPortTypeResponse(portType, portId);
}
logger.debug("extendOutputPortTransactionTTL request: portType={}, portId={}, transactionId={}",
portType, portId, transactionId);
final int transportProtocolVersion = validationResult.transportProtocolVersion;
final ByteArrayOutputStream out = new ByteArrayOutputStream();
final Peer peer = constructPeer(req, inputStream, out, portId, transactionId);
try {
// Do handshake
initiateServerProtocol(peer, transportProtocolVersion);
transactionManager.extendsTransaction(transactionId);
final TransactionResultEntity entity = new TransactionResultEntity();
entity.setResponseCode(ResponseCode.CONTINUE_TRANSACTION.getCode());
entity.setMessage("Extended TTL.");
return clusterContext(noCache(setCommonHeaders(Response.ok(entity), transportProtocolVersion, transactionManager))).build();
} catch (HandshakeException e) {
return responseCreator.handshakeExceptionResponse(e);
} catch (Exception e) {
return responseCreator.unexpectedErrorResponse(portId, transactionId, e);
}
}
private class ValidateRequestResult {
private Integer transportProtocolVersion;
private Response errResponse;
}
private ValidateRequestResult validateResult(HttpServletRequest req, String portId) {
return validateResult(req, portId, null);
}
private ValidateRequestResult validateResult(HttpServletRequest req, String portId, String transactionId) {
ValidateRequestResult result = new ValidateRequestResult();
if(!properties.isSiteToSiteHttpEnabled()) {
result.errResponse = responseCreator.httpSiteToSiteIsNotEnabledResponse();
return result;
}
// TODO: NCM no longer exists.
/*
if (properties.isClusterManager()) {
result.errResponse = responseCreator.nodeTypeErrorResponse(req.getPathInfo() + " is not available on a NiFi Cluster Manager.");
return result;
}
*/
try {
result.transportProtocolVersion = negotiateTransportProtocolVersion(req, transportProtocolVersionNegotiator);
} catch (BadRequestException e) {
result.errResponse = responseCreator.badRequestResponse(e);
return result;
}
if(!isEmpty(transactionId) && !transactionManager.isTransactionActive(transactionId)) {
result.errResponse = responseCreator.transactionNotFoundResponse(portId, transactionId);
return result;
}
return result;
}
// setters
public void setAuthorizer(Authorizer authorizer) {
this.authorizer = authorizer;
}
}

View File

@ -16,31 +16,13 @@
*/
package org.apache.nifi.web.api;
import java.util.ArrayList;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.sun.jersey.api.core.ResourceContext;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses;
import com.wordnik.swagger.annotations.Authorization;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.AccessDeniedException;
import org.apache.nifi.authorization.AuthorizationRequest;
@ -123,13 +105,29 @@ import org.apache.nifi.web.api.request.DateTimeParameter;
import org.apache.nifi.web.api.request.IntegerParameter;
import org.apache.nifi.web.api.request.LongParameter;
import com.sun.jersey.api.core.ResourceContext;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses;
import com.wordnik.swagger.annotations.Authorization;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* RESTful endpoint for managing a Flow.
@ -208,7 +206,7 @@ public class FlowResource extends ApplicationResource {
/**
* Authorizes access to the flow.
*/
private void authorizeFlow(final RequestAction action) {
private void authorizeFlow() {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
final Map<String,String> userContext;
@ -224,7 +222,7 @@ public class FlowResource extends ApplicationResource {
.identity(user.getIdentity())
.anonymous(user.isAnonymous())
.accessAttempt(true)
.action(action)
.action(RequestAction.READ)
.userContext(userContext)
.build();
@ -287,7 +285,7 @@ public class FlowResource extends ApplicationResource {
}
)
public Response generateClientId() {
authorizeFlow(RequestAction.READ);
authorizeFlow();
return clusterContext(generateOkResponse(generateUuid())).build();
}
@ -321,7 +319,7 @@ public class FlowResource extends ApplicationResource {
)
public Response getFlowConfig() {
authorizeFlow(RequestAction.READ);
authorizeFlow();
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
@ -350,7 +348,7 @@ public class FlowResource extends ApplicationResource {
)
public Response getCurrentUser() {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// note that the cluster manager will handle this request directly
final NiFiUser user = NiFiUserUtils.getNiFiUser();
@ -413,7 +411,7 @@ public class FlowResource extends ApplicationResource {
)
@QueryParam("recursive") @DefaultValue(RECURSIVE) Boolean recursive) throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
@ -458,7 +456,7 @@ public class FlowResource extends ApplicationResource {
)
public Response getControllerServicesFromController() {
authorizeFlow(RequestAction.READ);
authorizeFlow();
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
@ -511,7 +509,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String groupId) throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// get all the controller services
final Set<ControllerServiceEntity> controllerServices = serviceFacade.getControllerServices(groupId);
@ -566,7 +564,7 @@ public class FlowResource extends ApplicationResource {
)
@QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId) {
authorizeFlow(RequestAction.READ);
authorizeFlow();
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
@ -622,7 +620,7 @@ public class FlowResource extends ApplicationResource {
@PathParam("id") String id,
ScheduleComponentsEntity scheduleComponentsEntity) {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// ensure the same id is being used
if (!id.equals(scheduleComponentsEntity.getId())) {
@ -753,7 +751,7 @@ public class FlowResource extends ApplicationResource {
}
)
public Response searchFlow(@QueryParam("q") @DefaultValue(StringUtils.EMPTY) String value) throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// query the controller
final SearchResultsDTO results = serviceFacade.searchController(value);
@ -796,7 +794,7 @@ public class FlowResource extends ApplicationResource {
)
public Response getControllerStatus() throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
@ -841,7 +839,7 @@ public class FlowResource extends ApplicationResource {
)
public Response getBanners() {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// get the banner from the properties - will come from the NCM when clustered
final String bannerText = getProperties().getBannerText();
@ -888,7 +886,7 @@ public class FlowResource extends ApplicationResource {
}
)
public Response getProcessorTypes() throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// create response entity
final ProcessorTypesEntity entity = new ProcessorTypesEntity();
@ -933,7 +931,7 @@ public class FlowResource extends ApplicationResource {
required = false
)
@QueryParam("serviceType") String serviceType) throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// create response entity
final ControllerServiceTypesEntity entity = new ControllerServiceTypesEntity();
@ -972,7 +970,7 @@ public class FlowResource extends ApplicationResource {
}
)
public Response getReportingTaskTypes() throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// create response entity
final ReportingTaskTypesEntity entity = new ReportingTaskTypesEntity();
@ -1011,7 +1009,7 @@ public class FlowResource extends ApplicationResource {
}
)
public Response getPrioritizers() throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// create response entity
final PrioritizerTypesEntity entity = new PrioritizerTypesEntity();
@ -1049,7 +1047,7 @@ public class FlowResource extends ApplicationResource {
}
)
public Response getAboutInfo() {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// create the about dto
final AboutDTO aboutDTO = new AboutDTO();
@ -1139,7 +1137,7 @@ public class FlowResource extends ApplicationResource {
)
@QueryParam("limit") IntegerParameter limit) throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// replicate if cluster manager
if (isReplicateRequest()) {
@ -1230,7 +1228,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// ensure a valid request
if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
@ -1312,7 +1310,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// ensure a valid request
if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
@ -1394,7 +1392,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// ensure a valid request
if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
@ -1476,7 +1474,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// ensure a valid request
if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
@ -1567,7 +1565,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String groupId) throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// ensure a valid request
if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
@ -1670,7 +1668,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// ensure a valid request
if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
@ -1746,7 +1744,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// replicate if cluster manager
if (isReplicateRequest()) {
@ -1801,7 +1799,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String groupId) throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// replicate if cluster manager
if (isReplicateRequest()) {
@ -1856,7 +1854,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// replicate if cluster manager
if (isReplicateRequest()) {
@ -1911,7 +1909,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// replicate if cluster manager
if (isReplicateRequest()) {
@ -2022,7 +2020,7 @@ public class FlowResource extends ApplicationResource {
)
@QueryParam("sourceId") String sourceId) {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// ensure the page is specified
if (offset == null) {
@ -2130,7 +2128,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") IntegerParameter id) {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// ensure the id was specified
if (id == null) {
@ -2188,7 +2186,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("componentId") final String componentId) {
authorizeFlow(RequestAction.READ);
authorizeFlow();
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
@ -2240,7 +2238,7 @@ public class FlowResource extends ApplicationResource {
}
// authorize access
authorizeFlow(RequestAction.READ);
authorizeFlow();
// get all the templates
final Set<TemplateEntity> templates = serviceFacade.getTemplates();
@ -2295,7 +2293,7 @@ public class FlowResource extends ApplicationResource {
)
@QueryParam("q") @DefaultValue(StringUtils.EMPTY) String value) {
authorizeFlow(RequestAction.READ);
authorizeFlow();
// ensure connected to the cluster
if (!isConnectedToCluster()) {

View File

@ -33,8 +33,12 @@ import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.TenantDTO;
import org.apache.nifi.web.api.dto.UserDTO;
import org.apache.nifi.web.api.dto.UserGroupDTO;
import org.apache.nifi.web.api.entity.ClusterSearchResultsEntity;
import org.apache.nifi.web.api.entity.TenantEntity;
import org.apache.nifi.web.api.entity.TenantsEntity;
import org.apache.nifi.web.api.entity.UserEntity;
import org.apache.nifi.web.api.entity.UserGroupEntity;
import org.apache.nifi.web.api.entity.UserGroupsEntity;
@ -58,6 +62,9 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
@Path("tenants")
@ -182,8 +189,8 @@ public class TenantsResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable users = lookup.getTenantAuthorizable();
users.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
final Authorizable tenants = lookup.getTenant();
tenants.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
});
}
if (validationPhase) {
@ -247,8 +254,8 @@ public class TenantsResource extends ApplicationResource {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable users = lookup.getTenantAuthorizable();
users.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
final Authorizable tenants = lookup.getTenant();
tenants.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
});
// get the user
@ -294,8 +301,8 @@ public class TenantsResource extends ApplicationResource {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable users = lookup.getTenantAuthorizable();
users.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
final Authorizable tenants = lookup.getTenant();
tenants.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
});
// get all the users
@ -303,6 +310,7 @@ public class TenantsResource extends ApplicationResource {
// create the response entity
final UsersEntity entity = new UsersEntity();
entity.setGenerated(new Date());
entity.setUsers(populateRemainingUserEntitiesContent(users));
// generate the response
@ -375,8 +383,8 @@ public class TenantsResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable users = lookup.getTenantAuthorizable();
users.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
final Authorizable tenants = lookup.getTenant();
tenants.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
},
null,
() -> {
@ -450,8 +458,8 @@ public class TenantsResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable users = lookup.getTenantAuthorizable();
users.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
final Authorizable tenants = lookup.getTenant();
tenants.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
},
null,
() -> {
@ -567,8 +575,8 @@ public class TenantsResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable userGroups = lookup.getTenantAuthorizable();
userGroups.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
final Authorizable tenants = lookup.getTenant();
tenants.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
});
}
if (validationPhase) {
@ -632,8 +640,8 @@ public class TenantsResource extends ApplicationResource {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable userGroups = lookup.getTenantAuthorizable();
userGroups.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
final Authorizable tenants = lookup.getTenant();
tenants.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
});
// get the user group
@ -679,8 +687,8 @@ public class TenantsResource extends ApplicationResource {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable userGroups = lookup.getTenantAuthorizable();
userGroups.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
final Authorizable tenants = lookup.getTenant();
tenants.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
});
// get all the user groups
@ -760,8 +768,8 @@ public class TenantsResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable userGroups = lookup.getTenantAuthorizable();
userGroups.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
final Authorizable tenants = lookup.getTenant();
tenants.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
},
null,
() -> {
@ -835,8 +843,8 @@ public class TenantsResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable userGroups = lookup.getTenantAuthorizable();
userGroups.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
final Authorizable tenants = lookup.getTenant();
tenants.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
},
null,
() -> {
@ -846,4 +854,100 @@ public class TenantsResource extends ApplicationResource {
}
);
}
// ------------
// search users
// ------------
/**
* Searches the cluster for a node with a given address.
*
* @param value Search value that will be matched against a node's address
* @return Nodes that match the specified criteria
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("search-results")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Searches the cluster for a node with the specified address",
response = ClusterSearchResultsEntity.class,
authorizations = {
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
@Authorization(value = "DFM", type = "ROLE_DFM"),
@Authorization(value = "Admin", type = "ROLE_ADMIN")
}
)
@ApiResponses(
value = {
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
@ApiResponse(code = 401, message = "Client could not be authenticated."),
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
@ApiResponse(code = 404, message = "The specified resource could not be found."),
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
}
)
public Response searchCluster(
@ApiParam(
value = "Node address to search for.",
required = true
)
@QueryParam("q") @DefaultValue(StringUtils.EMPTY) String value) {
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
}
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable tenants = lookup.getTenant();
tenants.authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
});
final List<TenantEntity> userMatches = new ArrayList<>();
final List<TenantEntity> userGroupMatches = new ArrayList<>();
// get the users
for (final UserEntity userEntity : serviceFacade.getUsers()) {
final UserDTO user = userEntity.getComponent();
if (StringUtils.isBlank(value) || StringUtils.containsIgnoreCase(user.getIdentity(), value)) {
final TenantDTO tenant = new TenantDTO();
tenant.setId(user.getId());
tenant.setIdentity(user.getIdentity());
final TenantEntity entity = new TenantEntity();
entity.setPermissions(userEntity.getPermissions());
entity.setId(userEntity.getId());
entity.setComponent(tenant);
userMatches.add(entity);
}
}
// get the user groups
for (final UserGroupEntity userGroupEntity : serviceFacade.getUserGroups()) {
final UserGroupDTO userGroup = userGroupEntity.getComponent();
if (StringUtils.isBlank(value) || StringUtils.containsIgnoreCase(userGroup.getIdentity(), value)) {
final TenantDTO tenant = new TenantDTO();
tenant.setId(userGroup.getId());
tenant.setIdentity(userGroup.getIdentity());
final TenantEntity entity = new TenantEntity();
entity.setPermissions(userGroupEntity.getPermissions());
entity.setId(userGroupEntity.getId());
entity.setComponent(tenant);
userGroupMatches.add(entity);
}
}
// build the response
final TenantsEntity results = new TenantsEntity();
results.setUsers(userMatches);
results.setUserGroups(userGroupMatches);
// generate an 200 - OK response
return noCache(Response.ok(results)).build();
}
}

View File

@ -139,6 +139,7 @@ import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
import org.apache.nifi.web.api.dto.status.ProcessorStatusSnapshotDTO;
import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO;
import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity;
import org.apache.nifi.web.api.entity.FlowBreadcrumbEntity;
import org.apache.nifi.web.api.entity.TenantEntity;
import org.apache.nifi.web.controller.ControllerFacade;
@ -681,7 +682,7 @@ public final class DtoFactory {
* @param user user
* @return dto
*/
public UserDTO createUserDto(final User user, final Set<TenantEntity> groups) {
public UserDTO createUserDto(final User user, final Set<TenantEntity> groups, final Set<AccessPolicySummaryEntity> accessPolicies) {
if (user == null) {
return null;
}
@ -690,6 +691,7 @@ public final class DtoFactory {
dto.setId(user.getIdentifier());
dto.setUserGroups(groups);
dto.setIdentity(user.getIdentity());
dto.setAccessPolicies(accessPolicies);
return dto;
}
@ -1516,8 +1518,8 @@ public final class DtoFactory {
}
final FlowBreadcrumbDTO dto = createBreadcrumbDto(group);
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(group);
final FlowBreadcrumbEntity entity = entityFactory.createFlowBreadcrumbEntity(dto, accessPolicy);
final PermissionsDTO permissions = createPermissionsDto(group);
final FlowBreadcrumbEntity entity = entityFactory.createFlowBreadcrumbEntity(dto, permissions);
if (group.getParent() != null) {
entity.setParentBreadcrumb(createBreadcrumbEntity(group.getParent()));
@ -1544,6 +1546,18 @@ public final class DtoFactory {
return dto;
}
public AccessPolicySummaryDTO createAccessPolicySummaryDto(final AccessPolicy accessPolicy) {
if (accessPolicy == null) {
return null;
}
final AccessPolicySummaryDTO dto = new AccessPolicySummaryDTO();
dto.setId(accessPolicy.getIdentifier());
dto.setResource(accessPolicy.getResource());
dto.setAction(accessPolicy.getAction().toString());
return dto;
}
public AccessPolicyDTO createAccessPolicyDto(final AccessPolicy accessPolicy, Set<TenantEntity> userGroups, Set<TenantEntity> users) {
if (accessPolicy == null) {
return null;
@ -1554,23 +1568,18 @@ public final class DtoFactory {
dto.setUsers(users);
dto.setId(accessPolicy.getIdentifier());
dto.setResource(accessPolicy.getResource());
if (accessPolicy.getAction() == RequestAction.WRITE) {
dto.setCanWrite(Boolean.TRUE);
} else {
dto.setCanRead(Boolean.TRUE);
}
dto.setAction(accessPolicy.getAction().toString());
return dto;
}
/**
* Creates the AccessPolicyDTO based on the specified Authorizable.
* Creates the PermissionsDTO based on the specified Authorizable.
*
* @param authorizable authorizable
* @return dto
*/
public AccessPolicyDTO createAccessPolicyDto(final Authorizable authorizable) {
final AccessPolicyDTO dto = new AccessPolicyDTO();
public PermissionsDTO createPermissionsDto(final Authorizable authorizable) {
final PermissionsDTO dto = new PermissionsDTO();
dto.setCanRead(authorizable.isAuthorized(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()));
dto.setCanWrite(authorizable.isAuthorized(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()));
return dto;
@ -1614,7 +1623,7 @@ public final class DtoFactory {
// marshal the actual connection as the snippet is pruned
final ConnectionDTO dto = createConnectionDto(connection);
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(connection.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(connection);
final PermissionsDTO accessPolicy = createPermissionsDto(connection);
final ConnectionStatusDTO status = getComponentStatus(
() -> groupStatus.getConnectionStatus().stream().filter(connectionStatus -> connection.getIdentifier().equals(connectionStatus.getId())).findFirst().orElse(null),
connectionStatus -> createConnectionStatusDto(connectionStatus)
@ -1628,7 +1637,7 @@ public final class DtoFactory {
// marshal the actual funnel as the snippet is pruned
final FunnelDTO dto = createFunnelDto(funnel);
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(funnel.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(funnel);
final PermissionsDTO accessPolicy = createPermissionsDto(funnel);
flow.getFunnels().add(entityFactory.createFunnelEntity(dto, revision, accessPolicy));
}
@ -1638,7 +1647,7 @@ public final class DtoFactory {
// marshal the actual port as the snippet is pruned
final PortDTO dto = createPortDto(inputPort);
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(inputPort.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(inputPort);
final PermissionsDTO accessPolicy = createPermissionsDto(inputPort);
final PortStatusDTO status = getComponentStatus(
() -> groupStatus.getInputPortStatus().stream().filter(inputPortStatus -> inputPort.getIdentifier().equals(inputPortStatus.getId())).findFirst().orElse(null),
inputPortStatus -> createPortStatusDto(inputPortStatus)
@ -1653,7 +1662,7 @@ public final class DtoFactory {
// marshal the actual port as the snippet is pruned
final PortDTO dto = createPortDto(outputPort);
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(outputPort.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(outputPort);
final PermissionsDTO accessPolicy = createPermissionsDto(outputPort);
final PortStatusDTO status = getComponentStatus(
() -> groupStatus.getOutputPortStatus().stream().filter(outputPortStatus -> outputPort.getIdentifier().equals(outputPortStatus.getId())).findFirst().orElse(null),
outputPortStatus -> createPortStatusDto(outputPortStatus)
@ -1668,7 +1677,7 @@ public final class DtoFactory {
// marshal the actual label as the snippet is pruned
final LabelDTO dto = createLabelDto(label);
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(label.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(label);
final PermissionsDTO accessPolicy = createPermissionsDto(label);
flow.getLabels().add(entityFactory.createLabelEntity(dto, revision, accessPolicy));
}
@ -1678,7 +1687,7 @@ public final class DtoFactory {
// marshal the actual group as the snippet is pruned
final ProcessGroupDTO dto = createProcessGroupDto(processGroup);
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(processGroup.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(processGroup);
final PermissionsDTO accessPolicy = createPermissionsDto(processGroup);
final ProcessGroupStatusDTO status = getComponentStatus(
() -> groupStatus.getProcessGroupStatus().stream().filter(processGroupStatus -> processGroup.getIdentifier().equals(processGroupStatus.getId())).findFirst().orElse(null),
processGroupStatus -> createConciseProcessGroupStatusDto(processGroupStatus)
@ -1693,7 +1702,7 @@ public final class DtoFactory {
// marshal the actual processor as the snippet is pruned
final ProcessorDTO dto = createProcessorDto(processor);
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(processor.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(processor);
final PermissionsDTO accessPolicy = createPermissionsDto(processor);
final ProcessorStatusDTO status = getComponentStatus(
() -> groupStatus.getProcessorStatus().stream().filter(processorStatus -> processor.getIdentifier().equals(processorStatus.getId())).findFirst().orElse(null),
processorStatus -> createProcessorStatusDto(processorStatus)
@ -1708,7 +1717,7 @@ public final class DtoFactory {
// marshal the actual rpm as the snippet is pruned
final RemoteProcessGroupDTO dto = createRemoteProcessGroupDto(remoteProcessGroup);
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(remoteProcessGroup.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(remoteProcessGroup);
final PermissionsDTO accessPolicy = createPermissionsDto(remoteProcessGroup);
final RemoteProcessGroupStatusDTO status = getComponentStatus(
() -> groupStatus.getRemoteProcessGroupStatus().stream().filter(rpgStatus -> remoteProcessGroup.getIdentifier().equals(rpgStatus.getId())).findFirst().orElse(null),
remoteProcessGroupStatus -> createRemoteProcessGroupStatusDto(remoteProcessGroupStatus)
@ -1736,79 +1745,79 @@ public final class DtoFactory {
for (final ProcessorNode procNode : group.getProcessors()) {
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(procNode.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(procNode);
final PermissionsDTO permissions = createPermissionsDto(procNode);
final ProcessorStatusDTO status = getComponentStatus(
() -> groupStatus.getProcessorStatus().stream().filter(processorStatus -> procNode.getIdentifier().equals(processorStatus.getId())).findFirst().orElse(null),
processorStatus -> createProcessorStatusDto(processorStatus)
);
final List<BulletinDTO> bulletins = createBulletinDtos(bulletinRepository.findBulletinsForSource(procNode.getIdentifier()));
dto.getProcessors().add(entityFactory.createProcessorEntity(createProcessorDto(procNode), revision, accessPolicy, status, bulletins));
dto.getProcessors().add(entityFactory.createProcessorEntity(createProcessorDto(procNode), revision, permissions, status, bulletins));
}
for (final Connection connNode : group.getConnections()) {
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(connNode.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(connNode);
final PermissionsDTO permissions = createPermissionsDto(connNode);
final ConnectionStatusDTO status = getComponentStatus(
() -> groupStatus.getConnectionStatus().stream().filter(connectionStatus -> connNode.getIdentifier().equals(connectionStatus.getId())).findFirst().orElse(null),
connectionStatus -> createConnectionStatusDto(connectionStatus)
);
dto.getConnections().add(entityFactory.createConnectionEntity(createConnectionDto(connNode), revision, accessPolicy, status));
dto.getConnections().add(entityFactory.createConnectionEntity(createConnectionDto(connNode), revision, permissions, status));
}
for (final Label label : group.getLabels()) {
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(label.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(label);
dto.getLabels().add(entityFactory.createLabelEntity(createLabelDto(label), revision, accessPolicy));
final PermissionsDTO permissions = createPermissionsDto(label);
dto.getLabels().add(entityFactory.createLabelEntity(createLabelDto(label), revision, permissions));
}
for (final Funnel funnel : group.getFunnels()) {
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(funnel.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(funnel);
dto.getFunnels().add(entityFactory.createFunnelEntity(createFunnelDto(funnel), revision, accessPolicy));
final PermissionsDTO permissions = createPermissionsDto(funnel);
dto.getFunnels().add(entityFactory.createFunnelEntity(createFunnelDto(funnel), revision, permissions));
}
for (final ProcessGroup childGroup : group.getProcessGroups()) {
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(childGroup.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(childGroup);
final PermissionsDTO permissions = createPermissionsDto(childGroup);
final ProcessGroupStatusDTO status = getComponentStatus(
() -> groupStatus.getProcessGroupStatus().stream().filter(processGroupStatus -> childGroup.getIdentifier().equals(processGroupStatus.getId())).findFirst().orElse(null),
processGroupStatus -> createConciseProcessGroupStatusDto(processGroupStatus)
);
final List<BulletinDTO> bulletins = createBulletinDtos(bulletinRepository.findBulletinsForSource(childGroup.getIdentifier()));
dto.getProcessGroups().add(entityFactory.createProcessGroupEntity(createProcessGroupDto(childGroup), revision, accessPolicy, status, bulletins));
dto.getProcessGroups().add(entityFactory.createProcessGroupEntity(createProcessGroupDto(childGroup), revision, permissions, status, bulletins));
}
for (final RemoteProcessGroup rpg : group.getRemoteProcessGroups()) {
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(rpg.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(rpg);
final PermissionsDTO permissions = createPermissionsDto(rpg);
final RemoteProcessGroupStatusDTO status = getComponentStatus(
() -> groupStatus.getRemoteProcessGroupStatus().stream().filter(remoteProcessGroupStatus -> rpg.getIdentifier().equals(remoteProcessGroupStatus.getId())).findFirst().orElse(null),
remoteProcessGroupStatus -> createRemoteProcessGroupStatusDto(remoteProcessGroupStatus)
);
final List<BulletinDTO> bulletins = createBulletinDtos(bulletinRepository.findBulletinsForSource(rpg.getIdentifier()));
dto.getRemoteProcessGroups().add(entityFactory.createRemoteProcessGroupEntity(createRemoteProcessGroupDto(rpg), revision, accessPolicy, status, bulletins));
dto.getRemoteProcessGroups().add(entityFactory.createRemoteProcessGroupEntity(createRemoteProcessGroupDto(rpg), revision, permissions, status, bulletins));
}
for (final Port inputPort : group.getInputPorts()) {
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(inputPort.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(inputPort);
final PermissionsDTO permissions = createPermissionsDto(inputPort);
final PortStatusDTO status = getComponentStatus(
() -> groupStatus.getInputPortStatus().stream().filter(inputPortStatus -> inputPort.getIdentifier().equals(inputPortStatus.getId())).findFirst().orElse(null),
inputPortStatus -> createPortStatusDto(inputPortStatus)
);
final List<BulletinDTO> bulletins = createBulletinDtos(bulletinRepository.findBulletinsForSource(inputPort.getIdentifier()));
dto.getInputPorts().add(entityFactory.createPortEntity(createPortDto(inputPort), revision, accessPolicy, status, bulletins));
dto.getInputPorts().add(entityFactory.createPortEntity(createPortDto(inputPort), revision, permissions, status, bulletins));
}
for (final Port outputPort : group.getOutputPorts()) {
final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(outputPort.getIdentifier()));
final AccessPolicyDTO accessPolicy = createAccessPolicyDto(outputPort);
final PermissionsDTO permissions = createPermissionsDto(outputPort);
final PortStatusDTO status = getComponentStatus(
() -> groupStatus.getOutputPortStatus().stream().filter(outputPortStatus -> outputPort.getIdentifier().equals(outputPortStatus.getId())).findFirst().orElse(null),
outputPortStatus -> createPortStatusDto(outputPortStatus)
);
final List<BulletinDTO> bulletins = createBulletinDtos(bulletinRepository.findBulletinsForSource(outputPort.getIdentifier()));
dto.getOutputPorts().add(entityFactory.createPortEntity(createPortDto(outputPort), revision, accessPolicy, status, bulletins));
dto.getOutputPorts().add(entityFactory.createPortEntity(createPortDto(outputPort), revision, permissions, status, bulletins));
}
return dto;

View File

@ -24,6 +24,7 @@ import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
import org.apache.nifi.web.api.entity.AccessPolicyEntity;
import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity;
import org.apache.nifi.web.api.entity.ConnectionEntity;
import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
@ -48,37 +49,37 @@ import java.util.List;
public final class EntityFactory {
public ControllerConfigurationEntity createControllerConfigurationEntity(final ControllerConfigurationDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
public ControllerConfigurationEntity createControllerConfigurationEntity(final ControllerConfigurationDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) {
final ControllerConfigurationEntity entity = new ControllerConfigurationEntity();
entity.setRevision(revision);
entity.setCurrentTime(new Date());
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
if (accessPolicy != null && accessPolicy.getCanRead()) {
entity.setPermissions(permissions);
if (permissions != null && permissions.getCanRead()) {
entity.setControllerConfiguration(dto);
}
}
return entity;
}
public ProcessGroupFlowEntity createProcessGroupFlowEntity(final ProcessGroupFlowDTO dto, final AccessPolicyDTO accessPolicy) {
public ProcessGroupFlowEntity createProcessGroupFlowEntity(final ProcessGroupFlowDTO dto, final PermissionsDTO permissions) {
final ProcessGroupFlowEntity entity = new ProcessGroupFlowEntity();
entity.setProcessGroupFlow(dto);
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
return entity;
}
public ProcessorEntity createProcessorEntity(final ProcessorDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy,
public ProcessorEntity createProcessorEntity(final ProcessorDTO dto, final RevisionDTO revision, final PermissionsDTO permissions,
final ProcessorStatusDTO status, final List<BulletinDTO> bulletins) {
final ProcessorEntity entity = new ProcessorEntity();
entity.setRevision(revision);
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setStatus(status);
entity.setId(dto.getId());
entity.setPosition(dto.getPosition());
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setComponent(dto);
entity.setBulletins(bulletins);
}
@ -86,16 +87,16 @@ public final class EntityFactory {
return entity;
}
public PortEntity createPortEntity(final PortDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy, final PortStatusDTO status, final List<BulletinDTO> bulletins) {
public PortEntity createPortEntity(final PortDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final PortStatusDTO status, final List<BulletinDTO> bulletins) {
final PortEntity entity = new PortEntity();
entity.setRevision(revision);
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setStatus(status);
entity.setId(dto.getId());
entity.setPosition(dto.getPosition());
entity.setPortType(dto.getType());
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setComponent(dto);
entity.setBulletins(bulletins);
}
@ -103,13 +104,13 @@ public final class EntityFactory {
return entity;
}
public ProcessGroupEntity createProcessGroupEntity(final ProcessGroupDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy,
public ProcessGroupEntity createProcessGroupEntity(final ProcessGroupDTO dto, final RevisionDTO revision, final PermissionsDTO permissions,
final ProcessGroupStatusDTO status, final List<BulletinDTO> bulletins) {
final ProcessGroupEntity entity = new ProcessGroupEntity();
entity.setRevision(revision);
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setStatus(status);
entity.setId(dto.getId());
entity.setPosition(dto.getPosition());
@ -121,7 +122,7 @@ public final class EntityFactory {
entity.setDisabledCount(dto.getDisabledCount());
entity.setActiveRemotePortCount(dto.getActiveRemotePortCount());
entity.setInactiveRemotePortCount(dto.getInactiveRemotePortCount());
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setComponent(dto);
entity.setBulletins(bulletins);
}
@ -129,11 +130,11 @@ public final class EntityFactory {
return entity;
}
public LabelEntity createLabelEntity(final LabelDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
public LabelEntity createLabelEntity(final LabelDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) {
final LabelEntity entity = new LabelEntity();
entity.setRevision(revision);
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setId(dto.getId());
entity.setPosition(dto.getPosition());
@ -142,88 +143,103 @@ public final class EntityFactory {
dimensions.setWidth(dto.getWidth());
entity.setDimensions(dimensions);
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setComponent(dto);
}
}
return entity;
}
public UserEntity createUserEntity(final UserDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
public UserEntity createUserEntity(final UserDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) {
final UserEntity entity = new UserEntity();
entity.setRevision(revision);
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setId(dto.getId());
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setComponent(dto);
}
}
return entity;
}
public TenantEntity createTenantEntity(final TenantDTO dto, final RevisionDTO revsion, final AccessPolicyDTO accessPolicy) {
public TenantEntity createTenantEntity(final TenantDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) {
final TenantEntity entity = new TenantEntity();
entity.setRevision(revsion);
entity.setRevision(revision);
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setId(dto.getId());
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setComponent(dto);
}
}
return entity;
}
public UserGroupEntity createUserGroupEntity(final UserGroupDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
public AccessPolicySummaryEntity createAccessPolicySummaryEntity(final AccessPolicySummaryDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) {
final AccessPolicySummaryEntity entity = new AccessPolicySummaryEntity();
entity.setRevision(revision);
if (dto != null) {
entity.setPermissions(permissions);
entity.setId(dto.getId());
if (permissions != null && permissions.getCanRead()) {
entity.setComponent(dto);
}
}
return entity;
}
public UserGroupEntity createUserGroupEntity(final UserGroupDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) {
final UserGroupEntity entity = new UserGroupEntity();
entity.setRevision(revision);
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setId(dto.getId());
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setComponent(dto);
}
}
return entity;
}
public AccessPolicyEntity createAccessPolicyEntity(final AccessPolicyDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
public AccessPolicyEntity createAccessPolicyEntity(final AccessPolicyDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) {
final AccessPolicyEntity entity = new AccessPolicyEntity();
entity.setRevision(revision);
entity.setGenerated(new Date());
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setId(dto.getId());
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setComponent(dto);
}
}
return entity;
}
public FunnelEntity createFunnelEntity(final FunnelDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
public FunnelEntity createFunnelEntity(final FunnelDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) {
final FunnelEntity entity = new FunnelEntity();
entity.setRevision(revision);
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setId(dto.getId());
entity.setPosition(dto.getPosition());
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setComponent(dto);
}
}
return entity;
}
public ConnectionEntity createConnectionEntity(final ConnectionDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy, final ConnectionStatusDTO status) {
public ConnectionEntity createConnectionEntity(final ConnectionDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final ConnectionStatusDTO status) {
final ConnectionEntity entity = new ConnectionEntity();
entity.setRevision(revision);
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setStatus(status);
entity.setId(dto.getId());
entity.setPosition(dto.getPosition());
@ -233,26 +249,26 @@ public final class EntityFactory {
entity.setSourceGroupId(dto.getSource().getGroupId());
entity.setDestinationId(dto.getDestination().getId());
entity.setDestinationGroupId(dto.getDestination().getGroupId());
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setComponent(dto);
}
}
return entity;
}
public RemoteProcessGroupEntity createRemoteProcessGroupEntity(final RemoteProcessGroupDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy,
public RemoteProcessGroupEntity createRemoteProcessGroupEntity(final RemoteProcessGroupDTO dto, final RevisionDTO revision, final PermissionsDTO permissions,
final RemoteProcessGroupStatusDTO status, final List<BulletinDTO> bulletins) {
final RemoteProcessGroupEntity entity = new RemoteProcessGroupEntity();
entity.setRevision(revision);
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setStatus(status);
entity.setId(dto.getId());
entity.setPosition(dto.getPosition());
entity.setInputPortCount(dto.getInputPortCount());
entity.setOutputPortCount(dto.getOutputPortCount());
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setComponent(dto);
entity.setBulletins(bulletins);
}
@ -260,13 +276,13 @@ public final class EntityFactory {
return entity;
}
public RemoteProcessGroupPortEntity createRemoteProcessGroupPortEntity(final RemoteProcessGroupPortDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
public RemoteProcessGroupPortEntity createRemoteProcessGroupPortEntity(final RemoteProcessGroupPortDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) {
final RemoteProcessGroupPortEntity entity = new RemoteProcessGroupPortEntity();
entity.setRevision(revision);
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setId(dto.getId());
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setRemoteProcessGroupPort(dto);
}
}
@ -280,13 +296,13 @@ public final class EntityFactory {
return entity;
}
public ReportingTaskEntity createReportingTaskEntity(final ReportingTaskDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy, final List<BulletinDTO> bulletins) {
public ReportingTaskEntity createReportingTaskEntity(final ReportingTaskDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final List<BulletinDTO> bulletins) {
final ReportingTaskEntity entity = new ReportingTaskEntity();
entity.setRevision(revision);
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setId(dto.getId());
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setComponent(dto);
entity.setBulletins(bulletins);
}
@ -295,14 +311,14 @@ public final class EntityFactory {
return entity;
}
public ControllerServiceEntity createControllerServiceEntity(final ControllerServiceDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy, final List<BulletinDTO> bulletins) {
public ControllerServiceEntity createControllerServiceEntity(final ControllerServiceDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final List<BulletinDTO> bulletins) {
final ControllerServiceEntity entity = new ControllerServiceEntity();
entity.setRevision(revision);
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setId(dto.getId());
entity.setPosition(dto.getPosition());
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setComponent(dto);
entity.setBulletins(bulletins);
}
@ -311,14 +327,14 @@ public final class EntityFactory {
}
public ControllerServiceReferencingComponentEntity createControllerServiceReferencingComponentEntity(
final ControllerServiceReferencingComponentDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
final ControllerServiceReferencingComponentDTO dto, final RevisionDTO revision, final PermissionsDTO permissions) {
final ControllerServiceReferencingComponentEntity entity = new ControllerServiceReferencingComponentEntity();
entity.setRevision(revision);
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setId(dto.getId());
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setComponent(dto);
}
}
@ -326,12 +342,12 @@ public final class EntityFactory {
return entity;
}
public FlowBreadcrumbEntity createFlowBreadcrumbEntity(final FlowBreadcrumbDTO dto, final AccessPolicyDTO accessPolicy) {
public FlowBreadcrumbEntity createFlowBreadcrumbEntity(final FlowBreadcrumbDTO dto, final PermissionsDTO permissions) {
final FlowBreadcrumbEntity entity = new FlowBreadcrumbEntity();
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
entity.setPermissions(permissions);
entity.setId(dto.getId());
if (accessPolicy != null && accessPolicy.getCanRead()) {
if (permissions != null && permissions.getCanRead()) {
entity.setBreadcrumb(dto);
}
}

View File

@ -1328,6 +1328,16 @@ public class ControllerFacade implements Authorizable {
}
}
/**
* Gets an authorizable for proveance events for a given component id.
*
* @param componentId component id
* @return authorizable
*/
public Authorizable getProvenanceEventAuthorizable(final String componentId) {
return flowController.createProvenanceAuthorizable(componentId);
}
/**
* Creates a ProvenanceEventDTO for the specified ProvenanceEventRecord.
*

View File

@ -17,6 +17,8 @@
package org.apache.nifi.web.dao;
import org.apache.nifi.authorization.AccessPolicy;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
public interface AccessPolicyDAO {
@ -36,13 +38,22 @@ public interface AccessPolicyDAO {
AccessPolicy createAccessPolicy(AccessPolicyDTO accessPolicyDTO);
/**
* Gets the acess policy with the specified ID.
* Gets the access policy with the specified ID.
*
* @param accessPolicyId The access policy ID
* @return The access policy transfer object
*/
AccessPolicy getAccessPolicy(String accessPolicyId);
/**
* Gets the access policy according to the action and authorizable.
*
* @param requestAction action
* @param authorizable authorizable
* @return access policy
*/
AccessPolicy getAccessPolicy(RequestAction requestAction, Authorizable authorizable);
/**
* Updates the specified access policy.
*

View File

@ -16,6 +16,7 @@
*/
package org.apache.nifi.web.dao;
import org.apache.nifi.authorization.AccessPolicy;
import org.apache.nifi.authorization.Group;
import org.apache.nifi.web.api.dto.UserGroupDTO;
@ -53,6 +54,14 @@ public interface UserGroupDAO {
*/
Set<Group> getUserGroupsForUser(String userId);
/**
* Gets the access policies for the user with the specified ID.
*
* @param userId The user ID
* @return The set of access policies
*/
Set<AccessPolicy> getAccessPoliciesForUser(String userId);
/**
* Gets all user groups.
*

View File

@ -28,6 +28,7 @@ import org.apache.nifi.authorization.UsersAndAccessPolicies;
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.web.ResourceNotFoundException;
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
import org.apache.nifi.web.api.dto.UserDTO;
@ -151,6 +152,13 @@ public class StandardPolicyBasedAuthorizerDAO implements AccessPolicyDAO, UserGr
}
}
private AccessPolicy findAccessPolicy(final RequestAction requestAction, final String resource) {
return authorizer.getAccessPolicies().stream()
.filter(policy -> policy.getAction().equals(requestAction) && policy.getResource().equals(resource))
.findFirst()
.orElse(null);
}
@Override
public boolean hasAccessPolicy(final String accessPolicyId) {
return authorizer.getAccessPolicy(accessPolicyId) != null;
@ -158,7 +166,8 @@ public class StandardPolicyBasedAuthorizerDAO implements AccessPolicyDAO, UserGr
@Override
public AccessPolicy createAccessPolicy(final AccessPolicyDTO accessPolicyDTO) {
return authorizer.addAccessPolicy(buildAccessPolicy(accessPolicyDTO.getId(), accessPolicyDTO));
return authorizer.addAccessPolicy(buildAccessPolicy(accessPolicyDTO.getId(),
accessPolicyDTO.getResource(), RequestAction.valueOfValue(accessPolicyDTO.getAction()), accessPolicyDTO));
}
@Override
@ -170,9 +179,28 @@ public class StandardPolicyBasedAuthorizerDAO implements AccessPolicyDAO, UserGr
return accessPolicy;
}
@Override
public AccessPolicy getAccessPolicy(final RequestAction requestAction, final Authorizable authorizable) {
final String resource = authorizable.getResource().getIdentifier();
final AccessPolicy accessPolicy = findAccessPolicy(requestAction, authorizable.getResource().getIdentifier());
if (accessPolicy == null) {
final Authorizable parentAuthorizable = authorizable.getParentAuthorizable();
if (parentAuthorizable == null) {
throw new ResourceNotFoundException(String.format("Unable to find access policy for %s on %s", requestAction.toString(), resource));
} else {
return getAccessPolicy(requestAction, parentAuthorizable);
}
}
return accessPolicy;
}
@Override
public AccessPolicy updateAccessPolicy(final AccessPolicyDTO accessPolicyDTO) {
return authorizer.updateAccessPolicy(buildAccessPolicy(getAccessPolicy(accessPolicyDTO.getId()).getIdentifier(), accessPolicyDTO));
final AccessPolicy currentAccessPolicy = getAccessPolicy(accessPolicyDTO.getId());
return authorizer.updateAccessPolicy(buildAccessPolicy(currentAccessPolicy.getIdentifier(),
currentAccessPolicy.getResource(), currentAccessPolicy.getAction(), accessPolicyDTO));
}
@Override
@ -180,23 +208,19 @@ public class StandardPolicyBasedAuthorizerDAO implements AccessPolicyDAO, UserGr
return authorizer.deleteAccessPolicy(getAccessPolicy(accessPolicyId));
}
private AccessPolicy buildAccessPolicy(final String identifier, final AccessPolicyDTO accessPolicyDTO) {
private AccessPolicy buildAccessPolicy(final String identifier, final String resource, final RequestAction action, final AccessPolicyDTO accessPolicyDTO) {
final Set<TenantEntity> userGroups = accessPolicyDTO.getUserGroups();
final Set<TenantEntity> users = accessPolicyDTO.getUsers();
final AccessPolicy.Builder builder = new AccessPolicy.Builder()
.identifier(identifier)
.resource(accessPolicyDTO.getResource());
.resource(resource);
if (userGroups != null) {
builder.addGroups(userGroups.stream().map(ComponentEntity::getId).collect(Collectors.toSet()));
}
if (users != null) {
builder.addUsers(users.stream().map(ComponentEntity::getId).collect(Collectors.toSet()));
}
if (Boolean.TRUE == accessPolicyDTO.getCanWrite()) {
builder.action(RequestAction.WRITE);
} else {
builder.action(RequestAction.READ);
}
builder.action(action);
return builder.build();
}
@ -226,6 +250,21 @@ public class StandardPolicyBasedAuthorizerDAO implements AccessPolicyDAO, UserGr
.collect(Collectors.toSet());
}
@Override
public Set<AccessPolicy> getAccessPoliciesForUser(String userId) {
return authorizer.getAccessPolicies().stream()
.filter(p -> {
// policy contains the user
if (p.getUsers().contains(userId)) {
return true;
}
// policy contains a group with the user
return !p.getGroups().stream().filter(g -> authorizer.getGroup(g).getUsers().contains(userId)).collect(Collectors.toSet()).isEmpty();
})
.collect(Collectors.toSet());
}
@Override
public Set<Group> getUserGroups() {
return authorizer.getGroups();
@ -281,12 +320,12 @@ public class StandardPolicyBasedAuthorizerDAO implements AccessPolicyDAO, UserGr
@Override
public User deleteUser(final String userId) {
return authorizer.deleteUser(getUser(userId));
final User user = getUser(userId);
return authorizer.deleteUser(user);
}
private User buildUser(final String identifier, final UserDTO userDTO) {
final User.Builder builder = new User.Builder().identifier(identifier).identity(userDTO.getIdentity());
return builder.build();
}
}

View File

@ -219,6 +219,12 @@
<property name="requestReplicator" ref="requestReplicator" />
<property name="authorizer" ref="authorizer"/>
</bean>
<bean id="dataTransferResource" class="org.apache.nifi.web.api.DataTransferResource" scope="singleton">
<property name="properties" ref="nifiProperties"/>
<property name="clusterCoordinator" ref="clusterCoordinator"/>
<property name="requestReplicator" ref="requestReplicator" />
<property name="authorizer" ref="authorizer"/>
</bean>
<bean id="snippetResource" class="org.apache.nifi.web.api.SnippetResource" scope="singleton">
<property name="serviceFacade" ref="serviceFacade"/>
<property name="properties" ref="nifiProperties"/>

View File

@ -74,8 +74,8 @@ class StandardNiFiServiceFacadeSpec extends Specification {
if (isAuthorized) {
assert userEntity?.component?.id == userDto.id
assert userEntity?.component?.identity?.equals(userDto.identity)
assert userEntity?.accessPolicy?.canRead
assert userEntity?.accessPolicy?.canWrite
assert userEntity?.permissions?.canRead
assert userEntity?.permissions?.canWrite
} else {
assert userEntity.component == null
}
@ -174,8 +174,8 @@ class StandardNiFiServiceFacadeSpec extends Specification {
def userEntity = userEntityUpdateResult?.result
if (isAuthorized) {
assert userEntity?.component?.id?.equals(userDto.id)
assert userEntity?.accessPolicy?.canRead
assert userEntity?.accessPolicy?.canWrite
assert userEntity?.getPermissions?.canRead
assert userEntity?.getPermissions?.canWrite
} else {
assert userEntity.component == null
}
@ -294,8 +294,8 @@ class StandardNiFiServiceFacadeSpec extends Specification {
if (isAuthorized) {
assert userGroupEntity?.component?.id == userGroupDto.id
assert userGroupEntity?.component?.users?.equals(userGroupDto.users)
assert userGroupEntity?.accessPolicy?.canRead
assert userGroupEntity?.accessPolicy?.canWrite
assert userGroupEntity?.permissions?.canRead
assert userGroupEntity?.permissions?.canWrite
} else {
assert userGroupEntity?.component == null
}
@ -425,8 +425,8 @@ class StandardNiFiServiceFacadeSpec extends Specification {
assert userGroupEntity != null
if (isAuthorized) {
assert userGroupEntity?.component?.id?.equals(userGroupDto.id)
assert userGroupEntity?.accessPolicy?.canRead
assert userGroupEntity?.accessPolicy?.canWrite
assert userGroupEntity?.getPermissions?.canRead
assert userGroupEntity?.getPermissions?.canWrite
} else {
assert userGroupEntity.component == null
}
@ -577,8 +577,8 @@ class StandardNiFiServiceFacadeSpec extends Specification {
assert accessPolicyEntity != null
if (isAuthorized) {
assert accessPolicyEntity?.component?.id?.equals(accessPolicyDto.id)
assert accessPolicyEntity?.accessPolicy?.canRead
assert accessPolicyEntity?.accessPolicy?.canWrite
assert accessPolicyEntity?.permissions?.canRead
assert accessPolicyEntity?.permissions?.canWrite
} else {
assert accessPolicyEntity.component == null
}
@ -722,8 +722,8 @@ class StandardNiFiServiceFacadeSpec extends Specification {
assert accessPolicyEntity != null
if (isAuthorized) {
assert accessPolicyEntity?.component?.id?.equals(accessPolicyDto.id)
assert accessPolicyEntity?.accessPolicy?.canRead
assert accessPolicyEntity?.accessPolicy?.canWrite
assert accessPolicyEntity?.getPermissions?.canRead
assert accessPolicyEntity?.getPermissions?.canWrite
} else {
assert accessPolicyEntity.component == null
}

View File

@ -38,7 +38,7 @@ class StandardPolicyBasedAuthorizerDAOSpec extends Specification {
where:
method | daoMethod
'createAccessPolicy' | { new StandardPolicyBasedAuthorizerDAO(Mock(Authorizer)).createAccessPolicy(new AccessPolicyDTO(id: '1', resource: '/1', canRead: true)) }
'createAccessPolicy' | { new StandardPolicyBasedAuthorizerDAO(Mock(Authorizer)).createAccessPolicy(new AccessPolicyDTO(id: '1', resource: '/1', action: "read")) }
'createUser' | { new StandardPolicyBasedAuthorizerDAO(Mock(Authorizer)).createUser(new UserDTO(id: '1', identity: 'a')) }
'createUserGroup' | { new StandardPolicyBasedAuthorizerDAO(Mock(Authorizer)).createUserGroup(new UserGroupDTO(id: '1', identity: 'a')) }
'deleteAccessPolicy' | { new StandardPolicyBasedAuthorizerDAO(Mock(Authorizer)).deleteAccessPolicy('1') }
@ -50,7 +50,7 @@ class StandardPolicyBasedAuthorizerDAOSpec extends Specification {
'hasAccessPolicy' | { new StandardPolicyBasedAuthorizerDAO(Mock(Authorizer)).hasAccessPolicy('1') }
'hasUser' | { new StandardPolicyBasedAuthorizerDAO(Mock(Authorizer)).hasUser('1') }
'hasUserGroup' | { new StandardPolicyBasedAuthorizerDAO(Mock(Authorizer)).hasUserGroup('1') }
'updateAccessPolicy' | { new StandardPolicyBasedAuthorizerDAO(Mock(Authorizer)).updateAccessPolicy(new AccessPolicyDTO(id: '1', resource: '/1', canRead: true)) }
'updateAccessPolicy' | { new StandardPolicyBasedAuthorizerDAO(Mock(Authorizer)).updateAccessPolicy(new AccessPolicyDTO(id: '1', resource: '/1', action: "read")) }
'updateUser' | { new StandardPolicyBasedAuthorizerDAO(Mock(Authorizer)).updateUser(new UserDTO(id: '1', identity: 'a')) }
'updateUserGroup' | { new StandardPolicyBasedAuthorizerDAO(Mock(Authorizer)).updateUserGroup(new UserGroupDTO(id: '1', identity: 'a')) }
}
@ -81,8 +81,7 @@ class StandardPolicyBasedAuthorizerDAOSpec extends Specification {
given:
def authorizer = Mock AbstractPolicyBasedAuthorizer
def dao = new StandardPolicyBasedAuthorizerDAO(authorizer)
def requestDTO = new AccessPolicyDTO(id: 'policy-id-1', resource: '/fake/resource', canRead: true,
canWrite: true,
def requestDTO = new AccessPolicyDTO(id: 'policy-id-1', resource: '/fake/resource', action: "read",
users: [new TenantEntity(id: 'user-id-1')] as Set,
userGroups: [new TenantEntity(id: 'user-group-id-1')] as Set)
@ -144,8 +143,7 @@ class StandardPolicyBasedAuthorizerDAOSpec extends Specification {
given:
def authorizer = Mock AbstractPolicyBasedAuthorizer
def dao = new StandardPolicyBasedAuthorizerDAO(authorizer)
def requestDTO = new AccessPolicyDTO(id: 'policy-id-1', resource: '/fake/resource', canRead: true,
canWrite: true,
def requestDTO = new AccessPolicyDTO(id: 'policy-id-1', resource: '/fake/resource', action: "read",
users: [new TenantEntity(id: 'user-id-1')] as Set,
userGroups: [new TenantEntity(id: 'user-group-id-1')] as Set)
@ -169,8 +167,7 @@ class StandardPolicyBasedAuthorizerDAOSpec extends Specification {
given:
def authorizer = Mock AbstractPolicyBasedAuthorizer
def dao = new StandardPolicyBasedAuthorizerDAO(authorizer)
def requestDTO = new AccessPolicyDTO(id: 'policy-id-1', resource: '/fake/resource', canRead: true,
canWrite: true,
def requestDTO = new AccessPolicyDTO(id: 'policy-id-1', resource: '/fake/resource', action: "read",
users: [new TenantEntity(id: 'user-id-1')] as Set,
userGroups: [new TenantEntity(id: 'user-group-id-1')] as Set)

View File

@ -69,8 +69,8 @@ public class ITConnectionAccessControl {
@Test
public void testReadUserGetConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
}
@ -82,8 +82,8 @@ public class ITConnectionAccessControl {
@Test
public void testReadWriteUserGetConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
}
@ -95,8 +95,8 @@ public class ITConnectionAccessControl {
@Test
public void testWriteUserGetConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
}
@ -108,8 +108,8 @@ public class ITConnectionAccessControl {
@Test
public void testNoneUserGetConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
}
@ -121,8 +121,8 @@ public class ITConnectionAccessControl {
@Test
public void testReadUserPutConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
// attempt update the name
@ -144,8 +144,8 @@ public class ITConnectionAccessControl {
@Test
public void testReadWriteUserPutConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
final String updatedName = "Updated Name";
@ -209,8 +209,8 @@ public class ITConnectionAccessControl {
@Test
public void testWriteUserPutConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name";
@ -252,8 +252,8 @@ public class ITConnectionAccessControl {
@Test
public void testNoneUserPutConnection() throws Exception {
final ConnectionEntity entity = getRandomConnection(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name";

View File

@ -65,8 +65,8 @@ public class ITFunnelAccessControl {
@Test
public void testReadUserGetFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
}
@ -78,8 +78,8 @@ public class ITFunnelAccessControl {
@Test
public void testReadWriteUserGetFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
}
@ -91,8 +91,8 @@ public class ITFunnelAccessControl {
@Test
public void testWriteUserGetFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
}
@ -104,8 +104,8 @@ public class ITFunnelAccessControl {
@Test
public void testNoneUserGetFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
}
@ -117,8 +117,8 @@ public class ITFunnelAccessControl {
@Test
public void testReadUserPutFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
// attempt update the position
@ -140,8 +140,8 @@ public class ITFunnelAccessControl {
@Test
public void testReadWriteUserPutFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
final double y = 15.0;
@ -174,8 +174,8 @@ public class ITFunnelAccessControl {
@Test
public void testWriteUserPutFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
final double y = 15.0;
@ -217,8 +217,8 @@ public class ITFunnelAccessControl {
@Test
public void testNoneUserPutFunnel() throws Exception {
final FunnelEntity entity = getRandomFunnel(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
// attempt to update the position

View File

@ -66,8 +66,8 @@ public class ITInputPortAccessControl {
@Test
public void testReadUserGetInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
}
@ -79,8 +79,8 @@ public class ITInputPortAccessControl {
@Test
public void testReadWriteUserGetInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
}
@ -92,8 +92,8 @@ public class ITInputPortAccessControl {
@Test
public void testWriteUserGetInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
}
@ -105,8 +105,8 @@ public class ITInputPortAccessControl {
@Test
public void testNoneUserGetInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
}
@ -118,8 +118,8 @@ public class ITInputPortAccessControl {
@Test
public void testReadUserPutInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
// attempt update the name
@ -141,8 +141,8 @@ public class ITInputPortAccessControl {
@Test
public void testReadWriteUserPutInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;
@ -206,8 +206,8 @@ public class ITInputPortAccessControl {
@Test
public void testWriteUserPutInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;
@ -249,8 +249,8 @@ public class ITInputPortAccessControl {
@Test
public void testNoneUserPutInputPort() throws Exception {
final PortEntity entity = getRandomInputPort(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;

View File

@ -65,8 +65,8 @@ public class ITLabelAccessControl {
@Test
public void testReadUserGetLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
}
@ -78,8 +78,8 @@ public class ITLabelAccessControl {
@Test
public void testReadWriteUserGetLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
}
@ -91,8 +91,8 @@ public class ITLabelAccessControl {
@Test
public void testWriteUserGetLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
}
@ -104,8 +104,8 @@ public class ITLabelAccessControl {
@Test
public void testNoneUserGetLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
}
@ -117,8 +117,8 @@ public class ITLabelAccessControl {
@Test
public void testReadUserPutLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
// attempt update the name
@ -140,8 +140,8 @@ public class ITLabelAccessControl {
@Test
public void testReadWriteUserPutLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
final String updatedLabel = "Updated Name";
@ -205,8 +205,8 @@ public class ITLabelAccessControl {
@Test
public void testWriteUserPutLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
final String updatedLabel = "Updated Name";
@ -248,8 +248,8 @@ public class ITLabelAccessControl {
@Test
public void testNoneUserPutLabel() throws Exception {
final LabelEntity entity = getRandomLabel(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name";

View File

@ -66,8 +66,8 @@ public class ITOutputPortAccessControl {
@Test
public void testReadUserGetOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
}
@ -79,8 +79,8 @@ public class ITOutputPortAccessControl {
@Test
public void testReadWriteUserGetOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
}
@ -92,8 +92,8 @@ public class ITOutputPortAccessControl {
@Test
public void testWriteUserGetOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
}
@ -105,8 +105,8 @@ public class ITOutputPortAccessControl {
@Test
public void testNoneUserGetOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
}
@ -118,8 +118,8 @@ public class ITOutputPortAccessControl {
@Test
public void testReadUserPutOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
// attempt update the name
@ -141,8 +141,8 @@ public class ITOutputPortAccessControl {
@Test
public void testReadWriteUserPutOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;
@ -206,8 +206,8 @@ public class ITOutputPortAccessControl {
@Test
public void testWriteUserPutOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;
@ -249,8 +249,8 @@ public class ITOutputPortAccessControl {
@Test
public void testNoneUserPutOutputPort() throws Exception {
final PortEntity entity = getRandomOutputPort(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;

View File

@ -66,8 +66,8 @@ public class ITProcessGroupAccessControl {
@Test
public void testReadUserGetProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
}
@ -79,8 +79,8 @@ public class ITProcessGroupAccessControl {
@Test
public void testReadWriteUserGetProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
}
@ -92,8 +92,8 @@ public class ITProcessGroupAccessControl {
@Test
public void testWriteUserGetProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
}
@ -105,8 +105,8 @@ public class ITProcessGroupAccessControl {
@Test
public void testNoneUserGetProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
}
@ -118,8 +118,8 @@ public class ITProcessGroupAccessControl {
@Test
public void testReadUserPutProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
// attempt update the name
@ -141,8 +141,8 @@ public class ITProcessGroupAccessControl {
@Test
public void testReadWriteUserPutProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;
@ -206,8 +206,8 @@ public class ITProcessGroupAccessControl {
@Test
public void testWriteUserPutProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;
@ -249,8 +249,8 @@ public class ITProcessGroupAccessControl {
@Test
public void testNoneUserPutProcessGroup() throws Exception {
final ProcessGroupEntity entity = getRandomProcessGroup(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name" + count++;

View File

@ -66,8 +66,8 @@ public class ITProcessorAccessControl {
@Test
public void testReadUserGetProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
}
@ -79,8 +79,8 @@ public class ITProcessorAccessControl {
@Test
public void testReadWriteUserGetProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
}
@ -92,8 +92,8 @@ public class ITProcessorAccessControl {
@Test
public void testWriteUserGetProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
}
@ -105,8 +105,8 @@ public class ITProcessorAccessControl {
@Test
public void testNoneUserGetProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
}
@ -118,8 +118,8 @@ public class ITProcessorAccessControl {
@Test
public void testReadUserPutProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
// attempt update the name
@ -141,8 +141,8 @@ public class ITProcessorAccessControl {
@Test
public void testReadWriteUserPutProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadWriteUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
final String updatedName = "Updated Name";
@ -206,8 +206,8 @@ public class ITProcessorAccessControl {
@Test
public void testWriteUserPutProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getWriteUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertTrue(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertTrue(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name";
@ -249,8 +249,8 @@ public class ITProcessorAccessControl {
@Test
public void testNoneUserPutProcessor() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getNoneUser());
assertFalse(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertFalse(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNull(entity.getComponent());
final String updatedName = "Updated Name";
@ -285,8 +285,8 @@ public class ITProcessorAccessControl {
@Test
public void testReadUserClearState() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
final String url = helper.getBaseUrl() + "/processors/" + entity.getId() + "/state/clear-requests";
@ -306,8 +306,8 @@ public class ITProcessorAccessControl {
@Test
public void testNoneUserClearState() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
final String url = helper.getBaseUrl() + "/processors/" + entity.getId() + "/state/clear-requests";
@ -327,8 +327,8 @@ public class ITProcessorAccessControl {
@Test
public void testReadWriteUserClearState() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
final String url = helper.getBaseUrl() + "/processors/" + entity.getId() + "/state/clear-requests";
@ -348,8 +348,8 @@ public class ITProcessorAccessControl {
@Test
public void testWriteUserClearState() throws Exception {
final ProcessorEntity entity = getRandomProcessor(helper.getReadUser());
assertTrue(entity.getAccessPolicy().getCanRead());
assertFalse(entity.getAccessPolicy().getCanWrite());
assertTrue(entity.getPermissions().getCanRead());
assertFalse(entity.getPermissions().getCanWrite());
assertNotNull(entity.getComponent());
final String url = helper.getBaseUrl() + "/processors/" + entity.getId() + "/state/clear-requests";

View File

@ -0,0 +1,355 @@
/*
* 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.web.api;
import org.apache.nifi.authorization.resource.ResourceType;
import org.apache.nifi.remote.HttpRemoteSiteListener;
import org.apache.nifi.remote.Peer;
import org.apache.nifi.remote.RootGroupPort;
import org.apache.nifi.remote.VersionNegotiator;
import org.apache.nifi.remote.exception.HandshakeException;
import org.apache.nifi.remote.io.http.HttpServerCommunicationsSession;
import org.apache.nifi.remote.protocol.ResponseCode;
import org.apache.nifi.remote.protocol.http.HttpFlowFileServerProtocol;
import org.apache.nifi.remote.protocol.http.HttpHeaders;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.api.entity.TransactionResultEntity;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
public class TestDataTransferResource {
@BeforeClass
public static void setup() throws Exception {
final URL resource = TestDataTransferResource.class.getResource("/site-to-site/nifi.properties");
final String propertiesFile = resource.toURI().getPath();
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, propertiesFile);
}
private HttpServletRequest createCommonHttpServletRequest() {
final HttpServletRequest req = mock(HttpServletRequest.class);
doReturn("1").when(req).getHeader(eq(HttpHeaders.PROTOCOL_VERSION));
return req;
}
@Test
public void testCreateTransactionPortNotFound() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final DataTransferResource resource = getDataTransferResource();
final HttpFlowFileServerProtocol serverProtocol = resource.getHttpFlowFileServerProtocol(null);
doThrow(new HandshakeException(ResponseCode.UNKNOWN_PORT, "Not found.")).when(serverProtocol).handshake(any());
final ServletContext context = null;
final UriInfo uriInfo = null;
final InputStream inputStream = null;
final Response response = resource.createPortTransaction("input-ports", "port-id", req, context, uriInfo, inputStream);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(404, response.getStatus());
assertEquals(ResponseCode.UNKNOWN_PORT.getCode(), resultEntity.getResponseCode());
}
@Test
public void testCreateTransactionPortNotInValidState() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final DataTransferResource resource = getDataTransferResource();
final HttpFlowFileServerProtocol serverProtocol = resource.getHttpFlowFileServerProtocol(null);
doThrow(new HandshakeException(ResponseCode.PORT_NOT_IN_VALID_STATE, "Not in valid state.")).when(serverProtocol).handshake(any());
final ServletContext context = null;
final UriInfo uriInfo = null;
final InputStream inputStream = null;
final Response response = resource.createPortTransaction("input-ports", "port-id", req, context, uriInfo, inputStream);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(503, response.getStatus());
assertEquals(ResponseCode.PORT_NOT_IN_VALID_STATE.getCode(), resultEntity.getResponseCode());
}
@Test
public void testCreateTransactionUnauthorized() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final DataTransferResource resource = getDataTransferResource();
final HttpFlowFileServerProtocol serverProtocol = resource.getHttpFlowFileServerProtocol(null);
doThrow(new HandshakeException(ResponseCode.UNAUTHORIZED, "Unauthorized.")).when(serverProtocol).handshake(any());
final ServletContext context = null;
final UriInfo uriInfo = null;
final InputStream inputStream = null;
final Response response = resource.createPortTransaction("input-ports", "port-id", req, context, uriInfo, inputStream);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(401, response.getStatus());
assertEquals(ResponseCode.UNAUTHORIZED.getCode(), resultEntity.getResponseCode());
}
private UriInfo mockUriInfo(final String locationUriStr) throws URISyntaxException {
final UriInfo uriInfo = mock(UriInfo.class);
final UriBuilder uriBuilder = mock(UriBuilder.class);
final URI locationUri = new URI(locationUriStr);
doReturn(uriBuilder).when(uriInfo).getBaseUriBuilder();
doReturn(uriBuilder).when(uriBuilder).path(any(String.class));
doReturn(locationUri).when(uriBuilder).build();
return uriInfo;
}
@Test
public void testCreateTransaction() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final DataTransferResource resource = getDataTransferResource();
final String locationUriStr = "http://localhost:8080/nifi-api/data-transfer/input-ports/port-id/transactions/transaction-id";
final ServletContext context = null;
final UriInfo uriInfo = mockUriInfo(locationUriStr);
final InputStream inputStream = null;
final Response response = resource.createPortTransaction("input-ports", "port-id", req, context, uriInfo, inputStream);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(201, response.getStatus());
assertEquals(ResponseCode.PROPERTIES_OK.getCode(), resultEntity.getResponseCode());
assertEquals(locationUriStr, response.getMetadata().getFirst(HttpHeaders.LOCATION_HEADER_NAME).toString());
}
@Test
public void testExtendTransaction() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final DataTransferResource resource = getDataTransferResource();
final String locationUriStr = "http://localhost:8080/nifi-api/data-transfer/input-ports/port-id/transactions/transaction-id";
final ServletContext context = null;
final HttpServletResponse res = null;
final UriInfo uriInfo = mockUriInfo(locationUriStr);
final InputStream inputStream = null;
final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
final String transactionId = transactionManager.createTransaction();
final Response response = resource.extendPortTransactionTTL("input-ports", "port-id", transactionId, req, res, context, uriInfo, inputStream);
transactionManager.cancelTransaction(transactionId);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(200, response.getStatus());
assertEquals(ResponseCode.CONTINUE_TRANSACTION.getCode(), resultEntity.getResponseCode());
}
@Test
public void testReceiveFlowFiles() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final DataTransferResource resource = getDataTransferResource();
final HttpFlowFileServerProtocol serverProtocol = resource.getHttpFlowFileServerProtocol(null);
final RootGroupPort port = mock(RootGroupPort.class);
doReturn(port).when(serverProtocol).getPort();
doAnswer(invocation -> {
Peer peer = (Peer) invocation.getArguments()[0];
((HttpServerCommunicationsSession)peer.getCommunicationsSession()).setChecksum("server-checksum");
return 7;
}).when(port).receiveFlowFiles(any(Peer.class), any());
final ServletContext context = null;
final InputStream inputStream = null;
final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
final String transactionId = transactionManager.createTransaction();
final Response response = resource.receiveFlowFiles("port-id", transactionId, req, context, inputStream);
transactionManager.cancelTransaction(transactionId);
final Object entity = response.getEntity();
assertEquals(202, response.getStatus());
assertEquals("server-checksum", entity);
}
@Test
public void testReceiveZeroFlowFiles() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final DataTransferResource resource = getDataTransferResource();
final HttpFlowFileServerProtocol serverProtocol = resource.getHttpFlowFileServerProtocol(null);
final RootGroupPort port = mock(RootGroupPort.class);
doReturn(port).when(serverProtocol).getPort();
doAnswer(invocation -> 0).when(port).receiveFlowFiles(any(Peer.class), any());
final ServletContext context = null;
final InputStream inputStream = null;
final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
final String transactionId = transactionManager.createTransaction();
final Response response = resource.receiveFlowFiles("port-id", transactionId, req, context, inputStream);
transactionManager.cancelTransaction(transactionId);
assertEquals(400, response.getStatus());
}
@Test
public void testCommitInputPortTransaction() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final DataTransferResource resource = getDataTransferResource();
final ServletContext context = null;
final InputStream inputStream = null;
final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
final String transactionId = transactionManager.createTransaction();
final Response response = resource.commitInputPortTransaction(ResponseCode.CONFIRM_TRANSACTION.getCode(), "port-id", transactionId, req, context, inputStream);
transactionManager.cancelTransaction(transactionId);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(200, response.getStatus());
assertEquals(ResponseCode.CONFIRM_TRANSACTION.getCode(), resultEntity.getResponseCode());
}
@Test
public void testTransferFlowFiles() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final DataTransferResource resource = getDataTransferResource();
final ServletContext context = null;
final HttpServletResponse res = null;
final InputStream inputStream = null;
final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
final String transactionId = transactionManager.createTransaction();
final Response response = resource.transferFlowFiles("port-id", transactionId, req, res, context, inputStream);
transactionManager.cancelTransaction(transactionId);
final Object entity = response.getEntity();
assertEquals(202, response.getStatus());
assertTrue(entity instanceof StreamingOutput);
}
@Test
public void testCommitOutputPortTransaction() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final DataTransferResource resource = getDataTransferResource();
final ServletContext context = null;
final InputStream inputStream = null;
final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
final String transactionId = transactionManager.createTransaction();
final Response response = resource.commitOutputPortTransaction(ResponseCode.CONFIRM_TRANSACTION.getCode(),
"client-checksum", "port-id", transactionId, req, context, inputStream);
transactionManager.cancelTransaction(transactionId);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(200, response.getStatus());
assertEquals(ResponseCode.CONFIRM_TRANSACTION.getCode(), resultEntity.getResponseCode());
}
@Test
public void testCommitOutputPortTransactionBadChecksum() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final DataTransferResource resource = getDataTransferResource();
final HttpFlowFileServerProtocol serverProtocol = resource.getHttpFlowFileServerProtocol(null);
doThrow(new HandshakeException(ResponseCode.BAD_CHECKSUM, "Bad checksum.")).when(serverProtocol).commitTransferTransaction(any(), any());
final ServletContext context = null;
final InputStream inputStream = null;
final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
final String transactionId = transactionManager.createTransaction();
final Response response = resource.commitOutputPortTransaction(ResponseCode.CONFIRM_TRANSACTION.getCode(),
"client-checksum", "port-id", transactionId, req, context, inputStream);
transactionManager.cancelTransaction(transactionId);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(400, response.getStatus());
assertEquals(ResponseCode.BAD_CHECKSUM.getCode(), resultEntity.getResponseCode());
}
private DataTransferResource getDataTransferResource() {
final HttpFlowFileServerProtocol serverProtocol = mock(HttpFlowFileServerProtocol.class);
final DataTransferResource resource = new DataTransferResource() {
@Override
protected void authorizeDataTransfer(ResourceType resourceType, String identifier) {
}
@Override
HttpFlowFileServerProtocol getHttpFlowFileServerProtocol(VersionNegotiator versionNegotiator) {
return serverProtocol;
}
};
resource.setProperties(NiFiProperties.getInstance());
return resource;
}
}

View File

@ -16,14 +16,7 @@
*/
package org.apache.nifi.web.api;
import org.apache.nifi.remote.HttpRemoteSiteListener;
import org.apache.nifi.remote.Peer;
import org.apache.nifi.remote.RootGroupPort;
import org.apache.nifi.remote.VersionNegotiator;
import org.apache.nifi.remote.exception.HandshakeException;
import org.apache.nifi.remote.io.http.HttpServerCommunicationsSession;
import org.apache.nifi.remote.protocol.ResponseCode;
import org.apache.nifi.remote.protocol.http.HttpFlowFileServerProtocol;
import org.apache.nifi.remote.protocol.http.HttpHeaders;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.NiFiServiceFacade;
@ -31,32 +24,18 @@ import org.apache.nifi.web.api.dto.ControllerDTO;
import org.apache.nifi.web.api.entity.ControllerEntity;
import org.apache.nifi.web.api.entity.PeersEntity;
import org.apache.nifi.web.api.entity.TransactionResultEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
public class TestSiteToSiteResource {
@ -78,12 +57,10 @@ public class TestSiteToSiteResource {
controller.setRemoteSiteHttpListeningPort(8080);
controller.setRemoteSiteListeningPort(9990);
doReturn(controller).when(serviceFacade).getController();
doReturn(controller).when(serviceFacade).getSiteToSiteDetails();
final SiteToSiteResource resource = new SiteToSiteResource();
resource.setProperties(NiFiProperties.getInstance());
resource.setServiceFacade(serviceFacade);
final Response response = resource.getSiteToSite(req);
final SiteToSiteResource resource = getSiteToSiteResource(serviceFacade);
final Response response = resource.getSiteToSiteDetails(req);
ControllerEntity resultEntity = (ControllerEntity)response.getEntity();
@ -105,12 +82,10 @@ public class TestSiteToSiteResource {
controller.setRemoteSiteHttpListeningPort(8080);
controller.setRemoteSiteListeningPort(9990);
doReturn(controller).when(serviceFacade).getController();
doReturn(controller).when(serviceFacade).getSiteToSiteDetails();
final SiteToSiteResource resource = new SiteToSiteResource();
resource.setProperties(NiFiProperties.getInstance());
resource.setServiceFacade(serviceFacade);
final Response response = resource.getSiteToSite(req);
final SiteToSiteResource resource = getSiteToSiteResource(serviceFacade);
final Response response = resource.getSiteToSiteDetails(req);
ControllerEntity resultEntity = (ControllerEntity)response.getEntity();
@ -131,11 +106,9 @@ public class TestSiteToSiteResource {
final NiFiServiceFacade serviceFacade = mock(NiFiServiceFacade.class);
final SiteToSiteResource resource = new SiteToSiteResource();
resource.setProperties(NiFiProperties.getInstance());
resource.setServiceFacade(serviceFacade);
final SiteToSiteResource resource = getSiteToSiteResource(serviceFacade);
final Response response = resource.getPeers(null, req);
final Response response = resource.getPeers(req);
PeersEntity resultEntity = (PeersEntity) response.getEntity();
@ -150,11 +123,9 @@ public class TestSiteToSiteResource {
final NiFiServiceFacade serviceFacade = mock(NiFiServiceFacade.class);
final SiteToSiteResource resource = new SiteToSiteResource();
resource.setProperties(NiFiProperties.getInstance());
resource.setServiceFacade(serviceFacade);
final SiteToSiteResource resource = getSiteToSiteResource(serviceFacade);
final Response response = resource.getPeers(null, req);
final Response response = resource.getPeers(req);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(400, response.getStatus());
@ -168,11 +139,9 @@ public class TestSiteToSiteResource {
final NiFiServiceFacade serviceFacade = mock(NiFiServiceFacade.class);
final SiteToSiteResource resource = new SiteToSiteResource();
resource.setProperties(NiFiProperties.getInstance());
resource.setServiceFacade(serviceFacade);
final SiteToSiteResource resource = getSiteToSiteResource(serviceFacade);
final Response response = resource.getPeers(null, req);
final Response response = resource.getPeers(req);
PeersEntity resultEntity = (PeersEntity) response.getEntity();
@ -181,336 +150,14 @@ public class TestSiteToSiteResource {
assertEquals(new Integer(1), response.getMetadata().getFirst(HttpHeaders.PROTOCOL_VERSION));
}
@Test
public void testCreateTransactionPortNotFound() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final NiFiServiceFacade serviceFacade = mock(NiFiServiceFacade.class);
final SiteToSiteResource resource = spySiteToSiteResource(serviceFacade);
final HttpFlowFileServerProtocol serverProtocol = mockHttpFlowFileServerProtocol(resource);
doThrow(new HandshakeException(ResponseCode.UNKNOWN_PORT, "Not found.")).when(serverProtocol).handshake(any());
final ClientIdParameter clientId = new ClientIdParameter("client-id");
final ServletContext context = null;
final UriInfo uriInfo = null;
final InputStream inputStream = null;
final Response response = resource.createPortTransaction(clientId, "input-ports", "port-id", req, context, uriInfo, inputStream);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(404, response.getStatus());
assertEquals(ResponseCode.UNKNOWN_PORT.getCode(), resultEntity.getResponseCode());
}
@Test
public void testCreateTransactionPortNotInValidState() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final NiFiServiceFacade serviceFacade = mock(NiFiServiceFacade.class);
final SiteToSiteResource resource = spySiteToSiteResource(serviceFacade);
final HttpFlowFileServerProtocol serverProtocol = mockHttpFlowFileServerProtocol(resource);
doThrow(new HandshakeException(ResponseCode.PORT_NOT_IN_VALID_STATE, "Not in valid state.")).when(serverProtocol).handshake(any());
final ClientIdParameter clientId = new ClientIdParameter("client-id");
final ServletContext context = null;
final UriInfo uriInfo = null;
final InputStream inputStream = null;
final Response response = resource.createPortTransaction(clientId, "input-ports", "port-id", req, context, uriInfo, inputStream);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(503, response.getStatus());
assertEquals(ResponseCode.PORT_NOT_IN_VALID_STATE.getCode(), resultEntity.getResponseCode());
}
@Test
public void testCreateTransactionUnauthorized() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final NiFiServiceFacade serviceFacade = mock(NiFiServiceFacade.class);
final SiteToSiteResource resource = spySiteToSiteResource(serviceFacade);
final HttpFlowFileServerProtocol serverProtocol = mockHttpFlowFileServerProtocol(resource);
doThrow(new HandshakeException(ResponseCode.UNAUTHORIZED, "Unauthorized.")).when(serverProtocol).handshake(any());
final ClientIdParameter clientId = new ClientIdParameter("client-id");
final ServletContext context = null;
final UriInfo uriInfo = null;
final InputStream inputStream = null;
final Response response = resource.createPortTransaction(clientId, "input-ports", "port-id", req, context, uriInfo, inputStream);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(401, response.getStatus());
assertEquals(ResponseCode.UNAUTHORIZED.getCode(), resultEntity.getResponseCode());
}
private UriInfo mockUriInfo(final String locationUriStr) throws URISyntaxException {
final UriInfo uriInfo = mock(UriInfo.class);
final UriBuilder uriBuilder = mock(UriBuilder.class);
final URI locationUri = new URI(locationUriStr);
doReturn(uriBuilder).when(uriInfo).getBaseUriBuilder();
doReturn(uriBuilder).when(uriBuilder).path(any(String.class));
doReturn(locationUri).when(uriBuilder).build();
return uriInfo;
}
@Test
public void testCreateTransaction() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final NiFiServiceFacade serviceFacade = mock(NiFiServiceFacade.class);
final SiteToSiteResource resource = spySiteToSiteResource(serviceFacade);
mockHttpFlowFileServerProtocol(resource);
final String locationUriStr = "http://localhost:8080/nifi-api/site-to-site/input-ports/port-id/transactions/transaction-id";
final ClientIdParameter clientId = new ClientIdParameter("client-id");
final ServletContext context = null;
final UriInfo uriInfo = mockUriInfo(locationUriStr);
final InputStream inputStream = null;
final Response response = resource.createPortTransaction(clientId, "input-ports", "port-id", req, context, uriInfo, inputStream);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(201, response.getStatus());
assertEquals(ResponseCode.PROPERTIES_OK.getCode(), resultEntity.getResponseCode());
assertEquals(locationUriStr, response.getMetadata().getFirst(HttpHeaders.LOCATION_HEADER_NAME).toString());
}
@Test
public void testExtendTransaction() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final NiFiServiceFacade serviceFacade = mock(NiFiServiceFacade.class);
final SiteToSiteResource resource = spySiteToSiteResource(serviceFacade);
mockHttpFlowFileServerProtocol(resource);
final String locationUriStr = "http://localhost:8080/nifi-api/site-to-site/input-ports/port-id/transactions/transaction-id";
final ClientIdParameter clientId = new ClientIdParameter("client-id");
final ServletContext context = null;
final HttpServletResponse res = null;
final UriInfo uriInfo = mockUriInfo(locationUriStr);
final InputStream inputStream = null;
final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
final String transactionId = transactionManager.createTransaction();
final Response response = resource.extendPortTransactionTTL(clientId, "input-ports", "port-id", transactionId, req, res, context, uriInfo, inputStream);
transactionManager.cancelTransaction(transactionId);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(200, response.getStatus());
assertEquals(ResponseCode.CONTINUE_TRANSACTION.getCode(), resultEntity.getResponseCode());
}
@Test
public void testReceiveFlowFiles() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final NiFiServiceFacade serviceFacade = mock(NiFiServiceFacade.class);
final SiteToSiteResource resource = spySiteToSiteResource(serviceFacade);
final HttpFlowFileServerProtocol serverProtocol = mockHttpFlowFileServerProtocol(resource);
final RootGroupPort port = mock(RootGroupPort.class);
doReturn(port).when(serverProtocol).getPort();
doAnswer(invocation -> {
Peer peer = (Peer) invocation.getArguments()[0];
((HttpServerCommunicationsSession)peer.getCommunicationsSession()).setChecksum("server-checksum");
return 7;
}).when(port).receiveFlowFiles(any(Peer.class), any());
final ClientIdParameter clientId = new ClientIdParameter("client-id");
final ServletContext context = null;
final InputStream inputStream = null;
final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
final String transactionId = transactionManager.createTransaction();
final Response response = resource.receiveFlowFiles(clientId, "port-id", transactionId, req, context, inputStream);
transactionManager.cancelTransaction(transactionId);
final Object entity = response.getEntity();
assertEquals(202, response.getStatus());
assertEquals("server-checksum", entity);
}
@Test
public void testReceiveZeroFlowFiles() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final NiFiServiceFacade serviceFacade = mock(NiFiServiceFacade.class);
final SiteToSiteResource resource = spySiteToSiteResource(serviceFacade);
final HttpFlowFileServerProtocol serverProtocol = mockHttpFlowFileServerProtocol(resource);
final RootGroupPort port = mock(RootGroupPort.class);
doReturn(port).when(serverProtocol).getPort();
doAnswer(invocation -> 0).when(port).receiveFlowFiles(any(Peer.class), any());
final ClientIdParameter clientId = new ClientIdParameter("client-id");
final ServletContext context = null;
final InputStream inputStream = null;
final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
final String transactionId = transactionManager.createTransaction();
final Response response = resource.receiveFlowFiles(clientId, "port-id", transactionId, req, context, inputStream);
transactionManager.cancelTransaction(transactionId);
assertEquals(400, response.getStatus());
}
@Test
public void testCommitInputPortTransaction() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final NiFiServiceFacade serviceFacade = mock(NiFiServiceFacade.class);
final SiteToSiteResource resource = spySiteToSiteResource(serviceFacade);
mockHttpFlowFileServerProtocol(resource);
final ClientIdParameter clientId = new ClientIdParameter("client-id");
final ServletContext context = null;
final InputStream inputStream = null;
final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
final String transactionId = transactionManager.createTransaction();
final Response response = resource.commitInputPortTransaction(clientId, ResponseCode.CONFIRM_TRANSACTION.getCode(), "port-id", transactionId, req, context, inputStream);
transactionManager.cancelTransaction(transactionId);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(200, response.getStatus());
assertEquals(ResponseCode.CONFIRM_TRANSACTION.getCode(), resultEntity.getResponseCode());
}
@Test
public void testTransferFlowFiles() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final NiFiServiceFacade serviceFacade = mock(NiFiServiceFacade.class);
final SiteToSiteResource resource = spySiteToSiteResource(serviceFacade);
mockHttpFlowFileServerProtocol(resource);
final ClientIdParameter clientId = new ClientIdParameter("client-id");
final ServletContext context = null;
final HttpServletResponse res = null;
final InputStream inputStream = null;
final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
final String transactionId = transactionManager.createTransaction();
final Response response = resource.transferFlowFiles(clientId, "port-id", transactionId, req, res, context, inputStream);
transactionManager.cancelTransaction(transactionId);
final Object entity = response.getEntity();
assertEquals(202, response.getStatus());
assertTrue(entity instanceof StreamingOutput);
}
@Test
public void testCommitOutputPortTransaction() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final NiFiServiceFacade serviceFacade = mock(NiFiServiceFacade.class);
final SiteToSiteResource resource = spySiteToSiteResource(serviceFacade);
mockHttpFlowFileServerProtocol(resource);
final ClientIdParameter clientId = new ClientIdParameter("client-id");
final ServletContext context = null;
final InputStream inputStream = null;
final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
final String transactionId = transactionManager.createTransaction();
final Response response = resource.commitOutputPortTransaction(clientId, ResponseCode.CONFIRM_TRANSACTION.getCode(),
"client-checksum", "port-id", transactionId, req, context, inputStream);
transactionManager.cancelTransaction(transactionId);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(200, response.getStatus());
assertEquals(ResponseCode.CONFIRM_TRANSACTION.getCode(), resultEntity.getResponseCode());
}
@Test
public void testCommitOutputPortTransactionBadChecksum() throws Exception {
final HttpServletRequest req = createCommonHttpServletRequest();
final NiFiServiceFacade serviceFacade = mock(NiFiServiceFacade.class);
final SiteToSiteResource resource = spySiteToSiteResource(serviceFacade);
final HttpFlowFileServerProtocol serverProtocol = mockHttpFlowFileServerProtocol(resource);
doThrow(new HandshakeException(ResponseCode.BAD_CHECKSUM, "Bad checksum.")).when(serverProtocol).commitTransferTransaction(any(), any());
final ClientIdParameter clientId = new ClientIdParameter("client-id");
final ServletContext context = null;
final InputStream inputStream = null;
final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
final String transactionId = transactionManager.createTransaction();
final Response response = resource.commitOutputPortTransaction(clientId, ResponseCode.CONFIRM_TRANSACTION.getCode(),
"client-checksum", "port-id", transactionId, req, context, inputStream);
transactionManager.cancelTransaction(transactionId);
TransactionResultEntity resultEntity = (TransactionResultEntity) response.getEntity();
assertEquals(400, response.getStatus());
assertEquals(ResponseCode.BAD_CHECKSUM.getCode(), resultEntity.getResponseCode());
}
private HttpFlowFileServerProtocol mockHttpFlowFileServerProtocol(SiteToSiteResource resource) {
final HttpFlowFileServerProtocol serverProtocol = mock(HttpFlowFileServerProtocol.class);
doReturn(serverProtocol).when(resource).getHttpFlowFileServerProtocol(any(VersionNegotiator.class));
return serverProtocol;
}
private SiteToSiteResource spySiteToSiteResource(NiFiServiceFacade serviceFacade) {
final SiteToSiteResource resource = spy(SiteToSiteResource.class);
private SiteToSiteResource getSiteToSiteResource(final NiFiServiceFacade serviceFacade) {
final SiteToSiteResource resource = new SiteToSiteResource() {
@Override
protected void authorizeSiteToSite() {
}
};
resource.setProperties(NiFiProperties.getInstance());
resource.setServiceFacade(serviceFacade);
return resource;
}
}

View File

@ -32,6 +32,7 @@
<counters.filter>counters.properties</counters.filter>
<cluster.filter>cluster.properties</cluster.filter>
<templates.filter>templates.properties</templates.filter>
<users.filter>users.properties</users.filter>
<bulletin.board.filter>bulletin-board.properties</bulletin.board.filter>
<login.filter>login.properties</login.filter>
<provenance.filter>provenance.properties</provenance.filter>
@ -61,6 +62,7 @@
<filter>src/main/resources/filters/${counters.filter}</filter>
<filter>src/main/resources/filters/${cluster.filter}</filter>
<filter>src/main/resources/filters/${templates.filter}</filter>
<filter>src/main/resources/filters/${users.filter}</filter>
<filter>src/main/resources/filters/${bulletin.board.filter}</filter>
<filter>src/main/resources/filters/${login.filter}</filter>
<filter>src/main/resources/filters/${provenance.filter}</filter>
@ -96,6 +98,7 @@
**/counters.jsp,
**/cluster.jsp,
**/templates.jsp,
**/users.jsp,
**/bulletin-board.jsp,
**/login.jsp
</excludes>
@ -205,6 +208,14 @@
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/webapp/WEB-INF/pages</directory>
<targetPath>WEB-INF/pages</targetPath>
<includes>
<include>users.jsp</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/webapp/WEB-INF/pages</directory>
<targetPath>WEB-INF/pages</targetPath>
@ -247,7 +258,6 @@
<configuration>
<installDirectory>${frontend.working.dir}</installDirectory>
</configuration>
<executions>
<execution>
<id>install-node-and-npm</id>
@ -297,6 +307,7 @@
<counters.filter>counters-min.properties</counters.filter>
<cluster.filter>cluster-min.properties</cluster.filter>
<templates.filter>templates-min.properties</templates.filter>
<users.filter>users-min.properties</users.filter>
<bulletin.board.filter>bulletin-board-min.properties</bulletin.board.filter>
<login.filter>login-min.properties</login.filter>
<provenance.filter>provenance-min.properties</provenance.filter>
@ -346,7 +357,7 @@
<include>${staging.dir}/js/nf/canvas/nf-processor-configuration.js</include>
<include>${staging.dir}/js/nf/nf-processor-details.js</include>
<include>${staging.dir}/js/nf/canvas/nf-process-group-configuration.js</include>
<include>${staging.dir}/js/nf/canvas/nf-process-group-details.js</include>
<include>${staging.dir}/js/nf/canvas/nf-policy-management.js</include>
<include>${staging.dir}/js/nf/canvas/nf-remote-process-group-configuration.js</include>
<include>${staging.dir}/js/nf/canvas/nf-remote-process-group-details.js</include>
<include>${staging.dir}/js/nf/canvas/nf-remote-process-group-ports.js</include>
@ -464,6 +475,20 @@
<include>${staging.dir}/js/nf/counters/nf-counters-table.js</include>
</includes>
</aggregation>
<aggregation>
<insertNewLine>true</insertNewLine>
<output>${project.build.directory}/${project.build.finalName}/js/nf/users/nf-users-all.js</output>
<includes>
<include>${staging.dir}/js/nf/nf-client.js</include>
<include>${staging.dir}/js/nf/nf-common.js</include>
<include>${staging.dir}/js/nf/nf-universal-capture.js</include>
<include>${staging.dir}/js/nf/nf-dialog.js</include>
<include>${staging.dir}/js/nf/nf-storage.js</include>
<include>${staging.dir}/js/nf/nf-ajax-setup.js</include>
<include>${staging.dir}/js/nf/users/nf-users.js</include>
<include>${staging.dir}/js/nf/users/nf-users-table.js</include>
</includes>
</aggregation>
<aggregation>
<insertNewLine>true</insertNewLine>
<output>${project.build.directory}/${project.build.finalName}/js/nf/templates/nf-templates-all.js</output>
@ -531,7 +556,7 @@
<include>${staging.dir}/css/processor-configuration.css</include>
<include>${staging.dir}/css/processor-details.css</include>
<include>${staging.dir}/css/process-group-configuration.css</include>
<include>${staging.dir}/css/process-group-details.css</include>
<include>${staging.dir}/css/policy-management.css</include>
<include>${staging.dir}/css/remote-process-group-configuration.css</include>
<include>${staging.dir}/css/port-configuration.css</include>
<include>${staging.dir}/css/port-details.css</include>
@ -609,6 +634,16 @@
<include>${staging.dir}/css/cluster.css</include>
</includes>
</aggregation>
<aggregation>
<insertNewLine>true</insertNewLine>
<output>${project.build.directory}/${project.build.finalName}/css/nf-users-all.css</output>
<includes>
<include>${staging.dir}/css/main.css</include>
<include>${staging.dir}/css/banner.css</include>
<include>${staging.dir}/css/dialog.css</include>
<include>${staging.dir}/css/users.css</include>
</includes>
</aggregation>
<aggregation>
<insertNewLine>true</insertNewLine>
<output>${project.build.directory}/${project.build.finalName}/css/nf-templates-all.css</output>
@ -673,6 +708,8 @@
css/nf-counters-all.css.gz,
css/nf-cluster-all.css,
css/nf-cluster-all.css.gz,
css/nf-users-all.css,
css/nf-users-all.css.gz,
css/nf-templates-all.css,
css/nf-templates-all.css.gz,
css/nf-bulletin-board-all.css,
@ -712,6 +749,8 @@
js/nf/counters/nf-counters-all.js.gz,
js/nf/cluster/nf-cluster-all.js,
js/nf/cluster/nf-cluster-all.js.gz,
js/nf/users/nf-users-all.js,
js/nf/users/nf-users-all.js.gz,
js/nf/templates/nf-templates-all.js,
js/nf/templates/nf-templates-all.js.gz,
js/nf/bulletin-board/nf-bulletin-board-all.js,

View File

@ -13,8 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
nf.bulletin.board.script.tags=<script type="text/javascript" src="js/nf/nf-namespace.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
nf.bulletin.board.script.tags=<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-universal-capture.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-dialog.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-storage.js?${project.version}"></script>\n\

View File

@ -13,8 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
nf.canvas.script.tags=<script type="text/javascript" src="js/nf/nf-namespace.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-client.js?${project.version}"></script>\n\
nf.canvas.script.tags=<script type="text/javascript" src="js/nf/nf-client.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-universal-capture.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/canvas/nf-canvas-utils.js?${project.version}"></script>\n\
@ -32,7 +31,7 @@ nf.canvas.script.tags=<script type="text/javascript" src="js/nf/nf-namespace.js?
<script type="text/javascript" src="js/nf/canvas/nf-processor-configuration.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-processor-details.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/canvas/nf-process-group-configuration.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/canvas/nf-process-group-details.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/canvas/nf-policy-management.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/canvas/nf-remote-process-group-configuration.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/canvas/nf-remote-process-group-details.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/canvas/nf-remote-process-group-ports.js?${project.version}"></script>\n\

View File

@ -13,8 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
nf.cluster.script.tags=<script type="text/javascript" src="js/nf/nf-namespace.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
nf.cluster.script.tags=<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-universal-capture.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-dialog.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-storage.js?${project.version}"></script>\n\

View File

@ -13,8 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
nf.counters.script.tags=<script type="text/javascript" src="js/nf/nf-namespace.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
nf.counters.script.tags=<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-universal-capture.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-dialog.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-storage.js?${project.version}"></script>\n\

View File

@ -13,8 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
nf.history.script.tags=<script type="text/javascript" src="js/nf/nf-namespace.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
nf.history.script.tags=<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-universal-capture.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-dialog.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-storage.js?${project.version}"></script>\n\

View File

@ -13,8 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
nf.provenance.script.tags=<script type="text/javascript" src="js/nf/nf-namespace.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
nf.provenance.script.tags=<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-universal-capture.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-dialog.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-storage.js?${project.version}"></script>\n\

View File

@ -13,8 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
nf.summary.script.tags=<script type="text/javascript" src="js/nf/nf-namespace.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
nf.summary.script.tags=<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-universal-capture.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-dialog.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-storage.js?${project.version}"></script>\n\

View File

@ -13,8 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
nf.templates.script.tags=<script type="text/javascript" src="js/nf/nf-namespace.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
nf.templates.script.tags=<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-universal-capture.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-dialog.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-storage.js?${project.version}"></script>\n\

View File

@ -0,0 +1,18 @@
# 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.
nf.users.script.tags=<script type="text/javascript" src="js/nf/users/nf-users-all.js?${project.version}"></script>
nf.users.style.tags=<link rel="stylesheet" href="css/nf-users-all.css?${project.version}" type="text/css" />\n\
<link rel="stylesheet" href="css/message-pane.css?${project.version}" type="text/css" />

View File

@ -0,0 +1,29 @@
# 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.
nf.users.script.tags=<script type="text/javascript" src="js/nf/nf-client.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-common.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-universal-capture.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-dialog.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-storage.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/nf-ajax-setup.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/users/nf-users.js?${project.version}"></script>\n\
<script type="text/javascript" src="js/nf/users/nf-users-table.js?${project.version}"></script>
nf.users.style.tags=<link rel="stylesheet" href="css/reset.css?${project.version}" type="text/css" />\n\
<link rel="stylesheet" href="css/main.css?${project.version}" type="text/css" />\n\
<link rel="stylesheet" href="css/banner.css?${project.version}" type="text/css" />\n\
<link rel="stylesheet" href="css/dialog.css?${project.version}" type="text/css" />\n\
<link rel="stylesheet" href="css/message-pane.css?${project.version}" type="text/css" />\n\
<link rel="stylesheet" href="css/users.css?${project.version}" type="text/css" />

View File

@ -95,6 +95,7 @@
<jsp:include page="/WEB-INF/partials/ok-dialog.jsp"/>
<jsp:include page="/WEB-INF/partials/yes-no-dialog.jsp"/>
<jsp:include page="/WEB-INF/partials/status-history-dialog.jsp"/>
<jsp:include page="/WEB-INF/partials/canvas/search-users-dialog.jsp"/>
<jsp:include page="/WEB-INF/partials/canvas/disable-controller-service-dialog.jsp"/>
<jsp:include page="/WEB-INF/partials/canvas/enable-controller-service-dialog.jsp"/>
<jsp:include page="/WEB-INF/partials/canvas/new-controller-service-dialog.jsp"/>
@ -123,6 +124,7 @@
<jsp:include page="/WEB-INF/partials/canvas/processor-configuration.jsp"/>
<jsp:include page="/WEB-INF/partials/processor-details.jsp"/>
<jsp:include page="/WEB-INF/partials/canvas/process-group-configuration.jsp"/>
<jsp:include page="/WEB-INF/partials/canvas/policy-management.jsp"/>
<jsp:include page="/WEB-INF/partials/canvas/process-group-details.jsp"/>
<jsp:include page="/WEB-INF/partials/canvas/remote-process-group-configuration.jsp"/>
<jsp:include page="/WEB-INF/partials/canvas/remote-process-group-details.jsp"/>

View File

@ -0,0 +1,70 @@
<%--
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.
--%>
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
<!DOCTYPE html>
<html>
<head>
<title>NiFi Users</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="shortcut icon" href="images/nifi16.ico"/>
<link rel="stylesheet" href="css/reset.css" type="text/css" />
${nf.users.style.tags}
<link rel="stylesheet" href="js/jquery/tabbs/jquery.tabbs.css?${project.version}" type="text/css" />
<link rel="stylesheet" href="js/jquery/combo/jquery.combo.css?${project.version}" type="text/css" />
<link rel="stylesheet" href="js/jquery/modal/jquery.modal.css?${project.version}" type="text/css" />
<link rel="stylesheet" href="js/jquery/qtip2/jquery.qtip.min.css?" type="text/css" />
<link rel="stylesheet" href="js/jquery/ui-smoothness/jquery-ui-1.10.4.min.css" type="text/css" />
<link rel="stylesheet" href="js/jquery/slickgrid/css/slick.grid.css" type="text/css" />
<link rel="stylesheet" href="js/jquery/slickgrid/css/slick-default-theme.css" type="text/css" />
<link rel="stylesheet" href="fonts/flowfont/flowfont.css" type="text/css" />
<link rel="stylesheet" href="assets/font-awesome/css/font-awesome.min.css" type="text/css" />
<script type="text/javascript" src="js/jquery/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="js/jquery/ui-smoothness/jquery-ui-1.10.4.min.js"></script>
<script type="text/javascript" src="js/jquery/jquery.base64.js"></script>
<script type="text/javascript" src="js/jquery/jquery.center.js"></script>
<script type="text/javascript" src="js/jquery/tabbs/jquery.tabbs.js?${project.version}"></script>
<script type="text/javascript" src="js/jquery/combo/jquery.combo.js?${project.version}"></script>
<script type="text/javascript" src="js/jquery/propertytable/jquery.propertytable.js?${project.version}"></script>
<script type="text/javascript" src="js/jquery/modal/jquery.modal.js?${project.version}"></script>
<script type="text/javascript" src="js/jquery/jquery.ellipsis.js"></script>
<script type="text/javascript" src="js/jquery/jquery.each.js"></script>
<script type="text/javascript" src="js/jquery/qtip2/jquery.qtip.min.js"></script>
<script type="text/javascript" src="js/jquery/jquery.event.drag-2.2.min.js"></script>
<script type="text/javascript" src="js/jquery/slickgrid/plugins/slick.cellrangeselector.js"></script>
<script type="text/javascript" src="js/jquery/slickgrid/plugins/slick.cellselectionmodel.js"></script>
<script type="text/javascript" src="js/jquery/slickgrid/plugins/slick.rowselectionmodel.js"></script>
<script type="text/javascript" src="js/jquery/slickgrid/plugins/slick.autotooltips.js"></script>
<script type="text/javascript" src="js/jquery/slickgrid/slick.formatters.js"></script>
<script type="text/javascript" src="js/jquery/slickgrid/slick.editors.js"></script>
<script type="text/javascript" src="js/jquery/slickgrid/slick.dataview.js"></script>
<script type="text/javascript" src="js/jquery/slickgrid/slick.core.js"></script>
<script type="text/javascript" src="js/jquery/slickgrid/slick.grid.js"></script>
<script type="text/javascript" src="js/nf/nf-namespace.js?${project.version}"></script>
<script type="text/javascript" src="js/nf/nf-ng-namespace.js?${project.version}"></script>
${nf.users.script.tags}
<script type="text/javascript" src="js/jquery/nfeditor/languages/nfel.js?${project.version}"></script>
<script type="text/javascript" src="js/jquery/nfeditor/jquery.nfeditor.js?${project.version}"></script>
</head>
<body ng-controller="ngSummaryAppCtrl">
<jsp:include page="/WEB-INF/partials/message-pane.jsp"/>
<jsp:include page="/WEB-INF/partials/banners-utility.jsp"/>
<jsp:include page="/WEB-INF/partials/ok-dialog.jsp"/>
<jsp:include page="/WEB-INF/partials/users/user-dialog.jsp"/>
<jsp:include page="/WEB-INF/partials/users/user-delete-dialog.jsp"/>
<jsp:include page="/WEB-INF/partials/users/users-content.jsp"/>
</body>
</html>

View File

@ -147,12 +147,19 @@
<i class="fa fa-history"></i>Flow Configuration History
</a>
</md-menu-item>
<md-menu-divider></md-menu-divider>
<md-menu-item layout-align="space-around center">
<a id="users-link" layout="row"
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.users.shell.launch();"
ng-class="{disabled: !appCtrl.nf.Common.canAccessTenants()}">
ng-class="{disabled: !appCtrl.nf.Common.canModifyTenants()}">
<i class="fa fa-users"></i>Users
<div id="has-pending-accounts" class="hidden"></div>
</a>
</md-menu-item>
<md-menu-item layout-align="space-around center">
<a id="policies-link" layout="row"
ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.policies.shell.launch();"
ng-class="{disabled: !(appCtrl.nf.Common.canAccessTenants() && appCtrl.nf.Common.canModifyPolicies())}">
<i class="fa fa-key"></i>Policies
</a>
</md-menu-item>
<md-menu-divider></md-menu-divider>

View File

@ -99,6 +99,12 @@
ng-disabled="false">
<div class="graph-control-action-icon fa fa-gear"></div></button>
</div>
<div class="button-spacer-small">&nbsp;</div>
<div id="operate-policy" class="action-button" title="Access Policies">
<button ng-click="appCtrl.nf.Actions['managePolicies'](appCtrl.nf.CanvasUtils.getSelection());"
ng-disabled="appCtrl.nf.CanvasUtils.getSelection().size() > 1">
<div class="graph-control-action-icon fa fa-key"></div></button>
</div>
<div class="button-spacer-large">&nbsp;</div>
<div id="operate-enable" class="action-button" title="Enable">
<button ng-click="appCtrl.nf.Actions['enable'](appCtrl.nf.CanvasUtils.getSelection());"

View File

@ -0,0 +1,92 @@
<%--
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.
--%>
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
<div id="policy-management">
<div id="policy-management-header-text">Access Policies</div>
<div id="policy-controls-container">
<span id="selected-policy-action" class="hidden"></span>
<span id="selected-policy-type" class="hidden"></span>
<div id="policy-message-container">
<div id="policy-message"></div>
<div id="new-policy-message" class="hidden"><span id="create-policy-link" class="link">Create</span> a new policy.</div>
<div id="override-policy-message" class="hidden"><span id="override-policy-link" class="link">Override</span> this policy.</div>
<div class="clear"></div>
</div>
<div id="global-policy-controls" class="hidden policy-controls">
<div id="policy-type-list"></div>
<div id="controller-policy-target"></div>
<div class="clear"></div>
</div>
<div id="component-policy-controls" class="hidden policy-controls">
<div id="policy-selected-component-container" class="hidden policy-selected-component-container">
<div class="policy-selected-component-type-icon">
<i class="icon icon-drop" ng-class="appCtrl.serviceProvider.graphControlsCtrl.getContextIcon()"></i>
</div>
<div class="policy-selected-component-details-container">
<div class="policy-selected-component-name">{{appCtrl.serviceProvider.graphControlsCtrl.getContextName()}}</div>
<div class="policy-selected-component-type" ng-class="appCtrl.serviceProvider.graphControlsCtrl.hide()">{{appCtrl.serviceProvider.graphControlsCtrl.getContextType()}}</div>
</div>
<div class="clear"></div>
</div>
<div id="policy-selected-template-container" class="hidden policy-selected-component-container">
<div class="policy-selected-component-type-icon">
<i class="icon icon-template"></i>
</div>
<div class="policy-selected-component-details-container">
<div class="policy-selected-component-name"></div>
<div class="policy-selected-component-type">Template</div>
</div>
<div class="clear"></div>
</div>
<div id="policy-selected-controller-service-container" class="hidden policy-selected-component-container">
<div class="policy-selected-component-type-icon">
<i class="icon icon-drop"></i>
</div>
<div class="policy-selected-component-details-container">
<div class="policy-selected-component-name"></div>
<div class="policy-selected-component-type">Controller Service</div>
</div>
<div class="clear"></div>
</div>
<div id="policy-selected-reporting-task-container" class="hidden policy-selected-component-container">
<div class="policy-selected-component-type-icon">
<i class="icon icon-drop"></i>
</div>
<div class="policy-selected-component-details-container">
<div class="policy-selected-component-name"></div>
<div class="policy-selected-component-type">Reporting Task</div>
</div>
<div class="clear"></div>
</div>
<div id="selected-policy-component-id" class="hidden"></div>
<div id="selected-policy-component-type" class="hidden"></div>
<div id="component-policy-target"></div>
<div class="clear"></div>
</div>
<button id="delete-policy-button" class="fa fa-trash policy-button"></button>
<button id="new-policy-user-button" class="fa fa-user-plus policy-button"></button>
<div class="clear"></div>
</div>
<div id="policy-table"></div>
<div id="policy-refresh-container">
<button id="policy-refresh-button" class="refresh-button pointer fa fa-refresh" title="Refresh"></button>
<div class="last-refreshed-container">
Last updated:&nbsp;<span id="policy-last-refreshed" class="last-refreshed"></span>
</div>
<div id="policy-loading-container" class="loading-container"></div>
</div>
</div>

View File

@ -0,0 +1,23 @@
<%--
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.
--%>
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
<div id="search-users-dialog" class="hidden">
<div class="dialog-content">
<input id="search-users-field" type="text" placeholder="User Identity"/>
</div>
</div>
<div id="search-users-results"></div>

View File

@ -0,0 +1,21 @@
<%--
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.
--%>
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
<div id="user-delete-dialog" class="hidden">
<div class="dialog-content">
<input type="hidden" id="user-id-delete-dialog"/>
Are you sure you want to delete the user account for '<span id="user-identity-delete-dialog"></span>'?
</div>
</div>

View File

@ -0,0 +1,48 @@
<%--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--%>
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
<div id="user-dialog" class="hidden">
<div class="dialog-content">
<div class="setting">
<div class="setting-field">
<input id="individual-radio-button" type="radio" name="userOrGroup" value="individual" checked="checked"/> Individual
<input id="group-radio-button" type="radio" name="userOrGroup" value="group" style="margin-left: 20px;"/> Group
</div>
<div class="clear"></div>
</div>
<div class="setting">
<div class="setting-name">Identity</div>
<div class="setting-field">
<span id="user-id-edit-dialog" class="hidden"></span>
<input type="text" id="user-identity-edit-dialog"/>
</div>
<div class="clear"></div>
</div>
<div id="user-groups" class="setting">
<div class="setting-name">Member of</div>
<div class="setting-field">
<ul id="available-groups" class="usersGroupsList"></ul>
</div>
<div class="clear"></div>
</div>
<div id="group-members" class="setting hidden">
<div class="setting-name">Members</div>
<div class="setting-field">
<ul id="available-users" class="usersGroupsList"></ul>
</div>
<div class="clear"></div>
</div>
</div>
</div>

View File

@ -0,0 +1,41 @@
<%--
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.
--%>
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
<div id="users">
<div id="users-header-and-filter">
<div id="users-header-text">NiFi Users</div>
</div>
<div id="users-filter-controls">
<div id="users-filter-status" class="filter-status">
Displaying&nbsp;<span id="displayed-users"></span>&nbsp;of&nbsp;<span id="total-users"></span>
</div>
<div id="users-filter-container" class="filter-container">
<input type="text" placeholder="Filter" id="users-filter" class="filter"/>
<div id="users-filter-type" class="filter-type"></div>
</div>
<button id="new-user-button" class="fa fa-user-plus"></button>
<div class="clear"></div>
</div>
<div id="users-table"></div>
</div>
<div id="users-refresh-container">
<button id="user-refresh-button" class="refresh-button pointer fa fa-refresh" title="Refresh"></button>
<div id="users-last-refreshed-container" class="last-refreshed-container">
Last updated:&nbsp;<span id="users-last-refreshed" class="value-color"></span>
</div>
<div id="users-loading-container" class="loading-container"></div>
</div>

View File

@ -18,7 +18,7 @@
@import url(processor-configuration.css);
@import url(processor-details.css);
@import url(process-group-configuration.css);
@import url(process-group-details.css);
@import url(policy-management.css);
@import url(queue-listing.css);
@import url(remote-process-group-configuration.css);
@import url(controller-service.css);

View File

@ -202,13 +202,4 @@ md-toolbar.md-small .md-toolbar-tools {
font-size: 12px;
color: #262626;
padding-right: 5px;
}
#has-pending-accounts {
background-image: url(../images/starburst.png);
width: 9px;
height: 9px;
margin-top: 3px;
margin-left: 5px;
background-color: transparent;
}

View File

@ -297,7 +297,7 @@ input::placeholder {
color: #728e9b; /*base-color*/
}
input, input[type=text], input[type=password], textarea {
input[type=text], input[type=password], textarea {
background-color: #eaeef0;
border: 1px solid #eaeef0;
font-family: Roboto, sans-serif;
@ -569,6 +569,7 @@ input.filter {
button.fa {
color: #004849;
font-size: 16px;
cursor: pointer;
}
button.icon {

View File

@ -0,0 +1,205 @@
/*
* 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.
*/
#policy-management {
display: none;
position: absolute;
top: 0px;
bottom: 0px;
left: 20px;
right: 20px;
overflow: auto;
}
#policy-management-header-text {
font-size: 18px;
font-weight: bold;
color: #728E9B;
font-family: Roboto Slab;
margin-bottom: 24px;
}
#new-policy-user-button {
margin-right: 5px;
}
button.policy-button {
float: right;
margin-top: 4px;
}
button.policy-button:disabled {
color: #CCDADB;
cursor: not-allowed;
border: 1px solid #CCDADB;
}
/*
policy message
*/
#policy-message-container {
height: 18px;
color: #775351;
font-family: Roboto;
font-size: 13px;
font-weight: 500;
}
#policy-message {
float: left;
margin-right: 4px;
}
#new-policy-message {
float: left;
}
#override-policy-message {
float: left;
}
/*
policy selection
*/
div.policy-controls {
float: left;
}
#policy-type-list {
float: left;
width: 190px;
margin-right: 3px;
border-left: 1px solid transparent;
border-right: 1px solid transparent;
}
#component-policy-target {
float: left;
width: 200px;
margin-right: 3px;
border-left: 1px solid transparent;
border-right: 1px solid transparent;
}
#controller-policy-target {
float: left;
width: 160px;
margin-right: 3px;
border-left: 1px solid transparent;
border-right: 1px solid transparent;
}
div.policy-selected-component-container {
float: left;
margin-right: 20px;
}
div.policy-selected-component-details-container {
float: left;
padding-left: 10px;
}
div.policy-selected-component-type-icon {
float: left;
}
div.policy-selected-component-type-icon i.icon {
font-size: 28px;
font-family: flowfont;
color: #ad9897;
}
div.policy-selected-component-name {
height: 14px;
font-size: 15px;
font-family: Roboto;
color: #262626;
max-width: 300px;
text-overflow: ellipsis;
overflow-x: hidden;
white-space: nowrap;
}
div.policy-selected-component-type {
font-size: 12px;
font-family: Roboto;
color: #728e9b;
margin-top: 3px;
}
/*
policy table
*/
#policy-table {
position: absolute;
top: 92px;
left: 0px;
bottom: 0px;
right: 0px;
overflow: hidden;
background-color: #fff;
}
#policy-refresh-container {
position: absolute;
bottom: 20px;
left: 0px;
height: 32px;
}
#policy-refresh-button {
float: left;
}
#policy-loading-container {
float: left;
width: 16px;
height: 16px;
background-color: transparent;
margin-top: 4px;
margin-left: 3px;
}
#policy-last-refreshed {
font-weight: bold;
}
/*
search users dialog
*/
#search-users-dialog {
width: 450px;
height: 250px;
}
#search-users-results .ui-autocomplete {
max-height: 300px;
overflow: auto;
border: 1px solid #aaaaaa;
z-index: 1351;
border-radius: 0;
}
#search-users-results .ui-menu .ui-menu-item a.ui-state-focus {
background: #D4E0E5 !important;
border: 1px solid #999999;
border-radius: 0;
}

View File

@ -0,0 +1,128 @@
/*
* 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 Styles
*/
#users {
position: absolute;
top: 0px;
bottom: 0px;
left: 20px;
right: 20px;
overflow: auto;
}
#users-header-and-filter {
height: 32px;
}
#users-header-text {
font-size: 18px;
font-weight: bold;
color: #728E9B;
font-family: Roboto Slab;
margin-bottom: 30px;
}
#users-refresh-container {
position: absolute;
left: 20px;
bottom: 0px;
}
#users-loading-container {
float: left;
width: 16px;
height: 16px;
background-color: transparent;
margin-top: 4px;
margin-left: 3px;
}
#users-last-refreshed {
font-weight: bold;
}
#users-header {
padding-top: 10px;
}
#new-user-button {
float: right;
margin-top: 4px;
}
/* users table */
#users-table {
position: absolute;
top: 92px;
left: 0px;
bottom: 0px;
right: 0px;
overflow: hidden;
background-color: #fff;
}
/* users dialog */
#user-dialog {
width: 450px;
height: 500px;
}
#user-identity {
width: 410px;
}
/* user delete dialog */
#user-delete-dialog {
width: 450px;
height: 165px;
}
/* users/groups list */
ul.usersGroupsList li {
height: 24px;
line-height: 24px;
border-bottom: 1px solid #c7d2d7;
width: 100%;
display: inline-flex;
}
ul.usersGroupsList li.even {
background-color: #f4f6f7;
}
ul.usersGroupsList li div.nf-checkbox {
margin: 0 10px;
margin-top: 6px;
min-width: 12px;
max-width: 12px;
}
div.available-identities {
margin-left: 5px;
margin-right: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

View File

@ -118,6 +118,30 @@
};
var setDisabled = function (combo, optionElement, option, disabled) {
// reset the option element
optionElement.removeClass('unset').off('click');
if (disabled === true) {
optionElement.addClass('unset');
} else {
optionElement.on('click', function () {
//remove active styles
$('.combo').removeClass('combo-open');
// select the option
selectOption(combo, option.text, option.value);
// click the glass pane which will hide the options
$('.combo-glass-pane').click();
}).hover(function () {
$(this).addClass('pointer').css('background', '#eaeef0');
}, function () {
$(this).removeClass('pointer').css('background', '#ffffff');
});
}
};
var methods = {
/**
@ -146,6 +170,8 @@
}, function () {
combo.removeClass('button-over').addClass('combo-button-normal');
}).click(function (event) {
var comboConfigOptions = combo.data('options');
//add active styles
$(this).addClass('combo-open');
@ -166,8 +192,8 @@
// set the max height if necessary
var maxHeight = -1;
if (isDefinedAndNotNull(options.maxHeight)) {
maxHeight = parseInt(options.maxHeight);
if (isDefinedAndNotNull(comboConfigOptions.maxHeight)) {
maxHeight = parseInt(comboConfigOptions.maxHeight);
if (maxHeight > 0) {
comboOptions.css('max-height', maxHeight + 'px');
}
@ -177,7 +203,7 @@
var optionList = $('<ul></ul>').appendTo(comboOptions);
// process the options
$.each(options.options, function (i, option) {
$.each(comboConfigOptions.options, function (i, option) {
var optionText = $('<span class="combo-option-text"></span>').attr('title', option.text).text(option.text);
var optionValue = $('<span class="hidden"></span>').text(option.value);
@ -297,14 +323,35 @@
});
},
/**
* Sets whether the specified option is enabled or disabled.
*
* @param option
* @param enabled
*/
setOptionEnabled: function (option, enabled) {
return this.each(function () {
var combo = $(this);
var comboConfigOptions = combo.data('options');
$.each(comboConfigOptions.options, function (i, configOption) {
if (configOption.value === option.value) {
configOption.disabled = !enabled;
}
});
});
},
/**
* Destroy's the combo.
*/
destroy: function () {
$(this).empty().unbind().removeData();
return this.each(function () {
$(this).empty().unbind().removeData();
// remove the options if open
$('div.combo-glass-pane').click();
// remove the options if open
$('div.combo-glass-pane').click();
});
}
};

View File

@ -42,7 +42,7 @@ nf.ng.BreadcrumbsCtrl = function (serviceProvider, $sanitize) {
*/
generateBreadcrumbs: function(breadcrumbEntity) {
var label = breadcrumbEntity.id;
if (breadcrumbEntity.accessPolicy.canRead) {
if (breadcrumbEntity.permissions.canRead) {
label = breadcrumbEntity.breadcrumb.name;
}

View File

@ -382,13 +382,6 @@ nf.ng.Canvas.FlowStatusCtrl = function (serviceProvider, $sanitize) {
nf.Common.isDefinedAndNotNull(status.connectedNodes) ? $sanitize(status.connectedNodes) : '-';
this.bulletins.update(status);
// handle any pending user request
if (status.hasPendingAccounts === true) {
$('#has-pending-accounts').show();
} else {
$('#has-pending-accounts').hide();
}
}
}

View File

@ -193,13 +193,34 @@ nf.ng.Canvas.GlobalMenuCtrl = function (serviceProvider) {
* Launch the users shell.
*/
launch: function () {
if (nf.Common.canAccessTenants()) {
if (nf.Common.canModifyTenants()) {
nf.Shell.showPage('users');
}
}
}
};
/**
* The policies menu item controller.
*/
this.policies = {
/**
* The policies menu item's shell controller.
*/
shell: {
/**
* Launch the policies shell.
*/
launch: function () {
if (nf.Common.canModifyPolicies() && nf.Common.canAccessTenants()) {
nf.PolicyManagement.showGlobalPolicies();
}
}
}
};
/**
* The templates menu item controller.
*/

View File

@ -215,7 +215,7 @@ nf.ng.Canvas.GraphControlsCtrl = function (serviceProvider, navigateCtrl, operat
} else {
if (selection.size() === 1) {
var d = selection.datum();
if (d.accessPolicy.canRead) {
if (d.permissions.canRead) {
if (nf.CanvasUtils.isLabel(selection)) {
if ($.trim(d.component.label) !== '') {
return d.component.label;

View File

@ -298,7 +298,7 @@ nf.ng.Canvas.OperateCtrl = function () {
}).fail(function (xhr, status, error) {
if (xhr.status === 400 || xhr.status === 404 || xhr.status === 409) {
nf.Dialog.showOkDialog({
headerText: 'Malformed Request',
headerText: 'Error',
dialogContent: nf.Common.escapeHtml(xhr.responseText)
});
}

View File

@ -173,7 +173,7 @@ nf.ng.TemplateComponent = function (serviceProvider) {
if (nf.Common.isDefinedAndNotNull(templates) && templates.length > 0) {
var options = [];
$.each(templates, function (_, templateEntity) {
if (templateEntity.accessPolicy.canRead === true) {
if (templateEntity.permissions.canRead === true) {
options.push({
text: templateEntity.template.name,
value: templateEntity.id,

View File

@ -157,7 +157,7 @@ nf.Actions = (function () {
// reload the group's connections
var connections = nf.Connection.getComponentConnections(remoteProcessGroup.id);
$.each(connections, function (_, connection) {
if (connection.accessPolicy.canRead) {
if (connection.permissions.canRead) {
nf.Connection.reload(connection.component);
}
});
@ -702,16 +702,27 @@ nf.Actions = (function () {
}
},
/**
* Opens the policy management page for the selected component.
*
* @param selection
*/
managePolicies: function(selection) {
if (selection.size() <= 1) {
nf.PolicyManagement.showComponentPolicy(selection);
}
},
// Defines an action for showing component details (like configuration but read only).
showDetails: function (selection) {
if (selection.empty()) {
nf.ProcessGroupDetails.showConfiguration(nf.Canvas.getGroupId());
nf.ProcessGroupConfiguration.showConfiguration(nf.Canvas.getGroupId());
} else if (selection.size() === 1) {
var selectionData = selection.datum();
if (nf.CanvasUtils.isProcessor(selection)) {
nf.ProcessorDetails.showDetails(nf.Canvas.getGroupId(), selectionData.id);
} else if (nf.CanvasUtils.isProcessGroup(selection)) {
nf.ProcessGroupDetails.showConfiguration(selectionData.id);
nf.ProcessGroupConfiguration.showConfiguration(selectionData.id);
} else if (nf.CanvasUtils.isRemoteProcessGroup(selection)) {
nf.RemoteProcessGroupDetails.showDetails(selection);
} else if (nf.CanvasUtils.isInputPort(selection) || nf.CanvasUtils.isOutputPort(selection)) {

View File

@ -151,7 +151,7 @@ nf.Birdseye = (function () {
$.each(components.labels, function (_, d) {
var color = nf.Label.defaultColor();
if (d.accessPolicy.canRead) {
if (d.permissions.canRead) {
// use the specified color if appropriate
if (nf.Common.isDefinedAndNotNull(d.component.style['background-color'])) {
color = d.component.style['background-color'];
@ -189,7 +189,7 @@ nf.Birdseye = (function () {
$.each(components.processors, function (_, d) {
var color = '#dde4eb';
if (d.accessPolicy.canRead) {
if (d.permissions.canRead) {
// use the specified color if appropriate
if (nf.Common.isDefinedAndNotNull(d.component.style['background-color'])) {
color = d.component.style['background-color'];

View File

@ -260,7 +260,7 @@ nf.CanvasUtils = (function () {
editable: function (selection) {
var selectionData = selection.datum();
if (selectionData.accessPolicy.canWrite && selectionData.accessPolicy.canRead) {
if (selectionData.permissions.canWrite && selectionData.permissions.canRead) {
if (!selection.classed('connectable')) {
selection.call(nf.Connectable.activate);
}
@ -888,7 +888,7 @@ nf.CanvasUtils = (function () {
canModify: function (selection) {
var selectionSize = selection.size();
var writableSize = selection.filter(function (d) {
return d.accessPolicy.canWrite && d.accessPolicy.canRead;
return d.permissions.canWrite && d.permissions.canRead;
}).size();
return selectionSize === writableSize;
@ -903,7 +903,7 @@ nf.CanvasUtils = (function () {
canRead: function (selection) {
var selectionSize = selection.size();
var readableSize = selection.filter(function (d) {
return d.accessPolicy.canRead;
return d.permissions.canRead;
}).size();
return selectionSize === readableSize;
@ -923,7 +923,7 @@ nf.CanvasUtils = (function () {
var selectionData = selection.datum();
// check access policies first
if (selectionData.accessPolicy.canRead === false || selectionData.accessPolicy.canWrite === false) {
if (selectionData.permissions.canRead === false || selectionData.permissions.canWrite === false) {
return false;
}
@ -1101,7 +1101,7 @@ nf.CanvasUtils = (function () {
if (source.empty() === false) {
var sourceData = source.datum();
if (sourceData.accessPolicy.canRead) {
if (sourceData.permissions.canRead) {
// update the source status if necessary
if (nf.CanvasUtils.isProcessor(source)) {
nf.Processor.reload(sourceData.component);
@ -1119,7 +1119,7 @@ nf.CanvasUtils = (function () {
if (destination.empty() === false) {
var destinationData = destination.datum();
if (destinationData.accessPolicy.canRead) {
if (destinationData.permissions.canRead) {
// update the destination component accordingly
if (nf.CanvasUtils.isProcessor(destination)) {
nf.Processor.reload(destinationData.component);

View File

@ -114,7 +114,7 @@ nf.Canvas = (function () {
var polling = false;
var groupId = 'root';
var groupName = null;
var accessPolicy = null;
var permissions = null;
var parentGroupId = null;
var clustered = false;
var svg = null;
@ -631,15 +631,15 @@ nf.Canvas = (function () {
// get the current group name from the breadcrumb
var breadcrumb = processGroupFlow.breadcrumb;
if (breadcrumb.accessPolicy.canRead) {
if (breadcrumb.permissions.canRead) {
nf.Canvas.setGroupName(breadcrumb.breadcrumb.name);
} else {
nf.Canvas.setGroupName(breadcrumb.id);
}
// update the access policies
accessPolicy = flowResponse.accessPolicy;
permissions = flowResponse.permissions;
// update the breadcrumbs
nf.ng.Bridge.injector.get('breadcrumbsCtrl').resetBreadcrumbs();
nf.ng.Bridge.injector.get('breadcrumbsCtrl').generateBreadcrumbs(breadcrumb);
@ -832,6 +832,7 @@ nf.Canvas = (function () {
nf.ConnectionConfiguration.init();
nf.ControllerService.init();
nf.ReportingTask.init();
nf.PolicyManagement.init();
nf.ProcessorConfiguration.init();
nf.ProcessGroupConfiguration.init();
nf.RemoteProcessGroupConfiguration.init();
@ -839,7 +840,6 @@ nf.Canvas = (function () {
nf.PortConfiguration.init();
nf.LabelConfiguration.init();
nf.ProcessorDetails.init();
nf.ProcessGroupDetails.init();
nf.PortDetails.init();
nf.ConnectionDetails.init();
nf.RemoteProcessGroupDetails.init();
@ -925,10 +925,10 @@ nf.Canvas = (function () {
* @returns {boolean} can write
*/
canRead: function () {
if (accessPolicy === null) {
if (permissions === null) {
return false;
} else {
return accessPolicy.canRead === true;
return permissions.canRead === true;
}
},
@ -938,10 +938,10 @@ nf.Canvas = (function () {
* @returns {boolean} can write
*/
canWrite: function () {
if (accessPolicy === null) {
if (permissions === null) {
return false;
} else {
return accessPolicy.canWrite === true;
return permissions.canWrite === true;
}
},

View File

@ -281,7 +281,7 @@ nf.ConnectionConfiguration = (function () {
// show the output port options
var options = [];
$.each(processGroupContents.outputPorts, function (i, outputPort) {
if (outputPort.accessPolicy.canRead && outputPort.accessPolicy.canWrite) {
if (outputPort.permissions.canRead && outputPort.permissions.canWrite) {
var component = outputPort.component;
options.push({
text: component.name,
@ -506,7 +506,7 @@ nf.ConnectionConfiguration = (function () {
// show the input port options
var options = [];
$.each(processGroupContents.inputPorts, function (i, inputPort) {
if (inputPort.accessPolicy.canRead && inputPort.accessPolicy.canWrite) {
if (inputPort.permissions.canRead && inputPort.permissions.canWrite) {
var component = inputPort.component;
options.push({
text: component.name,

View File

@ -308,7 +308,7 @@ nf.Connection = (function () {
.classed('grouped', function (d) {
var grouped = false;
if (d.accessPolicy.canRead) {
if (d.permissions.canRead) {
// if there are more than one selected relationship, mark this as grouped
if (nf.Common.isDefinedAndNotNull(d.component.selectedRelationships) && d.component.selectedRelationships.length > 1) {
grouped = true;
@ -320,7 +320,7 @@ nf.Connection = (function () {
.classed('ghost', function (d) {
var ghost = false;
if (d.accessPolicy.canRead) {
if (d.permissions.canRead) {
// if the connection has a relationship that is unavailable, mark it a ghost relationship
if (hasUnavailableRelationship(d)) {
ghost = true;
@ -333,13 +333,13 @@ nf.Connection = (function () {
// update connection path
updated.select('path.connection-path')
.classed('unauthorized', function (d) {
return d.accessPolicy.canRead === false;
return d.permissions.canRead === false;
});
// update connection behavior
updated.select('path.connection-path-selectable')
.on('dblclick', function (d) {
if (d.accessPolicy.canWrite && d.accessPolicy.canRead) {
if (d.permissions.canWrite && d.permissions.canRead) {
var position = d3.mouse(this.parentNode);
// find where to put this bend point
@ -466,7 +466,7 @@ nf.Connection = (function () {
'marker-end': function () {
var marker = 'normal';
if (d.accessPolicy.canRead) {
if (d.permissions.canRead) {
// if the connection has a relationship that is unavailable, mark it a ghost relationship
if (hasUnavailableRelationship(d)) {
marker = 'ghost';
@ -501,7 +501,7 @@ nf.Connection = (function () {
var endpoints = connection.selectAll('rect.endpoint');
var midpoints = connection.selectAll('rect.midpoint');
if (d.accessPolicy.canWrite) {
if (d.permissions.canWrite) {
// ------------------
// bends - startpoint
@ -695,7 +695,7 @@ nf.Connection = (function () {
var backgrounds = [];
var borders = [];
if (d.accessPolicy.canRead) {
if (d.permissions.canRead) {
// -----------------------
// connection label - from
@ -1087,14 +1087,14 @@ nf.Connection = (function () {
return (rowHeight * labelCount);
})
.classed('unauthorized', function () {
return d.accessPolicy.canRead === false;
return d.permissions.canRead === false;
});
connectionLabelContainer.select('rect.border')
.attr('height', function () {
return (rowHeight * labelCount);
})
.classed('unauthorized', function () {
return d.accessPolicy.canRead === false;
return d.permissions.canRead === false;
});
// update the coloring of the backgrounds
@ -1115,7 +1115,7 @@ nf.Connection = (function () {
}
});
if (d.accessPolicy.canRead) {
if (d.permissions.canRead) {
// determine whether or not to show the expiration icon
connectionLabelContainer.select('g.expiration-icon')
.classed('hidden', function () {
@ -1126,7 +1126,7 @@ nf.Connection = (function () {
});
}
if (d.accessPolicy.canWrite) {
if (d.permissions.canWrite) {
// only support dragging the label when appropriate
connectionLabelContainer.call(labelDrag);
}

View File

@ -179,7 +179,7 @@ nf.ControllerService = (function () {
// reload all dependent processors if they are currently visible
$.each(controllerService.referencingComponents, function (_, referencingComponentEntity) {
// ensure we can read the referencing component prior to reloading
if (referencingComponentEntity.accessPolicy.canRead === false) {
if (referencingComponentEntity.permissions.canRead === false) {
return;
}
@ -401,7 +401,7 @@ nf.ControllerService = (function () {
var unauthorized = $('<ul class="referencing-component-listing clear"></ul>');
$.each(referencingComponents, function (_, referencingComponentEntity) {
// check the access policy for this referencing component
if (referencingComponentEntity.accessPolicy.canRead === false || referencingComponentEntity.accessPolicy.canWrite === false) {
if (referencingComponentEntity.permissions.canRead === false || referencingComponentEntity.permissions.canWrite === false) {
var unauthorizedReferencingComponent = $('<div class="unset"></div>').text(referencingComponentEntity.id);
unauthorized.append(unauthorizedReferencingComponent);
} else {
@ -1029,7 +1029,7 @@ nf.ControllerService = (function () {
var hasUnauthorized = false;
$.each(controllerService.referencingComponents, function (_, referencingComponent) {
if (referencingComponent.accessPolicy.canRead === false || referencingComponent.accessPolicy.canWrite === false) {
if (referencingComponent.permissions.canRead === false || referencingComponent.permissions.canWrite === false) {
hasUnauthorized = true;
return false;
}
@ -1263,7 +1263,7 @@ nf.ControllerService = (function () {
var hasUnauthorized = false;
$.each(controllerService.referencingComponents, function (_, referencingComponent) {
if (referencingComponent.accessPolicy.canRead === false || referencingComponent.accessPolicy.canWrite === false) {
if (referencingComponent.permissions.canRead === false || referencingComponent.permissions.canWrite === false) {
hasUnauthorized = true;
return false;
}

View File

@ -415,7 +415,7 @@ nf.ControllerServices = (function () {
* @returns {String}
*/
var nameFormatter = function (row, cell, value, columnDef, dataContext) {
if (!dataContext.accessPolicy.canRead) {
if (!dataContext.permissions.canRead) {
return '<span class="blank">' + dataContext.id + '</span>';
}
@ -433,7 +433,7 @@ nf.ControllerServices = (function () {
* @returns {String}
*/
var typeFormatter = function (row, cell, value, columnDef, dataContext) {
if (!dataContext.accessPolicy.canRead) {
if (!dataContext.permissions.canRead) {
return '';
}
@ -492,24 +492,24 @@ nf.ControllerServices = (function () {
var initControllerServices = function (serviceTable) {
// more details formatter
var moreControllerServiceDetails = function (row, cell, value, columnDef, dataContext) {
if (!dataContext.accessPolicy.canRead) {
if (!dataContext.permissions.canRead) {
return '';
}
var markup = '<div class="pointer view-controller-service fa fa-info-circle" title="View Details" style="margin-top: 5px; float: left;" ></div>';
var markup = '<div class="pointer view-controller-service fa fa-info-circle" title="View Details" style="margin-top: 5px; margin-right: 3px;" ></div>';
// always include a button to view the usage
markup += '<div title="Usage" class="pointer controller-service-usage fa fa-book" style="margin-left: 3px; margin-top: 5px; float: left;" ></div>';
markup += '<div title="Usage" class="pointer controller-service-usage fa fa-book" style="margin-top: 5px; margin-right: 3px;" ></div>';
var hasErrors = !nf.Common.isEmpty(dataContext.component.validationErrors);
var hasBulletins = !nf.Common.isEmpty(dataContext.bulletins);
if (hasErrors) {
markup += '<div class="pointer has-errors fa fa-warning" style="margin-top: 4px; margin-left: 3px; float: left;" ></div>';
markup += '<div class="pointer has-errors fa fa-warning" style="margin-top: 4px; margin-right: 3px;" ></div>';
}
if (hasBulletins) {
markup += '<div class="has-bulletins fa fa-sticky-note-o" style="margin-top: 5px; margin-left: 5px; float: left;"></div>';
markup += '<div class="has-bulletins fa fa-sticky-note-o" style="margin-top: 5px; margin-right: 3px;"></div>';
}
if (hasErrors || hasBulletins) {
@ -520,7 +520,7 @@ nf.ControllerServices = (function () {
};
var controllerServiceStateFormatter = function (row, cell, value, columnDef, dataContext) {
if (!dataContext.accessPolicy.canRead) {
if (!dataContext.permissions.canRead) {
return '';
}
@ -553,25 +553,28 @@ nf.ControllerServices = (function () {
var controllerServiceActionFormatter = function (row, cell, value, columnDef, dataContext) {
var markup = '';
if (dataContext.accessPolicy.canRead && dataContext.accessPolicy.canWrite) {
if (dataContext.permissions.canRead && dataContext.permissions.canWrite) {
if (dataContext.component.state === 'ENABLED' || dataContext.component.state === 'ENABLING') {
markup += '<div class="pointer disable-controller-service icon icon-enable-false" title="Disable" style="margin-top: 2px;" ></div>';
markup += '<div class="pointer disable-controller-service icon icon-enable-false" title="Disable" style="margin-top: 2px; margin-right: 3px;" ></div>';
} else if (dataContext.component.state === 'DISABLED') {
markup += '<div class="pointer edit-controller-service fa fa-pencil" title="Edit" style="margin-top: 2px;" ></div>';
markup += '<div class="pointer edit-controller-service fa fa-pencil" title="Edit" style="margin-top: 2px; margin-right: 3px;" ></div>';
// if there are no validation errors allow enabling
if (nf.Common.isEmpty(dataContext.component.validationErrors)) {
markup += '<div class="pointer enable-controller-service fa fa-flash" title="Enable" style="margin-top: 2px; margin-left: 6px;"></div>';
markup += '<div class="pointer enable-controller-service fa fa-flash" title="Enable" style="margin-top: 2px; margin-right: 3px;"></div>';
}
markup += '<div class="pointer delete-controller-service fa fa-trash" title="Remove" style="margin-top: 2px; margin-left: 3px;" ></div>';
markup += '<div class="pointer delete-controller-service fa fa-trash" title="Remove" style="margin-top: 2px; margin-right: 3px;" ></div>';
}
if (dataContext.component.persistsState === true) {
markup += '<div title="View State" class="pointer view-state-controller-service fa fa-tasks" style="margin-top: 2px; margin-left: 3px;" ></div>';
markup += '<div title="View State" class="pointer view-state-controller-service fa fa-tasks" style="margin-top: 2px; margin-right: 3px;" ></div>';
}
}
// TODO - only if we can adminster policies
markup += '<div title="Access Policies" class="pointer edit-access-policies fa fa-key" style="margin-top: 2px;"></div>';
return markup;
};
@ -629,6 +632,12 @@ nf.ControllerServices = (function () {
nf.ControllerService.remove(serviceTable, controllerServiceEntity);
} else if (target.hasClass('view-state-controller-service')) {
nf.ComponentState.showState(controllerServiceEntity.component, controllerServiceEntity.state === 'DISABLED');
} else if (target.hasClass('edit-access-policies')) {
// show the policies for this service
nf.PolicyManagement.showControllerServicePolicy(controllerServiceEntity);
// close the settings dialog
$('#shell-close-button').click();
}
} else if (controllerServicesGrid.getColumns()[args.cell].id === 'moreDetails') {
if (target.hasClass('view-controller-service')) {

View File

@ -128,13 +128,13 @@ nf.Funnel = (function () {
// funnel border authorization
updated.select('rect.border')
.classed('unauthorized', function (d) {
return d.accessPolicy.canRead === false;
return d.permissions.canRead === false;
});
// funnel body authorization
updated.select('rect.body')
.classed('unauthorized', function (d) {
return d.accessPolicy.canRead === false;
return d.permissions.canRead === false;
});
updated.each(function () {

View File

@ -129,7 +129,7 @@ nf.Label = (function () {
}
})
.classed('unauthorized', function (d) {
return d.accessPolicy.canRead === false;
return d.permissions.canRead === false;
});
// update the body fill using the configured color
@ -143,7 +143,7 @@ nf.Label = (function () {
}
})
.style('fill', function (d) {
if (!d.accessPolicy.canRead) {
if (!d.permissions.canRead) {
return null;
}
@ -157,7 +157,7 @@ nf.Label = (function () {
return color;
})
.classed('unauthorized', function (d) {
return d.accessPolicy.canRead === false;
return d.permissions.canRead === false;
});
// go through each label being updated
@ -170,7 +170,7 @@ nf.Label = (function () {
// update the label
var labelText = label.select('text.label-value');
var labelPoint = label.selectAll('rect.labelpoint');
if (d.accessPolicy.canRead) {
if (d.permissions.canRead) {
// udpate the font size
labelText.attr('font-size', function () {
var fontSize = '12px';
@ -209,7 +209,7 @@ nf.Label = (function () {
// labelpoints
// -----------
if (d.accessPolicy.canWrite) {
if (d.permissions.canWrite) {
var pointData = [
{x: d.dimensions.width, y: d.dimensions.height}
];

View File

@ -159,7 +159,7 @@ nf.Port = (function () {
// only activate dragging and connecting if appropriate
port.filter(function (d) {
return d.accessPolicy.canWrite && d.accessPolicy.canRead;
return d.permissions.canWrite && d.permissions.canRead;
}).call(nf.Draggable.activate).call(nf.Connectable.activate);
};
@ -176,13 +176,13 @@ nf.Port = (function () {
// port border authorization
updated.select('rect.border')
.classed('unauthorized', function (d) {
return d.accessPolicy.canRead === false;
return d.permissions.canRead === false;
});
// port body authorization
updated.select('rect.body')
.classed('unauthorized', function (d) {
return d.accessPolicy.canRead === false;
return d.permissions.canRead === false;
});
updated.each(function (portData) {
@ -262,7 +262,7 @@ nf.Port = (function () {
});
}
if (portData.accessPolicy.canRead) {
if (portData.permissions.canRead) {
// update the port name
port.select('text.port-name')
.each(function (d) {
@ -291,7 +291,7 @@ nf.Port = (function () {
// populate the stats
port.call(updatePortStatus);
} else {
if (portData.accessPolicy.canRead) {
if (portData.permissions.canRead) {
// update the port name
port.select('text.port-name')
.text(function (d) {
@ -364,7 +364,7 @@ nf.Port = (function () {
}
// if there are validation errors generate a tooltip
if (d.accessPolicy.canRead && !nf.Common.isEmpty(d.component.validationErrors)) {
if (d.permissions.canRead && !nf.Common.isEmpty(d.component.validationErrors)) {
tip = d3.select('#port-tooltips').append('div')
.attr('id', function () {
return 'run-status-tip-' + d.id;

View File

@ -74,7 +74,7 @@ nf.ProcessGroupConfiguration = (function () {
contentType: 'application/json'
}).done(function (response) {
// refresh the process group if necessary
if (response.accessPolicy.canRead && response.component.parentGroupId === nf.Canvas.getGroupId()) {
if (response.permissions.canRead && response.component.parentGroupId === nf.Canvas.getGroupId()) {
nf.ProcessGroup.set(response);
}
@ -122,7 +122,7 @@ nf.ProcessGroupConfiguration = (function () {
url: config.urls.api + '/process-groups/' + encodeURIComponent(groupId),
dataType: 'json'
}).done(function (response) {
if (response.accessPolicy.canWrite) {
if (response.permissions.canWrite) {
var processGroup = response.component;
// populate the process group settings
@ -137,7 +137,7 @@ nf.ProcessGroupConfiguration = (function () {
saveConfiguration(response.revision.version, response.id);
});
} else {
if (response.accessPolicy.canRead) {
if (response.permissions.canRead) {
// populate the process group settings
$('#read-only-process-group-name').removeClass('unset').text(response.component.name);
$('#read-only-process-group-comments').removeClass('unset').text(response.component.comments);

View File

@ -1,68 +0,0 @@
/*
* 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.
*/
/* global nf */
nf.ProcessGroupDetails = (function () {
return {
init: function () {
// configure the processor details dialog
$('#process-group-details').modal({
scrollableContentStyle: 'scrollable',
headerText: 'Process Group Details',
buttons: [{
buttonText: 'Ok',
color: {
base: '#728E9B',
hover: '#004849',
text: '#ffffff'
},
handler: {
click: function () {
// hide the dialog
$('#process-group-details').modal('hide');
}
}
}],
handler: {
close: function () {
// clear the processor details
nf.Common.clearField('read-only-process-group-id');
nf.Common.clearField('read-only-process-group-name');
nf.Common.clearField('read-only-process-group-comments');
}
}
});
},
showDetails: function (selection) {
// if the specified selection is a process group
if (nf.CanvasUtils.isProcessGroup(selection)) {
var selectionData = selection.datum();
// populate the port settings
nf.Common.populateField('read-only-process-group-id', selectionData.id);
nf.Common.populateField('read-only-process-group-name', selectionData.component.name);
nf.Common.populateField('read-only-process-group-comments', selectionData.component.comments);
// show the details
$('#process-group-details').modal('show');
}
}
};
}());

View File

@ -157,7 +157,7 @@ nf.ProcessGroup = (function () {
// only support dragging, connection, and drag and drop if appropriate
processGroup.filter(function (d) {
return d.accessPolicy.canWrite && d.accessPolicy.canRead;
return d.permissions.canWrite && d.permissions.canRead;
})
.on('mouseover.drop', function (d) {
// Using mouseover/out to workaround chrome issue #122746
@ -210,13 +210,13 @@ nf.ProcessGroup = (function () {
// process group border authorization
updated.select('rect.border')
.classed('unauthorized', function (d) {
return d.accessPolicy.canRead === false;
return d.permissions.canRead === false;
});
// process group body authorization
updated.select('rect.body')
.classed('unauthorized', function (d) {
return d.accessPolicy.canRead === false;
return d.permissions.canRead === false;
});
updated.each(function (processGroupData) {
@ -742,7 +742,7 @@ nf.ProcessGroup = (function () {
return stoppedX + stoppedCount.node().getComputedTextLength() + CONTENTS_SPACER;
})
.classed('has-validation-errors', function (d) {
return d.accessPolicy.canRead && d.component.invalidCount > 0;
return d.permissions.canRead && d.component.invalidCount > 0;
});
var invalidCount = details.select('text.process-group-invalid-count')
.attr('x', function () {
@ -768,7 +768,7 @@ nf.ProcessGroup = (function () {
return d.disabledCount;
});
if (processGroupData.accessPolicy.canRead) {
if (processGroupData.permissions.canRead) {
// update the process group comments
details.select('text.process-group-comments')
.each(function (d) {
@ -812,7 +812,7 @@ nf.ProcessGroup = (function () {
// populate the stats
processGroup.call(updateProcessGroupStatus);
} else {
if (processGroupData.accessPolicy.canRead) {
if (processGroupData.permissions.canRead) {
// update the process group name
processGroup.select('text.process-group-name')
.text(function (d) {

Some files were not shown because too many files have changed in this diff Show More