Skip to content

Commit f30f877

Browse files
NIFI-15875 Standardize Authorization for Verify Configuration Methods (#11179)
* NIFI-15875 Standardized Authorization for Verify Configuration Methods - Added AuthorizeConfigVerification class for shared component authorization handling * NIFI-15875 Added Parameter Reference authorization
1 parent 0574c82 commit f30f877

7 files changed

Lines changed: 266 additions & 39 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.nifi.authorization;
18+
19+
import org.apache.nifi.authorization.resource.Authorizable;
20+
import org.apache.nifi.authorization.user.NiFiUser;
21+
import org.apache.nifi.authorization.user.NiFiUserUtils;
22+
import org.apache.nifi.parameter.ParameterContext;
23+
24+
import java.util.Map;
25+
26+
/**
27+
* Authorizes configuration-verification requests for any component type that supports verification.
28+
* Requires WRITE on the target component, plus READ on any Controller Services referenced by
29+
* the proposed properties.
30+
*/
31+
public final class AuthorizeConfigVerification {
32+
33+
private AuthorizeConfigVerification() {
34+
}
35+
36+
/**
37+
* Authorize a configuration-verification request against a single ComponentAuthorizable
38+
*
39+
* @param authorizer Authorizer used for determining results
40+
* @param lookup Authorizable Lookup used to resolve referenced Controller Services
41+
* @param component Component whose configuration is being verified
42+
* @param proposedProperties Properties submitted for verification
43+
*/
44+
public static void authorize(
45+
final Authorizer authorizer,
46+
final AuthorizableLookup lookup,
47+
final ComponentAuthorizable component,
48+
final Map<String, String> proposedProperties
49+
) {
50+
authorize(authorizer, lookup, component, proposedProperties, null);
51+
}
52+
53+
/**
54+
* Authorize a configuration-verification request against a single ComponentAuthorizable with an optional ancestor
55+
*
56+
* @param authorizer Authorizer used for determining results
57+
* @param lookup Authorizable Lookup used to resolve referenced Controller Services
58+
* @param component Component whose configuration is being verified
59+
* @param proposedProperties Properties submitted for verification
60+
* @param ancestor optional parent Authorizable that must also be authorized
61+
*/
62+
public static void authorize(
63+
final Authorizer authorizer,
64+
final AuthorizableLookup lookup,
65+
final ComponentAuthorizable component,
66+
final Map<String, String> proposedProperties,
67+
final Authorizable ancestor
68+
) {
69+
final NiFiUser user = NiFiUserUtils.getNiFiUser();
70+
71+
if (ancestor != null) {
72+
ancestor.authorize(authorizer, RequestAction.WRITE, user);
73+
}
74+
75+
component.getAuthorizable().authorize(authorizer, RequestAction.WRITE, user);
76+
77+
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(proposedProperties, component, authorizer, lookup);
78+
79+
final ParameterContext parameterContext = component.getParameterContext();
80+
if (parameterContext != null) {
81+
AuthorizeParameterReference.authorizeParameterReferences(proposedProperties, authorizer, parameterContext, user);
82+
}
83+
}
84+
}

nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import jakarta.ws.rs.core.StreamingOutput;
4242
import org.apache.commons.lang3.StringUtils;
4343
import org.apache.nifi.authorization.AuthorizeComponentReference;
44+
import org.apache.nifi.authorization.AuthorizeConfigVerification;
4445
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
4546
import org.apache.nifi.authorization.Authorizer;
4647
import org.apache.nifi.authorization.ComponentAuthorizable;
@@ -1252,7 +1253,9 @@ public Response analyzeFlowAnalysisRuleConfiguration(
12521253
"issuing a GET request to /flow-analysis-rules/{taskId}/verification-requests/{requestId}. Once the request is completed, the client is expected to issue a DELETE request to " +
12531254
"/flow-analysis-rules/{serviceId}/verification-requests/{requestId}.",
12541255
security = {
1255-
@SecurityRequirement(name = "Read - /flow-analysis-rules/{uuid}")
1256+
@SecurityRequirement(name = "Write - /controller"),
1257+
@SecurityRequirement(name = "Write - /flow-analysis-rules/{uuid}"),
1258+
@SecurityRequirement(name = "Read - any referenced Controller Services - /controller-services/{uuid}")
12561259
}
12571260
)
12581261
public Response submitFlowAnalysisRuleConfigVerificationRequest(
@@ -1286,7 +1289,7 @@ public Response submitFlowAnalysisRuleConfigVerificationRequest(
12861289
return withWriteLock(
12871290
serviceFacade,
12881291
flowAnalysisRuleConfigRequest,
1289-
lookup -> authorizeController(RequestAction.READ),
1292+
lookup -> AuthorizeConfigVerification.authorize(authorizer, lookup, lookup.getFlowAnalysisRule(flowAnalysisRuleId), requestDto.getProperties(), lookup.getController()),
12901293
() -> serviceFacade.verifyCanVerifyFlowAnalysisRuleConfig(flowAnalysisRuleId),
12911294
entity -> performAsyncFlowAnalysisRuleConfigVerification(entity, user)
12921295
);
@@ -1596,7 +1599,8 @@ public Response analyzeFlowRegistryClientConfiguration(
15961599
+ "/controller/registry-clients/{clientId}/config/verification-requests/{requestId} for status and "
15971600
+ "DELETE the request once verification completes.",
15981601
security = {
1599-
@SecurityRequirement(name = "Read - /controller")
1602+
@SecurityRequirement(name = "Write - /controller/registry-clients/{uuid}"),
1603+
@SecurityRequirement(name = "Read - any referenced Controller Services - /controller-services/{uuid}")
16001604
}
16011605
)
16021606
public Response submitRegistryClientConfigVerificationRequest(
@@ -1630,10 +1634,7 @@ public Response submitRegistryClientConfigVerificationRequest(
16301634
return withWriteLock(
16311635
serviceFacade,
16321636
registryClientConfigRequest,
1633-
lookup -> {
1634-
final Authorizable authorizable = lookup.getFlowRegistryClient(registryClientId).getAuthorizable();
1635-
authorizable.authorize(authorizer, RequestAction.READ, user);
1636-
},
1637+
lookup -> AuthorizeConfigVerification.authorize(authorizer, lookup, lookup.getFlowRegistryClient(registryClientId), requestDto.getProperties()),
16371638
() -> serviceFacade.verifyCanVerifyFlowRegistryClientConfig(registryClientId),
16381639
entity -> performAsyncRegistryClientConfigVerification(entity, user)
16391640
);

nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import jakarta.ws.rs.core.Response;
4141
import org.apache.commons.lang3.StringUtils;
4242
import org.apache.nifi.authorization.AuthorizeComponentReference;
43+
import org.apache.nifi.authorization.AuthorizeConfigVerification;
4344
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
4445
import org.apache.nifi.authorization.Authorizer;
4546
import org.apache.nifi.authorization.ComponentAuthorizable;
@@ -993,7 +994,8 @@ public Response analyzeConfiguration(
993994
"issuing a GET request to /controller-services/{serviceId}/verification-requests/{requestId}. Once the request is completed, the client is expected to issue a DELETE request to " +
994995
"/controller-services/{serviceId}/verification-requests/{requestId}.",
995996
security = {
996-
@SecurityRequirement(name = "Read - /controller-services/{uuid}")
997+
@SecurityRequirement(name = "Write - /controller-services/{uuid}"),
998+
@SecurityRequirement(name = "Read - any referenced Controller Services - /controller-services/{uuid}")
997999
}
9981000
)
9991001
public Response submitConfigVerificationRequest(
@@ -1027,13 +1029,8 @@ public Response submitConfigVerificationRequest(
10271029
return withWriteLock(
10281030
serviceFacade,
10291031
controllerServiceConfigRequest,
1030-
lookup -> {
1031-
final ComponentAuthorizable controllerService = lookup.getControllerService(controllerServiceId);
1032-
controllerService.getAuthorizable().authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
1033-
},
1034-
() -> {
1035-
serviceFacade.verifyCanVerifyControllerServiceConfig(controllerServiceId);
1036-
},
1032+
lookup -> AuthorizeConfigVerification.authorize(authorizer, lookup, lookup.getControllerService(controllerServiceId), requestDto.getProperties()),
1033+
() -> serviceFacade.verifyCanVerifyControllerServiceConfig(controllerServiceId),
10371034
entity -> performAsyncConfigVerification(entity, user)
10381035
);
10391036
}

nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ParameterProviderResource.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.apache.commons.lang3.StringUtils;
4444
import org.apache.nifi.authorization.AuthorizableLookup;
4545
import org.apache.nifi.authorization.AuthorizeComponentReference;
46+
import org.apache.nifi.authorization.AuthorizeConfigVerification;
4647
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
4748
import org.apache.nifi.authorization.Authorizer;
4849
import org.apache.nifi.authorization.ComponentAuthorizable;
@@ -1227,7 +1228,8 @@ public Response analyzeConfiguration(
12271228
"issuing a GET request to /parameter-providers/{serviceId}/verification-requests/{requestId}. Once the request is completed, the client is expected to issue a DELETE request to " +
12281229
"/parameter-providers/{providerId}/verification-requests/{requestId}.",
12291230
security = {
1230-
@SecurityRequirement(name = "Read - /parameter-providers/{uuid}")
1231+
@SecurityRequirement(name = "Write - /parameter-providers/{uuid}"),
1232+
@SecurityRequirement(name = "Read - any referenced Controller Services - /controller-services/{uuid}")
12311233
}
12321234
)
12331235
public Response submitConfigVerificationRequest(
@@ -1260,13 +1262,8 @@ public Response submitConfigVerificationRequest(
12601262
return withWriteLock(
12611263
serviceFacade,
12621264
parameterProviderConfigRequest,
1263-
lookup -> {
1264-
final ComponentAuthorizable parameterProvider = lookup.getParameterProvider(parameterProviderId);
1265-
parameterProvider.getAuthorizable().authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
1266-
},
1267-
() -> {
1268-
serviceFacade.verifyCanVerifyParameterProviderConfig(parameterProviderId);
1269-
},
1265+
lookup -> AuthorizeConfigVerification.authorize(authorizer, lookup, lookup.getParameterProvider(parameterProviderId), requestDto.getProperties()),
1266+
() -> serviceFacade.verifyCanVerifyParameterProviderConfig(parameterProviderId),
12701267
entity -> performAsyncConfigVerification(entity, user)
12711268
);
12721269
}

nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import jakarta.ws.rs.core.Response;
4141
import org.apache.commons.lang3.StringUtils;
4242
import org.apache.nifi.authorization.AuthorizeComponentReference;
43+
import org.apache.nifi.authorization.AuthorizeConfigVerification;
4344
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
4445
import org.apache.nifi.authorization.Authorizer;
4546
import org.apache.nifi.authorization.ComponentAuthorizable;
@@ -703,7 +704,8 @@ public Response analyzeConfiguration(
703704
"issuing a GET request to /processors/{processorId}/verification-requests/{requestId}. Once the request is completed, the client is expected to issue a DELETE request to " +
704705
"/processors/{processorId}/verification-requests/{requestId}.",
705706
security = {
706-
@SecurityRequirement(name = "Read - /processors/{uuid}")
707+
@SecurityRequirement(name = "Write - /processors/{uuid}"),
708+
@SecurityRequirement(name = "Read - any referenced Controller Services - /controller-services/{uuid}")
707709
}
708710
)
709711
public Response submitProcessorVerificationRequest(
@@ -736,13 +738,8 @@ public Response submitProcessorVerificationRequest(
736738
return withWriteLock(
737739
serviceFacade,
738740
processorConfigRequest,
739-
lookup -> {
740-
final ComponentAuthorizable processor = lookup.getProcessor(processorId);
741-
processor.getAuthorizable().authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
742-
},
743-
() -> {
744-
serviceFacade.verifyCanVerifyProcessorConfig(processorId);
745-
},
741+
lookup -> AuthorizeConfigVerification.authorize(authorizer, lookup, lookup.getProcessor(processorId), requestDto.getProperties()),
742+
() -> serviceFacade.verifyCanVerifyProcessorConfig(processorId),
746743
entity -> performAsyncConfigVerification(entity, user)
747744
);
748745
}

nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import jakarta.ws.rs.core.Response;
4141
import org.apache.commons.lang3.StringUtils;
4242
import org.apache.nifi.authorization.AuthorizeComponentReference;
43+
import org.apache.nifi.authorization.AuthorizeConfigVerification;
4344
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
4445
import org.apache.nifi.authorization.Authorizer;
4546
import org.apache.nifi.authorization.ComponentAuthorizable;
@@ -795,7 +796,8 @@ public Response analyzeConfiguration(
795796
"issuing a GET request to /reporting-tasks/{taskId}/verification-requests/{requestId}. Once the request is completed, the client is expected to issue a DELETE request to " +
796797
"/reporting-tasks/{serviceId}/verification-requests/{requestId}.",
797798
security = {
798-
@SecurityRequirement(name = "Read - /reporting-tasks/{uuid}")
799+
@SecurityRequirement(name = "Write - /reporting-tasks/{uuid}"),
800+
@SecurityRequirement(name = "Read - any referenced Controller Services - /controller-services/{uuid}")
799801
}
800802
)
801803
public Response submitConfigVerificationRequest(
@@ -828,13 +830,8 @@ public Response submitConfigVerificationRequest(
828830
return withWriteLock(
829831
serviceFacade,
830832
reportingTaskConfigRequest,
831-
lookup -> {
832-
final ComponentAuthorizable reportingTask = lookup.getReportingTask(reportingTaskId);
833-
reportingTask.getAuthorizable().authorize(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser());
834-
},
835-
() -> {
836-
serviceFacade.verifyCanVerifyReportingTaskConfig(reportingTaskId);
837-
},
833+
lookup -> AuthorizeConfigVerification.authorize(authorizer, lookup, lookup.getReportingTask(reportingTaskId), requestDto.getProperties()),
834+
() -> serviceFacade.verifyCanVerifyReportingTaskConfig(reportingTaskId),
838835
entity -> performAsyncConfigVerification(entity, user)
839836
);
840837
}

0 commit comments

Comments
 (0)