Repository: impala
Updated Branches:
  refs/heads/master 0a901fcb2 -> d29300281


IMPALA-6989: Implement SHOW GRANT USER statement

This patch implements SHOW GRANT USER command to show the list of
privileges for a given user.

Syntax:
SHOW GRANT USER <user>
SHOW GRANT USER <user> ON SERVER
SHOW GRANT USER <user> ON DATABASE <db>
SHOW GRANT USER <user> ON TABLE <table>
SHOW GRANT USER <user> ON URI <uri>

Testing:
- Add FE tests
- Ran all FE tests

Change-Id: Ia96fcf02d249501c471d03511c22625ae2fec225
Reviewed-on: http://gerrit.cloudera.org:8080/11244
Reviewed-by: Impala Public Jenkins <[email protected]>
Tested-by: Impala Public Jenkins <[email protected]>


Project: http://git-wip-us.apache.org/repos/asf/impala/repo
Commit: http://git-wip-us.apache.org/repos/asf/impala/commit/73d37d6e
Tree: http://git-wip-us.apache.org/repos/asf/impala/tree/73d37d6e
Diff: http://git-wip-us.apache.org/repos/asf/impala/diff/73d37d6e

Branch: refs/heads/master
Commit: 73d37d6ebbccba7045fff2f228f7364cc1302582
Parents: 0a901fc
Author: Fredy Wijaya <[email protected]>
Authored: Wed Jul 25 17:35:52 2018 -0500
Committer: Impala Public Jenkins <[email protected]>
Committed: Mon Aug 20 01:50:54 2018 +0000

----------------------------------------------------------------------
 be/src/service/client-request-state.cc          |  6 +-
 be/src/service/frontend.cc                      |  6 +-
 be/src/service/frontend.h                       |  7 +-
 common/thrift/Frontend.thrift                   | 21 +++--
 fe/src/main/cup/sql-parser.cup                  | 42 ++++++---
 .../apache/impala/analysis/AnalysisContext.java |  6 +-
 .../impala/analysis/ShowGrantPrincipalStmt.java | 95 ++++++++++++++++++++
 .../impala/analysis/ShowGrantRoleStmt.java      | 86 ------------------
 .../impala/catalog/AuthorizationPolicy.java     | 24 +----
 .../org/apache/impala/service/Frontend.java     | 17 ++--
 .../org/apache/impala/service/JniFrontend.java  | 17 ++--
 .../impala/analysis/AnalyzeAuthStmtsTest.java   | 33 ++++---
 .../impala/analysis/AuthorizationStmtTest.java  | 16 ++--
 .../org/apache/impala/analysis/ParserTest.java  | 35 ++++----
 14 files changed, 223 insertions(+), 188 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/be/src/service/client-request-state.cc
----------------------------------------------------------------------
diff --git a/be/src/service/client-request-state.cc 
b/be/src/service/client-request-state.cc
index 5839e9c..0db511d 100644
--- a/be/src/service/client-request-state.cc
+++ b/be/src/service/client-request-state.cc
@@ -346,8 +346,8 @@ Status ClientRequestState::ExecLocalCatalogOp(
       SetResultSet(result.role_names);
       return Status::OK();
     }
-    case TCatalogOpType::SHOW_GRANT_ROLE: {
-      const TShowGrantRoleParams& params = catalog_op.show_grant_role_params;
+    case TCatalogOpType::SHOW_GRANT_PRINCIPAL: {
+      const TShowGrantPrincipalParams& params = 
catalog_op.show_grant_principal_params;
       if (params.is_admin_op) {
         // Verify the user has privileges to perform this operation by 
checking against
         // the Sentry Service (via the Catalog Server).
@@ -361,7 +361,7 @@ Status ClientRequestState::ExecLocalCatalogOp(
       }
 
       TResultSet response;
-      RETURN_IF_ERROR(frontend_->GetRolePrivileges(params, &response));
+      RETURN_IF_ERROR(frontend_->GetPrincipalPrivileges(params, &response));
       // Set the result set and its schema from the response.
       request_result_set_.reset(new vector<TResultRow>(response.rows));
       result_metadata_ = response.schema;

http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/be/src/service/frontend.cc
----------------------------------------------------------------------
diff --git a/be/src/service/frontend.cc b/be/src/service/frontend.cc
index ca3f79f..aec92f7 100644
--- a/be/src/service/frontend.cc
+++ b/be/src/service/frontend.cc
@@ -93,7 +93,7 @@ Frontend::Frontend() {
     {"getFunctions", "([B)[B", &get_functions_id_},
     {"getCatalogObject", "([B)[B", &get_catalog_object_id_},
     {"getRoles", "([B)[B", &show_roles_id_},
-    {"getRolePrivileges", "([B)[B", &get_role_privileges_id_},
+    {"getPrincipalPrivileges", "([B)[B", &get_principal_privileges_id_},
     {"execHiveServer2MetadataOp", "([B)[B", &exec_hs2_metadata_op_id_},
     {"setCatalogIsReady", "()V", &set_catalog_is_ready_id_},
     {"waitForCatalog", "()V", &wait_for_catalog_id_},
@@ -186,9 +186,9 @@ Status Frontend::GetStats(const TShowStatsParams& params,
   return JniUtil::CallJniMethod(fe_, get_stats_id_, params, result);
 }
 
-Status Frontend::GetRolePrivileges(const TShowGrantRoleParams& params,
+Status Frontend::GetPrincipalPrivileges(const TShowGrantPrincipalParams& 
params,
     TResultSet* result) {
-  return JniUtil::CallJniMethod(fe_, get_role_privileges_id_, params, result);
+  return JniUtil::CallJniMethod(fe_, get_principal_privileges_id_, params, 
result);
 }
 
 Status Frontend::GetFunctions(TFunctionCategory::type fn_category, const 
string& db,

http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/be/src/service/frontend.h
----------------------------------------------------------------------
diff --git a/be/src/service/frontend.h b/be/src/service/frontend.h
index 2327e8f..3788fa5 100644
--- a/be/src/service/frontend.h
+++ b/be/src/service/frontend.h
@@ -92,8 +92,9 @@ class Frontend {
   /// Call FE to get the table/column stats.
   Status GetStats(const TShowStatsParams& params, TResultSet* result);
 
-  /// Call FE to get the privileges granted to a role.
-  Status GetRolePrivileges(const TShowGrantRoleParams& params, TResultSet* 
result);
+  /// Call FE to get the privileges granted to a principal.
+  Status GetPrincipalPrivileges(const TShowGrantPrincipalParams& params,
+      TResultSet* result);
 
   /// Return all functions of 'category' that match the optional argument 
'pattern'.
   /// If pattern is NULL match all functions, otherwise match only those 
functions that
@@ -208,7 +209,7 @@ class Frontend {
   jmethodID get_functions_id_; // JniFrontend.getFunctions
   jmethodID get_catalog_object_id_; // JniFrontend.getCatalogObject
   jmethodID show_roles_id_; // JniFrontend.getRoles
-  jmethodID get_role_privileges_id_; // JniFrontend.getRolePrivileges
+  jmethodID get_principal_privileges_id_; // JniFrontend.getPrincipalPrivileges
   jmethodID exec_hs2_metadata_op_id_; // JniFrontend.execHiveServer2MetadataOp
   jmethodID load_table_data_id_; // JniFrontend.loadTableData
   jmethodID set_catalog_is_ready_id_; // JniFrontend.setCatalogIsReady

http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/common/thrift/Frontend.thrift
----------------------------------------------------------------------
diff --git a/common/thrift/Frontend.thrift b/common/thrift/Frontend.thrift
index abb2d77..a7d56d7 100644
--- a/common/thrift/Frontend.thrift
+++ b/common/thrift/Frontend.thrift
@@ -265,20 +265,23 @@ struct TShowRolesResult {
   1: required list<string> role_names
 }
 
-// Parameters for SHOW GRANT ROLE commands
-struct TShowGrantRoleParams {
+// Parameters for SHOW GRANT ROLE/USER commands
+struct TShowGrantPrincipalParams {
   // The effective user who submitted this request.
   1: optional string requesting_user
 
-  // The target role name.
-  2: required string role_name
+  // The target name.
+  2: required string name
+
+  // The principal type.
+  3: required CatalogObjects.TPrincipalType principal_type;
 
   // True if this operation requires admin privileges on the Sentry Service 
(when
   // the requesting user has not been granted the target role name).
-  3: required bool is_admin_op
+  4: required bool is_admin_op
 
   // An optional filter to show grants that match a specific privilege spec.
-  4: optional CatalogObjects.TPrivilege privilege
+  5: optional CatalogObjects.TPrivilege privilege
 }
 
 // Arguments to getFunctions(), which returns a list of non-qualified function
@@ -436,7 +439,7 @@ enum TCatalogOpType {
   SHOW_CREATE_TABLE,
   SHOW_DATA_SRCS,
   SHOW_ROLES,
-  SHOW_GRANT_ROLE,
+  SHOW_GRANT_PRINCIPAL,
   SHOW_FILES,
   SHOW_CREATE_FUNCTION
 }
@@ -473,8 +476,8 @@ struct TCatalogOpRequest {
   // Parameters for SHOW ROLES
   10: optional TShowRolesParams show_roles_params
 
-  // Parameters for SHOW GRANT ROLE
-  11: optional TShowGrantRoleParams show_grant_role_params
+  // Parameters for SHOW GRANT ROLE/USER
+  11: optional TShowGrantPrincipalParams show_grant_principal_params
 
   // Parameters for DDL requests executed using the CatalogServer
   // such as CREATE, ALTER, and DROP. See CatalogService.TDdlExecRequest

http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/main/cup/sql-parser.cup
----------------------------------------------------------------------
diff --git a/fe/src/main/cup/sql-parser.cup b/fe/src/main/cup/sql-parser.cup
index 94b69e4..e334591 100644
--- a/fe/src/main/cup/sql-parser.cup
+++ b/fe/src/main/cup/sql-parser.cup
@@ -54,6 +54,7 @@ import org.apache.impala.thrift.TOwnerType;
 import org.apache.impala.thrift.TPrivilegeLevel;
 import org.apache.impala.thrift.TShowStatsOp;
 import org.apache.impala.thrift.TTablePropertyType;
+import org.apache.impala.thrift.TPrincipalType;
 
 parser code {:
   private Symbol errorToken_;
@@ -497,7 +498,8 @@ nonterminal Map<Option, Object> column_options_map;
 
 // For GRANT/REVOKE/AUTH DDL statements
 nonterminal ShowRolesStmt show_roles_stmt;
-nonterminal ShowGrantRoleStmt show_grant_role_stmt;
+nonterminal ShowGrantPrincipalStmt show_grant_principal_stmt;
+nonterminal TPrincipalType principal_type;
 nonterminal CreateDropRoleStmt create_drop_role_stmt;
 nonterminal GrantRevokeRoleStmt grant_role_stmt;
 nonterminal GrantRevokeRoleStmt revoke_role_stmt;
@@ -655,8 +657,8 @@ stmt ::=
   {: RESULT = set; :}
   | show_roles_stmt:show_roles
   {: RESULT = show_roles; :}
-  | show_grant_role_stmt:show_grant_role
-  {: RESULT = show_grant_role; :}
+  | show_grant_principal_stmt:show_grant_principal
+  {: RESULT = show_grant_principal; :}
   | create_drop_role_stmt:create_drop_role
   {: RESULT = create_drop_role; :}
   | grant_role_stmt:grant_role
@@ -903,29 +905,31 @@ show_roles_stmt ::=
   {: RESULT = new ShowRolesStmt(true, null); :}
   ;
 
-show_grant_role_stmt ::=
-  KW_SHOW KW_GRANT KW_ROLE ident_or_default:role
-  {: RESULT = new ShowGrantRoleStmt(role, null); :}
-  | KW_SHOW KW_GRANT KW_ROLE ident_or_default:role KW_ON server_ident:server_kw
+show_grant_principal_stmt ::=
+  KW_SHOW KW_GRANT principal_type:type ident_or_default:name
+  {: RESULT = new ShowGrantPrincipalStmt(name, type, null); :}
+  | KW_SHOW KW_GRANT principal_type:type ident_or_default:name KW_ON
+  server_ident:server_kw
   {:
-    RESULT = new ShowGrantRoleStmt(role,
+    RESULT = new ShowGrantPrincipalStmt(name, type,
         PrivilegeSpec.createServerScopedPriv(TPrivilegeLevel.ALL));
   :}
-  | KW_SHOW KW_GRANT KW_ROLE ident_or_default:role KW_ON
+  | KW_SHOW KW_GRANT principal_type:type ident_or_default:name KW_ON
     KW_DATABASE ident_or_default:db_name
   {:
-    RESULT = new ShowGrantRoleStmt(role,
+    RESULT = new ShowGrantPrincipalStmt(name, type,
         PrivilegeSpec.createDbScopedPriv(TPrivilegeLevel.ALL, db_name));
   :}
-  | KW_SHOW KW_GRANT KW_ROLE ident_or_default:role KW_ON KW_TABLE 
table_name:tbl_name
+  | KW_SHOW KW_GRANT principal_type:type ident_or_default:name KW_ON KW_TABLE
+  table_name:tbl_name
   {:
-    RESULT = new ShowGrantRoleStmt(role,
+    RESULT = new ShowGrantPrincipalStmt(name, type,
         PrivilegeSpec.createTableScopedPriv(TPrivilegeLevel.ALL, tbl_name));
   :}
-  | KW_SHOW KW_GRANT KW_ROLE ident_or_default:role KW_ON uri_ident:uri_kw
+  | KW_SHOW KW_GRANT principal_type:type ident_or_default:name KW_ON 
uri_ident:uri_kw
     STRING_LITERAL:uri
   {:
-    RESULT = new ShowGrantRoleStmt(role,
+    RESULT = new ShowGrantPrincipalStmt(name, type,
         PrivilegeSpec.createUriScopedPriv(TPrivilegeLevel.ALL, new 
HdfsUri(uri)));
   :}
   ;
@@ -991,6 +995,16 @@ privilege ::=
   {: RESULT = TPrivilegeLevel.ALL; :}
   ;
 
+principal_type ::=
+  KW_ROLE
+  {: RESULT = TPrincipalType.ROLE; :}
+  | IDENT:user
+  {:
+    parser.checkIdentKeyword("USER", user);
+    RESULT = TPrincipalType.USER;
+  :}
+  ;
+
 opt_grantopt_for ::=
   KW_GRANT option_ident:option KW_FOR
   {: RESULT = true; :}

http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/main/java/org/apache/impala/analysis/AnalysisContext.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/org/apache/impala/analysis/AnalysisContext.java 
b/fe/src/main/java/org/apache/impala/analysis/AnalysisContext.java
index 47fe8a7..2f51c71 100644
--- a/fe/src/main/java/org/apache/impala/analysis/AnalysisContext.java
+++ b/fe/src/main/java/org/apache/impala/analysis/AnalysisContext.java
@@ -137,7 +137,9 @@ public class AnalysisContext {
     public boolean isResetMetadataStmt() { return stmt_ instanceof 
ResetMetadataStmt; }
     public boolean isExplainStmt() { return stmt_.isExplain(); }
     public boolean isShowRolesStmt() { return stmt_ instanceof ShowRolesStmt; }
-    public boolean isShowGrantRoleStmt() { return stmt_ instanceof 
ShowGrantRoleStmt; }
+    public boolean isShowGrantPrincipalStmt() {
+      return stmt_ instanceof ShowGrantPrincipalStmt;
+    }
     public boolean isCreateDropRoleStmt() { return stmt_ instanceof 
CreateDropRoleStmt; }
     public boolean isGrantRevokeRoleStmt() {
       return stmt_ instanceof GrantRevokeRoleStmt;
@@ -171,7 +173,7 @@ public class AnalysisContext {
 
     private boolean isViewMetadataStmt() {
       return isShowFilesStmt() || isShowTablesStmt() || isShowDbsStmt() ||
-          isShowFunctionsStmt() || isShowRolesStmt() || isShowGrantRoleStmt() 
||
+          isShowFunctionsStmt() || isShowRolesStmt() || 
isShowGrantPrincipalStmt() ||
           isShowCreateTableStmt() || isShowDataSrcsStmt() || isShowStatsStmt() 
||
           isDescribeTableStmt() || isDescribeDbStmt() || 
isShowCreateFunctionStmt();
     }

http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/main/java/org/apache/impala/analysis/ShowGrantPrincipalStmt.java
----------------------------------------------------------------------
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/ShowGrantPrincipalStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/ShowGrantPrincipalStmt.java
new file mode 100644
index 0000000..6e84acc
--- /dev/null
+++ b/fe/src/main/java/org/apache/impala/analysis/ShowGrantPrincipalStmt.java
@@ -0,0 +1,95 @@
+// 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.impala.analysis;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import org.apache.impala.catalog.Principal;
+import org.apache.impala.common.AnalysisException;
+import org.apache.impala.common.InternalException;
+import org.apache.impala.thrift.TPrincipalType;
+import org.apache.impala.thrift.TShowGrantPrincipalParams;
+
+import java.util.List;
+
+/**
+ * Represents "SHOW GRANT ROLE <role>" [ON <privilegeSpec>]" and
+ * "SHOW GRANT USER <user> [ON <privilegeSpec>]" statements.
+ */
+public class ShowGrantPrincipalStmt extends AuthorizationStmt {
+  private final PrivilegeSpec privilegeSpec_;
+  private final String name_;
+  private final TPrincipalType principalType_;
+
+  // Set/modified during analysis.
+  private Principal principal_;
+
+  public ShowGrantPrincipalStmt(String name, TPrincipalType principalType,
+      PrivilegeSpec privilegeSpec) {
+    Preconditions.checkNotNull(name);
+    Preconditions.checkNotNull(principalType);
+    name_ = name;
+    principalType_ = principalType;
+    privilegeSpec_ = privilegeSpec;
+  }
+
+  @Override
+  public void analyze(Analyzer analyzer) throws AnalysisException {
+    super.analyze(analyzer);
+    if (Strings.isNullOrEmpty(name_)) {
+      throw new AnalysisException(String.format("%s name in SHOW GRANT %s 
cannot be " +
+          "empty.", Principal.toString(principalType_),
+          Principal.toString(principalType_).toUpperCase()));
+    }
+    principal_ = analyzer.getCatalog().getAuthPolicy().getPrincipal(name_,
+        principalType_);
+    if (principal_ == null) {
+      throw new AnalysisException(String.format("%s '%s' does not exist.",
+          Principal.toString(principalType_), name_));
+    }
+    if (privilegeSpec_ != null) privilegeSpec_.analyze(analyzer);
+  }
+
+  @Override
+  public String toSql() {
+    StringBuilder sb = new StringBuilder(String.format("SHOW GRANT %s ",
+        Principal.toString(principalType_).toUpperCase()));
+    sb.append(name_);
+    if (privilegeSpec_ != null) sb.append(" " + privilegeSpec_.toSql());
+    return sb.toString();
+  }
+
+  @Override
+  public void collectTableRefs(List<TableRef> tblRefs) {
+    if (privilegeSpec_ != null) privilegeSpec_.collectTableRefs(tblRefs);
+  }
+
+  public TShowGrantPrincipalParams toThrift() throws InternalException {
+    TShowGrantPrincipalParams params = new TShowGrantPrincipalParams();
+    params.setName(name_);
+    params.setPrincipal_type(principalType_);
+    params.setRequesting_user(requestingUser_.getShortName());
+    if (privilegeSpec_ != null) {
+      params.setPrivilege(privilegeSpec_.toThrift().get(0));
+      params.getPrivilege().setPrincipal_id(principal_.getId());
+    }
+    return params;
+  }
+
+  public Principal getPrincipal() { return principal_; }
+}

http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/main/java/org/apache/impala/analysis/ShowGrantRoleStmt.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/org/apache/impala/analysis/ShowGrantRoleStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/ShowGrantRoleStmt.java
deleted file mode 100644
index 749bcc2..0000000
--- a/fe/src/main/java/org/apache/impala/analysis/ShowGrantRoleStmt.java
+++ /dev/null
@@ -1,86 +0,0 @@
-// 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.impala.analysis;
-
-import java.util.List;
-
-import org.apache.impala.catalog.Role;
-import org.apache.impala.common.AnalysisException;
-import org.apache.impala.common.InternalException;
-import org.apache.impala.thrift.TShowGrantRoleParams;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-
-/**
- * Represents a "SHOW GRANT ROLE <role> [ON <privilegeSpec>]" statement.
- */
-public class ShowGrantRoleStmt extends AuthorizationStmt {
-  private final PrivilegeSpec privilegeSpec_;
-  private final String roleName_;
-
-  // Set/modified during analysis
-  private Role role_;
-
-  public ShowGrantRoleStmt(String roleName, PrivilegeSpec privilegeSpec) {
-    Preconditions.checkNotNull(roleName);
-    roleName_ = roleName;
-    privilegeSpec_ = privilegeSpec;
-  }
-
-  public TShowGrantRoleParams toThrift() throws InternalException {
-    TShowGrantRoleParams params = new TShowGrantRoleParams();
-    params.setRole_name(roleName_);
-    params.setRequesting_user(requestingUser_.getShortName());
-    if (privilegeSpec_ != null) {
-      params.setPrivilege(privilegeSpec_.toThrift().get(0));
-      params.getPrivilege().setPrincipal_id(role_.getId());
-      params.getPrivilege().setPrincipal_type(role_.getPrincipalType());
-    }
-    return params;
-  }
-
-  @Override
-  public String toSql() {
-    StringBuilder sb = new StringBuilder("SHOW GRANT ROLE ");
-    sb.append(roleName_);
-    if (privilegeSpec_ != null) sb.append(" " + privilegeSpec_.toSql());
-    return sb.toString();
-  }
-
-  @Override
-  public void collectTableRefs(List<TableRef> tblRefs) {
-    if (privilegeSpec_ != null) privilegeSpec_.collectTableRefs(tblRefs);
-  }
-
-  @Override
-  public void analyze(Analyzer analyzer) throws AnalysisException {
-    super.analyze(analyzer);
-    if (Strings.isNullOrEmpty(roleName_)) {
-      throw new AnalysisException("Role name in SHOW GRANT ROLE cannot be " +
-          "empty.");
-    }
-    role_ = analyzer.getCatalog().getAuthPolicy().getRole(roleName_);
-    if (role_ == null) {
-      throw new AnalysisException(String.format("Role '%s' does not exist.", 
roleName_));
-    }
-    if (privilegeSpec_ != null) privilegeSpec_.analyze(analyzer);
-  }
-
-  public Role getRole() { return role_; }
-}

http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/main/java/org/apache/impala/catalog/AuthorizationPolicy.java
----------------------------------------------------------------------
diff --git 
a/fe/src/main/java/org/apache/impala/catalog/AuthorizationPolicy.java 
b/fe/src/main/java/org/apache/impala/catalog/AuthorizationPolicy.java
index a151eb4..ffb8cfd 100644
--- a/fe/src/main/java/org/apache/impala/catalog/AuthorizationPolicy.java
+++ b/fe/src/main/java/org/apache/impala/catalog/AuthorizationPolicy.java
@@ -413,30 +413,12 @@ public class AuthorizationPolicy implements 
PrivilegeCache {
   }
 
   /**
-   * Returns the privileges that have been granted to a role as a tabular 
result set.
-   * Allows for filtering based on a specific privilege spec or showing all 
privileges
-   * granted to the role. Used by the SHOW GRANT ROLE statement.
-   */
-  public synchronized TResultSet getRolePrivileges(String roleName, TPrivilege 
filter) {
-    return getPrincipalPrivileges(roleName, filter, TPrincipalType.ROLE);
-  }
-
-  /**
-   * Returns the privileges that have been granted to a user as a tabular 
result set.
-   * Allows for filtering based on a specific privilege spec or showing all 
privileges
-   * granted to the user. Used by the SHOW GRANT USER statement.
-   */
-  public synchronized TResultSet getUserPrivileges(String userName, TPrivilege 
filter) {
-    return getPrincipalPrivileges(userName, filter, TPrincipalType.USER);
-  }
-
-  /**
    * Returns the privileges that have been granted to a principal as a tabular 
result set.
    * Allows for filtering based on a specific privilege spec or showing all 
privileges
-   * granted to the principal.
+   * granted to the principal. Used by the SHOW GRANT ROLE/USER statement.
    */
-  private TResultSet getPrincipalPrivileges(String principalName, TPrivilege 
filter,
-      TPrincipalType type) {
+  public synchronized TResultSet getPrincipalPrivileges(String principalName,
+      TPrivilege filter, TPrincipalType type) {
     TResultSet result = new TResultSet();
     result.setSchema(new TResultSetMetadata());
     result.getSchema().addToColumns(new TColumn("scope", 
Type.STRING.toThrift()));

http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/main/java/org/apache/impala/service/Frontend.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/org/apache/impala/service/Frontend.java 
b/fe/src/main/java/org/apache/impala/service/Frontend.java
index 29d917e..fcb5ce2 100644
--- a/fe/src/main/java/org/apache/impala/service/Frontend.java
+++ b/fe/src/main/java/org/apache/impala/service/Frontend.java
@@ -55,7 +55,7 @@ import org.apache.impala.analysis.InsertStmt;
 import org.apache.impala.analysis.QueryStmt;
 import org.apache.impala.analysis.ResetMetadataStmt;
 import org.apache.impala.analysis.ShowFunctionsStmt;
-import org.apache.impala.analysis.ShowGrantRoleStmt;
+import org.apache.impala.analysis.ShowGrantPrincipalStmt;
 import org.apache.impala.analysis.ShowRolesStmt;
 import org.apache.impala.analysis.SqlParser;
 import org.apache.impala.analysis.SqlScanner;
@@ -472,16 +472,17 @@ public class Frontend {
       }
       metadata.setColumns(Arrays.asList(
           new TColumn("role_name", Type.STRING.toThrift())));
-    } else if (analysis.isShowGrantRoleStmt()) {
-      ddl.op_type = TCatalogOpType.SHOW_GRANT_ROLE;
-      ShowGrantRoleStmt showGrantRoleStmt = (ShowGrantRoleStmt) 
analysis.getStmt();
-      ddl.setShow_grant_role_params(showGrantRoleStmt.toThrift());
+    } else if (analysis.isShowGrantPrincipalStmt()) {
+      ddl.op_type = TCatalogOpType.SHOW_GRANT_PRINCIPAL;
+      ShowGrantPrincipalStmt showGrantPrincipalStmt =
+          (ShowGrantPrincipalStmt) analysis.getStmt();
+      ddl.setShow_grant_principal_params(showGrantPrincipalStmt.toThrift());
       Set<String> groupNames =
           getAuthzChecker().getUserGroups(analysis.getAnalyzer().getUser());
       // User must be an admin to execute this operation if they have not been 
granted
-      // this role.
-      
ddl.getShow_grant_role_params().setIs_admin_op(Sets.intersection(groupNames,
-          showGrantRoleStmt.getRole().getGrantGroups()).isEmpty());
+      // this principal.
+      
ddl.getShow_grant_principal_params().setIs_admin_op(Sets.intersection(groupNames,
+          showGrantPrincipalStmt.getPrincipal().getGrantGroups()).isEmpty());
       metadata.setColumns(Arrays.asList(
           new TColumn("name", Type.STRING.toThrift())));
     } else if (analysis.isCreateDropRoleStmt()) {

http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/main/java/org/apache/impala/service/JniFrontend.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/org/apache/impala/service/JniFrontend.java 
b/fe/src/main/java/org/apache/impala/service/JniFrontend.java
index ce16b51..2781865 100644
--- a/fe/src/main/java/org/apache/impala/service/JniFrontend.java
+++ b/fe/src/main/java/org/apache/impala/service/JniFrontend.java
@@ -87,7 +87,7 @@ import org.apache.impala.thrift.TMetadataOpRequest;
 import org.apache.impala.thrift.TQueryCtx;
 import org.apache.impala.thrift.TResultSet;
 import org.apache.impala.thrift.TShowFilesParams;
-import org.apache.impala.thrift.TShowGrantRoleParams;
+import org.apache.impala.thrift.TShowGrantPrincipalParams;
 import org.apache.impala.thrift.TShowRolesParams;
 import org.apache.impala.thrift.TShowRolesResult;
 import org.apache.impala.thrift.TShowStatsOp;
@@ -551,11 +551,16 @@ public class JniFrontend {
     }
   }
 
-  public byte[] getRolePrivileges(byte[] showGrantRolesParams) throws 
ImpalaException {
-    TShowGrantRoleParams params = new TShowGrantRoleParams();
-    JniUtil.deserializeThrift(protocolFactory_, params, showGrantRolesParams);
-    TResultSet result = 
frontend_.getCatalog().getAuthPolicy().getRolePrivileges(
-        params.getRole_name(), params.getPrivilege());
+  /**
+   * Gets the principal privileges for the given principal.
+   */
+  public byte[] getPrincipalPrivileges(byte[] showGrantPrincipalParams)
+      throws ImpalaException {
+    TShowGrantPrincipalParams params = new TShowGrantPrincipalParams();
+    JniUtil.deserializeThrift(protocolFactory_, params, 
showGrantPrincipalParams);
+    TResultSet result;
+    result = frontend_.getCatalog().getAuthPolicy().getPrincipalPrivileges(
+        params.getName(), params.getPrivilege(), params.getPrincipal_type());
     TSerializer serializer = new TSerializer(protocolFactory_);
     try {
       return serializer.serialize(result);

http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
----------------------------------------------------------------------
diff --git 
a/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java 
b/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
index dd58131..580434a 100644
--- a/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
@@ -22,6 +22,7 @@ import java.util.HashSet;
 import org.apache.impala.authorization.AuthorizationConfig;
 import org.apache.impala.catalog.Catalog;
 import org.apache.impala.catalog.Role;
+import org.apache.impala.catalog.User;
 import org.apache.impala.common.AnalysisException;
 import org.apache.impala.testutil.TestUtils;
 import org.apache.impala.thrift.TQueryCtx;
@@ -32,6 +33,8 @@ public class AnalyzeAuthStmtsTest extends AnalyzerTest {
   public AnalyzeAuthStmtsTest() {
     catalog_.getAuthPolicy().addPrincipal(
         new Role("myRole", new HashSet<String>()));
+    catalog_.getAuthPolicy().addPrincipal(
+        new User("myUser", new HashSet<String>()));
   }
 
   @Override
@@ -70,22 +73,30 @@ public class AnalyzeAuthStmtsTest extends AnalyzerTest {
   }
 
   @Test
-  public void AnalyzeShowGrantRole() {
-    AnalyzesOk("SHOW GRANT ROLE myRole");
-    AnalyzesOk("SHOW GRANT ROLE myRole ON SERVER");
-    AnalyzesOk("SHOW GRANT ROLE myRole ON DATABASE functional");
-    AnalyzesOk("SHOW GRANT ROLE myRole ON TABLE functional.alltypes");
-    AnalyzesOk("SHOW GRANT ROLE myRole ON URI 'hdfs:////test-warehouse//foo'");
+  public void AnalyzeShowGrantPrincipal() {
+    for (String type: new String[]{"ROLE myRole", "USER myUser"}) {
+      AnalyzesOk(String.format("SHOW GRANT %s", type));
+      AnalyzesOk(String.format("SHOW GRANT %s ON SERVER", type));
+      AnalyzesOk(String.format("SHOW GRANT %s ON DATABASE functional", type));
+      AnalyzesOk(String.format("SHOW GRANT %s ON TABLE functional.alltypes", 
type));
+      AnalyzesOk(String.format("SHOW GRANT %s ON URI 
'hdfs:////test-warehouse//foo'",
+          type));
+
+      AnalysisContext authDisabledCtx = createAuthDisabledAnalysisCtx();
+      AnalysisError("SHOW GRANT ROLE myRole", authDisabledCtx,
+          "Authorization is not enabled.");
+      AnalysisError("SHOW GRANT ROLE myRole ON SERVER", authDisabledCtx,
+          "Authorization is not enabled.");
+    }
     AnalysisError("SHOW GRANT ROLE does_not_exist",
         "Role 'does_not_exist' does not exist.");
     AnalysisError("SHOW GRANT ROLE does_not_exist ON SERVER",
         "Role 'does_not_exist' does not exist.");
 
-    AnalysisContext authDisabledCtx = createAuthDisabledAnalysisCtx();
-    AnalysisError("SHOW GRANT ROLE myRole", authDisabledCtx,
-        "Authorization is not enabled.");
-    AnalysisError("SHOW GRANT ROLE myRole ON SERVER", authDisabledCtx,
-        "Authorization is not enabled.");
+    AnalysisError("SHOW GRANT USER does_not_exist",
+        "User 'does_not_exist' does not exist.");
+    AnalysisError("SHOW GRANT USER does_not_exist ON SERVER",
+        "User 'does_not_exist' does not exist.");
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java
----------------------------------------------------------------------
diff --git 
a/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java 
b/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java
index 7e10eee..a750c6f 100644
--- a/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/AuthorizationStmtTest.java
@@ -1093,16 +1093,20 @@ public class AuthorizationStmtTest extends 
FrontendTestBase {
     // Show role grant group should always be allowed.
     authorize(String.format("show role grant group `%s`", 
USER.getName())).ok();
 
-    // Show grant role should always be allowed.
+    // Show grant role/user should always be allowed.
     try {
       authzCatalog_.addRole("test_role");
-      authorize("show grant role test_role").ok();
-      authorize("show grant role test_role on server").ok();
-      authorize("show grant role test_role on database functional").ok();
-      authorize("show grant role test_role on table functional.alltypes").ok();
-      authorize("show grant role test_role on uri '/test-warehouse'").ok();
+      authzCatalog_.addUser("test_user");
+      for (String type : new String[]{"role test_role", "user test_user"}) {
+        authorize(String.format("show grant %s", type)).ok();
+        authorize(String.format("show grant %s on server", type)).ok();
+        authorize(String.format("show grant %s on database functional", 
type)).ok();
+        authorize(String.format("show grant %s on table functional.alltypes", 
type)).ok();
+        authorize(String.format("show grant %s on uri '/test-warehouse'", 
type)).ok();
+      }
     } finally {
       authzCatalog_.removeRole("test_role");
+      authzCatalog_.removeUser("test_user");
     }
 
     // Show create table.

http://git-wip-us.apache.org/repos/asf/impala/blob/73d37d6e/fe/src/test/java/org/apache/impala/analysis/ParserTest.java
----------------------------------------------------------------------
diff --git a/fe/src/test/java/org/apache/impala/analysis/ParserTest.java 
b/fe/src/test/java/org/apache/impala/analysis/ParserTest.java
index a86f467..be97d67 100644
--- a/fe/src/test/java/org/apache/impala/analysis/ParserTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/ParserTest.java
@@ -3675,22 +3675,25 @@ public class ParserTest extends FrontendTestBase {
   }
 
   @Test
-  public void TestShowGrantRole() {
-    // Show all grants on a role
-    ParsesOk("SHOW GRANT ROLE foo");
-
-    // Show grants on a specific object
-    ParsesOk("SHOW GRANT ROLE foo ON SERVER");
-    ParsesOk("SHOW GRANT ROLE foo ON DATABASE foo");
-    ParsesOk("SHOW GRANT ROLE foo ON TABLE foo");
-    ParsesOk("SHOW GRANT ROLE foo ON TABLE foo.bar");
-    ParsesOk("SHOW GRANT ROLE foo ON URI '/abc/123'");
-
-    ParserError("SHOW GRANT ROLE");
-    ParserError("SHOW GRANT ROLE foo ON SERVER foo");
-    ParserError("SHOW GRANT ROLE foo ON DATABASE");
-    ParserError("SHOW GRANT ROLE foo ON TABLE");
-    ParserError("SHOW GRANT ROLE foo ON URI abc");
+  public void TestShowGrantPrincipal() {
+    for (String type: new String[]{"ROLE", "USER"}) {
+      // Show all grants on a particular principal type.
+      ParsesOk(String.format("SHOW GRANT %s foo", type));
+
+      // Show grants on a specific object
+      ParsesOk(String.format("SHOW GRANT %s foo ON SERVER", type));
+      ParsesOk(String.format("SHOW GRANT %s foo ON DATABASE foo", type));
+      ParsesOk(String.format("SHOW GRANT %s foo ON TABLE foo", type));
+      ParsesOk(String.format("SHOW GRANT %s foo ON TABLE foo.bar", type));
+      ParsesOk(String.format("SHOW GRANT %s foo ON URI '/abc/123'", type));
+
+      ParserError(String.format("SHOW GRANT %s", type));
+      ParserError(String.format("SHOW GRANT %s foo ON SERVER foo", type));
+      ParserError(String.format("SHOW GRANT %s foo ON DATABASE", type));
+      ParserError(String.format("SHOW GRANT %s foo ON TABLE", type));
+      ParserError(String.format("SHOW GRANT %s foo ON URI abc", type));
+    }
+    ParserError("SHOW GRANT FOO bar");
   }
 
   @Test

Reply via email to