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

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 8e3db001f21 [Enhancement](tvf)catalog tvf implements user permission 
checks and hides sensitive information (#41497)
8e3db001f21 is described below

commit 8e3db001f21d00170af2b8b6d876e1fddfee0fac
Author: daidai <2017501...@qq.com>
AuthorDate: Tue Oct 8 18:13:41 2024 +0800

    [Enhancement](tvf)catalog tvf implements user permission checks and hides 
sensitive information (#41497)
    
    before #21790
    ## Proposed changes
    This PR unifies the duplicate parts of `catalog tvf` and `show
    catalogs`, adds permission check when querying `catalog tvf`, and hides
    sensitive information.
---
 be/src/vec/exec/scan/vmeta_scanner.cpp             |  1 +
 .../org/apache/doris/datasource/CatalogMgr.java    | 85 +++++++++++++---------
 .../doris/tablefunction/MetadataGenerator.java     |  9 ++-
 .../external_table_p0/tvf/test_catalogs_tvf.out    | 40 ++++++++++
 .../external_table_p0/tvf/test_catalogs_tvf.groovy | 68 ++++++++++++++++-
 5 files changed, 162 insertions(+), 41 deletions(-)

diff --git a/be/src/vec/exec/scan/vmeta_scanner.cpp 
b/be/src/vec/exec/scan/vmeta_scanner.cpp
index 74fed8c80c7..180d18b0c2c 100644
--- a/be/src/vec/exec/scan/vmeta_scanner.cpp
+++ b/be/src/vec/exec/scan/vmeta_scanner.cpp
@@ -400,6 +400,7 @@ Status VMetaScanner::_build_catalogs_metadata_request(const 
TMetaScanRange& meta
     // create TMetadataTableRequestParams
     TMetadataTableRequestParams metadata_table_params;
     metadata_table_params.__set_metadata_type(TMetadataType::CATALOGS);
+    metadata_table_params.__set_current_user_ident(_user_identity);
 
     request->__set_metada_table_params(metadata_table_params);
     return Status::OK();
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/CatalogMgr.java 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/CatalogMgr.java
index b77374e3094..3b8551da144 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/datasource/CatalogMgr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/CatalogMgr.java
@@ -24,6 +24,7 @@ import org.apache.doris.analysis.CreateCatalogStmt;
 import org.apache.doris.analysis.DropCatalogStmt;
 import org.apache.doris.analysis.ShowCatalogStmt;
 import org.apache.doris.analysis.ShowCreateCatalogStmt;
+import org.apache.doris.analysis.UserIdentity;
 import org.apache.doris.catalog.DatabaseIf;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.EnvFactory;
@@ -371,30 +372,27 @@ public class CatalogMgr implements Writable, 
GsonPostProcessable {
                     matcher = 
PatternMatcherWrapper.createMysqlPattern(showStmt.getPattern(),
                             CaseSensibility.CATALOG.getCaseSensibility());
                 }
-                for (CatalogIf catalog : nameToCatalog.values()) {
-                    if (Env.getCurrentEnv().getAccessManager()
-                            .checkCtlPriv(ConnectContext.get(), 
catalog.getName(), PrivPredicate.SHOW)) {
-                        String name = catalog.getName();
-                        // Filter catalog name
-                        if (matcher != null && !matcher.match(name)) {
-                            continue;
-                        }
-                        List<String> row = Lists.newArrayList();
-                        row.add(String.valueOf(catalog.getId()));
-                        row.add(name);
-                        row.add(catalog.getType());
-                        if (name.equals(currentCtlg)) {
-                            row.add("Yes");
-                        } else {
-                            row.add("No");
-                        }
-                        Map<String, String> props = catalog.getProperties();
-                        String createTime = 
props.getOrDefault(ExternalCatalog.CREATE_TIME, FeConstants.null_string);
-                        row.add(createTime);
-                        
row.add(TimeUtils.longToTimeString(catalog.getLastUpdateTime()));
-                        row.add(catalog.getComment());
-                        rows.add(row);
+                for (CatalogIf catalog : 
listCatalogsWithCheckPriv(ConnectContext.get().getCurrentUserIdentity())) {
+                    String name = catalog.getName();
+                    // Filter catalog name
+                    if (matcher != null && !matcher.match(name)) {
+                        continue;
+                    }
+                    List<String> row = Lists.newArrayList();
+                    row.add(String.valueOf(catalog.getId()));
+                    row.add(name);
+                    row.add(catalog.getType());
+                    if (name.equals(currentCtlg)) {
+                        row.add("Yes");
+                    } else {
+                        row.add("No");
                     }
+                    Map<String, String> props = catalog.getProperties();
+                    String createTime = 
props.getOrDefault(ExternalCatalog.CREATE_TIME, FeConstants.null_string);
+                    row.add(createTime);
+                    
row.add(TimeUtils.longToTimeString(catalog.getLastUpdateTime()));
+                    row.add(catalog.getComment());
+                    rows.add(row);
 
                     // sort by catalog name
                     rows.sort((x, y) -> {
@@ -414,18 +412,8 @@ public class CatalogMgr implements Writable, 
GsonPostProcessable {
                 if (!Strings.isNullOrEmpty(catalog.getResource())) {
                     rows.add(Arrays.asList("resource", catalog.getResource()));
                 }
-                // use tree map to maintain display order, making it easier to 
view properties
-                Map<String, String> sortedMap = new 
TreeMap<>(catalog.getProperties()).descendingMap();
-                for (Map.Entry<String, String> elem : sortedMap.entrySet()) {
-                    if (PrintableMap.HIDDEN_KEY.contains(elem.getKey())) {
-                        continue;
-                    }
-                    if (PrintableMap.SENSITIVE_KEY.contains(elem.getKey())) {
-                        rows.add(Arrays.asList(elem.getKey(), 
PrintableMap.PASSWORD_MASK));
-                    } else {
-                        rows.add(Arrays.asList(elem.getKey(), 
elem.getValue()));
-                    }
-                }
+                Map<String, String> sortedMap = 
getCatalogPropertiesWithPrintable(catalog);
+                sortedMap.forEach((k, v) -> rows.add(Arrays.asList(k, v)));
             }
         } finally {
             readUnlock();
@@ -434,6 +422,25 @@ public class CatalogMgr implements Writable, 
GsonPostProcessable {
         return new ShowResultSet(showStmt.getMetaData(), rows);
     }
 
+    public static Map<String, String> 
getCatalogPropertiesWithPrintable(CatalogIf<?> catalog) {
+        // use tree map to maintain display order, making it easier to view 
properties
+        Map<String, String> sortedMap = new TreeMap<>();
+        catalog.getProperties().forEach(
+                (key, value) -> {
+                    if (PrintableMap.HIDDEN_KEY.contains(key)) {
+                        return;
+                    }
+                    if (PrintableMap.SENSITIVE_KEY.contains(key)) {
+                        sortedMap.put(key, PrintableMap.PASSWORD_MASK);
+                    } else {
+                        sortedMap.put(key, value);
+                    }
+                }
+        );
+        return sortedMap;
+    }
+
+
     public ShowResultSet showCreateCatalog(ShowCreateCatalogStmt showStmt) 
throws AnalysisException {
         List<List<String>> rows = Lists.newArrayList();
         readLock();
@@ -538,6 +545,14 @@ public class CatalogMgr implements Writable, 
GsonPostProcessable {
         return nameToCatalog.values().stream().collect(Collectors.toList());
     }
 
+    public List<CatalogIf> listCatalogsWithCheckPriv(UserIdentity 
userIdentity) {
+        return nameToCatalog.values().stream().filter(
+                catalog -> Env.getCurrentEnv().getAccessManager()
+                        .checkCtlPriv(userIdentity, catalog.getName(), 
PrivPredicate.SHOW)
+        ).collect(Collectors.toList());
+    }
+
+
     /**
      * Reply for alter catalog props event.
      */
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataGenerator.java
 
b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataGenerator.java
index 466d324c369..a1cac535995 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataGenerator.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/MetadataGenerator.java
@@ -47,6 +47,7 @@ import org.apache.doris.common.util.NetUtils;
 import org.apache.doris.common.util.TimeUtils;
 import org.apache.doris.common.util.Util;
 import org.apache.doris.datasource.CatalogIf;
+import org.apache.doris.datasource.CatalogMgr;
 import org.apache.doris.datasource.ExternalCatalog;
 import org.apache.doris.datasource.ExternalMetaCacheMgr;
 import org.apache.doris.datasource.InternalCatalog;
@@ -513,17 +514,17 @@ public class MetadataGenerator {
 
     private static TFetchSchemaTableDataResult 
catalogsMetadataResult(TMetadataTableRequestParams params) {
         TFetchSchemaTableDataResult result = new TFetchSchemaTableDataResult();
-        List<CatalogIf> info = 
Env.getCurrentEnv().getCatalogMgr().listCatalogs();
-        List<TRow> dataBatch = Lists.newArrayList();
 
+        UserIdentity currentUserIdentity = 
UserIdentity.fromThrift(params.getCurrentUserIdent());
+        List<CatalogIf> info = 
Env.getCurrentEnv().getCatalogMgr().listCatalogsWithCheckPriv(currentUserIdentity);
+        List<TRow> dataBatch = Lists.newArrayList();
         for (CatalogIf catalog : info) {
             TRow trow = new TRow();
             trow.addToColumnValue(new TCell().setLongVal(catalog.getId()));
             trow.addToColumnValue(new TCell().setStringVal(catalog.getName()));
             trow.addToColumnValue(new TCell().setStringVal(catalog.getType()));
 
-            Map<String, String> properties = catalog.getProperties();
-
+            Map<String, String> properties = 
CatalogMgr.getCatalogPropertiesWithPrintable(catalog);
             for (Map.Entry<String, String> entry : properties.entrySet()) {
                 TRow subTrow = new TRow(trow);
                 subTrow.addToColumnValue(new 
TCell().setStringVal(entry.getKey()));
diff --git a/regression-test/data/external_table_p0/tvf/test_catalogs_tvf.out 
b/regression-test/data/external_table_p0/tvf/test_catalogs_tvf.out
index 310da69d766..7f97c337999 100644
--- a/regression-test/data/external_table_p0/tvf/test_catalogs_tvf.out
+++ b/regression-test/data/external_table_p0/tvf/test_catalogs_tvf.out
@@ -8,3 +8,43 @@ catalog_test_hive00    hms     type    hms
 -- !create --
 catalog_test_es00      es      type    es
 
+-- !test_10 --
+catalog_tvf_test_dlf   hms     dlf.catalog.id  987654321
+
+-- !test_11 --
+catalog_tvf_test_dlf   hms     dlf.secret_key  *XXX
+
+-- !test_12 --
+catalog_tvf_test_dlf   hms     dlf.access_key  AAAAAAAAAAAAAAAAAAAAAA
+
+-- !test_13 --
+catalog_tvf_test_dlf   hms     dlf.uid 123456789
+
+-- !test_14 --
+catalog_tvf_test_dlf   hms     type    hms
+
+-- !test_15 --
+
+-- !test_16 --
+internal       internal        NULL    NULL
+
+-- !test_17 --
+catalog_tvf_test_dlf   hms     dlf.secret_key  *XXX
+
+-- !test_18 --
+catalog_tvf_test_dlf   hms     dlf.access_key  AAAAAAAAAAAAAAAAAAAAAA
+
+-- !test_19 --
+catalog_tvf_test_dlf   hms     dlf.uid 123456789
+
+-- !test_20 --
+catalog_tvf_test_dlf   hms     type    hms
+
+-- !test_21 --
+
+-- !test_22 --
+
+-- !test_23 --
+
+-- !test_24 --
+
diff --git 
a/regression-test/suites/external_table_p0/tvf/test_catalogs_tvf.groovy 
b/regression-test/suites/external_table_p0/tvf/test_catalogs_tvf.groovy
index a59953cf567..748a7e49d14 100644
--- a/regression-test/suites/external_table_p0/tvf/test_catalogs_tvf.groovy
+++ b/regression-test/suites/external_table_p0/tvf/test_catalogs_tvf.groovy
@@ -18,12 +18,12 @@
 suite("test_catalogs_tvf","p0,external,tvf,external_docker") {
     List<List<Object>> table =  sql """ select * from catalogs(); """
     assertTrue(table.size() > 0)
-    assertEquals(5, table[0].size)
+    assertEquals(5, table[0].size())
 
     
     table = sql """ select CatalogId,CatalogName from catalogs();"""
     assertTrue(table.size() > 0)
-    assertTrue(table[0].size == 2)
+    assertTrue(table[0].size() == 2)
 
 
     table = sql """ select * from catalogs() where CatalogId=0;"""
@@ -76,4 +76,68 @@ suite("test_catalogs_tvf","p0,external,tvf,external_docker") 
{
         // check exception
         exception "catalogs table-valued-function does not support any params"
     }
+
+    sql """ drop catalog if exists catalog_tvf_test_dlf """ 
+
+    sql """ 
+        CREATE CATALOG catalog_tvf_test_dlf PROPERTIES (
+        "type"="hms",
+        "hive.metastore.type" = "dlf",
+        "dlf.proxy.mode" = "DLF_ONLY",
+        "dlf.endpoint" = "dlf-vpc.cn-beijing.aliyuncs.com",
+        "dlf.region" = "cn-beijing",
+        "dlf.uid" = "123456789",
+        "dlf.catalog.id" = "987654321",
+        "dlf.access_key" = "AAAAAAAAAAAAAAAAAAAAAA",
+        "dlf.secret_key" = "BBBBBBBBBBBBBBBBBBBBBB"
+        );"""
+    
+    order_qt_test_10 """ select  CatalogName,CatalogType,Property,Value from 
catalogs() where CatalogName = "catalog_tvf_test_dlf" and   Property= 
"dlf.catalog.id" """ 
+    order_qt_test_11 """ select  CatalogName,CatalogType,Property,Value from 
catalogs() where CatalogName = "catalog_tvf_test_dlf" and   Property= 
"dlf.secret_key" """ 
+    order_qt_test_12 """ select  CatalogName,CatalogType,Property,Value from 
catalogs() where CatalogName = "catalog_tvf_test_dlf" and   Property= 
"dlf.access_key" """ 
+    order_qt_test_13 """ select  CatalogName,CatalogType,Property,Value from 
catalogs() where CatalogName = "catalog_tvf_test_dlf" and   Property= "dlf.uid" 
""" 
+    order_qt_test_14 """ select  CatalogName,CatalogType,Property,Value from 
catalogs() where CatalogName = "catalog_tvf_test_dlf" and   Property= "type" 
""" 
+
+
+    def user = 'catalog_user_test'
+    def pwd = 'C123_567p'
+    try_sql("DROP USER ${user}")
+
+    sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'"""
+    sql """GRANT SELECT_PRIV on `internal`.``.`` to '${user}'"""
+
+
+
+    connect(user=user, password="${pwd}", url=context.config.jdbcUrl) {
+        sql """ switch internal """
+        order_qt_test_15 """ select  CatalogName,CatalogType,Property,Value 
from catalogs() where CatalogName = "catalog_tvf_test_dlf" and   Property= 
"type" """ 
+        order_qt_test_16 """ select  CatalogName,CatalogType,Property,Value 
from catalogs()  """ 
+    }
+
+    sql """GRANT SELECT_PRIV on `catalog_tvf_test_dlf`.``.`` to '${user}'"""
+
+
+    connect(user=user, password="${pwd}", url=context.config.jdbcUrl) {
+        sql """ switch internal """
+
+        order_qt_test_17 """ select  CatalogName,CatalogType,Property,Value 
from catalogs() where CatalogName = "catalog_tvf_test_dlf" and   Property= 
"dlf.secret_key" """ 
+        order_qt_test_18 """ select  CatalogName,CatalogType,Property,Value 
from catalogs() where CatalogName = "catalog_tvf_test_dlf" and   Property= 
"dlf.access_key" """ 
+        order_qt_test_19 """ select  CatalogName,CatalogType,Property,Value 
from catalogs() where CatalogName = "catalog_tvf_test_dlf" and   Property= 
"dlf.uid" """ 
+        order_qt_test_20 """ select  CatalogName,CatalogType,Property,Value 
from catalogs() where CatalogName = "catalog_tvf_test_dlf" and   Property= 
"type" """ 
+    }
+
+    sql """REVOKE SELECT_PRIV on `catalog_tvf_test_dlf`.``.`` FROM '${user}'"""
+
+
+    connect(user=user, password="${pwd}", url=context.config.jdbcUrl) {
+        sql """ switch internal """
+
+        order_qt_test_21 """ select  CatalogName,CatalogType,Property,Value 
from catalogs() where CatalogName = "catalog_tvf_test_dlf" and   Property= 
"dlf.secret_key" """ 
+        order_qt_test_22 """ select  CatalogName,CatalogType,Property,Value 
from catalogs() where CatalogName = "catalog_tvf_test_dlf" and   Property= 
"dlf.access_key" """ 
+        order_qt_test_23 """ select  CatalogName,CatalogType,Property,Value 
from catalogs() where CatalogName = "catalog_tvf_test_dlf" and   Property= 
"dlf.uid" """ 
+        order_qt_test_24 """ select  CatalogName,CatalogType,Property,Value 
from catalogs() where CatalogName = "catalog_tvf_test_dlf" and   Property= 
"type" """ 
+    }
+    
+
+    
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to