diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/AdminCopyTabletStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/AdminCopyTabletStmt.java index 63832d9cd65d22..475219ca343c53 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/AdminCopyTabletStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/AdminCopyTabletStmt.java @@ -71,8 +71,9 @@ public long getExpirationMinutes() { @Override public void analyze(Analyzer analyzer) throws AnalysisException { - if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.OPERATOR)) { - ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "NODE"); + if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.ADMIN.getPrivs().toString()); } if (properties == null) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterPolicyStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterPolicyStmt.java index 91a5f143752c3b..c8128e2bcbdb68 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterPolicyStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterPolicyStmt.java @@ -53,8 +53,10 @@ public void analyze(Analyzer analyzer) throws UserException { super.analyze(analyzer); // check auth - if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { - ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "ADMIN"); + if (!Env.getCurrentEnv().getAccessManager() + .checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.ADMIN.getPrivs().toString()); } if (properties == null || properties.isEmpty()) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterViewStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterViewStmt.java index 6e0da716b078bf..355c9723c8b220 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterViewStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterViewStmt.java @@ -62,9 +62,8 @@ public void analyze(Analyzer analyzer) throws UserException { if (!Env.getCurrentEnv().getAccessManager() .checkTblPriv(ConnectContext.get(), tableName.getCtl(), tableName.getDb(), tableName.getTbl(), PrivPredicate.ALTER)) { - ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR, "ALTER VIEW", - ConnectContext.get().getQualifiedUser(), ConnectContext.get().getRemoteIP(), - tableName.getDb() + ": " + tableName.getTbl()); + ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLE_ACCESS_DENIED_ERROR, + PrivPredicate.ALTER.getPrivs().toString(), tableName.getTbl()); } if (cols != null) { @@ -74,7 +73,7 @@ public void analyze(Analyzer analyzer) throws UserException { viewDefStmt.setNeedToSql(true); Analyzer viewAnalyzer = new Analyzer(analyzer); viewDefStmt.analyze(viewAnalyzer); - + checkQueryAuth(); createColumnAndViewDefs(analyzer); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/BaseViewStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/BaseViewStmt.java index d8740f03f523b9..545d7c1c57a4dd 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/BaseViewStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/BaseViewStmt.java @@ -18,15 +18,20 @@ package org.apache.doris.analysis; import org.apache.doris.catalog.Column; +import org.apache.doris.catalog.Env; import org.apache.doris.catalog.Type; import org.apache.doris.common.AnalysisException; import org.apache.doris.common.ErrorCode; import org.apache.doris.common.ErrorReport; import org.apache.doris.common.UserException; import org.apache.doris.common.util.ToSqlContext; +import org.apache.doris.datasource.InternalCatalog; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.qe.ConnectContext; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -72,6 +77,28 @@ public String getInlineViewDef() { return inlineViewDef; } + protected void checkQueryAuth() throws UserException { + for (int i = 0; i < viewDefStmt.getBaseTblResultExprs().size(); ++i) { + Expr expr = viewDefStmt.getBaseTblResultExprs().get(i); + if (!(expr instanceof SlotRef)) { + continue; + } + SlotRef slotRef = (SlotRef) expr; + TableName queryTableName = slotRef.getTableName(); + if (queryTableName == null) { + continue; + } + String queryColumnName = slotRef.getColumnName(); + String ctlName = StringUtils.isEmpty(queryTableName.getCtl()) ? InternalCatalog.INTERNAL_CATALOG_NAME + : queryTableName.getCtl(); + // check privilege + Env.getCurrentEnv().getAccessManager() + .checkColumnsPriv(ConnectContext.get().getCurrentUserIdentity(), ctlName, + queryTableName.getDb(), queryTableName.getTbl(), Sets.newHashSet(queryColumnName), + PrivPredicate.SELECT); + } + } + /** * Sets the originalViewDef and the expanded inlineViewDef based on viewDefStmt. * If columnNames were given, checks that they do not contain duplicate column names diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CancelAlterSystemStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CancelAlterSystemStmt.java index 9b547a4de53b77..e3a465d2d904ea 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CancelAlterSystemStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CancelAlterSystemStmt.java @@ -17,7 +17,12 @@ package org.apache.doris.analysis; +import org.apache.doris.catalog.Env; import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.qe.ConnectContext; import org.apache.doris.system.SystemInfoService; import org.apache.doris.system.SystemInfoService.HostInfo; @@ -44,6 +49,10 @@ public CancelAlterSystemStmt(List params) { @Override public void analyze(Analyzer analyzer) throws AnalysisException { + if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.OPERATOR)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.OPERATOR.getPrivs().toString()); + } for (String param : params) { if (!param.contains(":")) { ids.add(param); diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreatePolicyStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreatePolicyStmt.java index 4d8527c0f79245..8aedccb6e75ca2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreatePolicyStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreatePolicyStmt.java @@ -101,6 +101,12 @@ public void analyze(Analyzer analyzer) throws UserException { throw new UserException("storage policy feature is disabled by default. " + "Enable it by setting 'enable_storage_policy=true' in fe.conf"); } + // check auth + if (!Env.getCurrentEnv().getAccessManager() + .checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.ADMIN.getPrivs().toString()); + } break; case ROW: default: @@ -112,10 +118,12 @@ public void analyze(Analyzer analyzer) throws UserException { user.getQualifiedUser(), user.getHost(), tableName.getTbl()); } } - } - // check auth - if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { - ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "ADMIN"); + // check auth + if (!Env.getCurrentEnv().getAccessManager() + .checkGlobalPriv(ConnectContext.get(), PrivPredicate.GRANT)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.GRANT.getPrivs().toString()); + } } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateViewStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateViewStmt.java index 8b53d18fd9b602..2029b464100daa 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateViewStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateViewStmt.java @@ -67,7 +67,8 @@ public void analyze(Analyzer analyzer) throws UserException { if (!Env.getCurrentEnv().getAccessManager() .checkTblPriv(ConnectContext.get(), tableName.getCtl(), tableName.getDb(), tableName.getTbl(), PrivPredicate.CREATE)) { - ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "CREATE"); + ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLE_ACCESS_DENIED_ERROR, + PrivPredicate.CREATE.getPrivs().toString(), tableName.getTbl()); } // Do not rewrite nondeterministic functions to constant in create view's def stmt @@ -84,7 +85,7 @@ public void analyze(Analyzer analyzer) throws UserException { Analyzer viewAnalyzer = new Analyzer(analyzer); viewDefStmt.forbiddenMVRewrite(); viewDefStmt.analyze(viewAnalyzer); - + checkQueryAuth(); createColumnAndViewDefs(viewAnalyzer); } finally { // must reset this flag, otherwise, all following query statement in this connection diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropMaterializedViewStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropMaterializedViewStmt.java index 9fe01f20a066fc..377cdcf415240e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropMaterializedViewStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropMaterializedViewStmt.java @@ -73,8 +73,9 @@ public void analyze(Analyzer analyzer) throws UserException { // check access if (!Env.getCurrentEnv().getAccessManager() .checkTblPriv(ConnectContext.get(), tableName.getCtl(), tableName.getDb(), - tableName.getTbl(), PrivPredicate.DROP)) { - ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "DROP"); + tableName.getTbl(), PrivPredicate.ALTER)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLE_ACCESS_DENIED_ERROR, + PrivPredicate.ALTER.getPrivs().toString(), tableName.getTbl()); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropPolicyStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropPolicyStmt.java index 2a3e3a2bf5c5fc..4bd20fe8c9b084 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropPolicyStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropPolicyStmt.java @@ -60,6 +60,12 @@ public void analyze(Analyzer analyzer) throws UserException { super.analyze(analyzer); switch (type) { case STORAGE: + // check auth + if (!Env.getCurrentEnv().getAccessManager() + .checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.ADMIN.getPrivs().toString()); + } break; case ROW: default: @@ -67,10 +73,12 @@ public void analyze(Analyzer analyzer) throws UserException { if (user != null) { user.analyze(); } - } - // check auth - if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { - ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "ADMIN"); + // check auth + if (!Env.getCurrentEnv().getAccessManager() + .checkGlobalPriv(ConnectContext.get(), PrivPredicate.GRANT)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.GRANT.getPrivs().toString()); + } } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/SetLdapPassVar.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/SetLdapPassVar.java index c4eed0e5b262e6..5f33c171a81567 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/SetLdapPassVar.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/SetLdapPassVar.java @@ -17,8 +17,11 @@ package org.apache.doris.analysis; +import org.apache.doris.catalog.Env; import org.apache.doris.common.AnalysisException; -import org.apache.doris.mysql.privilege.Auth; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; +import org.apache.doris.mysql.privilege.PrivPredicate; import org.apache.doris.qe.ConnectContext; public class SetLdapPassVar extends SetVar { @@ -35,11 +38,10 @@ public String getLdapPassword() { @Override public void analyze(Analyzer analyzer) throws AnalysisException { - if (!ConnectContext.get().getCurrentUserIdentity().getQualifiedUser().equals(Auth.ROOT_USER) - && !ConnectContext.get().getCurrentUserIdentity().getQualifiedUser().equals(Auth.ADMIN_USER)) { - throw new AnalysisException("Only root and admin user can set ldap admin password."); + if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.ADMIN.getPrivs().toString()); } - if (!passVar.isPlain()) { throw new AnalysisException("Only support set ldap password with plain text"); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCatalogRecycleBinStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCatalogRecycleBinStmt.java index fe241acf04764f..f15c3657240d87 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCatalogRecycleBinStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCatalogRecycleBinStmt.java @@ -18,12 +18,17 @@ package org.apache.doris.analysis; import org.apache.doris.catalog.Column; +import org.apache.doris.catalog.Env; import org.apache.doris.catalog.ScalarType; import org.apache.doris.common.AnalysisException; import org.apache.doris.common.CaseSensibility; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; import org.apache.doris.common.PatternMatcher; import org.apache.doris.common.PatternMatcherWrapper; import org.apache.doris.common.UserException; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.ShowResultSetMetaData; import com.google.common.base.Strings; @@ -52,6 +57,12 @@ public String getNameValue() { public void analyze(Analyzer analyzer) throws UserException { super.analyze(analyzer); + // check auth + if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.ADMIN.getPrivs().toString()); + } + if (where == null) { return; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateDbStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateDbStmt.java index d6c00c959ee4cc..b709be8d7e95c2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateDbStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateDbStmt.java @@ -24,7 +24,6 @@ import org.apache.doris.common.ErrorCode; import org.apache.doris.common.ErrorReport; import org.apache.doris.common.UserException; -import org.apache.doris.datasource.InternalCatalog; import org.apache.doris.mysql.privilege.PrivPredicate; import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.ShowResultSetMetaData; @@ -67,11 +66,10 @@ public void analyze(Analyzer analyzer) throws AnalysisException, UserException { ErrorReport.reportAnalysisException(ErrorCode.ERR_WRONG_DB_NAME, db); } - if (!Env.getCurrentEnv().getAccessManager() - .checkDbPriv(ConnectContext.get(), InternalCatalog.INTERNAL_CATALOG_NAME, db, - PrivPredicate.ALTER_CREATE_DROP)) { - ErrorReport.reportAnalysisException(ErrorCode.ERR_DBACCESS_DENIED_ERROR, - ConnectContext.get().getQualifiedUser(), db); + if (!Env.getCurrentEnv().getAccessManager().checkDbPriv(ConnectContext.get(), ctl, db, + PrivPredicate.SHOW)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_DB_ACCESS_DENIED_ERROR, + PrivPredicate.SHOW.getPrivs().toString(), db); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateRepositoryStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateRepositoryStmt.java index f11a02253699c3..9de7dd0e9eed72 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateRepositoryStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateRepositoryStmt.java @@ -18,8 +18,13 @@ package org.apache.doris.analysis; import org.apache.doris.catalog.Column; +import org.apache.doris.catalog.Env; import org.apache.doris.catalog.ScalarType; import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.ShowResultSetMetaData; // SHOW CREATE REPOSITORY statement @@ -43,7 +48,11 @@ public String getRepoName() { @Override public void analyze(Analyzer analyzer) throws AnalysisException { - + // check auth + if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.ADMIN.getPrivs().toString()); + } } @Override diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowDataStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowDataStmt.java index 04534b17a467dd..97828a005f9114 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowDataStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowDataStmt.java @@ -424,7 +424,12 @@ public String toString() { return toSql(); } - private void getAllDbStats() { + private void getAllDbStats() throws AnalysisException { + // check auth + if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.ADMIN.getPrivs().toString()); + } List dbNames = Env.getCurrentInternalCatalog().getDbNames(); if (dbNames == null || dbNames.isEmpty()) { return; diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowEncryptKeysStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowEncryptKeysStmt.java index f72c972c6e1c91..83358209c23539 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowEncryptKeysStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowEncryptKeysStmt.java @@ -24,7 +24,6 @@ import org.apache.doris.common.ErrorCode; import org.apache.doris.common.ErrorReport; import org.apache.doris.common.UserException; -import org.apache.doris.datasource.InternalCatalog; import org.apache.doris.mysql.privilege.PrivPredicate; import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.ShowResultSetMetaData; @@ -64,14 +63,11 @@ public void analyze(Analyzer analyzer) throws AnalysisException, UserException { } } - // must check after analyze dbName, for case dbName is null. - if (!Env.getCurrentEnv().getAccessManager() - .checkDbPriv(ConnectContext.get(), InternalCatalog.INTERNAL_CATALOG_NAME, dbName, - PrivPredicate.ADMIN)) { - ErrorReport.reportAnalysisException( - ErrorCode.ERR_DBACCESS_DENIED_ERROR, ConnectContext.get().getQualifiedUser(), dbName); + // check auth + if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.ADMIN.getPrivs().toString()); } - } public boolean like(String str) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowPluginsStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowPluginsStmt.java index 65ffa65622af33..249e49da28dbaf 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowPluginsStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowPluginsStmt.java @@ -18,7 +18,13 @@ package org.apache.doris.analysis; import org.apache.doris.catalog.Column; +import org.apache.doris.catalog.Env; import org.apache.doris.catalog.ScalarType; +import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.ShowResultSetMetaData; // Show plugins statement. @@ -39,7 +45,12 @@ public class ShowPluginsStmt extends ShowStmt { .build(); @Override - public void analyze(Analyzer analyzer) { + public void analyze(Analyzer analyzer) throws AnalysisException { + // check auth + if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.ADMIN.getPrivs().toString()); + } } @Override diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowRepositoriesStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowRepositoriesStmt.java index dbbd5d7b36f98d..6e5166a5c870b8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowRepositoriesStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowRepositoriesStmt.java @@ -18,7 +18,13 @@ package org.apache.doris.analysis; import org.apache.doris.catalog.Column; +import org.apache.doris.catalog.Env; import org.apache.doris.catalog.ScalarType; +import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.ShowResultSetMetaData; import com.google.common.collect.ImmutableList; @@ -33,6 +39,15 @@ public ShowRepositoriesStmt() { } + @Override + public void analyze(Analyzer analyzer) throws AnalysisException { + // check auth + if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.ADMIN.getPrivs().toString()); + } + } + @Override public ShowResultSetMetaData getMetaData() { ShowResultSetMetaData.Builder builder = ShowResultSetMetaData.builder(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowSnapshotStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowSnapshotStmt.java index d10d216b120ad1..83465a34600587 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowSnapshotStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowSnapshotStmt.java @@ -19,9 +19,14 @@ import org.apache.doris.analysis.CompoundPredicate.Operator; import org.apache.doris.catalog.Column; +import org.apache.doris.catalog.Env; import org.apache.doris.catalog.ScalarType; import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; import org.apache.doris.common.UserException; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.ShowResultSetMetaData; import com.google.common.base.Strings; @@ -55,6 +60,12 @@ public ShowSnapshotStmt(String repoName, Expr where) { public void analyze(Analyzer analyzer) throws UserException { super.analyze(analyzer); + // check auth + if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.ADMIN.getPrivs().toString()); + } + // analyze where clause if not null if (where != null) { // eg: WHERE snapshot="snapshot_label" [and timestamp="2018-04-19-11-11:11"]; diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowTabletsBelongStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowTabletsBelongStmt.java index b321dace7f555e..3819541fea9a72 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowTabletsBelongStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowTabletsBelongStmt.java @@ -18,8 +18,13 @@ package org.apache.doris.analysis; import org.apache.doris.catalog.Column; +import org.apache.doris.catalog.Env; import org.apache.doris.catalog.ScalarType; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; import org.apache.doris.common.UserException; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.ShowResultSetMetaData; import com.google.common.collect.ImmutableList; @@ -54,6 +59,11 @@ public List getTabletIds() { @Override public void analyze(Analyzer analyzer) throws UserException { + // check auth + if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.ADMIN.getPrivs().toString()); + } if (tabletIds == null || tabletIds.isEmpty()) { throw new UserException("Please supply at least one tablet id"); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowTransactionStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowTransactionStmt.java index f34c0e5e3363bb..3d5d03bdf8f768 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowTransactionStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowTransactionStmt.java @@ -19,12 +19,15 @@ import org.apache.doris.analysis.BinaryPredicate.Operator; import org.apache.doris.catalog.Column; +import org.apache.doris.catalog.Env; import org.apache.doris.catalog.ScalarType; import org.apache.doris.common.AnalysisException; import org.apache.doris.common.ErrorCode; import org.apache.doris.common.ErrorReport; import org.apache.doris.common.UserException; import org.apache.doris.common.proc.TransProcDir; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.ShowResultSetMetaData; import org.apache.doris.transaction.TransactionStatus; @@ -70,9 +73,15 @@ public boolean labelMatch() { } @Override - public void analyze(Analyzer analyzer) throws AnalysisException, UserException { + public void analyze(Analyzer analyzer) throws UserException { super.analyze(analyzer); + // check auth + if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, + PrivPredicate.ADMIN.getPrivs().toString()); + } + if (Strings.isNullOrEmpty(dbName)) { dbName = analyzer.getDefaultDb(); if (Strings.isNullOrEmpty(dbName)) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/common/ErrorCode.java b/fe/fe-core/src/main/java/org/apache/doris/common/ErrorCode.java index c5841f571b4752..6474f208c6d958 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/common/ErrorCode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/common/ErrorCode.java @@ -73,8 +73,14 @@ public enum ErrorCode { ERR_USER_LIMIT_REACHED(1226, new byte[]{'4', '2', '0', '0', '0'}, "User '%s' has exceeded the '%s' resource " + "(current value: %d)"), ERR_SPECIFIC_ACCESS_DENIED_ERROR(1227, new byte[]{'4', '2', '0', '0', '0'}, "Access denied; you need (at least " - + "one of) the %s privilege(s) for this operation"), - ERR_SPECIFIC_ALL_ACCESS_DENIED_ERROR(1227, new byte[] {'4', '2', '0', '0', '0'}, "Access denied; you need all " + + "one of) the (%s) privilege(s) for this operation"), + ERR_DB_ACCESS_DENIED_ERROR(1225, new byte[]{'4', '2', '0', '0', '0'}, "Access denied; you need (at least " + + "one of) the (%s) privilege(s) on database %s for this operation"), + + ERR_TABLE_ACCESS_DENIED_ERROR(1224, new byte[]{'4', '2', '0', '0', '0'}, "Access denied; you need (at least " + + "one of) the (%s) privilege(s) on table %s for this operation"), + + ERR_SPECIFIC_ALL_ACCESS_DENIED_ERROR(1223, new byte[] {'4', '2', '0', '0', '0'}, "Access denied; you need all " + " %s privilege(s) for this operation"), ERR_LOCAL_VARIABLE(1228, new byte[]{'H', 'Y', '0', '0', '0'}, "Variable '%s' is a SESSION variable and can't be " + "used with SET GLOBAL"), @@ -1019,6 +1025,8 @@ public enum ErrorCode { + "DISCARD the tablespace before IMPORT."), ERR_TABLESPACE_DISCARDED(1814, new byte[]{'H', 'Y', '0', '0', '0'}, "Tablespace has been discarded for table '%s'"), ERR_INTERNAL_ERROR(1815, new byte[]{'H', 'Y', '0', '0', '0'}, "Internal error: %s"), + + ERR_MUST_CHANGE_PASSWORD_LOGIN(1862, new byte[]{'H', 'Y', '0', '0', '0'}, "Your password has expired. To log in " + "you must change it using a client that supports expired passwords."), ERR_CREDENTIALS_CONTRADICT_TO_HISTORY(3638, new byte[] {'H', 'Y', '0', '0', '0'}, diff --git a/fe/fe-core/src/main/java/org/apache/doris/job/manager/JobManager.java b/fe/fe-core/src/main/java/org/apache/doris/job/manager/JobManager.java index 7e8b01ce28775a..d8a30a968a6716 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/job/manager/JobManager.java +++ b/fe/fe-core/src/main/java/org/apache/doris/job/manager/JobManager.java @@ -24,11 +24,14 @@ import org.apache.doris.common.AnalysisException; import org.apache.doris.common.CaseSensibility; import org.apache.doris.common.DdlException; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; import org.apache.doris.common.PatternMatcher; import org.apache.doris.common.PatternMatcherWrapper; import org.apache.doris.common.io.Writable; import org.apache.doris.common.util.LogBuilder; import org.apache.doris.common.util.LogKey; +import org.apache.doris.datasource.InternalCatalog; import org.apache.doris.job.base.AbstractJob; import org.apache.doris.job.common.JobStatus; import org.apache.doris.job.common.JobType; @@ -37,6 +40,8 @@ import org.apache.doris.job.extensions.insert.InsertJob; import org.apache.doris.job.scheduler.JobScheduler; import org.apache.doris.load.loadv2.JobState; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.qe.ConnectContext; import com.google.common.collect.Lists; import lombok.extern.log4j.Log4j2; @@ -48,6 +53,7 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.stream.Collectors; @@ -341,7 +347,7 @@ public T getJob(Long jobId) { public List> getLoadJobInfosByDb(long dbId, String dbName, String labelValue, boolean accurateMatch, - JobState jobState) throws AnalysisException { + JobState jobState, String catalogName) throws AnalysisException { LinkedList> loadJobInfos = new LinkedList<>(); if (!Env.getCurrentEnv().getLabelProcessor().existJobs(dbId)) { return loadJobInfos; @@ -356,6 +362,12 @@ public List> getLoadJobInfosByDb(long dbId, String dbName, if (jobState != null && !validState(jobState, loadJob)) { continue; } + // check auth + try { + checkJobAuth(catalogName, dbName, loadJob.getTableNames()); + } catch (AnalysisException e) { + continue; + } // add load job info, convert String list to Comparable list loadJobInfos.add(new ArrayList<>(loadJob.getShowInfo())); } catch (RuntimeException e) { @@ -369,6 +381,27 @@ public List> getLoadJobInfosByDb(long dbId, String dbName, } } + public void checkJobAuth(String ctlName, String dbName, Set tableNames) throws AnalysisException { + if (tableNames.isEmpty()) { + if (!Env.getCurrentEnv().getAccessManager() + .checkDbPriv(ConnectContext.get(), ctlName, dbName, + PrivPredicate.LOAD)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_DB_ACCESS_DENIED_ERROR, + PrivPredicate.LOAD.getPrivs().toString(), dbName); + } + } else { + for (String tblName : tableNames) { + if (!Env.getCurrentEnv().getAccessManager() + .checkTblPriv(ConnectContext.get(), ctlName, dbName, + tblName, PrivPredicate.LOAD)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLE_ACCESS_DENIED_ERROR, + PrivPredicate.LOAD.getPrivs().toString(), tblName); + return; + } + } + } + } + private static boolean validState(JobState jobState, InsertJob loadJob) { JobStatus status = loadJob.getJobStatus(); switch (status) { @@ -412,6 +445,27 @@ public void cancelLoadJob(CancelLoadStmt cs) } finally { readUnlock(); } + // check auth + if (unfinishedLoadJob.size() > 1 || unfinishedLoadJob.get(0).getTableNames().isEmpty()) { + if (Env.getCurrentEnv().getAccessManager() + .checkDbPriv(ConnectContext.get(), InternalCatalog.INTERNAL_CATALOG_NAME, dbName, + PrivPredicate.LOAD)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_DBACCESS_DENIED_ERROR, "LOAD", + ConnectContext.get().getQualifiedUser(), + ConnectContext.get().getRemoteIP(), dbName); + } + } else { + for (String tableName : unfinishedLoadJob.get(0).getTableNames()) { + if (Env.getCurrentEnv().getAccessManager() + .checkTblPriv(ConnectContext.get(), InternalCatalog.INTERNAL_CATALOG_NAME, dbName, + tableName, + PrivPredicate.LOAD)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR, "LOAD", + ConnectContext.get().getQualifiedUser(), + ConnectContext.get().getRemoteIP(), dbName + ":" + tableName); + } + } + } for (InsertJob loadJob : unfinishedLoadJob) { try { alterJobStatus(loadJob.getJobId(), JobStatus.STOPPED); diff --git a/fe/fe-core/src/main/java/org/apache/doris/load/ExportMgr.java b/fe/fe-core/src/main/java/org/apache/doris/load/ExportMgr.java index 4702dd7a9ae92b..afc7ea51984475 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/load/ExportMgr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/load/ExportMgr.java @@ -26,6 +26,8 @@ import org.apache.doris.common.CaseSensibility; import org.apache.doris.common.Config; import org.apache.doris.common.DdlException; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; import org.apache.doris.common.FeConstants; import org.apache.doris.common.LabelAlreadyUsedException; import org.apache.doris.common.PatternMatcher; @@ -123,6 +125,9 @@ public void cancelExportJob(CancelExportStmt stmt) throws DdlException, Analysis if (matchExportJobs.isEmpty()) { throw new DdlException("All export job(s) are at final state (CANCELLED/FINISHED)"); } + + // check auth + checkCancelExportJobAuth(InternalCatalog.INTERNAL_CATALOG_NAME, stmt.getDbName(), matchExportJobs); try { for (ExportJob exportJob : matchExportJobs) { // exportJob.cancel(ExportFailMsg.CancelType.USER_CANCEL, "user cancel"); @@ -134,6 +139,29 @@ public void cancelExportJob(CancelExportStmt stmt) throws DdlException, Analysis } } + public void checkCancelExportJobAuth(String ctlName, String dbName, List jobs) throws AnalysisException { + if (jobs.size() > 1) { + if (Env.getCurrentEnv().getAccessManager() + .checkDbPriv(ConnectContext.get(), ctlName, dbName, + PrivPredicate.SELECT)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_DB_ACCESS_DENIED_ERROR, + PrivPredicate.SELECT.getPrivs().toString(), dbName); + } + } else { + TableName tableName = jobs.get(0).getTableName(); + if (tableName == null) { + return; + } + if (Env.getCurrentEnv().getAccessManager() + .checkTblPriv(ConnectContext.get(), ctlName, dbName, + tableName.getTbl(), + PrivPredicate.SELECT)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLE_ACCESS_DENIED_ERROR, + PrivPredicate.SELECT.getPrivs().toString(), tableName.getTbl()); + } + } + } + public void unprotectAddJob(ExportJob job) { exportIdToJob.put(job.getId(), job); dbTolabelToExportJobId.computeIfAbsent(job.getDbId(), @@ -395,7 +423,7 @@ public void removeOldExportJobs() { ExportJob job = entry.getValue(); if ((currentTimeMs - job.getCreateTimeMs()) / 1000 > Config.history_job_keep_max_second && (job.getState() == ExportJobState.CANCELLED - || job.getState() == ExportJobState.FINISHED)) { + || job.getState() == ExportJobState.FINISHED)) { iter.remove(); Map labelJobs = dbTolabelToExportJobId.get(job.getDbId()); if (labelJobs != null) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/load/StreamLoadRecord.java b/fe/fe-core/src/main/java/org/apache/doris/load/StreamLoadRecord.java index ecbaa2f48eefe2..6ce8be66bbe50b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/load/StreamLoadRecord.java +++ b/fe/fe-core/src/main/java/org/apache/doris/load/StreamLoadRecord.java @@ -93,4 +93,12 @@ public String getStatus() { public String getFinishTime() { return this.finishTime; } + + public String getDb() { + return db; + } + + public String getTable() { + return table; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/load/StreamLoadRecordMgr.java b/fe/fe-core/src/main/java/org/apache/doris/load/StreamLoadRecordMgr.java index 488e73f3ab43c7..3ceeaa1f38a421 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/load/StreamLoadRecordMgr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/load/StreamLoadRecordMgr.java @@ -27,10 +27,13 @@ import org.apache.doris.common.io.Writable; import org.apache.doris.common.util.MasterDaemon; import org.apache.doris.common.util.TimeUtils; +import org.apache.doris.datasource.InternalCatalog; +import org.apache.doris.mysql.privilege.PrivPredicate; import org.apache.doris.persist.gson.GsonUtils; import org.apache.doris.plugin.audit.AuditEvent; import org.apache.doris.plugin.audit.AuditEvent.EventType; import org.apache.doris.plugin.audit.StreamLoadAuditEvent; +import org.apache.doris.qe.ConnectContext; import org.apache.doris.system.Backend; import org.apache.doris.thrift.BackendService; import org.apache.doris.thrift.TNetworkAddress; @@ -186,6 +189,13 @@ public List> getStreamLoadRecordByDb( if (state != null && !String.valueOf(state).equalsIgnoreCase(streamLoadRecord.getStatus())) { continue; } + // check auth + if (!Env.getCurrentEnv().getAccessManager() + .checkTblPriv(ConnectContext.get(), InternalCatalog.INTERNAL_CATALOG_NAME, + streamLoadRecord.getDb(), streamLoadRecord.getTable(), + PrivPredicate.LOAD)) { + continue; + } streamLoadRecords.add(streamLoadRecord.getStreamLoadInfo()); } catch (Exception e) { continue; diff --git a/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/LoadManager.java b/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/LoadManager.java index 073fec83e12985..0b67ba544c6bbe 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/LoadManager.java +++ b/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/LoadManager.java @@ -31,6 +31,8 @@ import org.apache.doris.common.Config; import org.apache.doris.common.DataQualityException; import org.apache.doris.common.DdlException; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; import org.apache.doris.common.LabelAlreadyUsedException; import org.apache.doris.common.MetaNotFoundException; import org.apache.doris.common.Pair; @@ -613,9 +615,16 @@ public List> getLoadJobInfosByDb(long dbId, String labelValue, if (!states.contains(loadJob.getState())) { continue; } + // check auth + try { + checkJobAuth(loadJob.getDb().getCatalog().getName(), loadJob.getDb().getName(), + loadJob.getTableNames()); + } catch (AnalysisException e) { + continue; + } // add load job info loadJobInfos.add(loadJob.getShowInfo()); - } catch (RuntimeException | DdlException e) { + } catch (RuntimeException | DdlException | MetaNotFoundException e) { // ignore this load job LOG.warn("get load job info failed. job id: {}", loadJob.getId(), e); } @@ -626,6 +635,27 @@ public List> getLoadJobInfosByDb(long dbId, String labelValue, } } + public void checkJobAuth(String ctlName, String dbName, Set tableNames) throws AnalysisException { + if (tableNames.isEmpty()) { + if (!Env.getCurrentEnv().getAccessManager() + .checkDbPriv(ConnectContext.get(), ctlName, dbName, + PrivPredicate.LOAD)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_DB_ACCESS_DENIED_ERROR, + PrivPredicate.LOAD.getPrivs().toString(), dbName); + } + } else { + for (String tblName : tableNames) { + if (!Env.getCurrentEnv().getAccessManager() + .checkTblPriv(ConnectContext.get(), ctlName, dbName, + tblName, PrivPredicate.LOAD)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLE_ACCESS_DENIED_ERROR, + PrivPredicate.LOAD.getPrivs().toString(), tblName); + return; + } + } + } + } + public List> getAllLoadJobInfos() { LinkedList> loadJobInfos = new LinkedList>(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PrivBitSet.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PrivBitSet.java index 1397d3ce477a9a..f2335e63c89268 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PrivBitSet.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/PrivBitSet.java @@ -158,10 +158,15 @@ public String toString() { StringBuilder sb = new StringBuilder(); Privilege.privileges.keySet().forEach(idx -> { if (get(idx)) { - sb.append(Privilege.getPriv(idx)).append(" "); + sb.append(Privilege.getPriv(idx)).append(","); } }); - return sb.toString(); + String res = sb.toString(); + if (res.length() > 0) { + return res.substring(0, res.length() - 1); + } else { + return res; + } } public static PrivBitSet read(DataInput in) throws IOException { diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java index 6136a0be42ebd9..e60c1aa68cbf05 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java @@ -1307,7 +1307,7 @@ private void handleShowLoad() throws AnalysisException { // add the nerieds load info JobManager loadMgr = env.getJobManager(); loadInfos.addAll(loadMgr.getLoadJobInfosByDb(dbId, db.getFullName(), showStmt.getLabelValue(), - showStmt.isAccurateMatch(), showStmt.getStateV2())); + showStmt.isAccurateMatch(), showStmt.getStateV2(), db.getCatalog().getName())); // order the result of List by orderByPairs in show stmt List orderByPairs = showStmt.getOrderByPairs(); diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/CancelExportStmtTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/CancelExportStmtTest.java index a5cff4fca1aa2a..0b4ecad12e23bd 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/CancelExportStmtTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/CancelExportStmtTest.java @@ -28,9 +28,9 @@ import org.apache.doris.utframe.TestWithFeService; import com.google.common.collect.Lists; +import org.junit.Assert; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.wildfly.common.Assert; import java.lang.reflect.Method; import java.util.List; @@ -350,4 +350,30 @@ public void testExportMgrCancelJob() throws UserException { exportMgr.cancelExportJob(stmt); Assert.assertTrue(job8.getState() == ExportJobState.CANCELLED); } + + @Test + public void testCancelAuth() { + ExportMgr exportMgr = new ExportMgr(); + List jobs = Lists.newArrayList(); + ExportJob job1 = new ExportJob(); + job1.setTableName(new TableName("ctl1", "db1", "table1")); + jobs.add(job1); + try { + // should check table auth + exportMgr.checkCancelExportJobAuth("ctl1", "db1", jobs); + throw new RuntimeException("should exception"); + } catch (AnalysisException e) { + Assert.assertTrue(e.getMessage().contains("Admin_priv,Select_priv")); + Assert.assertTrue(e.getMessage().contains("table1")); + } + jobs.add(new ExportJob()); + try { + // should check db auth + exportMgr.checkCancelExportJobAuth("ctl1", "db1", jobs); + throw new RuntimeException("should exception"); + } catch (AnalysisException e) { + Assert.assertTrue(e.getMessage().contains("Admin_priv,Select_priv")); + Assert.assertTrue(e.getMessage().contains("db1")); + } + } } diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/DropMaterializedViewStmtTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/DropMaterializedViewStmtTest.java index 617f6bf512e769..b43fa6a5ad48d1 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/DropMaterializedViewStmtTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/DropMaterializedViewStmtTest.java @@ -51,7 +51,7 @@ public void testNoPermission(@Injectable TableName tableName) { new Expectations() { { accessManager.checkTblPriv(ConnectContext.get(), tableName.getCtl(), tableName.getDb(), - tableName.getTbl(), PrivPredicate.DROP); + tableName.getTbl(), PrivPredicate.ALTER); result = false; } }; 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 d37058c20cd67d..aee15abd27884b 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 @@ -138,7 +138,7 @@ public void testRefreshPriv() throws Exception { user1.analyze(); 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", + "Access denied", () -> parseAndAnalyzeStmt("refresh table test1.db1.tbl11", user1Ctx)); ConnectContext.remove(); diff --git a/fe/fe-core/src/test/java/org/apache/doris/job/manager/JobManagerTest.java b/fe/fe-core/src/test/java/org/apache/doris/job/manager/JobManagerTest.java new file mode 100644 index 00000000000000..9e3aa386cd06e7 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/job/manager/JobManagerTest.java @@ -0,0 +1,65 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.job.manager; + +import org.apache.doris.analysis.UserIdentity; +import org.apache.doris.common.AnalysisException; +import org.apache.doris.qe.ConnectContext; +import org.apache.doris.utframe.TestWithFeService; + +import com.google.common.collect.Sets; +import mockit.Expectations; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.util.HashSet; + +public class JobManagerTest { + @Test + public void testJobAuth() throws IOException, AnalysisException { + UserIdentity user1 = new UserIdentity("testJobAuthUser", "%"); + user1.analyze(); + new Expectations() { + { + ConnectContext.get(); + minTimes = 0; + result = TestWithFeService.createCtx(user1, "%"); + } + }; + JobManager manager = new JobManager(); + HashSet tableNames = Sets.newHashSet(); + try { + // should check db auth + manager.checkJobAuth("ctl1", "db1", tableNames); + throw new RuntimeException("should exception"); + } catch (AnalysisException e) { + Assert.assertTrue(e.getMessage().contains("Admin_priv,Load_priv")); + Assert.assertTrue(e.getMessage().contains("db1")); + } + tableNames.add("table1"); + try { + // should check db auth + manager.checkJobAuth("ctl1", "db1", tableNames); + throw new RuntimeException("should exception"); + } catch (AnalysisException e) { + Assert.assertTrue(e.getMessage().contains("Admin_priv,Load_priv")); + Assert.assertTrue(e.getMessage().contains("table1")); + } + } +} diff --git a/fe/fe-core/src/test/java/org/apache/doris/load/loadv2/LoadManagerTest.java b/fe/fe-core/src/test/java/org/apache/doris/load/loadv2/LoadManagerTest.java index e9b3278cfd08fa..9c09c72bd79a56 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/load/loadv2/LoadManagerTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/load/loadv2/LoadManagerTest.java @@ -21,12 +21,16 @@ import org.apache.doris.catalog.Database; import org.apache.doris.catalog.Env; import org.apache.doris.catalog.Table; +import org.apache.doris.common.AnalysisException; import org.apache.doris.common.Config; import org.apache.doris.common.FeMetaVersion; import org.apache.doris.common.jmockit.Deencapsulation; import org.apache.doris.datasource.InternalCatalog; import org.apache.doris.meta.MetaContext; +import org.apache.doris.qe.ConnectContext; +import org.apache.doris.utframe.TestWithFeService; +import com.google.common.collect.Sets; import mockit.Expectations; import mockit.Injectable; import mockit.Mocked; @@ -40,6 +44,8 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; +import java.io.IOException; +import java.util.HashSet; import java.util.List; import java.util.Map; @@ -195,4 +201,36 @@ private LoadManager deserializeFromFile(File file) throws Exception { loadManager.readFields(dis); return loadManager; } + + @Test + public void testJobAuth() throws IOException, AnalysisException { + UserIdentity user1 = new UserIdentity("testJobAuthUser", "%"); + user1.analyze(); + new Expectations() { + { + ConnectContext.get(); + minTimes = 0; + result = TestWithFeService.createCtx(user1, "%"); + } + }; + LoadManager manager = new LoadManager(new LoadJobScheduler()); + HashSet tableNames = Sets.newHashSet(); + try { + // should check db auth + manager.checkJobAuth("ctl1", "db1", tableNames); + throw new RuntimeException("should exception"); + } catch (AnalysisException e) { + Assert.assertTrue(e.getMessage().contains("Admin_priv,Load_priv")); + Assert.assertTrue(e.getMessage().contains("db1")); + } + tableNames.add("table1"); + try { + // should check db auth + manager.checkJobAuth("ctl1", "db1", tableNames); + throw new RuntimeException("should exception"); + } catch (AnalysisException e) { + Assert.assertTrue(e.getMessage().contains("Admin_priv,Load_priv")); + Assert.assertTrue(e.getMessage().contains("table1")); + } + } } diff --git a/fe/fe-core/src/test/java/org/apache/doris/planner/PlannerTest.java b/fe/fe-core/src/test/java/org/apache/doris/planner/PlannerTest.java index 41f21110330478..de9e828bacb90c 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/planner/PlannerTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/planner/PlannerTest.java @@ -497,7 +497,7 @@ public void testUpdateUnique() throws Exception { QueryState state = connectContext.getState(); Assertions.assertEquals(MysqlStateType.ERR, state.getStateType()); Assertions.assertTrue(state.getErrorMessage() - .contains("you need (at least one of) the LOAD privilege(s) for this operation")); + .contains("you need (at least one of) the (LOAD) privilege(s) for this operation")); // set to admin user connectContext.setCurrentUserIdentity(UserIdentity.ADMIN); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/utframe/TestWithFeService.java b/fe/fe-core/src/test/java/org/apache/doris/utframe/TestWithFeService.java index 8b06b7a2633a2c..37bc5f431f8257 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/utframe/TestWithFeService.java +++ b/fe/fe-core/src/test/java/org/apache/doris/utframe/TestWithFeService.java @@ -278,7 +278,7 @@ public StatementBase analyzeAndGetStmtByNereids(String sql, ConnectContext ctx) return adapter; } - protected static ConnectContext createCtx(UserIdentity user, String host) throws IOException { + public static ConnectContext createCtx(UserIdentity user, String host) throws IOException { ConnectContext ctx = new ConnectContext(); ctx.setCurrentUserIdentity(user); ctx.setQualifiedUser(user.getQualifiedUser()); diff --git a/regression-test/data/auth_p0/test_strict_mode.csv b/regression-test/data/auth_p0/test_strict_mode.csv new file mode 100644 index 00000000000000..fbad74eb481183 --- /dev/null +++ b/regression-test/data/auth_p0/test_strict_mode.csv @@ -0,0 +1,2 @@ +1,1 +1,2 diff --git a/regression-test/suites/auth_p0/test_admin_copy_tablet_auth.groovy b/regression-test/suites/auth_p0/test_admin_copy_tablet_auth.groovy new file mode 100644 index 00000000000000..c040dfb8e956c3 --- /dev/null +++ b/regression-test/suites/auth_p0/test_admin_copy_tablet_auth.groovy @@ -0,0 +1,35 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_admin_copy_tablet_auth","p0,auth") { + String user = 'test_admin_copy_tablet_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "ADMIN COPY TABLET 10010 PROPERTIES('backend_id' = '10001');" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_alter_policy_auth.groovy b/regression-test/suites/auth_p0/test_alter_policy_auth.groovy new file mode 100644 index 00000000000000..3b1e9af6e2c609 --- /dev/null +++ b/regression-test/suites/auth_p0/test_alter_policy_auth.groovy @@ -0,0 +1,37 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_alter_policy_auth","p0,auth") { + String user = 'test_alter_policy_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql """ + ALTER STORAGE POLICY has_test_policy_to_alter PROPERTIES("cooldown_datetime" = "2023-06-08 00:00:00"); + """ + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_alter_view_auth.groovy b/regression-test/suites/auth_p0/test_alter_view_auth.groovy new file mode 100644 index 00000000000000..52bf8ac75c7217 --- /dev/null +++ b/regression-test/suites/auth_p0/test_alter_view_auth.groovy @@ -0,0 +1,66 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_alter_view_auth","p0,auth") { + String user = 'test_alter_view_auth_user' + String pwd = 'C123_567p' + String dbName = 'test_alter_view_auth_db' + String tableName = 'test_alter_view_auth_table' + String viewName = 'test_alter_view_auth_view' + try_sql("DROP USER ${user}") + try_sql """drop table if exists ${dbName}.${tableName}""" + try_sql """drop view if exists ${dbName}.${viewName}""" + sql """drop database if exists ${dbName}""" + + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """create database ${dbName}""" + sql """ + CREATE TABLE IF NOT EXISTS ${dbName}.`${tableName}` ( + id BIGINT, + username VARCHAR(20) + ) + DISTRIBUTED BY HASH(id) BUCKETS 2 + PROPERTIES ( + "replication_num" = "1" + ); + """ + sql """grant select_priv on regression_test to ${user}""" + sql """create view ${dbName}.${viewName} as select * from ${dbName}.${tableName};""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "alter view ${dbName}.${viewName} as select * from ${dbName}.${tableName};" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv,Alter_priv")) + } + } + sql """grant Alter_priv on ${dbName}.${viewName} to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "alter view ${dbName}.${viewName} as select * from ${dbName}.${tableName};" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv,Select_priv")) + } + } + try_sql """drop table if exists ${dbName}.${tableName}""" + try_sql """drop view if exists ${dbName}.${viewName}""" + sql """drop database if exists ${dbName}""" + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_cancel_alter_system_auth.groovy b/regression-test/suites/auth_p0/test_cancel_alter_system_auth.groovy new file mode 100644 index 00000000000000..0e630fdae8e9cc --- /dev/null +++ b/regression-test/suites/auth_p0/test_cancel_alter_system_auth.groovy @@ -0,0 +1,35 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_cancel_alter_system_auth","p0,auth") { + String user = 'test_cancel_alter_system_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "CANCEL DECOMMISSION BACKEND 'id1';" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Node_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_create_policy_auth.groovy b/regression-test/suites/auth_p0/test_create_policy_auth.groovy new file mode 100644 index 00000000000000..8debfaedb273a7 --- /dev/null +++ b/regression-test/suites/auth_p0/test_create_policy_auth.groovy @@ -0,0 +1,47 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_create_policy_auth","p0,auth") { + String user = 'test_create_policy_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "CREATE ROW POLICY test_create_policy_auth ON test.table1 AS RESTRICTIVE TO test USING (c1 = 'a');" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv,Grant_priv")) + } + try { + sql """ + CREATE STORAGE POLICY testPolicy + PROPERTIES( + "storage_resource" = "s3", + "cooldown_datetime" = "2022-06-08 00:00:00" + ); + """ + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_create_view_auth.groovy b/regression-test/suites/auth_p0/test_create_view_auth.groovy new file mode 100644 index 00000000000000..124d3f96014073 --- /dev/null +++ b/regression-test/suites/auth_p0/test_create_view_auth.groovy @@ -0,0 +1,62 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_create_view_auth","p0,auth") { + String user = 'test_create_view_auth_user' + String pwd = 'C123_567p' + String dbName = 'test_create_view_auth_db' + String tableName = 'test_create_view_auth_table' + try_sql("DROP USER ${user}") + try_sql """drop table if exists ${dbName}.${tableName}""" + sql """drop database if exists ${dbName}""" + + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """create database ${dbName}""" + sql """ + CREATE TABLE IF NOT EXISTS ${dbName}.`${tableName}` ( + id BIGINT, + username VARCHAR(20) + ) + DISTRIBUTED BY HASH(id) BUCKETS 2 + PROPERTIES ( + "replication_num" = "1" + ); + """ + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "create view ${dbName}.v1 as select * from ${dbName}.t1;" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv,Create_priv")) + } + } + sql """grant create_priv on ${dbName}.v1 to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "create view ${dbName}.v1 as select * from ${dbName}.${tableName};" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv,Select_priv")) + } + } + sql """drop table if exists ${dbName}.${tableName}""" + sql """drop database if exists ${dbName}""" + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_drop_materialized_view_auth.groovy b/regression-test/suites/auth_p0/test_drop_materialized_view_auth.groovy new file mode 100644 index 00000000000000..4d55b1482cff12 --- /dev/null +++ b/regression-test/suites/auth_p0/test_drop_materialized_view_auth.groovy @@ -0,0 +1,35 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_drop_materialized_view_auth","p0,auth") { + String user = 'test_drop_materialized_view_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "DROP MATERIALIZED VIEW mv_name ON table_name;" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv,Alter_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_drop_policy_auth.groovy b/regression-test/suites/auth_p0/test_drop_policy_auth.groovy new file mode 100644 index 00000000000000..0d6a9e103d173f --- /dev/null +++ b/regression-test/suites/auth_p0/test_drop_policy_auth.groovy @@ -0,0 +1,43 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_drop_policy_auth","p0,auth") { + String user = 'test_drop_policy_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "DROP ROW POLICY test_row_policy_1 on table1;" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv,Grant_priv")) + } + try { + sql """ + DROP STORAGE POLICY policy_name1 + """ + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_set_ldap_admin_password_auth.groovy b/regression-test/suites/auth_p0/test_set_ldap_admin_password_auth.groovy new file mode 100644 index 00000000000000..6c5032f7ef9867 --- /dev/null +++ b/regression-test/suites/auth_p0/test_set_ldap_admin_password_auth.groovy @@ -0,0 +1,35 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_set_ldap_admin_password_auth","p0,auth") { + String user = 'test_set_ldap_admin_password_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "SET LDAP_ADMIN_PASSWORD = PASSWORD('plain password')" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_show_catalog_recycle_bin_auth.groovy b/regression-test/suites/auth_p0/test_show_catalog_recycle_bin_auth.groovy new file mode 100644 index 00000000000000..aa3ba7f8e2bfa2 --- /dev/null +++ b/regression-test/suites/auth_p0/test_show_catalog_recycle_bin_auth.groovy @@ -0,0 +1,35 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_show_catalog_recycle_bin_auth","p0,auth") { + String user = 'test_show_catalog_recycle_bin_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "SHOW CATALOG RECYCLE BIN WHERE NAME = 'test'" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_show_create_database_auth.groovy b/regression-test/suites/auth_p0/test_show_create_database_auth.groovy new file mode 100644 index 00000000000000..c4efff7d662478 --- /dev/null +++ b/regression-test/suites/auth_p0/test_show_create_database_auth.groovy @@ -0,0 +1,35 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_show_create_database_auth","p0,auth") { + String user = 'test_show_create_database_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "SHOW CREATE DATABASE db_name" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv,Select_priv,Load_priv,Alter_priv,Create_priv,Drop_priv,Show_view_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_show_create_repository_auth.groovy b/regression-test/suites/auth_p0/test_show_create_repository_auth.groovy new file mode 100644 index 00000000000000..5e787aead258bf --- /dev/null +++ b/regression-test/suites/auth_p0/test_show_create_repository_auth.groovy @@ -0,0 +1,35 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_show_create_repository_auth","p0,auth") { + String user = 'test_show_create_repository_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "SHOW CREATE REPOSITORY for repository_name" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_show_data_auth.groovy b/regression-test/suites/auth_p0/test_show_data_auth.groovy new file mode 100644 index 00000000000000..fdd42d2759664f --- /dev/null +++ b/regression-test/suites/auth_p0/test_show_data_auth.groovy @@ -0,0 +1,35 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_show_data_auth","p0,auth") { + String user = 'test_show_data_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "SHOW DATA" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_show_encryptkeys_auth.groovy b/regression-test/suites/auth_p0/test_show_encryptkeys_auth.groovy new file mode 100644 index 00000000000000..1e2cf4c27fd212 --- /dev/null +++ b/regression-test/suites/auth_p0/test_show_encryptkeys_auth.groovy @@ -0,0 +1,36 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_show_encryptkeys_auth","p0,auth") { + String user = 'test_show_encryptkeys_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "use regression_test" + sql "SHOW ENCRYPTKEYS" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_show_plugins_auth.groovy b/regression-test/suites/auth_p0/test_show_plugins_auth.groovy new file mode 100644 index 00000000000000..b5b4de84265162 --- /dev/null +++ b/regression-test/suites/auth_p0/test_show_plugins_auth.groovy @@ -0,0 +1,35 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_show_plugins_auth","p0,auth") { + String user = 'test_show_plugins_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "SHOW PLUGINS" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_show_repositories_auth.groovy b/regression-test/suites/auth_p0/test_show_repositories_auth.groovy new file mode 100644 index 00000000000000..507d8768669973 --- /dev/null +++ b/regression-test/suites/auth_p0/test_show_repositories_auth.groovy @@ -0,0 +1,35 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_show_repositories_auth","p0,auth") { + String user = 'test_show_repositories_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "SHOW REPOSITORIES" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_show_snapshot_auth.groovy b/regression-test/suites/auth_p0/test_show_snapshot_auth.groovy new file mode 100644 index 00000000000000..f90e1fdc57aaab --- /dev/null +++ b/regression-test/suites/auth_p0/test_show_snapshot_auth.groovy @@ -0,0 +1,35 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_show_snapshot_auth","p0,auth") { + String user = 'test_show_snapshot_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "SHOW SNAPSHOT ON example_repo" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_show_stream_load_auth.groovy b/regression-test/suites/auth_p0/test_show_stream_load_auth.groovy new file mode 100644 index 00000000000000..cb2446f04405f3 --- /dev/null +++ b/regression-test/suites/auth_p0/test_show_stream_load_auth.groovy @@ -0,0 +1,75 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_show_stream_load_auth","p0,auth") { + String tableName = "test_show_stream_load_auth_table" + String label = "test_show_stream_load_auth_label" + System.currentTimeMillis(); + String user = 'test_show_stream_load_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """ DROP TABLE IF EXISTS ${tableName} """ + + + sql """ + CREATE TABLE IF NOT EXISTS ${tableName} ( + `k1` bigint(20) NULL, + `k2` bigint(20) NULL + ) ENGINE=OLAP + COMMENT 'OLAP' + DISTRIBUTED BY HASH(`k1`) BUCKETS 2 + PROPERTIES ("replication_allocation" = "tag.location.default: 1"); + """ + + streamLoad { + table "${tableName}" + + set 'column_separator', ',' + set 'columns', 'k1, k2' + set 'label', label + set 'strict_mode', 'true' + + file 'test_strict_mode.csv' + time 10000 // limit inflight 10s + } + + Thread.sleep(60000); + def res = sql "SHOW STREAM LOAD from regression_test_auth_p0 where label = '${label}'" + log.info(res.toString()) + if(res.size() == 0) { + // `show stream load` has some delay, and need be config `enable_stream_load_record=true` + // we not sure when can has result, so if `admin` can not get res, ignore this case. + return; + } + + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + res = sql "SHOW STREAM LOAD from regression_test_auth_p0 where label = '${label}'" + log.info(res.toString()) + assertFalse(res.toString().contains("${label}")) + } + sql """grant load_priv on regression_test_auth_p0.${tableName} to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + res = sql "SHOW STREAM LOAD from regression_test_auth_p0 where label = '${label}'" + log.info(res.toString()) + assertTrue(res.toString().contains("${label}")) + } + try_sql("DROP USER ${user}") + sql """ DROP TABLE IF EXISTS ${tableName} """ +} diff --git a/regression-test/suites/auth_p0/test_show_tablets_belong_auth.groovy b/regression-test/suites/auth_p0/test_show_tablets_belong_auth.groovy new file mode 100644 index 00000000000000..b7d66af9348f0d --- /dev/null +++ b/regression-test/suites/auth_p0/test_show_tablets_belong_auth.groovy @@ -0,0 +1,35 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_show_tablets_belong_auth","p0,auth") { + String user = 'test_show_tablets_belong_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "SHOW TABLETS BELONG 27028" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv")) + } + } + try_sql("DROP USER ${user}") +} diff --git a/regression-test/suites/auth_p0/test_show_transaction_auth.groovy b/regression-test/suites/auth_p0/test_show_transaction_auth.groovy new file mode 100644 index 00000000000000..f4e564c52889a0 --- /dev/null +++ b/regression-test/suites/auth_p0/test_show_transaction_auth.groovy @@ -0,0 +1,35 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Assert; + +suite("test_show_transaction_auth","p0,auth") { + String user = 'test_show_transaction_auth_user' + String pwd = 'C123_567p' + try_sql("DROP USER ${user}") + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + sql """grant select_priv on regression_test to ${user}""" + connect(user=user, password="${pwd}", url=context.config.jdbcUrl) { + try { + sql "SHOW TRANSACTION WHERE ID=4005;" + } catch (Exception e) { + log.info(e.getMessage()) + assertTrue(e.getMessage().contains("Admin_priv")) + } + } + try_sql("DROP USER ${user}") +}