This is an automated email from the ASF dual-hosted git repository.
kdoran pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi-registry.git
The following commit(s) were added to refs/heads/master by this push:
new 461219c NIFIREG-212 Separating proxy into Read, Write, and Delete so
some proxies can be set to read-only
461219c is described below
commit 461219c7d980533830947ab37b8fd6eecb1432c7
Author: Bryan Bende <[email protected]>
AuthorDate: Fri May 31 10:26:41 2019 -0400
NIFIREG-212 Separating proxy into Read, Write, and Delete so some proxies
can be set to read-only
This closes #194.
Signed-off-by: Kevin Doran <[email protected]>
---
.../src/main/asciidoc/administration-guide.adoc | 12 ++++-
.../file/FileAccessPolicyProvider.java | 8 ++-
.../x509/X509AuthenticationRequestDetails.java | 40 +++++++++++++++
.../x509/X509IdentityAuthenticationProvider.java | 60 +++++++++++++++++++---
.../authentication/x509/X509IdentityProvider.java | 5 +-
.../apache/nifi/registry/web/api/SecureFileIT.java | 2 +-
.../nifi/registry/web/api/SecureKerberosIT.java | 2 +-
.../apache/nifi/registry/web/api/SecureLdapIT.java | 4 +-
.../web/api/SecureNiFiRegistryClientIT.java | 2 +-
.../manage-group/nf-registry-manage-group.html | 22 +++++++-
.../manage-user/nf-registry-manage-user.html | 22 +++++++-
.../main/webapp/services/nf-registry.service.js | 2 +-
12 files changed, 159 insertions(+), 22 deletions(-)
diff --git
a/nifi-registry-core/nifi-registry-docs/src/main/asciidoc/administration-guide.adoc
b/nifi-registry-core/nifi-registry-docs/src/main/asciidoc/administration-guide.adoc
index 2193734..75c6f15 100644
---
a/nifi-registry-core/nifi-registry-docs/src/main/asciidoc/administration-guide.adoc
+++
b/nifi-registry-core/nifi-registry-docs/src/main/asciidoc/administration-guide.adoc
@@ -686,10 +686,18 @@ Special privilege policies govern the following system
level authorizations:
| Allows users to delete policies
| `resource="/policies" action="D"`
-| Can Proxy Requests
-| Allows users to proxy requests
+| Can Proxy Requests (Read)
+| Allows users to proxy read requests (GET)
+| `resource="/proxy" action="R"`
+
+| Can Proxy Requests (Write)
+| Allows users to proxy write requests (POST, PUT, PATCH)
| `resource="/proxy" action="W"`
+| Can Proxy Requests (Delete)
+| Allows users to proxy delete requests (DELETE)
+| `resource="/proxy" action="D"`
+
| View Swagger
| Allows users to access the self-hosted Swagger UI
| `resource="/swagger" action="R"`
diff --git
a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/file/FileAccessPolicyProvider.java
b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/file/FileAccessPolicyProvider.java
index c3434c4..5eb1874 100644
---
a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/file/FileAccessPolicyProvider.java
+++
b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/file/FileAccessPolicyProvider.java
@@ -131,14 +131,18 @@ public class FileAccessPolicyProvider implements
ConfigurableAccessPolicyProvide
new ResourceActionPair("/swagger", READ_CODE),
new ResourceActionPair("/swagger", WRITE_CODE),
new ResourceActionPair("/swagger", DELETE_CODE),
- new ResourceActionPair("/proxy", WRITE_CODE)
+ new ResourceActionPair("/proxy", READ_CODE),
+ new ResourceActionPair("/proxy", WRITE_CODE),
+ new ResourceActionPair("/proxy", DELETE_CODE)
};
/* TODO - move this somewhere into nifi-registry-security-framework so it
can be applied to any ConfigurableAccessPolicyProvider
* (and also gets us away from requiring magic strings here) */
private static final ResourceActionPair[] NIFI_ACCESS_POLICIES = {
new ResourceActionPair("/buckets", READ_CODE),
- new ResourceActionPair("/proxy", WRITE_CODE)
+ new ResourceActionPair("/proxy", READ_CODE),
+ new ResourceActionPair("/proxy", WRITE_CODE),
+ new ResourceActionPair("/proxy", DELETE_CODE)
};
static final String PROP_NIFI_IDENTITY_PREFIX = "NiFi Identity ";
diff --git
a/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/authentication/x509/X509AuthenticationRequestDetails.java
b/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/authentication/x509/X509AuthenticationRequestDetails.java
new file mode 100644
index 0000000..aa24cd6
--- /dev/null
+++
b/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/authentication/x509/X509AuthenticationRequestDetails.java
@@ -0,0 +1,40 @@
+/*
+ * 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.registry.web.security.authentication.x509;
+
+import java.util.Objects;
+
+public class X509AuthenticationRequestDetails {
+
+ private final String proxiedEntitiesChain;
+
+ private final String httpMethod;
+
+ public X509AuthenticationRequestDetails(final String proxiedEntitiesChain,
final String httpMethod) {
+ this.proxiedEntitiesChain = proxiedEntitiesChain;
+ this.httpMethod = Objects.requireNonNull(httpMethod);
+ }
+
+ public String getProxiedEntitiesChain() {
+ return proxiedEntitiesChain;
+ }
+
+ public String getHttpMethod() {
+ return httpMethod;
+ }
+
+}
diff --git
a/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/authentication/x509/X509IdentityAuthenticationProvider.java
b/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/authentication/x509/X509IdentityAuthenticationProvider.java
index aefdd5b..9d724ac 100644
---
a/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/authentication/x509/X509IdentityAuthenticationProvider.java
+++
b/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/authentication/x509/X509IdentityAuthenticationProvider.java
@@ -35,6 +35,9 @@ import
org.apache.nifi.registry.security.authorization.user.NiFiUserDetails;
import org.apache.nifi.registry.security.authorization.user.StandardNiFiUser;
import org.apache.nifi.registry.security.util.ProxiedEntitiesUtils;
import
org.apache.nifi.registry.web.security.authentication.exception.UntrustedProxyException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpMethod;
import java.util.List;
import java.util.ListIterator;
@@ -42,6 +45,8 @@ import java.util.Set;
public class X509IdentityAuthenticationProvider extends
IdentityAuthenticationProvider {
+ private static final Logger LOGGER =
LoggerFactory.getLogger(X509IdentityAuthenticationProvider.class);
+
private static final Authorizable PROXY_AUTHORIZABLE = new Authorizable() {
@Override
public Authorizable getParentAuthorizable() {
@@ -63,12 +68,16 @@ public class X509IdentityAuthenticationProvider extends
IdentityAuthenticationPr
AuthenticationRequestToken requestToken,
AuthenticationResponse response) {
- AuthenticationRequest authenticationRequest =
requestToken.getAuthenticationRequest();
+ final AuthenticationRequest authenticationRequest =
requestToken.getAuthenticationRequest();
+
+ final Object requestDetails = authenticationRequest.getDetails();
+ if (requestDetails == null || !(requestDetails instanceof
X509AuthenticationRequestDetails)) {
+ throw new IllegalStateException("Invalid request details
specified");
+ }
- String proxiedEntitiesChain = authenticationRequest.getDetails() !=
null
- ? (String)authenticationRequest.getDetails()
- : null;
+ final X509AuthenticationRequestDetails x509RequestDetails =
(X509AuthenticationRequestDetails) authenticationRequest.getDetails();
+ final String proxiedEntitiesChain =
x509RequestDetails.getProxiedEntitiesChain();
if (StringUtils.isBlank(proxiedEntitiesChain)) {
return super.buildAuthenticatedToken(requestToken, response);
}
@@ -77,6 +86,10 @@ public class X509IdentityAuthenticationProvider extends
IdentityAuthenticationPr
final List<String> proxyChain =
ProxiedEntitiesUtils.tokenizeProxiedEntitiesChain(proxiedEntitiesChain);
proxyChain.add(response.getIdentity());
+ final String httpMethodStr =
x509RequestDetails.getHttpMethod().toUpperCase();
+ final HttpMethod httpMethod = HttpMethod.resolve(httpMethodStr);
+ LOGGER.debug("HTTP method is {}", new Object[]{httpMethod});
+
// add the chain as appropriate to each proxy
NiFiUser proxy = null;
for (final ListIterator<String> chainIter =
proxyChain.listIterator(proxyChain.size()); chainIter.hasPrevious(); ) {
@@ -97,16 +110,47 @@ public class X509IdentityAuthenticationProvider extends
IdentityAuthenticationPr
proxy = createUser(identity, groups, proxy, clientAddress,
isAnonymous);
if (chainIter.hasPrevious()) {
- try {
- PROXY_AUTHORIZABLE.authorize(authorizer,
RequestAction.WRITE, proxy);
- } catch (final AccessDeniedException e) {
- throw new UntrustedProxyException(String.format("Untrusted
proxy [%s].", identity));
+ switch (httpMethod) {
+ case POST:
+ case PUT:
+ case PATCH:
+ authorizeWrite(proxy);
+ break;
+ case DELETE:
+ authorizeDelete(proxy);
+ break;
+ default:
+ authorizeRead(proxy);
+ break;
}
}
}
return new AuthenticationSuccessToken(new NiFiUserDetails(proxy));
+ }
+
+ private void authorizeRead(final NiFiUser proxy) {
+ try {
+ PROXY_AUTHORIZABLE.authorize(authorizer, RequestAction.READ,
proxy);
+ } catch (final AccessDeniedException e) {
+ throw new UntrustedProxyException(String.format("Untrusted proxy
for read operation [%s].", proxy.getIdentity()));
+ }
+ }
+
+ private void authorizeWrite(final NiFiUser proxy) {
+ try {
+ PROXY_AUTHORIZABLE.authorize(authorizer, RequestAction.WRITE,
proxy);
+ } catch (final AccessDeniedException e) {
+ throw new UntrustedProxyException(String.format("Untrusted proxy
for write operation [%s].", proxy.getIdentity()));
+ }
+ }
+ private void authorizeDelete(final NiFiUser proxy) {
+ try {
+ PROXY_AUTHORIZABLE.authorize(authorizer, RequestAction.DELETE,
proxy);
+ } catch (final AccessDeniedException e) {
+ throw new UntrustedProxyException(String.format("Untrusted proxy
for delete operation [%s].", proxy.getIdentity()));
+ }
}
/**
diff --git
a/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/authentication/x509/X509IdentityProvider.java
b/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/authentication/x509/X509IdentityProvider.java
index 2a1856e..fc74f66 100644
---
a/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/authentication/x509/X509IdentityProvider.java
+++
b/nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/security/authentication/x509/X509IdentityProvider.java
@@ -113,9 +113,10 @@ public class X509IdentityProvider implements
IdentityProvider {
final String principal = certificatePrincipal.toString();
// extract the proxiedEntitiesChain header value from the
servletRequest
- String proxiedEntitiesChainHeader =
servletRequest.getHeader(ProxiedEntitiesUtils.PROXY_ENTITIES_CHAIN);
+ final String proxiedEntitiesChainHeader =
servletRequest.getHeader(ProxiedEntitiesUtils.PROXY_ENTITIES_CHAIN);
+ final X509AuthenticationRequestDetails details = new
X509AuthenticationRequestDetails(proxiedEntitiesChainHeader,
servletRequest.getMethod());
- return new AuthenticationRequest(principal, certificates[0],
proxiedEntitiesChainHeader);
+ return new AuthenticationRequest(principal, certificates[0], details);
}
diff --git
a/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureFileIT.java
b/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureFileIT.java
index 67cb2e2..095d258 100644
---
a/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureFileIT.java
+++
b/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureFileIT.java
@@ -65,7 +65,7 @@ public class SecureFileIT extends IntegrationTestBase {
"\"buckets\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"tenants\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"policies\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
-
"\"proxy\":{\"canRead\":false,\"canWrite\":true,\"canDelete\":false}}" +
+
"\"proxy\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}}" +
"}";
// When: the /access endpoint is queried
diff --git
a/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureKerberosIT.java
b/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureKerberosIT.java
index 8d8ea97..de87fcf 100644
---
a/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureKerberosIT.java
+++
b/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureKerberosIT.java
@@ -195,7 +195,7 @@ public class SecureKerberosIT extends IntegrationTestBase {
"\"buckets\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"tenants\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"policies\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
-
"\"proxy\":{\"canRead\":false,\"canWrite\":true,\"canDelete\":false}}" +
+
"\"proxy\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}}" +
"}";
// When: the /access endpoint is queried using a JWT for the kerberos
user
diff --git
a/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureLdapIT.java
b/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureLdapIT.java
index 543ea87..11d7b33 100644
---
a/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureLdapIT.java
+++
b/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureLdapIT.java
@@ -256,7 +256,7 @@ public class SecureLdapIT extends IntegrationTestBase {
"\"buckets\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"tenants\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"policies\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
-
"\"proxy\":{\"canRead\":false,\"canWrite\":true,\"canDelete\":false}}" +
+
"\"proxy\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}}" +
"}";
// When: the /access endpoint is queried using a JWT for the nifiadmin
LDAP user
@@ -284,7 +284,7 @@ public class SecureLdapIT extends IntegrationTestBase {
"\"buckets\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"tenants\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"policies\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
-
"\"proxy\":{\"canRead\":false,\"canWrite\":true,\"canDelete\":false}}}," +
+
"\"proxy\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}}}," +
"{\"identity\":\"euler\",\"userGroups\":[{\"identity\":\"mathematicians\"}],\"accessPolicies\":[],\"configurable\":false},"
+
"{\"identity\":\"euclid\",\"userGroups\":[{\"identity\":\"mathematicians\"}],\"accessPolicies\":[],\"configurable\":false},"
+
"{\"identity\":\"boyle\",\"userGroups\":[{\"identity\":\"chemists\"}],\"accessPolicies\":[],\"configurable\":false},"
+
diff --git
a/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureNiFiRegistryClientIT.java
b/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureNiFiRegistryClientIT.java
index cb14b90..62aa098 100644
---
a/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureNiFiRegistryClientIT.java
+++
b/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/SecureNiFiRegistryClientIT.java
@@ -97,7 +97,7 @@ public class SecureNiFiRegistryClientIT extends
IntegrationTestBase {
Assert.assertEquals(fullAccess,
currentUser.getResourcePermissions().getBuckets());
Assert.assertEquals(fullAccess,
currentUser.getResourcePermissions().getTenants());
Assert.assertEquals(fullAccess,
currentUser.getResourcePermissions().getPolicies());
- Assert.assertEquals(new Permissions().withCanWrite(true),
currentUser.getResourcePermissions().getProxy());
+ Assert.assertEquals(new
Permissions().withCanWrite(true).withCanRead(true).withCanDelete(true),
currentUser.getResourcePermissions().getProxy());
}
@Test
diff --git
a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.html
b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.html
index 8317ee2..31eade4 100644
---
a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.html
+++
b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.html
@@ -128,12 +128,32 @@ limitations under the License.
</mat-checkbox>
</div>
<mat-checkbox [disabled]="!canEditSpecialPrivileges()"
-
[checked]="nfRegistryService.group.resourcePermissions.proxy.canWrite"
+
[checked]="nfRegistryService.group.resourcePermissions.proxy.canRead &&
nfRegistryService.group.resourcePermissions.proxy.canWrite &&
nfRegistryService.group.resourcePermissions.proxy.canDelete"
(change)="toggleGroupManageProxyPrivileges($event)">
<span class="description">Can proxy user requests<i
matTooltip="Allow a connected system (e.g., NiFi) to
process requests of authorized users of that system."
class="pad-left-sm fa fa-question-circle-o
help-icon"></i></span>
</mat-checkbox>
+ <div flex fxLayout="row" fxLayoutAlign="space-around center">
+ <mat-checkbox class="pad-left-md"
+ [disabled]="!canEditSpecialPrivileges()"
+
[(checked)]="nfRegistryService.group.resourcePermissions.proxy.canRead"
+
(change)="toggleGroupManageProxyPrivileges($event, 'read')">
+ <span class="description">Read</span>
+ </mat-checkbox>
+ <mat-checkbox class="pad-left-md"
+ [disabled]="!canEditSpecialPrivileges()"
+
[(checked)]="nfRegistryService.group.resourcePermissions.proxy.canWrite"
+
(change)="toggleGroupManageProxyPrivileges($event, 'write')">
+ <span class="description">Write</span>
+ </mat-checkbox>
+ <mat-checkbox class="pad-left-md"
+ [disabled]="!canEditSpecialPrivileges()"
+
[(checked)]="nfRegistryService.group.resourcePermissions.proxy.canDelete"
+
(change)="toggleGroupManageProxyPrivileges($event, 'delete')">
+ <span class="description">Delete</span>
+ </mat-checkbox>
+ </div>
</div>
<mat-button-toggle-group name="nifi-registry-manage-group-perspective"
class="pad-left-md tab-toggle-group">
<mat-button-toggle [checked]="manageGroupPerspective ===
'membership'"
diff --git
a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-user/nf-registry-manage-user.html
b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-user/nf-registry-manage-user.html
index 409dbd0..2b0a505 100644
---
a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-user/nf-registry-manage-user.html
+++
b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-user/nf-registry-manage-user.html
@@ -134,12 +134,32 @@ limitations under the License.
</div>
<mat-checkbox
[disabled]="!canEditSpecialPrivileges()"
-
[checked]="nfRegistryService.user.resourcePermissions.proxy.canWrite"
+
[checked]="nfRegistryService.user.resourcePermissions.proxy.canRead &&
nfRegistryService.user.resourcePermissions.proxy.canWrite &&
nfRegistryService.user.resourcePermissions.proxy.canDelete"
(change)="toggleUserManageProxyPrivileges($event)">
<span class="description">Can proxy user requests<i
matTooltip="Allow a connected system (e.g., NiFi) to
process requests of authorized users of that system."
class="pad-left-sm fa fa-question-circle-o
help-icon"></i></span>
</mat-checkbox>
+ <div flex fxLayout="row" fxLayoutAlign="space-around center">
+ <mat-checkbox class="pad-left-md"
+ [disabled]="!canEditSpecialPrivileges()"
+
[(checked)]="nfRegistryService.user.resourcePermissions.proxy.canRead"
+
(change)="toggleUserManageProxyPrivileges($event, 'read')">
+ <span class="description">Read</span>
+ </mat-checkbox>
+ <mat-checkbox class="pad-left-md"
+ [disabled]="!canEditSpecialPrivileges()"
+
[(checked)]="nfRegistryService.user.resourcePermissions.proxy.canWrite"
+
(change)="toggleUserManageProxyPrivileges($event, 'write')">
+ <span class="description">Write</span>
+ </mat-checkbox>
+ <mat-checkbox class="pad-left-md"
+ [disabled]="!canEditSpecialPrivileges()"
+
[(checked)]="nfRegistryService.user.resourcePermissions.proxy.canDelete"
+
(change)="toggleUserManageProxyPrivileges($event, 'delete')">
+ <span class="description">Delete</span>
+ </mat-checkbox>
+ </div>
</div>
<mat-button-toggle-group name="nifi-registry-manage-user-perspective"
class="pad-left-md tab-toggle-group">
<mat-button-toggle [checked]="manageUserPerspective ===
'membership'"
diff --git
a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.js
b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.js
index 5395acd..060c8dd 100644
---
a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.js
+++
b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.js
@@ -194,7 +194,7 @@ function NfRegistryService(nfRegistryApi, nfStorage,
tdDataTableService, router,
// model for proxy privileges
this.PROXY_PRIVS = {
- '/proxy': ['write']
+ '/proxy': ['read', 'write', 'delete']
};
//<editor-fold desc="application state objects">