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

albumenj pushed a commit to branch 3.2
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.2 by this push:
     new 1b838281a4 QoS Support anonymous command allow list (#12082)
1b838281a4 is described below

commit 1b838281a44cd5afec07ef3cd69eb42a36d935c2
Author: Albumen Kevin <[email protected]>
AuthorDate: Wed Apr 19 10:13:09 2023 +0800

    QoS Support anonymous command allow list (#12082)
    
    * QoS Support anonymous command allow list
    
    * Fix test
---
 .../dubbo/common/constants/QosConstants.java       |  2 ++
 .../org/apache/dubbo/config/ApplicationConfig.java | 15 ++++++++++++++
 .../src/main/resources/META-INF/dubbo.xsd          |  6 ++++++
 .../org/apache/dubbo/qos/api/QosConfiguration.java | 18 ++++++++++++++++
 .../DefaultAnonymousAccessPermissionChecker.java   | 14 ++++++++++++-
 .../dubbo/qos/protocol/QosProtocolWrapper.java     |  3 +++
 .../java/org/apache/dubbo/qos/server/Server.java   |  7 +++++++
 ...efaultAnonymousAccessPermissionCheckerTest.java | 24 +++++++++++++++++++++-
 8 files changed, 87 insertions(+), 2 deletions(-)

diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/QosConstants.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/QosConstants.java
index e02ec74a65..29b1993ca6 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/QosConstants.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/QosConstants.java
@@ -34,6 +34,8 @@ public interface QosConstants {
 
     String ANONYMOUS_ACCESS_PERMISSION_LEVEL = 
"qos.anonymous.access.permission.level";
 
+    String ANONYMOUS_ACCESS_ALLOW_COMMANDS = 
"qos.anonymous.access.allow.commands";
+
     String QOS_ENABLE_COMPATIBLE = "qos-enable";
 
     String QOS_HOST_COMPATIBLE = "qos-host";
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java 
b/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java
index 63dcfb5375..7336c6d144 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java
@@ -55,6 +55,7 @@ import static 
org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP;
 import static 
org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_COMPATIBLE;
 import static 
org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_WHITELIST;
 import static 
org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_WHITELIST_COMPATIBLE;
+import static 
org.apache.dubbo.common.constants.QosConstants.ANONYMOUS_ACCESS_ALLOW_COMMANDS;
 import static 
org.apache.dubbo.common.constants.QosConstants.ANONYMOUS_ACCESS_PERMISSION_LEVEL;
 import static 
org.apache.dubbo.common.constants.QosConstants.ANONYMOUS_ACCESS_PERMISSION_LEVEL_COMPATIBLE;
 import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE;
@@ -170,6 +171,11 @@ public class ApplicationConfig extends AbstractConfig {
      */
     private String qosAnonymousAccessPermissionLevel;
 
+    /**
+     * the anonymous(any foreign ip) allow commands, default is empty, can not 
access any cmd
+     */
+    private String qosAnonymousAllowCommands;
+
     /**
      * Customized parameters
      */
@@ -472,6 +478,15 @@ public class ApplicationConfig extends AbstractConfig {
         this.qosAnonymousAccessPermissionLevel = 
qosAnonymousAccessPermissionLevel;
     }
 
+    @Parameter(key = ANONYMOUS_ACCESS_ALLOW_COMMANDS)
+    public String getQosAnonymousAllowCommands() {
+        return qosAnonymousAllowCommands;
+    }
+
+    public void setQosAnonymousAllowCommands(String qosAnonymousAllowCommands) 
{
+        this.qosAnonymousAllowCommands = qosAnonymousAllowCommands;
+    }
+
     /**
      * The format is the same as the springboot, including: 
getQosEnableCompatible(), getQosPortCompatible(), 
getQosAcceptForeignIpCompatible().
      *
diff --git 
a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd 
b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
index 8ba022c68f..141b5d5169 100644
--- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
+++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
@@ -547,6 +547,12 @@
                     <![CDATA[ Anonymous (any foreign ip) access level, the 
default is NONE, can not access any cmd. ]]></xsd:documentation>
             </xsd:annotation>
         </xsd:attribute>
+        <xsd:attribute name="qos-anonymous-allow-commands" type="xsd:string">
+            <xsd:annotation>
+                <xsd:documentation>
+                    <![CDATA[ Anonymous(any foreign ip) allow commands, 
default is empty, can not access any cmd. ]]></xsd:documentation>
+            </xsd:annotation>
+        </xsd:attribute>
     </xsd:complexType>
 
     <xsd:complexType name="moduleType">
diff --git 
a/dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/QosConfiguration.java
 
b/dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/QosConfiguration.java
index 476079aa14..69f9b10e19 100644
--- 
a/dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/QosConfiguration.java
+++ 
b/dubbo-plugin/dubbo-qos-api/src/main/java/org/apache/dubbo/qos/api/QosConfiguration.java
@@ -38,6 +38,9 @@ public class QosConfiguration {
     // the default value is Cmd.PermissionLevel.PUBLIC, can only access PUBLIC 
level cmd
     private PermissionLevel anonymousAccessPermissionLevel = 
PermissionLevel.PUBLIC;
 
+    // the allow commands for anonymous access, the delimiter is colon(,)
+    private String anonymousAllowCommands;
+
     private QosConfiguration() {
     }
 
@@ -46,6 +49,7 @@ public class QosConfiguration {
         this.acceptForeignIp = builder.isAcceptForeignIp();
         this.acceptForeignIpWhitelist = builder.getAcceptForeignIpWhitelist();
         this.anonymousAccessPermissionLevel = 
builder.getAnonymousAccessPermissionLevel();
+        this.anonymousAllowCommands = builder.getAnonymousAllowCommands();
         buildPredicate();
     }
 
@@ -93,6 +97,10 @@ public class QosConfiguration {
         return acceptForeignIp;
     }
 
+    public String getAnonymousAllowCommands() {
+        return anonymousAllowCommands;
+    }
+
     public static Builder builder() {
         return new Builder();
     }
@@ -103,6 +111,7 @@ public class QosConfiguration {
         private boolean acceptForeignIp;
         private String acceptForeignIpWhitelist;
         private PermissionLevel anonymousAccessPermissionLevel = 
PermissionLevel.PUBLIC;
+        private String anonymousAllowCommands;
 
         private Builder() {
         }
@@ -127,6 +136,11 @@ public class QosConfiguration {
             return this;
         }
 
+        public Builder anonymousAllowCommands(String anonymousAllowCommands) {
+            this.anonymousAllowCommands = anonymousAllowCommands;
+            return this;
+        }
+
         public QosConfiguration build() {
             return new QosConfiguration(this);
         }
@@ -146,5 +160,9 @@ public class QosConfiguration {
         public PermissionLevel getAnonymousAccessPermissionLevel() {
             return anonymousAccessPermissionLevel;
         }
+
+        public String getAnonymousAllowCommands() {
+            return anonymousAllowCommands;
+        }
     }
 }
diff --git 
a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionChecker.java
 
b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionChecker.java
index 8efd756e00..61736f2247 100644
--- 
a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionChecker.java
+++ 
b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionChecker.java
@@ -16,13 +16,16 @@
  */
 package org.apache.dubbo.qos.permission;
 
-import io.netty.channel.Channel;
+import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.qos.api.CommandContext;
 import org.apache.dubbo.qos.api.PermissionLevel;
 import org.apache.dubbo.qos.api.QosConfiguration;
 
+import io.netty.channel.Channel;
+
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.util.Arrays;
 import java.util.Optional;
 
 public class DefaultAnonymousAccessPermissionChecker implements 
PermissionChecker {
@@ -37,6 +40,15 @@ public class DefaultAnonymousAccessPermissionChecker 
implements PermissionChecke
             .orElse(null);
 
         QosConfiguration qosConfiguration = 
commandContext.getQosConfiguration();
+        String anonymousAllowCommands = 
qosConfiguration.getAnonymousAllowCommands();
+        if (StringUtils.isNotEmpty(anonymousAllowCommands) &&
+            Arrays.stream(anonymousAllowCommands.split(","))
+                .filter(StringUtils::isNotEmpty)
+                .map(String::trim)
+                .anyMatch(cmd -> cmd.equals(commandContext.getCommandName()))) 
{
+            return true;
+        }
+
         PermissionLevel currentLevel = 
qosConfiguration.getAnonymousAccessPermissionLevel();
 
         // Local has private permission
diff --git 
a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java
 
b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java
index ef2f35c3dd..127fa8bb42 100644
--- 
a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java
+++ 
b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java
@@ -40,6 +40,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import static 
org.apache.dubbo.common.constants.LoggerCodeConstants.QOS_FAILED_START_SERVER;
 import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP;
 import static 
org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_WHITELIST;
+import static 
org.apache.dubbo.common.constants.QosConstants.ANONYMOUS_ACCESS_ALLOW_COMMANDS;
 import static 
org.apache.dubbo.common.constants.QosConstants.ANONYMOUS_ACCESS_PERMISSION_LEVEL;
 import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE;
 import static org.apache.dubbo.common.constants.QosConstants.QOS_HOST;
@@ -119,6 +120,7 @@ public class QosProtocolWrapper implements Protocol, 
ScopeModelAware {
             boolean acceptForeignIp = 
Boolean.parseBoolean(url.getParameter(ACCEPT_FOREIGN_IP, "false"));
             String acceptForeignIpWhitelist = 
url.getParameter(ACCEPT_FOREIGN_IP_WHITELIST, StringUtils.EMPTY_STRING);
             String anonymousAccessPermissionLevel = 
url.getParameter(ANONYMOUS_ACCESS_PERMISSION_LEVEL, 
PermissionLevel.PUBLIC.name());
+            String anonymousAllowCommands = 
url.getParameter(ANONYMOUS_ACCESS_ALLOW_COMMANDS, StringUtils.EMPTY_STRING);
             Server server = 
frameworkModel.getBeanFactory().getBean(Server.class);
 
             if (server.isStarted()) {
@@ -130,6 +132,7 @@ public class QosProtocolWrapper implements Protocol, 
ScopeModelAware {
             server.setAcceptForeignIp(acceptForeignIp);
             server.setAcceptForeignIpWhitelist(acceptForeignIpWhitelist);
             
server.setAnonymousAccessPermissionLevel(anonymousAccessPermissionLevel);
+            server.setAnonymousAllowCommands(anonymousAllowCommands);
             server.start();
 
         } catch (Throwable throwable) {
diff --git 
a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java 
b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java
index 4dc03d1cd7..65e7e3b9fa 100644
--- 
a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java
+++ 
b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java
@@ -58,6 +58,8 @@ public class Server {
 
     private String anonymousAccessPermissionLevel = 
PermissionLevel.NONE.name();
 
+    private String anonymousAllowCommands = StringUtils.EMPTY_STRING;
+
     private EventLoopGroup boss;
 
     private EventLoopGroup worker;
@@ -108,6 +110,7 @@ public class Server {
                         .acceptForeignIp(acceptForeignIp)
                         .acceptForeignIpWhitelist(acceptForeignIpWhitelist)
                         
.anonymousAccessPermissionLevel(anonymousAccessPermissionLevel)
+                        .anonymousAllowCommands(anonymousAllowCommands)
                         .build()
                 ));
             }
@@ -167,6 +170,10 @@ public class Server {
         this.anonymousAccessPermissionLevel = anonymousAccessPermissionLevel;
     }
 
+    public void setAnonymousAllowCommands(String anonymousAllowCommands) {
+        this.anonymousAllowCommands = anonymousAllowCommands;
+    }
+
     public String getWelcome() {
         return welcome;
     }
diff --git 
a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionCheckerTest.java
 
b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionCheckerTest.java
index 11f466ca39..eef2013fde 100644
--- 
a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionCheckerTest.java
+++ 
b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/permission/DefaultAnonymousAccessPermissionCheckerTest.java
@@ -16,10 +16,11 @@
  */
 package org.apache.dubbo.qos.permission;
 
-import io.netty.channel.Channel;
 import org.apache.dubbo.qos.api.CommandContext;
 import org.apache.dubbo.qos.api.PermissionLevel;
 import org.apache.dubbo.qos.api.QosConfiguration;
+
+import io.netty.channel.Channel;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
@@ -79,5 +80,26 @@ class DefaultAnonymousAccessPermissionCheckerTest {
         Assertions.assertTrue(checker.access(commandContext, 
PermissionLevel.PUBLIC));
         Assertions.assertTrue(checker.access(commandContext, 
PermissionLevel.PROTECTED));
         Assertions.assertFalse(checker.access(commandContext, 
PermissionLevel.PRIVATE));
+
+        
Mockito.when(qosConfiguration.getAcceptForeignIpWhitelistPredicate()).thenReturn(ip
 -> false);
+        
Mockito.when(qosConfiguration.getAnonymousAllowCommands()).thenReturn("test1,test2");
+
+        Mockito.when(commandContext.getCommandName()).thenReturn("test1");
+        Assertions.assertTrue(checker.access(commandContext, 
PermissionLevel.NONE));
+        Assertions.assertTrue(checker.access(commandContext, 
PermissionLevel.PUBLIC));
+        Assertions.assertTrue(checker.access(commandContext, 
PermissionLevel.PROTECTED));
+        Assertions.assertTrue(checker.access(commandContext, 
PermissionLevel.PRIVATE));
+
+        Mockito.when(commandContext.getCommandName()).thenReturn("test2");
+        Assertions.assertTrue(checker.access(commandContext, 
PermissionLevel.NONE));
+        Assertions.assertTrue(checker.access(commandContext, 
PermissionLevel.PUBLIC));
+        Assertions.assertTrue(checker.access(commandContext, 
PermissionLevel.PROTECTED));
+        Assertions.assertTrue(checker.access(commandContext, 
PermissionLevel.PRIVATE));
+
+        Mockito.when(commandContext.getCommandName()).thenReturn("test");
+        Assertions.assertTrue(checker.access(commandContext, 
PermissionLevel.NONE));
+        Assertions.assertFalse(checker.access(commandContext, 
PermissionLevel.PUBLIC));
+        Assertions.assertFalse(checker.access(commandContext, 
PermissionLevel.PROTECTED));
+        Assertions.assertFalse(checker.access(commandContext, 
PermissionLevel.PRIVATE));
     }
 }

Reply via email to