Skip to content

Commit

Permalink
[fix](refresh) fix priv issue of refresh database and table operation (
Browse files Browse the repository at this point in the history
  • Loading branch information
morningman authored and 胥剑旭 committed Dec 14, 2023
1 parent 1a6895d commit 7f9c107
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<String, Map<String, List<Column>>> MOCKED_META;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<String, Map<String, List<Column>>> MOCKED_META;

Expand Down

0 comments on commit 7f9c107

Please sign in to comment.