From commits-return-12703-archive-asf-public=cust-asf.ponee.io@sentry.apache.org Thu May 31 05:32:05 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id 254E31807AA for ; Thu, 31 May 2018 05:32:02 +0200 (CEST) Received: (qmail 38344 invoked by uid 500); 31 May 2018 03:32:01 -0000 Mailing-List: contact commits-help@sentry.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@sentry.apache.org Delivered-To: mailing list commits@sentry.apache.org Received: (qmail 34588 invoked by uid 99); 31 May 2018 03:31:42 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 31 May 2018 03:31:42 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 12008E1175; Thu, 31 May 2018 03:31:40 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: spena@apache.org To: commits@sentry.apache.org Date: Thu, 31 May 2018 03:32:07 -0000 Message-Id: In-Reply-To: <5efebc2704cd43a891f304274777fee8@git.apache.org> References: <5efebc2704cd43a891f304274777fee8@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [29/86] sentry git commit: Revert "SENTRY-2208: Refactor out Sentry service into own module from sentry-provider-db (Anthony Young-Garner, reviewed by Sergio Pena, Steve Moist, Na Li)" http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceIntegration.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceIntegration.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceIntegration.java new file mode 100644 index 0000000..73fca84 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceIntegration.java @@ -0,0 +1,1102 @@ +/** + * 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 createRequired 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import org.apache.sentry.core.common.ActiveRoleSet; +import org.apache.sentry.core.common.Authorizable; +import org.apache.sentry.core.model.db.AccessConstants; +import org.apache.sentry.core.model.db.AccessURI; +import org.apache.sentry.core.model.db.Database; +import org.apache.sentry.core.model.db.Server; +import org.apache.sentry.core.model.db.Table; +import org.apache.sentry.core.common.exception.SentryAccessDeniedException; +import org.apache.sentry.service.thrift.SentryServiceIntegrationBase; +import org.junit.Test; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + + +public class TestSentryServiceIntegration extends SentryServiceIntegrationBase { + + @Test + public void testCreateDropShowRole() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + String roleName = "admin_r"; + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + + client.dropRoleIfExists(requestorUserName, roleName); + + client.createRole(requestorUserName, roleName); + + Set roles = client.listAllRoles(requestorUserName); + assertEquals("Incorrect number of roles", 1, roles.size()); + + for (TSentryRole role:roles) { + assertTrue(role.getRoleName(), role.getRoleName().equalsIgnoreCase(roleName)); + } + client.dropRole(requestorUserName, roleName); + }}); + } + + @Test + public void testGranRevokePrivilegeOnTableForRole() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + String roleName1 = "admin_r1"; + String roleName2 = "admin_r2"; + + client.dropRoleIfExists(requestorUserName, roleName1); + client.createRole(requestorUserName, roleName1); + + client.grantTablePrivilege(requestorUserName, roleName1, "server", "db1", "table1", "ALL"); + client.grantTablePrivilege(requestorUserName, roleName1, "server", "db1", "table2", "ALL"); + client.grantTablePrivilege(requestorUserName, roleName1, "server", "db2", "table3", "ALL"); + client.grantTablePrivilege(requestorUserName, roleName1, "server", "db2", "table4", "ALL"); + + + client.dropRoleIfExists(requestorUserName, roleName2); + client.createRole(requestorUserName, roleName2); + + client.grantTablePrivilege(requestorUserName, roleName2, "server", "db1", "table1", "ALL"); + client.grantTablePrivilege(requestorUserName, roleName2, "server", "db1", "table2", "ALL"); + client.grantTablePrivilege(requestorUserName, roleName2, "server", "db2", "table3", "ALL"); + client.grantTablePrivilege(requestorUserName, roleName2, "server", "db2", "table4", "ALL"); + + Set listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName1); + assertEquals("Privilege not assigned to role1 !!", 4, listPrivilegesByRoleName.size()); + + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName2); + assertEquals("Privilege not assigned to role2 !!", 4, listPrivilegesByRoleName.size()); + + + client.revokeTablePrivilege(requestorUserName, roleName1, "server", "db1", "table1", "ALL"); + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName1); + assertTrue("Privilege not correctly revoked !!", listPrivilegesByRoleName.size() == 3); + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName2); + assertTrue("Privilege not correctly revoked !!", listPrivilegesByRoleName.size() == 4); + + client.revokeTablePrivilege(requestorUserName, roleName2, "server", "db1", "table1", "ALL"); + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName2); + assertTrue("Privilege not correctly revoked !!", listPrivilegesByRoleName.size() == 3); + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName1); + assertTrue("Privilege not correctly revoked !!", listPrivilegesByRoleName.size() == 3); + + client.revokeTablePrivilege(requestorUserName, roleName1, "server", "db1", "table2", "ALL"); + client.revokeTablePrivilege(requestorUserName, roleName1, "server", "db2", "table3", "ALL"); + client.revokeTablePrivilege(requestorUserName, roleName1, "server", "db2", "table4", "ALL"); + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName1); + assertTrue("Privilege not correctly revoked !!", listPrivilegesByRoleName.size() == 0); + + client.revokeTablePrivilege(requestorUserName, roleName2, "server", "db1", "table2", "ALL"); + client.revokeTablePrivilege(requestorUserName, roleName2, "server", "db2", "table3", "ALL"); + client.revokeTablePrivilege(requestorUserName, roleName2, "server", "db2", "table4", "ALL"); + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName2); + assertTrue("Privilege not correctly revoked !!", listPrivilegesByRoleName.size() == 0); + }}); + } + + @Test + public void testAddDeleteRolesForUser() throws Exception { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + + // user1->group1 + // user2->group1 + // user3->group1, group2 + // user4->group2, group3 + // group1->r1 + // group2->r2 + // group3->r2 + // user2->r3 + // user4->r3 + String roleName1 = "r1"; + String roleName2 = "r2"; + String roleName3 = "r3"; + String user1 = "u1"; + String user2 = "u2"; + String user3 = "u3"; + String user4 = "u4"; + String group1 = "g1"; + String group2 = "g2"; + String group3 = "g3"; + Map> userToGroups = Maps.newHashMap(); + userToGroups.put(user1, Sets.newHashSet(group1)); + userToGroups.put(user2, Sets.newHashSet(group1)); + userToGroups.put(user3, Sets.newHashSet(group1, group2)); + userToGroups.put(user4, Sets.newHashSet(group2, group3)); + + setLocalGroupMapping(user1, Sets.newHashSet(group1)); + setLocalGroupMapping(user2, Sets.newHashSet(group1)); + setLocalGroupMapping(user3, Sets.newHashSet(group1, group2)); + setLocalGroupMapping(user4, Sets.newHashSet(group2, group3)); + writePolicyFile(); + + client.dropRoleIfExists(requestorUserName, roleName1); + client.dropRoleIfExists(requestorUserName, roleName2); + client.dropRoleIfExists(requestorUserName, roleName3); + client.createRole(requestorUserName, roleName1); + client.createRole(requestorUserName, roleName2); + client.createRole(requestorUserName, roleName3); + + client.grantRoleToGroup(requestorUserName, group1, roleName1); + client.grantRoleToUser(requestorUserName, user2, roleName2); + client.grantRoleToUser(requestorUserName, user3, roleName2); + client.grantRoleToUser(requestorUserName, user2, roleName3); + client.grantRoleToUsers(requestorUserName, roleName3, Sets.newHashSet(user4)); + // following test cases also test the grantRoleToUser() and grantRoleToUsers() implicity + // admin always can get the role list + Set roles = client.listRolesByUserName(requestorUserName, user1); + assertEquals(0, roles.size()); + // the role list includes the role for user and the role for user's group + roles = client.listRolesByUserName(requestorUserName, user2); + assertEquals(2, roles.size()); + for (TSentryRole role : roles) { + assertTrue(roleName2.equals(role.getRoleName()) || roleName3.equals(role.getRoleName())); + } + // user has 2 groups whose role list are different + roles = client.listRolesByUserName(requestorUserName, user3); + assertEquals(1, roles.size()); + for (TSentryRole role : roles) { + assertTrue(roleName2.equals(role.getRoleName())); + } + // user has 2 groups whose role list are the same + roles = client.listRolesByUserName(requestorUserName, user4); + assertEquals(1, roles.size()); + for (TSentryRole role : roles) { + assertTrue(roleName3.equals(role.getRoleName())); + } + // user can get his own role list if he isn't an admin + roles = client.listRolesByUserName(user3, user3); + assertEquals(1, roles.size()); + // user can't get other's role list if he isn't an admin + try { + client.listRolesByUserName(user3, user2); + fail("SentryAccessDeniedException should be caught."); + } catch (SentryAccessDeniedException e) { + // excepted exception + } + // the user's name can't be empty + try { + client.listRolesByUserName(user3, ""); + fail("SentryAccessDeniedException should be caught."); + } catch (SentryAccessDeniedException e) { + // excepted exception + } + client.revokeRoleFromUser(requestorUserName, user2, roleName3); + client.revokeRoleFromUsers(requestorUserName, roleName3, Sets.newHashSet(user4)); + // test the result of revokeRoleFromUser() and revokeRoleFromUsers() + roles = client.listRolesByUserName(requestorUserName, user2); + assertEquals(1, roles.size()); + for (TSentryRole role : roles) { + assertTrue(roleName2.equals(role.getRoleName())); + } + roles = client.listRolesByUserName(requestorUserName, user4); + assertEquals(0, roles.size()); + } + }); + } + + @Test + public void testGranRevokePrivilegeForRoleWithUG() throws Exception { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + + // user1_1->group1 + // user1_2->group1 + // user2_1->group2 + // user2_2->group2 + // group1->r1 + // group2->r2 + // user1_1->r3 + // user2_1->r4 + String roleName1 = "r1"; + String roleName2 = "r2"; + String roleName3 = "r3"; + String roleName4 = "r4"; + String user1_1 = "u1_1"; + String user1_2 = "u1_2"; + String user2_1 = "u2_1"; + String user2_2 = "u2_2"; + String group1 = "g1"; + String group2 = "g2"; + Map userToGroup = Maps.newHashMap(); + userToGroup.put(user1_1, group1); + userToGroup.put(user1_2, group1); + userToGroup.put(user2_1, group2); + userToGroup.put(user2_2, user2_1); + + Set groupSet = Sets.newHashSet(group1); + setLocalGroupMapping(user1_1, groupSet); + setLocalGroupMapping(user1_2, groupSet); + groupSet = Sets.newHashSet(group2); + setLocalGroupMapping(user2_1, groupSet); + setLocalGroupMapping(user2_2, groupSet); + writePolicyFile(); + + client.dropRoleIfExists(requestorUserName, roleName1); + client.dropRoleIfExists(requestorUserName, roleName2); + client.dropRoleIfExists(requestorUserName, roleName3); + client.dropRoleIfExists(requestorUserName, roleName4); + client.createRole(requestorUserName, roleName1); + client.createRole(requestorUserName, roleName2); + client.createRole(requestorUserName, roleName3); + client.createRole(requestorUserName, roleName4); + + client.grantRoleToGroup(requestorUserName, group1, roleName1); + client.grantRoleToGroup(requestorUserName, group2, roleName2); + client.grantRoleToUser(requestorUserName, user1_1, roleName3); + client.grantRoleToUsers(requestorUserName, roleName4, Sets.newHashSet(user2_1)); + + client + .grantTablePrivilege(requestorUserName, roleName1, "server", "db1", "table1_1", "ALL"); + client + .grantTablePrivilege(requestorUserName, roleName1, "server", "db1", "table1_2", "ALL"); + client + .grantTablePrivilege(requestorUserName, roleName2, "server", "db1", "table2_1", "ALL"); + client + .grantTablePrivilege(requestorUserName, roleName2, "server", "db1", "table2_2", "ALL"); + client + .grantTablePrivilege(requestorUserName, roleName3, "server", "db1", "table3_1", "ALL"); + client + .grantTablePrivilege(requestorUserName, roleName3, "server", "db1", "table3_2", "ALL"); + client + .grantTablePrivilege(requestorUserName, roleName4, "server", "db1", "table4_1", "ALL"); + client + .grantTablePrivilege(requestorUserName, roleName4, "server", "db1", "table4_2", "ALL"); + + Set listPrivilegesForProvider = client.listPrivilegesForProvider( + Sets.newHashSet(group1), Sets.newHashSet(""), ActiveRoleSet.ALL, (Authorizable[]) null); + assertEquals("Privilege not correctly assigned to roles !!", Sets.newHashSet( + "server=server->db=db1->table=table1_1->action=all", + "server=server->db=db1->table=table1_2->action=all"), listPrivilegesForProvider); + + listPrivilegesForProvider = client.listPrivilegesForProvider( + Sets.newHashSet(userToGroup.get(user1_2)), + Sets.newHashSet(user1_2), ActiveRoleSet.ALL, (Authorizable[]) null); + assertEquals("Privilege not correctly assigned to roles !!", Sets.newHashSet( + "server=server->db=db1->table=table1_1->action=all", + "server=server->db=db1->table=table1_2->action=all"), listPrivilegesForProvider); + + listPrivilegesForProvider = client.listPrivilegesForProvider( + Sets.newHashSet(userToGroup.get(user1_1)), + Sets.newHashSet(user1_1), ActiveRoleSet.ALL, (Authorizable[]) null); + assertEquals("Privilege not correctly assigned to roles !!", Sets.newHashSet( + "server=server->db=db1->table=table1_1->action=all", + "server=server->db=db1->table=table1_2->action=all", + "server=server->db=db1->table=table3_1->action=all", + "server=server->db=db1->table=table3_2->action=all"), listPrivilegesForProvider); + + listPrivilegesForProvider = client.listPrivilegesForProvider(Sets.newHashSet(group1), + Sets.newHashSet(user1_1, user1_2), ActiveRoleSet.ALL, (Authorizable[]) null); + assertEquals("Privilege not correctly assigned to roles !!", Sets.newHashSet( + "server=server->db=db1->table=table1_1->action=all", + "server=server->db=db1->table=table1_2->action=all", + "server=server->db=db1->table=table3_1->action=all", + "server=server->db=db1->table=table3_2->action=all"), listPrivilegesForProvider); + + listPrivilegesForProvider = client.listPrivilegesForProvider( + Sets.newHashSet(group1, group2), Sets.newHashSet(user1_1, user1_2, user2_1, user2_2), + ActiveRoleSet.ALL, (Authorizable[]) null); + assertEquals("Privilege not correctly assigned to roles !!", Sets.newHashSet( + "server=server->db=db1->table=table1_1->action=all", + "server=server->db=db1->table=table1_2->action=all", + "server=server->db=db1->table=table2_1->action=all", + "server=server->db=db1->table=table2_2->action=all", + "server=server->db=db1->table=table3_1->action=all", + "server=server->db=db1->table=table3_2->action=all", + "server=server->db=db1->table=table4_1->action=all", + "server=server->db=db1->table=table4_2->action=all"), listPrivilegesForProvider); + + client.revokeRoleFromUser(requestorUserName, user1_1, roleName3); + client.revokeRoleFromUsers(requestorUserName, roleName4, Sets.newHashSet(user2_1)); + } + }); + } + + @Test + public void testMultipleRolesSamePrivilege() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + String roleName1 = "admin_r1"; + String roleName2 = "admin_r2"; + + client.dropRoleIfExists(requestorUserName, roleName1); + client.createRole(requestorUserName, roleName1); + + client.dropRoleIfExists(requestorUserName, roleName2); + client.createRole(requestorUserName, roleName2); + + client.grantTablePrivilege(requestorUserName, roleName1, "server", "db", "table", "ALL"); + Set listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName1); + assertTrue("Privilege not assigned to role1 !!", listPrivilegesByRoleName.size() == 1); + + client.grantTablePrivilege(requestorUserName, roleName2, "server", "db", "table", "ALL"); + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName2); + assertTrue("Privilege not assigned to role2 !!", listPrivilegesByRoleName.size() == 1); + }}); + } + + @Test + public void testShowRoleGrant() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + String roleName = "admin_testdb"; + String groupName = "group1"; + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + + client.dropRoleIfExists(requestorUserName, roleName); + client.createRole(requestorUserName, roleName); + + Set roles = client.listAllRoles(requestorUserName); + assertEquals("Incorrect number of roles", 1, roles.size()); + + client.grantRoleToGroup(requestorUserName, groupName, roleName); + Set groupRoles = client.listRolesByGroupName(requestorUserName, groupName); + assertTrue(groupRoles.size() == 1); + for (TSentryRole role:groupRoles) { + assertTrue(role.getRoleName(), role.getRoleName().equalsIgnoreCase(roleName)); + assertTrue(role.getGroups().size() == 1); + for (TSentryGroup group :role.getGroups()) { + assertTrue(group.getGroupName(), group.getGroupName().equalsIgnoreCase(groupName)); + } + } + + client.dropRole(requestorUserName, roleName); + }}); + } + + @Test + public void testShowGrant() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + String roleName = "admin_testdb"; + String server = "server1"; + String db = "testDB"; + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + + client.dropRoleIfExists(requestorUserName, roleName); + client.createRole(requestorUserName, roleName); + + Set roles = client.listAllRoles(requestorUserName); + assertEquals("Incorrect number of roles", 1, roles.size()); + + client.grantDatabasePrivilege(requestorUserName, roleName, server, db, AccessConstants.ALL); + Set privileges = client.listAllPrivilegesByRoleName(requestorUserName, roleName); + assertTrue(privileges.size() == 1); + + client.revokeDatabasePrivilege(requestorUserName, roleName, server, db, AccessConstants.ALL); + client.dropRole(requestorUserName, roleName); + }}); + } + + //See SENTRY-166 + @Test + public void testUriWithEquals() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + String roleName = "admin_testdb"; + String server = "server1"; + String uri = "file://u/w/h/t/partition=value/"; + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + + // Creating associated role + client.dropRoleIfExists(requestorUserName, roleName); + client.createRole(requestorUserName, roleName); + Set roles = client.listAllRoles(requestorUserName); + assertEquals("Incorrect number of roles", 1, roles.size()); + + client.grantURIPrivilege(requestorUserName, roleName, server, uri); + Set privileges = client.listAllPrivilegesByRoleName(requestorUserName, roleName); + assertTrue(privileges.size() == 1); + + // Revoking the same privilege + client.revokeURIPrivilege(requestorUserName, roleName, server, uri); + privileges = client.listAllPrivilegesByRoleName(requestorUserName, roleName); + assertTrue(privileges.size() == 0); + + // Clean up + client.dropRole(requestorUserName, roleName); + }}); + } + + + //See SENTRY-181 + @Test + public void testSameGrantTwice() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + String roleName = "admin_r1"; + + client.createRole(requestorUserName, roleName); + client.grantTablePrivilege(requestorUserName, roleName, "server", "db1", "table1", "ALL"); + client.grantTablePrivilege(requestorUserName, roleName, "server", "db1", "table1", "ALL"); + assertEquals(1, client.listAllPrivilegesByRoleName(requestorUserName, roleName).size()); + }}); + } + + @Test + public void testGrantRevokeWithGrantOption() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + // Grant a privilege with Grant Option + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + String roleName = "admin_r1"; + boolean grantOption = true; + boolean withoutGrantOption = false; + + client.dropRoleIfExists(requestorUserName, roleName); + client.createRole(requestorUserName, roleName); + + client.grantTablePrivilege(requestorUserName, roleName, "server", "db1", "table1", "ALL", grantOption); + assertEquals(1, client.listAllPrivilegesByRoleName(requestorUserName, roleName).size()); + + // Try to revoke the privilege without grantOption and can't revoke the privilege. + client.revokeTablePrivilege(requestorUserName, roleName, "server", "db1", "table1", "ALL", withoutGrantOption); + assertEquals(1, client.listAllPrivilegesByRoleName(requestorUserName, roleName).size()); + + // Try to revoke the privilege with grantOption, the privilege will be revoked. + client.revokeTablePrivilege(requestorUserName, roleName, "server", "db1", "table1", "ALL", grantOption); + assertEquals(0, client.listAllPrivilegesByRoleName(requestorUserName, roleName).size()); + }}); + } + + @Test + public void testGrantTwoPrivilegeDiffInGrantOption() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + // Grant a privilege with 'Grant Option'. + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + String roleName = "admin_r1"; + boolean grantOption = true; + boolean withoutGrantOption = false; + + client.dropRoleIfExists(requestorUserName, roleName); + client.createRole(requestorUserName, roleName); + + client.grantTablePrivilege(requestorUserName, roleName, "server", "db1", "table1", "ALL", grantOption); + assertEquals(1, client.listAllPrivilegesByRoleName(requestorUserName, roleName).size()); + + // Grant a privilege without 'Grant Option'. + client.grantTablePrivilege(requestorUserName, roleName, "server", "db1", "table1", "ALL", withoutGrantOption); + assertEquals(2, client.listAllPrivilegesByRoleName(requestorUserName, roleName).size()); + + // Use 'grantOption = null', the two privileges will be revoked. + client.revokeTablePrivilege(requestorUserName, roleName, "server", "db1", "table1", "ALL", null); + assertEquals(0, client.listAllPrivilegesByRoleName(requestorUserName, roleName).size()); + }}); + } + + @Test + public void testGranRevokePrivilegeOnColumnForRole() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + String roleName1 = "admin_r1"; + String roleName2 = "admin_r2"; + + client.dropRoleIfExists(requestorUserName, roleName1); + client.createRole(requestorUserName, roleName1); + + client.grantColumnPrivilege(requestorUserName, roleName1, "server", "db1", "table1", "col1", "ALL"); + client.grantColumnPrivilege(requestorUserName, roleName1, "server", "db1", "table1", "col2", "ALL"); + client.grantColumnPrivilege(requestorUserName, roleName1, "server", "db1", "table2", "col1", "ALL"); + client.grantColumnPrivilege(requestorUserName, roleName1, "server", "db1", "table2", "col2", "ALL"); + client.grantColumnPrivilege(requestorUserName, roleName1, "server", "db2", "table1", "col1", "ALL"); + client.grantColumnPrivilege(requestorUserName, roleName1, "server", "db2", "table2", "col1", "ALL"); + + + client.dropRoleIfExists(requestorUserName, roleName2); + client.createRole(requestorUserName, roleName2); + + client.grantColumnPrivilege(requestorUserName, roleName2, "server", "db1", "table1", "col1", "ALL"); + client.grantColumnPrivilege(requestorUserName, roleName2, "server", "db1", "table1", "col2", "ALL"); + client.grantColumnPrivilege(requestorUserName, roleName2, "server", "db1", "table2", "col1", "ALL"); + client.grantColumnPrivilege(requestorUserName, roleName2, "server", "db1", "table2", "col2", "ALL"); + client.grantColumnPrivilege(requestorUserName, roleName2, "server", "db2", "table1", "col1", "ALL"); + client.grantColumnPrivilege(requestorUserName, roleName2, "server", "db2", "table2", "col1", "ALL"); + + Set listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName1); + assertEquals("Privilege not assigned to role1 !!", 6, listPrivilegesByRoleName.size()); + + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName2); + assertEquals("Privilege not assigned to role2 !!", 6, listPrivilegesByRoleName.size()); + + + client.revokeColumnPrivilege(requestorUserName, roleName1, "server", "db1", "table1", "col1", "ALL"); + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName1); + assertTrue("Privilege not correctly revoked !!", listPrivilegesByRoleName.size() == 5); + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName2); + assertTrue("Privilege not correctly revoked !!", listPrivilegesByRoleName.size() == 6); + + client.revokeTablePrivilege(requestorUserName, roleName2, "server", "db1", "table1", "ALL"); + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName2); + assertTrue("Privilege not correctly revoked !!", listPrivilegesByRoleName.size() == 4); + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName1); + assertTrue("Privilege not correctly revoked !!", listPrivilegesByRoleName.size() == 5); + + client.revokeDatabasePrivilege(requestorUserName, roleName1, "server", "db1", "ALL"); + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName1); + assertTrue("Privilege not correctly revoked !!", listPrivilegesByRoleName.size() == 2); + client.revokeColumnPrivilege(requestorUserName, roleName1, "server", "db2", "table1", "col1", "ALL"); + client.revokeColumnPrivilege(requestorUserName, roleName1, "server", "db2", "table2", "col1", "ALL"); + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName1); + assertTrue("Privilege not correctly revoked !!", listPrivilegesByRoleName.size() == 0); + + client.revokeColumnPrivilege(requestorUserName, roleName2, "server", "db1", "table2", "col1", "ALL"); + client.revokeColumnPrivilege(requestorUserName, roleName2, "server", "db1", "table2", "col2", "ALL"); + client.revokeColumnPrivilege(requestorUserName, roleName2, "server", "db2", "table1", "col1", "ALL"); + client.revokeColumnPrivilege(requestorUserName, roleName2, "server", "db2", "table2", "col1", "ALL"); + listPrivilegesByRoleName = client.listAllPrivilegesByRoleName(requestorUserName, roleName2); + assertTrue("Privilege not correctly revoked !!", listPrivilegesByRoleName.size() == 0); + }}); + } + + @Test + public void testListByAuthDB() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + String roleName1 = "role1"; + String roleName2 = "role2"; + Set testRoleSet = Sets.newHashSet(roleName1, roleName2); + String group1 = "group1"; + String group2 = "group2"; + Set testGroupSet = Sets.newHashSet(group1, group2); + String server = "server1"; + String db = "testDB"; + String db2 = "testDB2"; + String tab = "testTab"; + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + String group1user = "group1user"; + setLocalGroupMapping(group1user, Sets.newHashSet(group1)); + String group2user = "group2user"; + setLocalGroupMapping(group2user, Sets.newHashSet(group2)); + setLocalGroupMapping("random", Sets.newHashSet("foo")); + writePolicyFile(); + + client.dropRoleIfExists(requestorUserName, roleName1); + client.createRole(requestorUserName, roleName1); + client.dropRoleIfExists(requestorUserName, roleName2); + client.createRole(requestorUserName, roleName2); + + TSentryPrivilege role1db1 = client.grantDatabasePrivilege( + requestorUserName, roleName1, server, db, AccessConstants.SELECT); + client.grantTablePrivilege(requestorUserName, roleName1, server, db, tab, + AccessConstants.ALL); + client.grantTablePrivilege(requestorUserName, roleName1, server, db2, tab, + AccessConstants.SELECT); + client.grantURIPrivilege(requestorUserName, roleName1, server, "hdfs:///fooUri"); + client.grantRoleToGroup(requestorUserName, group1, roleName1); + + TSentryPrivilege role2db1 = client.grantDatabasePrivilege( + requestorUserName, roleName2, server, db, + AccessConstants.ALL); + client.grantDatabasePrivilege(requestorUserName, roleName2, server, db2, + AccessConstants.SELECT); + client.grantTablePrivilege(requestorUserName, roleName2, server, db2, tab, + AccessConstants.ALL); + client.grantRoleToGroup(requestorUserName, group2, roleName2); + + // build expected output + TSentryPrivilegeMap db1RoleToPrivMap = new TSentryPrivilegeMap( + new TreeMap>()); + db1RoleToPrivMap.getPrivilegeMap() + .put(roleName1, Sets.newHashSet(role1db1)); + db1RoleToPrivMap.getPrivilegeMap() + .put(roleName2, Sets.newHashSet(role2db1)); + Map expectedResults = Maps + .newTreeMap(); + List db1Authrizable = Lists.newArrayList( + new Server(server), new Database(db)); + expectedResults.put( + SentryPolicyServiceClientDefaultImpl.setupSentryAuthorizable(db1Authrizable), + db1RoleToPrivMap); + + Set> authorizableSet = Sets.newHashSet(); + authorizableSet.add(db1Authrizable); + + // verify for null group and null roleset + Map authPrivMap = client + .listPrivilegsbyAuthorizable(requestorUserName, authorizableSet, null, null); + assertEquals(expectedResults, authPrivMap); + + // verify for null group and specific roleset + authPrivMap = client.listPrivilegsbyAuthorizable(requestorUserName, authorizableSet, + null, new ActiveRoleSet(testRoleSet)); + assertEquals(expectedResults, authPrivMap); + + // verify for null group and specific roleset + authPrivMap = client.listPrivilegsbyAuthorizable(requestorUserName, authorizableSet, null, + ActiveRoleSet.ALL); + assertEquals(expectedResults, authPrivMap); + + // verify for specific group and null roleset + authPrivMap = client.listPrivilegsbyAuthorizable(requestorUserName, authorizableSet, + testGroupSet, null); + assertEquals(expectedResults, authPrivMap); + + // verify for specific group and specific roleset + authPrivMap = client.listPrivilegsbyAuthorizable(requestorUserName, authorizableSet, + testGroupSet, new ActiveRoleSet(testRoleSet)); + assertEquals(expectedResults, authPrivMap); + + // verify for specific group and ALL roleset + authPrivMap = client.listPrivilegsbyAuthorizable(requestorUserName, authorizableSet, + testGroupSet, ActiveRoleSet.ALL); + assertEquals(expectedResults, authPrivMap); + + // verify users not belonging to any group are not shown anything + authPrivMap = client + .listPrivilegsbyAuthorizable("random", authorizableSet, + new HashSet(), ActiveRoleSet.ALL); + expectedResults.clear(); + expectedResults.put( + SentryPolicyServiceClientDefaultImpl.setupSentryAuthorizable(db1Authrizable), + new TSentryPrivilegeMap(new HashMap>())); + assertEquals(expectedResults, authPrivMap); + }}); + } + + @Test + public void testListByAuthTab() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + String roleName1 = "role1"; + String roleName2 = "role2"; + String server = "server1"; + String db = "testDB"; + String db2 = "testDB2"; + String tab = "testTab"; + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + + client.dropRoleIfExists(requestorUserName, roleName1); + client.createRole(requestorUserName, roleName1); + client.dropRoleIfExists(requestorUserName, roleName2); + client.createRole(requestorUserName, roleName2); + + client.grantDatabasePrivilege( + requestorUserName, roleName1, server, db, AccessConstants.SELECT); + client.grantTablePrivilege(requestorUserName, roleName1, server, db, tab, + AccessConstants.ALL); + TSentryPrivilege role1db2tab = client.grantTablePrivilege( + requestorUserName, roleName1, server, db2, tab, + AccessConstants.SELECT); + + client.grantDatabasePrivilege( + requestorUserName, roleName2, server, db, + AccessConstants.ALL); + client.grantDatabasePrivilege(requestorUserName, roleName2, server, db2, + AccessConstants.SELECT); + TSentryPrivilege role2db2tab = client.grantTablePrivilege( + requestorUserName, roleName2, server, db2, tab, + AccessConstants.ALL); + client.grantURIPrivilege(requestorUserName, roleName1, server, + "hdfs:///fooUri"); + + // build expected output + TSentryPrivilegeMap db1RoleToPrivMap = new TSentryPrivilegeMap( + new TreeMap>()); + db1RoleToPrivMap.getPrivilegeMap().put(roleName1, + Sets.newHashSet(role1db2tab)); + db1RoleToPrivMap.getPrivilegeMap().put(roleName2, + Sets.newHashSet(role2db2tab)); + Map expectedResults = Maps + .newTreeMap(); + List db2TabAuthrizable = Lists.newArrayList( + new Server(server), new Database(db2), new Table(tab)); + expectedResults.put( + SentryPolicyServiceClientDefaultImpl.setupSentryAuthorizable(db2TabAuthrizable), + db1RoleToPrivMap); + + Set> authorizableSet = Sets.newHashSet(); + authorizableSet.add(db2TabAuthrizable); + Map authPrivMap = client + .listPrivilegsbyAuthorizable(requestorUserName, authorizableSet, null, null); + + assertEquals(expectedResults, authPrivMap); + }}); + } + + @Test + public void testListByAuthUri() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + String roleName1 = "role1"; + String roleName2 = "role2"; + String server = "server1"; + String db = "testDB"; + String db2 = "testDB2"; + String tab = "testTab"; + String uri1 = "hdfs:///fooUri"; + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + + client.dropRoleIfExists(requestorUserName, roleName1); + client.createRole(requestorUserName, roleName1); + client.dropRoleIfExists(requestorUserName, roleName2); + client.createRole(requestorUserName, roleName2); + + client.grantDatabasePrivilege(requestorUserName, roleName1, server, db, + AccessConstants.SELECT); + client.grantTablePrivilege(requestorUserName, roleName1, server, db, tab, + AccessConstants.ALL); + client.grantTablePrivilege(requestorUserName, roleName1, server, db2, tab, + AccessConstants.SELECT); + TSentryPrivilege role1uri1 = client.grantURIPrivilege(requestorUserName, + roleName1, server, uri1); + + client.grantDatabasePrivilege(requestorUserName, roleName2, server, db, + AccessConstants.ALL); + client.grantDatabasePrivilege(requestorUserName, roleName2, server, db2, + AccessConstants.SELECT); + client.grantTablePrivilege(requestorUserName, roleName2, server, db2, tab, + AccessConstants.ALL); + TSentryPrivilege role2uri2 = client.grantURIPrivilege(requestorUserName, + roleName2, server, uri1); + + // build expected output + TSentryPrivilegeMap db1RoleToPrivMap = new TSentryPrivilegeMap( + new TreeMap>()); + db1RoleToPrivMap.getPrivilegeMap().put(roleName1, + Sets.newHashSet(role1uri1)); + db1RoleToPrivMap.getPrivilegeMap().put(roleName2, + Sets.newHashSet(role2uri2)); + Map expectedResults = Maps + .newTreeMap(); + List uri1Authrizable = Lists.newArrayList( + new Server(server), new AccessURI(uri1)); + expectedResults.put( + SentryPolicyServiceClientDefaultImpl.setupSentryAuthorizable(uri1Authrizable), + db1RoleToPrivMap); + + Set> authorizableSet = Sets.newHashSet(); + authorizableSet.add(uri1Authrizable); + Map authPrivMap = client + .listPrivilegsbyAuthorizable(requestorUserName, authorizableSet, null, null); + + assertEquals(expectedResults, authPrivMap); + }}); + } + + /** + * List privileges by authorizables executed by non-admin user + * Test various positive and negative cases for non-admin user + * @throws Exception + */ + @Test + public void testListByAuthTabForNonAdmin() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + String user1 = "user1"; + String group1 = "group1"; + String group2 = "group2"; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + Set userGroupNames1 = Sets.newHashSet(group1); + Set userGroupNames2 = Sets.newHashSet(group2); + String roleName1 = "role1"; + String roleName2 = "role2"; + String server = "server1"; + String db = "testDB"; + String db2 = "testDB2"; + String tab = "testTab"; + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + setLocalGroupMapping(user1, userGroupNames1); + writePolicyFile(); + + client.dropRoleIfExists(requestorUserName, roleName1); + client.createRole(requestorUserName, roleName1); + client.dropRoleIfExists(requestorUserName, roleName2); + client.createRole(requestorUserName, roleName2); + + client.grantDatabasePrivilege(requestorUserName, roleName1, server, db, + AccessConstants.SELECT); + client.grantTablePrivilege(requestorUserName, roleName1, server, db, tab, + AccessConstants.ALL); + TSentryPrivilege role1db2tab = client.grantTablePrivilege( + requestorUserName, roleName1, server, db2, tab, AccessConstants.SELECT); + client.grantRoleToGroup(requestorUserName, group1, roleName1); + + client.grantDatabasePrivilege(requestorUserName, roleName2, server, db, + AccessConstants.ALL); + client.grantDatabasePrivilege(requestorUserName, roleName2, server, db2, + AccessConstants.SELECT); + client.grantTablePrivilege(requestorUserName, roleName2, server, db2, tab, + AccessConstants.ALL); + client.grantURIPrivilege(requestorUserName, roleName1, server, + "hdfs:///fooUri"); + + // build expected output. user1 should see privileges on tab1 from role1 + TSentryPrivilegeMap db1RoleToPrivMap = new TSentryPrivilegeMap( + new TreeMap>()); + db1RoleToPrivMap.getPrivilegeMap().put(roleName1, Sets.newHashSet(role1db2tab)); + Map expectedResults = Maps.newTreeMap(); + List db2TabAuthorizable = Lists.newArrayList( + new Server(server), new Database(db2), new Table(tab)); + expectedResults.put( + SentryPolicyServiceClientDefaultImpl.setupSentryAuthorizable(db2TabAuthorizable), + db1RoleToPrivMap); + + Set> authorizableSet = Sets.newHashSet(); + authorizableSet.add(db2TabAuthorizable); + + // list privileges with null group and roles + Map authPrivMap = client + .listPrivilegsbyAuthorizable(user1, authorizableSet, null, null); + assertEquals(expectedResults, authPrivMap); + + // list privileges with empty group set and null roles + authPrivMap = client.listPrivilegsbyAuthorizable(user1, authorizableSet, + new HashSet(), null); + assertEquals(expectedResults, authPrivMap); + + // list privileges with null group set and ALL roleset + authPrivMap = client.listPrivilegsbyAuthorizable(user1, authorizableSet, + null, new ActiveRoleSet(true)); + assertEquals(expectedResults, authPrivMap); + + // list privileges with user1's group set and null roles + authPrivMap = client.listPrivilegsbyAuthorizable(user1, authorizableSet, + userGroupNames1, null); + assertEquals(expectedResults, authPrivMap); + + // list privileges with user1's group set and ALL roles + authPrivMap = client.listPrivilegsbyAuthorizable(user1, authorizableSet, + userGroupNames1, new ActiveRoleSet(true)); + assertEquals(expectedResults, authPrivMap); + + // list privileges with null group and user's specific roles with uppercase name + authPrivMap = client.listPrivilegsbyAuthorizable(user1, authorizableSet, + null, new ActiveRoleSet(Sets.newHashSet(roleName1.toUpperCase()))); + assertEquals(expectedResults, authPrivMap); + + // verify that user1 can't query group2 + try { + client.listPrivilegsbyAuthorizable(user1, authorizableSet, userGroupNames2, null); + fail("listPrivilegsbyAuthorizable() should fail for user1 accessing " + group2); + } catch (SentryAccessDeniedException e) { + // expected + } + + // verify that user1 can't query role2 + ActiveRoleSet roleSet2 = new ActiveRoleSet(Sets.newHashSet(roleName2)); + try { + client.listPrivilegsbyAuthorizable(user1, authorizableSet, null, roleSet2); + fail("listPrivilegsbyAuthorizable() should fail for user1 accessing " + roleName2); + } catch (SentryAccessDeniedException e) { + // expected + } + }}); + } + + /** + * Attempt to access a configuration value that is forbidden in getConfigVal + * @param configVal The banned value + * @param defaultVal A default to pass to getConfigValue + * @throws Exception + */ + private void checkBannedConfigVal(final String configVal, final String defaultVal) + throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + try { + client.getConfigValue(configVal, defaultVal); + fail("Attempt to access " + configVal + " succeeded"); + } catch (SentryAccessDeniedException e) { + assertTrue(e.toString().contains("was denied")); + assertTrue(e.toString().contains(configVal)); + } + }}); + } + + @Test + public void testGetConfigVal() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + + String val; + + // Basic success case + val = client.getConfigValue("sentry.service.admin.group", "xxx"); + assertEquals(val, "admin_group"); + + // Undefined value gets the default back + val = client.getConfigValue("sentry.this.is.not.defined", "hello"); + assertEquals(val, "hello"); + + // Undefined value and null default gets null back + val = client.getConfigValue("sentry.this.is.not.defined", null); + assertEquals(val, null); + + // Known config value with null default works as expected + val = client.getConfigValue("sentry.service.admin.group", null); + assertEquals(val, "admin_group"); + + // Value that is forbidden (anything not starting with "sentry") dies + checkBannedConfigVal("notsentry", "xxx"); + + // Ditto with a null default + checkBannedConfigVal("notsentry", null); + + // Values with .jdbc. are forbidden + checkBannedConfigVal("sentry.xxx.jdbc.xxx", null); + + // Values with password are forbidden + checkBannedConfigVal("sentry.xxx.password", null); + + // Attempt to get the location of the keytab also fails + checkBannedConfigVal("sentry.service.server.keytab", null); + + }}); + } + + /* SENTRY-841 */ + @Test + public void testGranRevokePrivilegeOnServerForRole() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + + String roleName1 = "admin_r1"; + + client.dropRoleIfExists(requestorUserName, roleName1); + client.createRole(requestorUserName, roleName1); + + client.grantServerPrivilege(requestorUserName, roleName1, "server", false); + + Set listPrivs = client.listAllPrivilegesByRoleName(requestorUserName, roleName1); + assertTrue("Privilege should be all:",listPrivs.iterator().next().getAction().equals("*")); + + client.revokeServerPrivilege(requestorUserName, roleName1, "server", false); + listPrivs = client.listAllPrivilegesByRoleName(requestorUserName, roleName1); + assertTrue("Privilege not correctly revoked !!", listPrivs.size() == 0); + + }}); + } + + @Test + public void testGranRevokePrivilegeWithoutAction() throws Exception { + runTestAsSubject(new TestOperation(){ + @Override + public void runTestAsSubject() throws Exception { + String requestorUserName = ADMIN_USER; + String roleName1 = "admin_r1"; + Set requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP); + setLocalGroupMapping(requestorUserName, requestorUserGroupNames); + writePolicyFile(); + + client.dropRoleIfExists(requestorUserName, roleName1); + client.createRole(requestorUserName, roleName1); + client.grantServerPrivilege(requestorUserName, roleName1, "server1", false); + + Set listPrivs = client.listAllPrivilegesByRoleName(requestorUserName, roleName1); + assertTrue("Privilege should be all:", listPrivs.iterator().next().getAction().equals("*")); + + client.revokeServerPrivilege(requestorUserName, roleName1, "server1", "ALL", false); + listPrivs = client.listAllPrivilegesByRoleName(requestorUserName, roleName1); + assertTrue("Privilege not correctly revoked !!", listPrivs.size() == 0); + + }}); + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceMetrics.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceMetrics.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceMetrics.java new file mode 100644 index 0000000..55c8c82 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceMetrics.java @@ -0,0 +1,86 @@ +/** + * 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 createRequired 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 org.apache.commons.io.IOUtils; +import org.apache.hadoop.security.authentication.client.AuthenticatedURL; +import org.apache.hadoop.security.authentication.client.KerberosAuthenticator; +import org.apache.sentry.service.thrift.SentryServiceIntegrationBase; +import org.apache.sentry.service.thrift.SentryWebMetricParser; +import org.junit.Assert; +import org.junit.Before; +import org.junit.After; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.security.PrivilegedExceptionAction; + +public class TestSentryServiceMetrics extends SentryServiceIntegrationBase { + + @BeforeClass + public static void setup() throws Exception { + kerberos = true; + webServerEnabled = true; + webSecurity = true; + setupConf(); + startSentryService(); + } + + //Overriding this method as the tests do not require a client handle + @Override + @Before + public void before() throws Exception { + + } + /* SENTRY-1319 */ + @Test + public void testSentryServiceGauges() throws Throwable { + //More Cases to be added once Sentry HA is implemented + + //Check for gauges with the server handle. + Assert.assertEquals(Boolean.TRUE,server.getIsActiveGauge().getValue()); + } + + @Test + public void testMetricsWeb() throws Exception { + clientUgi.doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + final URL url = new URL("http://"+ SERVER_HOST + ":" + webServerPort + "/metrics"); + HttpURLConnection conn = new AuthenticatedURL(new KerberosAuthenticator()). + openConnection(url, new AuthenticatedURL.Token()); + //make sure we are able to access the metrics page + Assert.assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); + String response = IOUtils.toString(conn.getInputStream()); + SentryWebMetricParser mp = new SentryWebMetricParser(response); + Assert.assertEquals(Boolean.FALSE,mp.isHA()); + Assert.assertEquals(Boolean.TRUE,mp.isActive()); + return null; + }} ); + } + + //Overriding this method as the client handle does not exist. + @Override + @After + public void after() { + + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceWithInvalidMsgSize.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceWithInvalidMsgSize.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceWithInvalidMsgSize.java new file mode 100644 index 0000000..8ac6308 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceWithInvalidMsgSize.java @@ -0,0 +1,122 @@ +/** + * 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 com.google.common.collect.Sets; +import org.apache.hadoop.conf.Configuration; +import org.apache.sentry.api.common.ApiConstants; +import org.apache.sentry.core.common.exception.SentryUserException; +import org.apache.sentry.service.thrift.SentryServiceClientFactory; +import org.apache.sentry.service.thrift.SentryServiceFactory; +import org.apache.sentry.service.thrift.SentryServiceIntegrationBase; +import org.apache.sentry.service.common.ServiceConstants; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Set; + +/** + * Test sentry service with a larger message size than the server's or client's thrift max message size. + */ +public class TestSentryServiceWithInvalidMsgSize extends SentryServiceIntegrationBase { + private final Set REQUESTER_USER_GROUP_NAMES = Sets.newHashSet(ADMIN_GROUP); + private final String ROLE_NAME = "admin_r"; + + /** + * Test the case when the message size is larger than the client's thrift max message size. + */ + @Test + public void testClientWithSmallMaxMsgSize() throws Exception { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + SentryServiceClientFactory oldFactory = SentryServiceClientFactory.factoryReset(null); + Configuration confWithSmallMaxMsgSize = new Configuration(conf); + confWithSmallMaxMsgSize.setLong(ApiConstants.ClientConfig.SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE, 20); + // create a client with a small thrift max message size + SentryPolicyServiceClient clientWithSmallMaxMsgSize = SentryServiceClientFactory.create(confWithSmallMaxMsgSize); + + setLocalGroupMapping(ADMIN_USER, REQUESTER_USER_GROUP_NAMES); + writePolicyFile(); + + boolean exceptionThrown = false; + try { + // client throws exception when message size is larger than the client's thrift max message size. + clientWithSmallMaxMsgSize.listAllRoles(ADMIN_USER); + } catch (SentryUserException e) { + exceptionThrown = true; + Assert.assertTrue(e.getMessage().contains("Thrift exception occurred")); + Assert.assertTrue(e.getCause().getMessage().contains("Length exceeded max allowed")); + } finally { + Assert.assertEquals(true, exceptionThrown); + clientWithSmallMaxMsgSize.close(); + SentryServiceClientFactory.factoryReset(oldFactory); + } + + // client can still talk with sentry server when message size is smaller. + client.dropRoleIfExists(ADMIN_USER, ROLE_NAME); + client.listAllRoles(ADMIN_USER); + client.createRole(ADMIN_USER, ROLE_NAME); + client.listAllRoles(ADMIN_USER); + } + }); + } + + /** + * Test the case when the message size is larger than the server's thrift max message size. + */ + @Test + public void testServerWithSmallMaxMsgSize() throws Exception { + runTestAsSubject(new TestOperation() { + @Override + public void runTestAsSubject() throws Exception { + Configuration confWithSmallMaxMsgSize = new Configuration(conf); + confWithSmallMaxMsgSize.setLong(ServiceConstants.ServerConfig.SENTRY_POLICY_SERVER_THRIFT_MAX_MESSAGE_SIZE, + 50); + stopSentryService(); + + // create a server with a small max thrift message size + server = SentryServiceFactory.create(confWithSmallMaxMsgSize); + startSentryService(); + + setLocalGroupMapping(ADMIN_USER, REQUESTER_USER_GROUP_NAMES); + writePolicyFile(); + + // client can talk with server when message size is smaller. + client.listAllRoles(ADMIN_USER); + client.createRole(ADMIN_USER, ROLE_NAME); + + boolean exceptionThrown = false; + try { + // client throws exception when message size is larger than the server's thrift max message size. + client.grantServerPrivilege(ADMIN_USER, ROLE_NAME, "server", false); + } catch (SentryUserException e) { + exceptionThrown = true; + Assert.assertTrue(e.getCause().getMessage().contains("org.apache.thrift.transport.TTransportException")); + } finally { + Assert.assertEquals(true, exceptionThrown); + } + + // client can still talk with sentry server when message size is smaller. + Set roles = client.listAllRoles(ADMIN_USER); + Assert.assertTrue(roles.size() == 1); + Assert.assertEquals(ROLE_NAME, roles.iterator().next().getRoleName()); + } + }); + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceWithKerberos.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceWithKerberos.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceWithKerberos.java new file mode 100644 index 0000000..eff051b --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceWithKerberos.java @@ -0,0 +1,58 @@ +/** + * 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 org.apache.sentry.service.thrift.SentryServiceIntegrationBase; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test various kerberos related stuff on the SentryService side + */ +public class TestSentryServiceWithKerberos extends SentryServiceIntegrationBase { + + @BeforeClass + public static void setup() throws Exception { + SERVER_KERBEROS_NAME = "sentry/_HOST@" + REALM; + SentryServiceIntegrationBase.setup(); + } + + @Override + @Before + public void before() throws Exception { + } + + @Override + @After + public void after() { + } + + /** + * Test that we are correctly substituting "_HOST" if/when needed. + * + * @throws Exception + */ + @Test + public void testHostSubstitution() throws Exception { + // We just need to ensure that we are able to correct connect to the server + connectToSentryService(); + } + +} http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryWebServerWithKerberos.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryWebServerWithKerberos.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryWebServerWithKerberos.java new file mode 100644 index 0000000..3cc9a9d --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryWebServerWithKerberos.java @@ -0,0 +1,175 @@ +/** + * 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 static org.junit.Assert.fail; + +import java.io.File; +import java.net.HttpURLConnection; +import java.net.URL; +import java.security.PrivilegedExceptionAction; +import java.util.HashSet; + +import javax.security.auth.Subject; +import javax.security.auth.kerberos.KerberosPrincipal; +import javax.security.auth.login.LoginContext; + +import org.apache.commons.io.IOUtils; +import org.apache.hadoop.security.authentication.client.AuthenticatedURL; +import org.apache.hadoop.security.authentication.client.AuthenticationException; +import org.apache.hadoop.security.authentication.client.KerberosAuthenticator; +import org.apache.sentry.service.thrift.KerberosConfiguration; +import org.apache.sentry.service.thrift.SentryServiceIntegrationBase; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Sets; + +public class TestSentryWebServerWithKerberos extends SentryServiceIntegrationBase { + + private static Logger LOG = LoggerFactory.getLogger(TestSentryWebServerWithKerberos.class); + + @BeforeClass + public static void setup() throws Exception { + webServerEnabled = true; + webSecurity = true; + SentryServiceIntegrationBase.setup(); + } + + @Override + @Before + public void before() throws Exception { + } + + @Override + @After + public void after() { + } + + @Test + public void testPing() throws Exception { + clientUgi.doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + final URL url = new URL("http://"+ SERVER_HOST + ":" + webServerPort + "/ping"); + HttpURLConnection conn = new AuthenticatedURL(new KerberosAuthenticator()). + openConnection(url, new AuthenticatedURL.Token()); + Assert.assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); + String response = IOUtils.toString(conn.getInputStream()); + Assert.assertEquals("pong\n", response); + return null; + }} ); + } + + @Test + public void testPingWithoutSubject() throws Exception { + final URL url = new URL("http://"+ SERVER_HOST + ":" + webServerPort + "/ping"); + try { + new AuthenticatedURL(new KerberosAuthenticator()).openConnection(url, new AuthenticatedURL.Token()); + fail("Here should fail."); + } catch (Exception e) { + boolean isExpectError = e.getMessage().contains("No valid credentials provided"); + Assert.assertTrue("Here should fail by 'No valid credentials provided'," + + " but the exception is:" + e, isExpectError); + } + } + + @Test + public void testPingUsingHttpURLConnection() throws Exception { + final URL url = new URL("http://"+ SERVER_HOST + ":" + webServerPort + "/ping"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + Assert.assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, conn.getResponseCode()); + String errorMessage = IOUtils.toString(conn.getErrorStream()); + Assert.assertTrue(errorMessage.contains("Authentication required")); + } + + @Test + public void testPingWithUnauthorizedUser() throws Exception { + // create an unauthorized User with Kerberos + String userPrinciple = "user/" + SERVER_HOST; + String userKerberosName = userPrinciple + "@" + REALM; + Subject userSubject = new Subject(false, Sets.newHashSet( + new KerberosPrincipal(userKerberosName)), new HashSet(),new HashSet()); + File userKeytab = new File(kdcWorkDir, "user.keytab"); + kdc.createPrincipal(userKeytab, userPrinciple); + LoginContext userLoginContext = new LoginContext("", userSubject, null, + KerberosConfiguration.createClientConfig(userKerberosName, userKeytab)); + userLoginContext.login(); + Subject.doAs(userLoginContext.getSubject(), new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + final URL url = new URL("http://"+ SERVER_HOST + ":" + webServerPort + "/ping"); + try { + new AuthenticatedURL(new KerberosAuthenticator()).openConnection(url, new AuthenticatedURL.Token()); + fail("Here should fail."); + } catch (AuthenticationException e) { + String expectedError = "status code: 403"; + if (!e.getMessage().contains(expectedError)) { + LOG.error("UnexpectedError: " + e.getMessage(), e); + fail("UnexpectedError: " + e.getMessage()); + } + } + return null; + } + }); + } + + @Test + public void testPingWithCaseSensitiveUser() throws Exception { + // USER1 is present in the list of users who are allowed to connect to sentry web ui. + String userPrinciple = "user1/" + SERVER_HOST; + String userKerberosName = userPrinciple + "@" + REALM; + Subject userSubject = new Subject(false, Sets.newHashSet( + new KerberosPrincipal(userKerberosName)), new HashSet(),new HashSet()); + File userKeytab = new File(kdcWorkDir, "user1.keytab"); + kdc.createPrincipal(userKeytab, userPrinciple); + LoginContext userLoginContext = new LoginContext("", userSubject, null, + KerberosConfiguration.createClientConfig(userKerberosName, userKeytab)); + userLoginContext.login(); + Subject.doAs(userLoginContext.getSubject(), new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + final URL url = new URL("http://"+ SERVER_HOST + ":" + webServerPort + "/ping"); + try { + new AuthenticatedURL(new KerberosAuthenticator()).openConnection(url, new AuthenticatedURL.Token()); + fail("Login with user1 should fail"); + } catch (AuthenticationException e) { + String expectedError = "status code: 403"; + if (!e.getMessage().contains(expectedError)) { + LOG.error("UnexpectedError: " + e.getMessage(), e); + fail("UnexpectedError: " + e.getMessage()); + } + } + return null; + } + }); + } + + @Test + public void testTraceIsDisabled() throws Exception { + final URL url = new URL("http://"+ SERVER_HOST + ":" + webServerPort); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("TRACE"); + Assert.assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode()); + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryWebServerWithSSL.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryWebServerWithSSL.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryWebServerWithSSL.java new file mode 100644 index 0000000..b4e1b85 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryWebServerWithSSL.java @@ -0,0 +1,64 @@ +/** + * 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 com.google.common.io.Resources; +import java.net.HttpURLConnection; +import org.apache.commons.io.IOUtils; +import org.apache.sentry.service.thrift.SentryServiceIntegrationBase; +import org.junit.*; + +import javax.net.ssl.HttpsURLConnection; +import java.net.URL; +import java.util.Properties; + +/** + * Test sentry web server when ssl is enabled. + */ +public class TestSentryWebServerWithSSL extends SentryServiceIntegrationBase { + @BeforeClass + public static void setup() throws Exception { + webServerEnabled = true; + webSecurity = false; + useSSL = true; + SentryServiceIntegrationBase.setup(); + } + + @Test + public void testPing() throws Exception { + final URL url = new URL("https://"+ SERVER_HOST + ":" + webServerPort + "/ping"); + Properties systemProps = System.getProperties(); + systemProps.put( "javax.net.ssl.trustStore", Resources.getResource("cacerts.jks").getPath()); + System.setProperties(systemProps); + HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); + Assert.assertEquals(HttpsURLConnection.HTTP_OK, conn.getResponseCode()); + String response = IOUtils.toString(conn.getInputStream()); + Assert.assertEquals("pong\n", response); + } + + @Test + public void testTraceIsDisabled() throws Exception { + final URL url = new URL("https://"+ SERVER_HOST + ":" + webServerPort); + Properties systemProps = System.getProperties(); + systemProps.put( "javax.net.ssl.trustStore", Resources.getResource("cacerts.jks").getPath()); + System.setProperties(systemProps); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("TRACE"); + Assert.assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode()); + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryWebServerWithoutSecurity.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryWebServerWithoutSecurity.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryWebServerWithoutSecurity.java new file mode 100644 index 0000000..6e741e8 --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/api/service/thrift/TestSentryWebServerWithoutSecurity.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.sentry.api.service.thrift; + +import java.net.HttpURLConnection; +import java.net.URL; + +import org.apache.commons.io.IOUtils; +import org.apache.sentry.service.thrift.SentryServiceIntegrationBase; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class TestSentryWebServerWithoutSecurity extends SentryServiceIntegrationBase { + + @BeforeClass + public static void setup() throws Exception { + webServerEnabled = true; + webSecurity = false; + SentryServiceIntegrationBase.setup(); + } + + @Override + @Before + public void before() throws Exception { + } + + @Override + @After + public void after() { + } + + @Test + public void testPing() throws Exception { + final URL url = new URL("http://"+ SERVER_HOST + ":" + webServerPort + "/ping"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + Assert.assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); + String response = IOUtils.toString(conn.getInputStream()); + Assert.assertEquals("pong\n", response); + } + + @Test + public void testConf() throws Exception { + // test bad format + final URL url = new URL("http://" + SERVER_HOST + ":" + webServerPort + "/conf?" + + ConfServlet.FORMAT_PARAM + "=badformat"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + Assert.assertEquals(HttpURLConnection.HTTP_BAD_REQUEST, conn.getResponseCode()); + + // test json format + final URL url1 = new URL("http://" + SERVER_HOST + ":" + webServerPort + "/conf?" + + ConfServlet.FORMAT_PARAM +"=" + ConfServlet.FORMAT_JSON); + conn = (HttpURLConnection) url1.openConnection(); + Assert.assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); + + // test xml format + final URL url2 = new URL("http://" + SERVER_HOST + ":" + webServerPort + "/conf?" + + ConfServlet.FORMAT_PARAM +"=" + ConfServlet.FORMAT_XML); + conn = (HttpURLConnection) url2.openConnection(); + Assert.assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); + String xmlResponse = IOUtils.toString(conn.getInputStream()); + + // test default is xml format + final URL url3 = new URL("http://" + SERVER_HOST + ":" + webServerPort + "/conf"); + conn = (HttpURLConnection) url3.openConnection(); + Assert.assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); + String defaultResponse = IOUtils.toString(conn.getInputStream()); + Assert.assertEquals(xmlResponse, defaultResponse); + } + + @Test + public void testTraceIsDisabled() throws Exception { + final URL url = new URL("http://"+ SERVER_HOST + ":" + webServerPort); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("TRACE"); + Assert.assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode()); + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/SentryStoreIntegrationBase.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/SentryStoreIntegrationBase.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/SentryStoreIntegrationBase.java new file mode 100644 index 0000000..3fe5b6a --- /dev/null +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/SentryStoreIntegrationBase.java @@ -0,0 +1,91 @@ +/** + * 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.provider.db.generic.service.persistent; + +import java.io.File; + +import org.apache.commons.io.FileUtils; +import org.apache.hadoop.conf.Configuration; +import org.apache.sentry.provider.file.PolicyFile; +import org.apache.sentry.service.common.ServiceConstants.ServerConfig; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; + +import com.google.common.io.Files; + +public abstract class SentryStoreIntegrationBase { + protected final static String[] adminGroups = { "adminGroup" }; + private static File dataDir; + private static File policyFilePath; + protected static Configuration conf; + protected static DelegateSentryStore sentryStore; + protected static PolicyFile policyFile; + + @BeforeClass + public static void setup() throws Exception { + conf = new Configuration(false); + setup(conf); + sentryStore = new DelegateSentryStore(conf); + } + + private static void setup(Configuration conf) throws Exception { + dataDir = new File(Files.createTempDir(), "sentry_policy_db"); + conf.set(ServerConfig.SENTRY_VERIFY_SCHEM_VERSION, "false"); + conf.set(ServerConfig.SENTRY_STORE_JDBC_URL, + "jdbc:derby:;databaseName=" + dataDir.getPath() + ";create=true"); + conf.set(ServerConfig.SENTRY_STORE_JDBC_PASS, "dummy"); + conf.setStrings(ServerConfig.ADMIN_GROUPS, adminGroups); + conf.set(ServerConfig.SENTRY_STORE_GROUP_MAPPING, + ServerConfig.SENTRY_STORE_LOCAL_GROUP_MAPPING); + + policyFilePath = new File(Files.createTempDir(), "local_policy_file.ini"); + conf.set(ServerConfig.SENTRY_STORE_GROUP_MAPPING_RESOURCE, + policyFilePath.getPath()); + } + + @After + public void clearData() throws Exception{ + sentryStore.clearAllTables(); + } + + @AfterClass + public static void teardown() { + if (sentryStore != null) { + sentryStore.close(); + } + if (dataDir != null) { + FileUtils.deleteQuietly(dataDir); + } + if (policyFilePath != null) { + FileUtils.deleteQuietly(policyFilePath); + } + } + + public static void addGroupsToUser(String user, String... groupNames) { + policyFile.addGroupsToUser(user, groupNames); + } + + public static void writePolicyFile() throws Exception { + policyFile.write(policyFilePath); + } + + public String[] getAdminGroups() { + return adminGroups; + } +}