You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by sp...@apache.org on 2018/06/19 22:45:39 UTC
sentry git commit: SENTRY-2224: Support SHOW GRANT on HIVE_OBJECT
(Arjun Mishra, reviewed by Sergio Pena)
Repository: sentry
Updated Branches:
refs/heads/master 6d2ad5fa5 -> bee44c28a
SENTRY-2224: Support SHOW GRANT on HIVE_OBJECT (Arjun Mishra, reviewed by Sergio Pena)
Project: http://git-wip-us.apache.org/repos/asf/sentry/repo
Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/bee44c28
Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/bee44c28
Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/bee44c28
Branch: refs/heads/master
Commit: bee44c28adac869ccf9972854d31e88adcc5f251
Parents: 6d2ad5f
Author: Sergio Pena <se...@cloudera.com>
Authored: Tue Jun 19 17:43:28 2018 -0500
Committer: Sergio Pena <se...@cloudera.com>
Committed: Tue Jun 19 17:43:28 2018 -0500
----------------------------------------------------------------------
.../SentryHiveAuthorizationTaskFactoryImpl.java | 59 +++--
.../authz/DefaultSentryAccessController.java | 78 +++++++
.../TestSentryHiveAuthorizationTaskFactory.java | 46 ++++
.../service/thrift/SentryObjectPrivileges.java | 54 +++++
.../thrift/SentryPolicyServiceClient.java | 22 ++
.../SentryPolicyServiceClientDefaultImpl.java | 33 ++-
.../tests/e2e/dbprovider/TestShowGrants.java | 227 +++++++++++++++++++
7 files changed, 500 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/sentry/blob/bee44c28/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
index 0518938..660bef1 100644
--- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
+import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hive.SentryHiveConstants;
import org.apache.hadoop.hive.conf.HiveConf;
@@ -188,30 +189,56 @@ public class SentryHiveAuthorizationTaskFactoryImpl implements HiveAuthorization
HashSet<WriteEntity> outputs) throws SemanticException {
SentryHivePrivilegeObjectDesc privHiveObj = null;
- ASTNode principal = (ASTNode) ast.getChild(0);
+ PrincipalDesc principalDesc = null;
PrincipalType type = null;
+
+ ASTNode principal = (ASTNode) ast.getChild(0);
switch (principal.getType()) {
- case HiveParser.TOK_USER:
- type = PrincipalType.USER;
- break;
- case HiveParser.TOK_GROUP:
- type = PrincipalType.GROUP;
- break;
- case HiveParser.TOK_ROLE:
- type = PrincipalType.ROLE;
- break;
- default:
- type = PrincipalType.USER;
+ case HiveParser.TOK_USER:
+ type = PrincipalType.USER;
+ break;
+ case HiveParser.TOK_GROUP:
+ type = PrincipalType.GROUP;
+ break;
+ case HiveParser.TOK_ROLE:
+ type = PrincipalType.ROLE;
+ break;
+ case HiveParser.TOK_PRIV_OBJECT_COL:
+ //Set type as null for SHOW GRANT ON <hive_object>
+ type = null;
+ break;
}
- if (type != PrincipalType.ROLE) {
+ if (type != null && type != PrincipalType.ROLE) {
String msg = SentryHiveConstants.SHOW_NOT_SUPPORTED_FOR_PRINCIPAL + type;
throw new SemanticException(msg);
}
- String principalName = BaseSemanticAnalyzer.unescapeIdentifier(principal.getChild(0).getText());
- PrincipalDesc principalDesc = new PrincipalDesc(principalName, type);
+
+ if(type != null) {
+ String principalName = BaseSemanticAnalyzer
+ .unescapeIdentifier(principal.getChild(0).getText());
+ principalDesc = new PrincipalDesc(principalName, type);
+ } else {
+ /**
+ * Commands like SHOW GRANT ON <hive_object
+ * Eg: ASTNode structure: TOK_SHOW_GRANT -> TOK_PRIV_OBJECT_COL -> TOK_TABLE_TYPE -> TOK_TABNAME -> <hive_object>
+ */
+ privHiveObj = analyzePrivilegeObject(principal);
+ if(privHiveObj == null) {
+ String msg =
+ SentryHiveConstants.SHOW_NOT_SUPPORTED_FOR_PRINCIPAL + "unspecified object name";
+ throw new SemanticException(msg);
+ }
+ //Principal name is list of all users or roles granted privilege to the object
+ principalDesc = new PrincipalDesc(StringUtils.EMPTY, type);
+ }
// Partition privileges are not supported by Sentry
- if (ast.getChildCount() > 1) {
+ if (type != null && ast.getChildCount() > 1) {
+ /**
+ * Support for SHOW GRANT ROLE/USER/GROUP <name> ON <hive_o
+ * bject>
+ * Eg: ASTNode structure: TOK_SHOW_GRANT -> {TOK_ROLE/TOK_GROUP/TOK_USER, TOK_PRIV_OBJECT_COL} -> TOK_TABLE_TYPE -> TOK_TABNAME -> <hive_object>
+ */
ASTNode child = (ASTNode) ast.getChild(1);
if (child.getToken().getType() == HiveParser.TOK_PRIV_OBJECT_COL) {
privHiveObj = analyzePrivilegeObject(child);
http://git-wip-us.apache.org/repos/asf/sentry/blob/bee44c28/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/DefaultSentryAccessController.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/DefaultSentryAccessController.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/DefaultSentryAccessController.java
index 321701d..318c1e8 100644
--- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/DefaultSentryAccessController.java
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/DefaultSentryAccessController.java
@@ -17,8 +17,10 @@ package org.apache.sentry.binding.hive.authz;
import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.hive.SentryHiveConstants;
@@ -37,6 +39,9 @@ import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilege;
import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeInfo;
import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject;
import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveRoleGrant;
+import org.apache.sentry.api.service.thrift.SentryObjectPrivileges;
+import org.apache.sentry.api.service.thrift.TSentryAuthorizable;
+import org.apache.sentry.api.service.thrift.TSentryPrivilegeMap;
import org.apache.sentry.binding.hive.SentryOnFailureHookContext;
import org.apache.sentry.binding.hive.SentryOnFailureHookContextImpl;
import org.apache.sentry.binding.hive.authz.HiveAuthzBinding.HiveHook;
@@ -201,6 +206,15 @@ public class DefaultSentryAccessController extends SentryHiveAccessController {
@Override
public List<HivePrivilegeInfo> showPrivileges(HivePrincipal principal, HivePrivilegeObject privObj)
throws HiveAuthzPluginException, HiveAccessControlException {
+ if(principal.getName().isEmpty()) {
+ return showPriviliegesForObject(privObj);
+ } else {
+ return showPrivilegesByPrincipal(principal, privObj);
+ }
+ }
+
+ public List<HivePrivilegeInfo> showPrivilegesByPrincipal(HivePrincipal principal,
+ HivePrivilegeObject privObj) throws HiveAuthzPluginException, HiveAccessControlException {
if (principal.getType() != HivePrincipalType.ROLE && principal.getType() != HivePrincipalType.USER) {
String msg =
SentryHiveConstants.SHOW_NOT_SUPPORTED_FOR_PRINCIPAL + principal.getType();
@@ -255,6 +269,70 @@ public class DefaultSentryAccessController extends SentryHiveAccessController {
return infoList;
}
+ private List<HivePrivilegeInfo> showPriviliegesForObject(HivePrivilegeObject privObj)
+ throws HiveAuthzPluginException, HiveAccessControlException {
+ List<HivePrivilegeInfo> infoList = new ArrayList<HivePrivilegeInfo>();
+
+ if (privObj == null) {
+ String msg =
+ SentryHiveConstants.SHOW_NOT_SUPPORTED_FOR_PRINCIPAL + "unspecified object name";
+ throw new HiveAuthzPluginException(msg);
+ }
+
+ try {
+ sentryClient = getSentryClient();
+ Set<List<? extends Authorizable>> authorizableSet =
+ Sets.newHashSet(SentryAuthorizerUtil.getAuthzHierarchy(new Server(serverName), privObj));
+
+ Set<String> users = Collections.singleton(authenticator.getUserName());
+ SentryObjectPrivileges sentryObjectPrivileges = null;
+ if (authorizableSet != null && !authorizableSet.isEmpty()) {
+ hiveAuthzBinding = new HiveAuthzBinding(hiveHook, this.conf, authzConf);
+ sentryObjectPrivileges = sentryClient
+ .getAllPrivilegsbyAuthorizable(authenticator.getUserName(), authorizableSet, null, users, hiveAuthzBinding.getActiveRoleSet());
+ } else {
+ String msg =
+ SentryHiveConstants.SHOW_NOT_SUPPORTED_FOR_PRINCIPAL + "object name [" + privObj.getObjectName() + "] does not exist";
+ throw new HiveAuthzPluginException(msg);
+ }
+
+ Map<TSentryAuthorizable, TSentryPrivilegeMap> rolePrivilegesMap = sentryObjectPrivileges.getPrivilegesForRoles();
+ generateHivePrincipalInfo(infoList, rolePrivilegesMap, HivePrincipalType.ROLE);
+ Map<TSentryAuthorizable, TSentryPrivilegeMap> userPrivilegesMap = sentryObjectPrivileges.getPrivilegesForUsers();
+ generateHivePrincipalInfo(infoList, userPrivilegesMap, HivePrincipalType.USER);
+
+ } catch (SentryAccessDeniedException e) {
+ HiveOperation hiveOp = HiveOperation.SHOW_GRANT;
+ executeOnFailureHooks(hiveOp, e);
+ } catch (SentryUserException e) {
+ String msg = "Error when sentryClient listPrivilegsbyAuthorizable: " + e;
+ executeOnErrorHooks(msg, e);
+ } catch (Exception e) {
+ String msg = "Error when sentryClient listPrivilegsbyAuthorizable: " + e;
+ executeOnErrorHooks(msg, e);
+ } finally {
+ closeClient();
+ }
+ return infoList;
+ }
+
+ private void generateHivePrincipalInfo(List<HivePrivilegeInfo> infoList,
+ Map<TSentryAuthorizable, TSentryPrivilegeMap> privilegesMap,
+ HivePrincipalType principalType) {
+ if (privilegesMap != null && !privilegesMap.isEmpty()) {
+ for (TSentryPrivilegeMap map : privilegesMap.values()) {
+ Map<String, Set<TSentryPrivilege>> principalNameToPrivilegeMap = map.getPrivilegeMap();
+ for (String principalName : principalNameToPrivilegeMap.keySet()) {
+ for (TSentryPrivilege priv : principalNameToPrivilegeMap.get(principalName)) {
+ infoList.add(SentryAuthorizerUtil
+ .convert2HivePrivilegeInfo(priv, new HivePrincipal(principalName,
+ principalType)));//For now only roles are retrieved
+ }
+ }
+ }
+ }
+ }
+
@Override
public void setCurrentRole(String roleName) throws HiveAccessControlException,
HiveAuthzPluginException {
http://git-wip-us.apache.org/repos/asf/sentry/blob/bee44c28/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryHiveAuthorizationTaskFactory.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryHiveAuthorizationTaskFactory.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryHiveAuthorizationTaskFactory.java
index 2e3fd7f..8b6b223 100644
--- a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryHiveAuthorizationTaskFactory.java
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryHiveAuthorizationTaskFactory.java
@@ -22,6 +22,7 @@ import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
+import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hive.ql.QueryState;
import org.junit.Assert;
@@ -472,6 +473,51 @@ public class TestSentryHiveAuthorizationTaskFactory {
Assert.assertEquals(SERVER, privilegeDesc.getObject());
}
+
+ /**
+ * SHOW GRANT ... ON SERVER ...
+ */
+ @Test
+ public void testShowGrantOnServer() throws Exception {
+ DDLWork work = analyze(parse("SHOW GRANT ON SERVER " + SERVER));
+ ShowGrantDesc grantDesc = work.getShowGrantDesc();
+ Assert.assertNotNull("Show grant should not be null", grantDesc);
+ Assert.assertEquals(null, grantDesc.getPrincipalDesc().getType());
+ Assert.assertEquals(StringUtils.EMPTY, grantDesc.getPrincipalDesc().getName());
+ Assert.assertEquals(SERVER, grantDesc.getHiveObj().getObject());
+ Assert.assertTrue("Expected server", ((SentryHivePrivilegeObjectDesc)grantDesc.getHiveObj()).getServer());
+ }
+
+ /**
+ * SHOW GRANT ... ON DATABASE ...
+ */
+ @Test
+ public void testShowGrantOnDatabase() throws Exception {
+ DDLWork work = analyze(parse("SHOW GRANT ON DATABASE " + DB));
+ ShowGrantDesc grantDesc = work.getShowGrantDesc();
+ Assert.assertNotNull("Show grant should not be null", grantDesc);
+ Assert.assertEquals(null, grantDesc.getPrincipalDesc().getType());
+ Assert.assertEquals(StringUtils.EMPTY, grantDesc.getPrincipalDesc().getName());
+ Assert.assertEquals(DB, grantDesc.getHiveObj().getObject());
+ //TODO - Part of SENTRY-2238 commit
+// Assert.assertTrue("Expected database", ((SentryHivePrivilegeObjectDesc)grantDesc.getHiveObj()).getDatabase());
+ }
+
+ /**
+ * SHOW GRANT ... ON TABLE ...
+ */
+ @Test
+ public void testShowGrantOnTable() throws Exception {
+ DDLWork work = analyze(parse("SHOW GRANT ON TABLE " + TABLE));
+ ShowGrantDesc grantDesc = work.getShowGrantDesc();
+ Assert.assertNotNull("Show grant should not be null", grantDesc);
+ Assert.assertEquals(null, grantDesc.getPrincipalDesc().getType());
+ Assert.assertEquals(StringUtils.EMPTY, grantDesc.getPrincipalDesc().getName());
+ Assert.assertEquals(TABLE, grantDesc.getHiveObj().getObject());
+ Assert.assertTrue("Expected table", ((SentryHivePrivilegeObjectDesc)grantDesc.getHiveObj()).getTable());
+ }
+
+
/*
Db prefix in grant
*/
http://git-wip-us.apache.org/repos/asf/sentry/blob/bee44c28/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryObjectPrivileges.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryObjectPrivileges.java b/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryObjectPrivileges.java
new file mode 100644
index 0000000..631857c
--- /dev/null
+++ b/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryObjectPrivileges.java
@@ -0,0 +1,54 @@
+/**
+ * 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.sentry.api.service.thrift;
+
+import java.util.Map;
+
+/**
+ * Wrapper around TListSentryPrivilegesByAuthResponse.
+ * <p>
+ * Allows getting all the results associated with the response
+ * in a single fetch
+ */
+public class SentryObjectPrivileges {
+
+ private Map<TSentryAuthorizable, TSentryPrivilegeMap> privilegesForRoles;
+ private Map<TSentryAuthorizable, TSentryPrivilegeMap> privilegesForUsers;
+
+ SentryObjectPrivileges(TListSentryPrivilegesByAuthResponse response) {
+
+ privilegesForRoles = response.getPrivilegesMapByAuth();
+ privilegesForUsers = response.getPrivilegesMapByAuthForUsers();
+ }
+
+ /**
+ * Return a map of authorizable to a mapping of roleNames to TSentryPrivileges
+ * @return
+ */
+ public Map<TSentryAuthorizable, TSentryPrivilegeMap> getPrivilegesForRoles() {
+ return privilegesForRoles;
+ }
+
+ /**
+ * Return a map of authorizable to a mapping of userNames to TSentryPrivileges
+ * @return
+ */
+ public Map<TSentryAuthorizable, TSentryPrivilegeMap> getPrivilegesForUsers() {
+ return privilegesForUsers;
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/bee44c28/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyServiceClient.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyServiceClient.java b/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyServiceClient.java
index 6f38ed2..3950ea5 100644
--- a/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyServiceClient.java
+++ b/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyServiceClient.java
@@ -243,6 +243,28 @@ public interface SentryPolicyServiceClient extends AutoCloseable {
Set<String> groups, Set<String> users, ActiveRoleSet roleSet) throws SentryUserException;
/**
+ * Returns an encapsulation of objects for all types assigned to a set of users and/or groups available in a
+ * set of authorizable objects.
+ *
+ * @param requestorUserName The user who is requesting the list of privileges.
+ * @param authorizables A list of authorizable objects to look for privileges.
+ * If null, then privileges of any authorizable object should be returned.
+ * @param groups A list of groups to look for privileges assigned.
+ * If null, then privileges of any group on the specified authorizable object
+ * should be returned.
+ * @param users A list of users to look for privileges assigned.
+ * If null, then privileges of any user on the specified authorizable object
+ * should be returned.
+ * @param roleSet The active role the group and/or user has. If null, then privileges of
+ * any role on the specified group or user should be returned.
+ * @return A an instance of SentryObjectPrivileges on the specified authorizable object.
+ * @throws SentryUserException In case an error occurs while getting the list of privileges.
+ */
+ SentryObjectPrivileges getAllPrivilegsbyAuthorizable(
+ String requestorUserName, Set<List<? extends Authorizable>> authorizables,
+ Set<String> groups, Set<String> users, ActiveRoleSet roleSet) throws SentryUserException;
+
+ /**
* Returns the configuration value in the sentry server associated with propertyName, or if
* propertyName does not exist, the defaultValue. There is no "requestorUserName" because this is
* regarded as an internal interface.
http://git-wip-us.apache.org/repos/asf/sentry/blob/bee44c28/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyServiceClientDefaultImpl.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyServiceClientDefaultImpl.java b/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyServiceClientDefaultImpl.java
index 45dce0e..28d345e 100644
--- a/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyServiceClientDefaultImpl.java
+++ b/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyServiceClientDefaultImpl.java
@@ -939,14 +939,37 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
String requestorUserName,
Set<List<? extends Authorizable>> authorizables, Set<String> groups,
Set<String> users, ActiveRoleSet roleSet) throws SentryUserException {
+
+ TListSentryPrivilegesByAuthResponse response =
+ getSentryPrivilegeByAuthResponse(requestorUserName, authorizables, groups, users, roleSet);
+
+ return response.getPrivilegesMapByAuth();
+ }
+
+ @Override
+ public SentryObjectPrivileges getAllPrivilegsbyAuthorizable
+ (
+ String requestorUserName,
+ Set<List<? extends Authorizable>> authorizables, Set<String> groups,
+ Set<String> users, ActiveRoleSet roleSet) throws SentryUserException {
+
+ TListSentryPrivilegesByAuthResponse response =
+ getSentryPrivilegeByAuthResponse(requestorUserName, authorizables, groups, users, roleSet);
+
+ return new SentryObjectPrivileges(response);
+ }
+
+ public TListSentryPrivilegesByAuthResponse getSentryPrivilegeByAuthResponse(String requestorUserName,
+ Set<List<? extends Authorizable>> authorizables, Set<String> groups, Set<String> users,
+ ActiveRoleSet roleSet) throws SentryUserException {
Set<TSentryAuthorizable> authSet = Sets.newTreeSet();
for (List<? extends Authorizable> authorizableHierarchy : authorizables) {
authSet.add(setupSentryAuthorizable(authorizableHierarchy));
}
TListSentryPrivilegesByAuthRequest request = new TListSentryPrivilegesByAuthRequest(
- ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
- authSet);
+ ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
+ authSet);
if (groups != null) {
request.setGroups(groups);
}
@@ -961,7 +984,11 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
TListSentryPrivilegesByAuthResponse response = client
.list_sentry_privileges_by_authorizable(request);
Status.throwIfNotOk(response.getStatus());
- return response.getPrivilegesMapByAuth();
+
+ if(response == null) {
+ throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE + ": received a NULL response while requesting for sentry privileges by authorizable");
+ }
+ return response;
} catch (TException e) {
throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
}
http://git-wip-us.apache.org/repos/asf/sentry/blob/bee44c28/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestShowGrants.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestShowGrants.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestShowGrants.java
new file mode 100644
index 0000000..500b38b
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestShowGrants.java
@@ -0,0 +1,227 @@
+/*
+ * 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.sentry.tests.e2e.dbprovider;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.junit.Assert;
+
+import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
+import org.apache.sentry.tests.e2e.hive.AbstractTestWithStaticConfiguration;
+import org.apache.sentry.tests.e2e.hive.DummySentryOnFailureHook;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServerFactory;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestShowGrants extends AbstractTestWithStaticConfiguration {
+
+ private static int SHOW_GRANT_DB_POSITION = 1;
+ private static int SHOW_GRANT_TABLE_POSITION = 2;
+
+ @BeforeClass
+ public static void setupTestStaticConfiguration() throws Exception {
+ useSentryService = true;
+ String hiveServer2Type = System
+ .getProperty(HiveServerFactory.HIVESERVER2_TYPE);
+ if ((hiveServer2Type == null)
+ || HiveServerFactory.isInternalServer(HiveServerFactory.HiveServer2Type
+ .valueOf(hiveServer2Type.trim()))) {
+ System.setProperty(
+ HiveAuthzConf.AuthzConfVars.AUTHZ_ONFAILURE_HOOKS.getVar(),
+ DummySentryOnFailureHook.class.getName());
+ }
+ AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
+ }
+
+ @Override
+ @Before
+ public void setup() throws Exception {
+ DummySentryOnFailureHook.invoked = false;
+ super.setupAdmin();
+ super.setup();
+ setupTestCase();
+ }
+
+ private void setupTestCase() throws Exception {
+ // setup db objects needed by the test
+ Connection connection = context.createConnection(ADMIN1);
+ Statement statement = context.createStatement(connection);
+
+ statement.execute("DROP DATABASE IF EXISTS db_1 CASCADE");
+ statement.execute("CREATE DATABASE db_1");
+ statement.execute("CREATE DATABASE db_2");
+ statement.execute("USE db_1");
+ statement.execute("CREATE TABLE foo (id int)");
+ statement.execute("USE db_2");
+ statement.execute("CREATE TABLE bar (id int)");
+
+ statement.execute("CREATE ROLE role1");
+ statement.execute("CREATE ROLE role2");
+ statement.execute("CREATE ROLE role3");
+ statement.execute("CREATE ROLE role4");
+
+ statement.execute("GRANT ROLE role1 TO GROUP " + USERGROUP1);
+ statement.execute("GRANT ROLE role1 TO GROUP " + USERGROUP2);
+ statement.execute("GRANT ROLE role2 TO GROUP " + USERGROUP2);
+ statement.execute("GRANT ROLE role3 TO GROUP " + USERGROUP2);
+ statement.execute("GRANT ROLE role4 TO GROUP " + USERGROUP3);
+ statement.execute("GRANT ROLE role4 TO GROUP " + USERGROUP4);
+
+ //Grant on server to role 1
+ statement.execute("GRANT ALL ON SERVER server1 TO ROLE role1");
+
+ // Grant select on database db_1 to role2
+ // Grant insert on database db_1 to role3
+ // Grant all on database db_2 to role3
+ statement.execute("GRANT SELECT ON DATABASE db_1 TO ROLE role2");
+ statement.execute("GRANT INSERT ON DATABASE db_1 TO ROLE role3");
+ statement.execute("GRANT ALL ON DATABASE db_2 TO ROLE role4");
+
+ // Grant select on table db_2.bar to role role2
+ // Grant insert on table db_2.bar to role role3
+ // Grant all on table db_1.foo to role role4
+ statement.execute("GRANT ALL ON TABLE db_1.foo TO ROLE role4");
+ statement.execute("GRANT ALL ON TABLE db_1.foo TO ROLE role3");
+ statement.execute("GRANT SELECT ON TABLE db_2.bar TO ROLE role2");
+ statement.execute("GRANT INSERT ON TABLE db_2.bar TO ROLE role3");
+
+ //Grant all on uri '/a/b/c' to role1
+ //Grant all on uri '/x/y/z' to role2, role3, role4
+ statement.execute("GRANT ALL ON URI \"file:///a/b/c\" TO ROLE role1");
+ statement.execute("GRANT ALL ON URI \"file:///x/y/z\" TO ROLE role3");
+ statement.execute("GRANT ALL ON URI \"file:///x/y/z\" TO ROLE role4");
+
+ statement.close();
+ connection.close();
+ }
+
+ /**
+ * Test show grants on objects for admin users
+ * @throws Exception
+ */
+ @Test
+ public void testShowGrantsOnObjectsForAdmin() throws Exception {
+ // setup db objects needed by the test
+ Connection connection = context.createConnection(ADMIN1);
+ Statement statement = context.createStatement(connection);
+
+ ResultSet resultSet = null;
+ resultSet = statement.executeQuery("SHOW GRANT ON SERVER server1");
+ assertResultSize(resultSet, 2);//Role1 + Admin
+ Assert.assertEquals("*", resultSet.getString(SHOW_GRANT_DB_POSITION));
+
+ resultSet = statement.executeQuery("SHOW GRANT ON DATABASE db_1");
+ assertResultSize(resultSet, 2);
+ Assert.assertEquals("db_1", resultSet.getString(SHOW_GRANT_DB_POSITION));
+
+ resultSet = statement.executeQuery("SHOW GRANT ON DATABASE db_2");
+ assertResultSize(resultSet, 1);
+ Assert.assertEquals("db_2", resultSet.getString(SHOW_GRANT_DB_POSITION));
+
+ resultSet = statement.executeQuery("SHOW GRANT ON TABLE db_1.foo");
+ assertResultSize(resultSet, 2);
+ Assert.assertEquals("foo", resultSet.getString(SHOW_GRANT_TABLE_POSITION));
+
+ resultSet = statement.executeQuery("SHOW GRANT ON TABLE db_2.bar");
+ assertResultSize(resultSet, 2);
+ Assert.assertEquals("bar", resultSet.getString(SHOW_GRANT_TABLE_POSITION));
+
+ resultSet = statement.executeQuery("SHOW GRANT ON URI \"file:///a/b/c\"");
+ assertResultSize(resultSet, 1);
+ Assert.assertEquals("file:///a/b/c", resultSet.getString(SHOW_GRANT_DB_POSITION));
+
+ resultSet = statement.executeQuery("SHOW GRANT ON URI \"file:///x/y/z\"");
+ assertResultSize(resultSet, 2);
+ Assert.assertEquals("file:///x/y/z", resultSet.getString(SHOW_GRANT_DB_POSITION));
+
+ statement.close();
+ connection.close();
+ }
+
+ /**
+ * Test show grants on objects for non-admin users
+ * @throws Exception
+ */
+ @Test
+ public void testShowGrantsOnObjectsForNonAdmins() throws Exception {
+ Connection connection = context.createConnection(USER1_1);
+ Statement statement = context.createStatement(connection);
+
+ ResultSet resultSet = null;
+
+ resultSet = statement.executeQuery("SHOW GRANT ON DATABASE db_1");
+ assertResultSize(resultSet, 0);
+
+ resultSet = statement.executeQuery("SHOW GRANT ON DATABASE db_2");
+ assertResultSize(resultSet, 0);
+
+ statement.close();
+ connection.close();
+
+ // setup db objects needed by the test
+ connection = context.createConnection(USER2_1);
+ statement = context.createStatement(connection);
+
+ resultSet = statement.executeQuery("SHOW GRANT ON DATABASE db_1");
+ assertResultSize(resultSet, 2);
+ Assert.assertEquals("db_1", resultSet.getString(SHOW_GRANT_DB_POSITION));
+
+ resultSet = statement.executeQuery("SHOW GRANT ON DATABASE db_2");
+ assertResultSize(resultSet, 0);
+
+ resultSet = statement.executeQuery("SHOW GRANT ON TABLE db_1.foo");
+ assertResultSize(resultSet, 2);
+
+ statement.close();
+ connection.close();
+
+ // setup db objects needed by the test
+ connection = context.createConnection(USER4_1);
+ statement = context.createStatement(connection);
+
+ resultSet = statement.executeQuery("SHOW GRANT ON TABLE db_1.foo");
+ assertResultSize(resultSet, 2);
+ Assert.assertEquals("foo", resultSet.getString(SHOW_GRANT_TABLE_POSITION));
+
+ resultSet = statement.executeQuery("SHOW GRANT ON TABLE db_2.bar");
+ assertResultSize(resultSet, 0);
+
+ resultSet = statement.executeQuery("SHOW GRANT ON URI \"file:///a/b/c\"");
+ assertResultSize(resultSet, 0);
+
+ resultSet = statement.executeQuery("SHOW GRANT ON URI \"file:///x/y/z\"");
+ assertResultSize(resultSet, 2);
+ Assert.assertEquals("file:///x/y/z", resultSet.getString(SHOW_GRANT_DB_POSITION));
+
+ statement.close();
+ connection.close();
+ }
+
+ private void assertResultSize(ResultSet resultSet, int expected) throws SQLException{
+ int count = 0;
+ while(resultSet.next()) {
+ count++;
+ }
+ Assert.assertEquals(count, expected);
+ }
+
+}