From 09518cde471f2272e360b57aeb71ed2100bf56d4 Mon Sep 17 00:00:00 2001 From: morningman Date: Fri, 10 Nov 2023 23:30:19 +0800 Subject: [PATCH] [fix](refresh) fix priv issue of refresh database and table operation --- .../apache/doris/analysis/RefreshDbStmt.java | 6 ++- .../doris/analysis/RefreshTableStmt.java | 6 ++- .../apache/doris/catalog/RefreshDbTest.java | 40 +++++++++++++++++++ .../doris/catalog/RefreshTableTest.java | 40 +++++++++++++++++++ 4 files changed, 88 insertions(+), 4 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/RefreshDbStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/RefreshDbStmt.java index cd8fef0c31e390..18124a08206155 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/RefreshDbStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/RefreshDbStmt.java @@ -85,11 +85,13 @@ public void analyze(Analyzer analyzer) throws AnalysisException, UserException { ErrorCode.ERR_DBACCESS_DENIED_ERROR, analyzer.getQualifiedUser(), dbName); } // check access - if (!Env.getCurrentEnv().getAccessManager().checkDbPriv(ConnectContext.get(), dbName, PrivPredicate.DROP)) { + if (!Env.getCurrentEnv().getAccessManager().checkDbPriv(ConnectContext.get(), catalogName, + dbName, PrivPredicate.DROP)) { ErrorReport.reportAnalysisException(ErrorCode.ERR_DBACCESS_DENIED_ERROR, ConnectContext.get().getQualifiedUser(), dbName); } - if (!Env.getCurrentEnv().getAccessManager().checkDbPriv(ConnectContext.get(), dbName, PrivPredicate.CREATE)) { + if (!Env.getCurrentEnv().getAccessManager().checkDbPriv(ConnectContext.get(), catalogName, + dbName, PrivPredicate.CREATE)) { ErrorReport.reportAnalysisException( ErrorCode.ERR_DBACCESS_DENIED_ERROR, analyzer.getQualifiedUser(), dbName); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/RefreshTableStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/RefreshTableStmt.java index b0eff7ed864517..65bf35f3059b45 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/RefreshTableStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/RefreshTableStmt.java @@ -58,12 +58,14 @@ public void analyze(Analyzer analyzer) throws UserException { tableName.analyze(analyzer); // check access - if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), tableName.getDb(), + if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), + tableName.getCtl(), tableName.getDb(), tableName.getTbl(), PrivPredicate.DROP)) { ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "DROP"); } - if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), tableName.getDb(), + if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), + tableName.getCtl(), tableName.getDb(), tableName.getTbl(), PrivPredicate.CREATE)) { ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "CREATE"); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/catalog/RefreshDbTest.java b/fe/fe-core/src/test/java/org/apache/doris/catalog/RefreshDbTest.java index 23def21689c70d..6ddc5b206ef36f 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/catalog/RefreshDbTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/RefreshDbTest.java @@ -18,16 +18,23 @@ package org.apache.doris.catalog; import org.apache.doris.analysis.CreateCatalogStmt; +import org.apache.doris.analysis.CreateUserStmt; import org.apache.doris.analysis.DropCatalogStmt; +import org.apache.doris.analysis.GrantStmt; import org.apache.doris.analysis.RefreshDbStmt; +import org.apache.doris.analysis.UserIdentity; import org.apache.doris.catalog.external.ExternalDatabase; import org.apache.doris.catalog.external.TestExternalDatabase; import org.apache.doris.catalog.external.TestExternalTable; +import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.ExceptionChecker; import org.apache.doris.common.FeConstants; import org.apache.doris.datasource.CatalogIf; import org.apache.doris.datasource.test.TestExternalCatalog; +import org.apache.doris.mysql.privilege.Auth; import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.DdlExecutor; +import org.apache.doris.system.SystemInfoService; import org.apache.doris.utframe.TestWithFeService; import com.google.common.collect.Lists; @@ -105,6 +112,39 @@ public void testRefreshDatabase() throws Exception { } } + @Test + public void testRefreshPriv() throws Exception { + Auth auth = Env.getCurrentEnv().getAuth(); + // create user1 + auth.createUser((CreateUserStmt) parseAndAnalyzeStmt( + "create user 'user1'@'%' identified by 'pwd1';", rootCtx)); + // grant only create_priv to user1 on test1.db1.tbl11 + GrantStmt grantStmt = (GrantStmt) parseAndAnalyzeStmt( + "grant create_priv on test1.db1.* to 'user1'@'%';", rootCtx); + auth.grant(grantStmt); + + // mock login user1 + UserIdentity user1 = new UserIdentity("user1", "%"); + user1.analyze(SystemInfoService.DEFAULT_CLUSTER); + ConnectContext user1Ctx = createCtx(user1, "127.0.0.1"); + ExceptionChecker.expectThrowsWithMsg(AnalysisException.class, + "Access denied for user 'default_cluster:user1' to database 'default_cluster:db1'", + () -> parseAndAnalyzeStmt("refresh database test1.db1", user1Ctx)); + ConnectContext.remove(); + + // add drop priv to user1 + rootCtx.setThreadLocalInfo(); + grantStmt = (GrantStmt) parseAndAnalyzeStmt( + "grant drop_priv on test1.db1.* to 'user1'@'%';", rootCtx); + auth.grant(grantStmt); + ConnectContext.remove(); + + // user1 can do refresh table + user1Ctx.setThreadLocalInfo(); + ExceptionChecker.expectThrowsNoException( + () -> parseAndAnalyzeStmt("refresh database test1.db1", user1Ctx)); + } + public static class RefreshTableProvider implements TestExternalCatalog.TestCatalogProvider { public static final Map>> MOCKED_META; diff --git a/fe/fe-core/src/test/java/org/apache/doris/catalog/RefreshTableTest.java b/fe/fe-core/src/test/java/org/apache/doris/catalog/RefreshTableTest.java index a37f1ca98f4530..feeec75a7b488a 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/catalog/RefreshTableTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/RefreshTableTest.java @@ -18,15 +18,22 @@ package org.apache.doris.catalog; import org.apache.doris.analysis.CreateCatalogStmt; +import org.apache.doris.analysis.CreateUserStmt; import org.apache.doris.analysis.DropCatalogStmt; +import org.apache.doris.analysis.GrantStmt; import org.apache.doris.analysis.RefreshTableStmt; import org.apache.doris.analysis.TableName; +import org.apache.doris.analysis.UserIdentity; import org.apache.doris.catalog.external.TestExternalTable; +import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.ExceptionChecker; import org.apache.doris.common.FeConstants; import org.apache.doris.datasource.CatalogIf; import org.apache.doris.datasource.test.TestExternalCatalog; +import org.apache.doris.mysql.privilege.Auth; import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.DdlExecutor; +import org.apache.doris.system.SystemInfoService; import org.apache.doris.utframe.TestWithFeService; import com.google.common.collect.Lists; @@ -93,6 +100,39 @@ public void testRefreshTable() throws Exception { Assertions.assertTrue(l5 == l4); } + @Test + public void testRefreshPriv() throws Exception { + Auth auth = Env.getCurrentEnv().getAuth(); + // create user1 + auth.createUser((CreateUserStmt) parseAndAnalyzeStmt( + "create user 'user1'@'%' identified by 'pwd1';", rootCtx)); + // grant only create_priv to user1 on test1.db1.tbl11 + GrantStmt grantStmt = (GrantStmt) parseAndAnalyzeStmt( + "grant create_priv on test1.db1.tbl11 to 'user1'@'%';", rootCtx); + auth.grant(grantStmt); + + // mock login user1 + UserIdentity user1 = new UserIdentity("user1", "%"); + user1.analyze(SystemInfoService.DEFAULT_CLUSTER); + ConnectContext user1Ctx = createCtx(user1, "127.0.0.1"); + ExceptionChecker.expectThrowsWithMsg(AnalysisException.class, + "Access denied; you need (at least one of) the DROP privilege(s) for this operation", + () -> parseAndAnalyzeStmt("refresh table test1.db1.tbl11", user1Ctx)); + ConnectContext.remove(); + + // add drop priv to user1 + rootCtx.setThreadLocalInfo(); + grantStmt = (GrantStmt) parseAndAnalyzeStmt( + "grant drop_priv on test1.db1.tbl11 to 'user1'@'%';", rootCtx); + auth.grant(grantStmt); + ConnectContext.remove(); + + // user1 can do refresh table + user1Ctx.setThreadLocalInfo(); + ExceptionChecker.expectThrowsNoException( + () -> parseAndAnalyzeStmt("refresh table test1.db1.tbl11", user1Ctx)); + } + public static class RefreshTableProvider implements TestExternalCatalog.TestCatalogProvider { public static final Map>> MOCKED_META;