This is an automated email from the ASF dual-hosted git repository.

xyz pushed a commit to branch branch-2.8
in repository https://gitbox.apache.org/repos/asf/pulsar.git

commit c0999e51125e260d3d24d44ad75373b781b67f4a
Author: Ruguo Yu <[email protected]>
AuthorDate: Wed Mar 2 16:57:11 2022 +0800

    [Authorization] Role with namespace produce authz can also get topics 
(#13773)
    
    (cherry picked from commit 89d60af1981f732b68fe783666bcc470c18afd32)
---
 .../authorization/PulsarAuthorizationProvider.java | 35 ++++++++++++++++++++++
 .../api/AuthorizationProducerConsumerTest.java     |  6 ++++
 2 files changed, 41 insertions(+)

diff --git 
a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authorization/PulsarAuthorizationProvider.java
 
b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authorization/PulsarAuthorizationProvider.java
index aab4b2b5ac1..d7e8ac98efd 100644
--- 
a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authorization/PulsarAuthorizationProvider.java
+++ 
b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authorization/PulsarAuthorizationProvider.java
@@ -230,6 +230,40 @@ public class PulsarAuthorizationProvider implements 
AuthorizationProvider {
         return allowTheSpecifiedActionOpsAsync(namespaceName, role, 
authenticationData, AuthAction.sinks);
     }
 
+    private CompletableFuture<Boolean> 
allowConsumeOrProduceOpsAsync(NamespaceName namespaceName,
+                                                                     String 
role,
+                                                                     
AuthenticationDataSource authenticationData) {
+        CompletableFuture<Boolean> finalResult = new CompletableFuture<>();
+        allowTheSpecifiedActionOpsAsync(namespaceName, role, 
authenticationData, AuthAction.consume)
+                .whenComplete((consumeAuthorized, e) -> {
+                    if (e == null) {
+                        if (consumeAuthorized) {
+                            finalResult.complete(consumeAuthorized);
+                            return;
+                        }
+                    } else {
+                        if (log.isDebugEnabled()) {
+                            log.debug("Namespace [{}] Role [{}] exception 
occurred while trying to check Consume "
+                                    + "permission. {}", namespaceName, role, 
e.getCause());
+                        }
+                    }
+                    allowTheSpecifiedActionOpsAsync(namespaceName, role, 
authenticationData, AuthAction.produce)
+                            .whenComplete((produceAuthorized, ex) -> {
+                                if (ex == null) {
+                                    finalResult.complete(produceAuthorized);
+                                } else {
+                                    if (log.isDebugEnabled()) {
+                                        log.debug("Namespace [{}] Role [{}] 
exception occurred while trying to check "
+                                                + "Produce permission. {}", 
namespaceName, role, ex.getCause());
+                                    }
+                                    
finalResult.completeExceptionally(ex.getCause());
+                                }
+                            });
+                });
+
+        return finalResult;
+    }
+
     private CompletableFuture<Boolean> 
allowTheSpecifiedActionOpsAsync(NamespaceName namespaceName, String role,
                                                                        
AuthenticationDataSource authenticationData,
                                                                        
AuthAction authAction) {
@@ -550,6 +584,7 @@ public class PulsarAuthorizationProvider implements 
AuthorizationProvider {
                                         namespaceName, role, authData, 
AuthAction.packages);
                             case GET_TOPIC:
                             case GET_TOPICS:
+                                return 
allowConsumeOrProduceOpsAsync(namespaceName, role, authData);
                             case UNSUBSCRIBE:
                             case CLEAR_BACKLOG:
                                 return allowTheSpecifiedActionOpsAsync(
diff --git 
a/pulsar-broker/src/test/java/org/apache/pulsar/client/api/AuthorizationProducerConsumerTest.java
 
b/pulsar-broker/src/test/java/org/apache/pulsar/client/api/AuthorizationProducerConsumerTest.java
index 475dc8d1ab8..31b2451575d 100644
--- 
a/pulsar-broker/src/test/java/org/apache/pulsar/client/api/AuthorizationProducerConsumerTest.java
+++ 
b/pulsar-broker/src/test/java/org/apache/pulsar/client/api/AuthorizationProducerConsumerTest.java
@@ -415,6 +415,12 @@ public class AuthorizationProducerConsumerTest extends 
ProducerConsumerBase {
         assertEquals(sub1Admin.topics().getStats(topicName + 
"-partition-0").getSubscriptions()
                 .get(subscriptionName).getMsgBacklog(), 0);
 
+        superAdmin.namespaces().revokePermissionsOnNamespace(namespace, 
subscriptionRole);
+        superAdmin.namespaces().grantPermissionOnNamespace(namespace, 
subscriptionRole,
+                Sets.newHashSet(AuthAction.produce));
+        assertEquals(sub1Admin.topics().getPartitionedTopicList(namespace),
+                Lists.newArrayList(topicName));
+
         log.info("-- Exiting {} test --", methodName);
     }
 

Reply via email to